Butterbur: Tesselation support for filling closed paths
[sdk] / deps / libtess / mesh.h
diff --git a/deps/libtess/mesh.h b/deps/libtess/mesh.h
new file mode 100644 (file)
index 0000000..3eea9dd
--- /dev/null
@@ -0,0 +1,273 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+** 
+** http://oss.sgi.com/projects/FreeB
+** 
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+** 
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+** 
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+/*
+** Author: Eric Veach, July 1994.
+**
+** $Date: 2001/03/17 00:25:41 $ $Revision: 1.1 $
+** $Header: /home/krh/git/sync/mesa-cvs-repo/Mesa/src/glu/sgi/libtess/mesh.h,v 1.1 2001/03/17 00:25:41 brianp Exp $
+*/
+
+#ifndef __mesh_h_
+#define __mesh_h_
+
+#include "glutess.h"
+
+typedef struct GLUmesh GLUmesh; 
+
+typedef struct GLUvertex GLUvertex;
+typedef struct GLUface GLUface;
+typedef struct GLUhalfEdge GLUhalfEdge;
+
+typedef struct ActiveRegion ActiveRegion;      /* Internal data */
+
+/* The mesh structure is similar in spirit, notation, and operations
+ * to the "quad-edge" structure (see L. Guibas and J. Stolfi, Primitives
+ * for the manipulation of general subdivisions and the computation of
+ * Voronoi diagrams, ACM Transactions on Graphics, 4(2):74-123, April 1985).
+ * For a simplified description, see the course notes for CS348a,
+ * "Mathematical Foundations of Computer Graphics", available at the
+ * Stanford bookstore (and taught during the fall quarter).
+ * The implementation also borrows a tiny subset of the graph-based approach
+ * use in Mantyla's Geometric Work Bench (see M. Mantyla, An Introduction
+ * to Sold Modeling, Computer Science Press, Rockville, Maryland, 1988).
+ *
+ * The fundamental data structure is the "half-edge".  Two half-edges
+ * go together to make an edge, but they point in opposite directions.
+ * Each half-edge has a pointer to its mate (the "symmetric" half-edge Sym),
+ * its origin vertex (Org), the face on its left side (Lface), and the
+ * adjacent half-edges in the CCW direction around the origin vertex
+ * (Onext) and around the left face (Lnext).  There is also a "next"
+ * pointer for the global edge list (see below).
+ *
+ * The notation used for mesh navigation:
+ *     Sym   = the mate of a half-edge (same edge, but opposite direction)
+ *     Onext = edge CCW around origin vertex (keep same origin)
+ *     Dnext = edge CCW around destination vertex (keep same dest)
+ *     Lnext = edge CCW around left face (dest becomes new origin)
+ *     Rnext = edge CCW around right face (origin becomes new dest)
+ *
+ * "prev" means to substitute CW for CCW in the definitions above.
+ *
+ * The mesh keeps global lists of all vertices, faces, and edges,
+ * stored as doubly-linked circular lists with a dummy header node.
+ * The mesh stores pointers to these dummy headers (vHead, fHead, eHead).
+ *
+ * The circular edge list is special; since half-edges always occur
+ * in pairs (e and e->Sym), each half-edge stores a pointer in only
+ * one direction.  Starting at eHead and following the e->next pointers
+ * will visit each *edge* once (ie. e or e->Sym, but not both).
+ * e->Sym stores a pointer in the opposite direction, thus it is
+ * always true that e->Sym->next->Sym->next == e.
+ *
+ * Each vertex has a pointer to next and previous vertices in the
+ * circular list, and a pointer to a half-edge with this vertex as
+ * the origin (NULL if this is the dummy header).  There is also a
+ * field "data" for client data.
+ *
+ * Each face has a pointer to the next and previous faces in the
+ * circular list, and a pointer to a half-edge with this face as
+ * the left face (NULL if this is the dummy header).  There is also
+ * a field "data" for client data.
+ *
+ * Note that what we call a "face" is really a loop; faces may consist
+ * of more than one loop (ie. not simply connected), but there is no
+ * record of this in the data structure.  The mesh may consist of
+ * several disconnected regions, so it may not be possible to visit
+ * the entire mesh by starting at a half-edge and traversing the edge
+ * structure.
+ *
+ * The mesh does NOT support isolated vertices; a vertex is deleted along
+ * with its last edge.  Similarly when two faces are merged, one of the
+ * faces is deleted (see __gl_meshDelete below).  For mesh operations,
+ * all face (loop) and vertex pointers must not be NULL.  However, once
+ * mesh manipulation is finished, __gl_MeshZapFace can be used to delete
+ * faces of the mesh, one at a time.  All external faces can be "zapped"
+ * before the mesh is returned to the client; then a NULL face indicates
+ * a region which is not part of the output polygon.
+ */
+
+struct GLUvertex {
+  GLUvertex    *next;          /* next vertex (never NULL) */
+  GLUvertex    *prev;          /* previous vertex (never NULL) */
+  GLUhalfEdge  *anEdge;        /* a half-edge with this origin */
+  void         *data;          /* client's data */
+
+  /* Internal data (keep hidden) */
+  GLdouble     coords[3];      /* vertex location in 3D */
+  GLdouble     s, t;           /* projection onto the sweep plane */
+  long         pqHandle;       /* to allow deletion from priority queue */
+};
+
+struct GLUface {
+  GLUface      *next;          /* next face (never NULL) */
+  GLUface      *prev;          /* previous face (never NULL) */
+  GLUhalfEdge  *anEdge;        /* a half edge with this left face */
+  void         *data;          /* room for client's data */
+
+  /* Internal data (keep hidden) */
+  GLUface      *trail;         /* "stack" for conversion to strips */
+  GLboolean    marked;         /* flag for conversion to strips */
+  GLboolean    inside;         /* this face is in the polygon interior */
+};
+
+struct GLUhalfEdge {
+  GLUhalfEdge  *next;          /* doubly-linked list (prev==Sym->next) */
+  GLUhalfEdge  *Sym;           /* same edge, opposite direction */
+  GLUhalfEdge  *Onext;         /* next edge CCW around origin */
+  GLUhalfEdge  *Lnext;         /* next edge CCW around left face */
+  GLUvertex    *Org;           /* origin vertex (Overtex too long) */
+  GLUface      *Lface;         /* left face */
+
+  /* Internal data (keep hidden) */
+  ActiveRegion *activeRegion;  /* a region with this upper edge (sweep.c) */
+  int          winding;        /* change in winding number when crossing
+                                   from the right face to the left face */
+};
+
+#define        Rface   Sym->Lface
+#define Dst    Sym->Org
+
+#define Oprev  Sym->Lnext
+#define Lprev   Onext->Sym
+#define Dprev  Lnext->Sym
+#define Rprev  Sym->Onext
+#define Dnext  Rprev->Sym      /* 3 pointers */
+#define Rnext  Oprev->Sym      /* 3 pointers */
+
+
+struct GLUmesh {
+  GLUvertex    vHead;          /* dummy header for vertex list */
+  GLUface      fHead;          /* dummy header for face list */
+  GLUhalfEdge  eHead;          /* dummy header for edge list */
+  GLUhalfEdge  eHeadSym;       /* and its symmetric counterpart */
+};
+
+/* The mesh operations below have three motivations: completeness,
+ * convenience, and efficiency.  The basic mesh operations are MakeEdge,
+ * Splice, and Delete.  All the other edge operations can be implemented
+ * in terms of these.  The other operations are provided for convenience
+ * and/or efficiency.
+ *
+ * When a face is split or a vertex is added, they are inserted into the
+ * global list *before* the existing vertex or face (ie. e->Org or e->Lface).
+ * This makes it easier to process all vertices or faces in the global lists
+ * without worrying about processing the same data twice.  As a convenience,
+ * when a face is split, the "inside" flag is copied from the old face.
+ * Other internal data (v->data, v->activeRegion, f->data, f->marked,
+ * f->trail, e->winding) is set to zero.
+ *
+ * ********************** Basic Edge Operations **************************
+ *
+ * __gl_meshMakeEdge( mesh ) creates one edge, two vertices, and a loop.
+ * The loop (face) consists of the two new half-edges.
+ *
+ * __gl_meshSplice( eOrg, eDst ) is the basic operation for changing the
+ * mesh connectivity and topology.  It changes the mesh so that
+ *     eOrg->Onext <- OLD( eDst->Onext )
+ *     eDst->Onext <- OLD( eOrg->Onext )
+ * where OLD(...) means the value before the meshSplice operation.
+ *
+ * This can have two effects on the vertex structure:
+ *  - if eOrg->Org != eDst->Org, the two vertices are merged together
+ *  - if eOrg->Org == eDst->Org, the origin is split into two vertices
+ * In both cases, eDst->Org is changed and eOrg->Org is untouched.
+ *
+ * Similarly (and independently) for the face structure,
+ *  - if eOrg->Lface == eDst->Lface, one loop is split into two
+ *  - if eOrg->Lface != eDst->Lface, two distinct loops are joined into one
+ * In both cases, eDst->Lface is changed and eOrg->Lface is unaffected.
+ *
+ * __gl_meshDelete( eDel ) removes the edge eDel.  There are several cases:
+ * if (eDel->Lface != eDel->Rface), we join two loops into one; the loop
+ * eDel->Lface is deleted.  Otherwise, we are splitting one loop into two;
+ * the newly created loop will contain eDel->Dst.  If the deletion of eDel
+ * would create isolated vertices, those are deleted as well.
+ *
+ * ********************** Other Edge Operations **************************
+ *
+ * __gl_meshAddEdgeVertex( eOrg ) creates a new edge eNew such that
+ * eNew == eOrg->Lnext, and eNew->Dst is a newly created vertex.
+ * eOrg and eNew will have the same left face.
+ *
+ * __gl_meshSplitEdge( eOrg ) splits eOrg into two edges eOrg and eNew,
+ * such that eNew == eOrg->Lnext.  The new vertex is eOrg->Dst == eNew->Org.
+ * eOrg and eNew will have the same left face.
+ *
+ * __gl_meshConnect( eOrg, eDst ) creates a new edge from eOrg->Dst
+ * to eDst->Org, and returns the corresponding half-edge eNew.
+ * If eOrg->Lface == eDst->Lface, this splits one loop into two,
+ * and the newly created loop is eNew->Lface.  Otherwise, two disjoint
+ * loops are merged into one, and the loop eDst->Lface is destroyed.
+ *
+ * ************************ Other Operations *****************************
+ *
+ * __gl_meshNewMesh() creates a new mesh with no edges, no vertices,
+ * and no loops (what we usually call a "face").
+ *
+ * __gl_meshUnion( mesh1, mesh2 ) forms the union of all structures in
+ * both meshes, and returns the new mesh (the old meshes are destroyed).
+ *
+ * __gl_meshDeleteMesh( mesh ) will free all storage for any valid mesh.
+ *
+ * __gl_meshZapFace( fZap ) destroys a face and removes it from the
+ * global face list.  All edges of fZap will have a NULL pointer as their
+ * left face.  Any edges which also have a NULL pointer as their right face
+ * are deleted entirely (along with any isolated vertices this produces).
+ * An entire mesh can be deleted by zapping its faces, one at a time,
+ * in any order.  Zapped faces cannot be used in further mesh operations!
+ *
+ * __gl_meshCheckMesh( mesh ) checks a mesh for self-consistency.
+ */
+
+GLUhalfEdge    *__gl_meshMakeEdge( GLUmesh *mesh );
+int            __gl_meshSplice( GLUhalfEdge *eOrg, GLUhalfEdge *eDst );
+int            __gl_meshDelete( GLUhalfEdge *eDel );
+
+GLUhalfEdge    *__gl_meshAddEdgeVertex( GLUhalfEdge *eOrg );
+GLUhalfEdge    *__gl_meshSplitEdge( GLUhalfEdge *eOrg );
+GLUhalfEdge    *__gl_meshConnect( GLUhalfEdge *eOrg, GLUhalfEdge *eDst );
+
+GLUmesh                *__gl_meshNewMesh( void );
+GLUmesh                *__gl_meshUnion( GLUmesh *mesh1, GLUmesh *mesh2 );
+void           __gl_meshDeleteMesh( GLUmesh *mesh );
+void           __gl_meshZapFace( GLUface *fZap );
+
+#ifdef NDEBUG
+#define                __gl_meshCheckMesh( mesh )
+#else
+void           __gl_meshCheckMesh( GLUmesh *mesh );
+#endif
+
+#endif