mesh.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. /*
  2. * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
  3. * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a
  6. * copy of this software and associated documentation files (the "Software"),
  7. * to deal in the Software without restriction, including without limitation
  8. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9. * and/or sell copies of the Software, and to permit persons to whom the
  10. * Software is furnished to do so, subject to the following conditions:
  11. *
  12. * The above copyright notice including the dates of first publication and
  13. * either this permission notice or a reference to
  14. * http://oss.sgi.com/projects/FreeB/
  15. * shall be included in all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  18. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  20. * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  21. * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
  22. * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  23. * SOFTWARE.
  24. *
  25. * Except as contained in this notice, the name of Silicon Graphics, Inc.
  26. * shall not be used in advertising or otherwise to promote the sale, use or
  27. * other dealings in this Software without prior written authorization from
  28. * Silicon Graphics, Inc.
  29. */
  30. /*
  31. ** Author: Eric Veach, July 1994.
  32. **
  33. */
  34. #ifndef __mesh_h_
  35. #define __mesh_h_
  36. // JDC #include <GL/glu.h>
  37. typedef struct GLUmesh GLUmesh;
  38. typedef struct GLUvertex GLUvertex;
  39. typedef struct GLUface GLUface;
  40. typedef struct GLUhalfEdge GLUhalfEdge;
  41. typedef struct ActiveRegion ActiveRegion; /* Internal data */
  42. /* The mesh structure is similar in spirit, notation, and operations
  43. * to the "quad-edge" structure (see L. Guibas and J. Stolfi, Primitives
  44. * for the manipulation of general subdivisions and the computation of
  45. * Voronoi diagrams, ACM Transactions on Graphics, 4(2):74-123, April 1985).
  46. * For a simplified description, see the course notes for CS348a,
  47. * "Mathematical Foundations of Computer Graphics", available at the
  48. * Stanford bookstore (and taught during the fall quarter).
  49. * The implementation also borrows a tiny subset of the graph-based approach
  50. * use in Mantyla's Geometric Work Bench (see M. Mantyla, An Introduction
  51. * to Sold Modeling, Computer Science Press, Rockville, Maryland, 1988).
  52. *
  53. * The fundamental data structure is the "half-edge". Two half-edges
  54. * go together to make an edge, but they point in opposite directions.
  55. * Each half-edge has a pointer to its mate (the "symmetric" half-edge Sym),
  56. * its origin vertex (Org), the face on its left side (Lface), and the
  57. * adjacent half-edges in the CCW direction around the origin vertex
  58. * (Onext) and around the left face (Lnext). There is also a "next"
  59. * pointer for the global edge list (see below).
  60. *
  61. * The notation used for mesh navigation:
  62. * Sym = the mate of a half-edge (same edge, but opposite direction)
  63. * Onext = edge CCW around origin vertex (keep same origin)
  64. * Dnext = edge CCW around destination vertex (keep same dest)
  65. * Lnext = edge CCW around left face (dest becomes new origin)
  66. * Rnext = edge CCW around right face (origin becomes new dest)
  67. *
  68. * "prev" means to substitute CW for CCW in the definitions above.
  69. *
  70. * The mesh keeps global lists of all vertices, faces, and edges,
  71. * stored as doubly-linked circular lists with a dummy header node.
  72. * The mesh stores pointers to these dummy headers (vHead, fHead, eHead).
  73. *
  74. * The circular edge list is special; since half-edges always occur
  75. * in pairs (e and e->Sym), each half-edge stores a pointer in only
  76. * one direction. Starting at eHead and following the e->next pointers
  77. * will visit each *edge* once (ie. e or e->Sym, but not both).
  78. * e->Sym stores a pointer in the opposite direction, thus it is
  79. * always true that e->Sym->next->Sym->next == e.
  80. *
  81. * Each vertex has a pointer to next and previous vertices in the
  82. * circular list, and a pointer to a half-edge with this vertex as
  83. * the origin (NULL if this is the dummy header). There is also a
  84. * field "data" for client data.
  85. *
  86. * Each face has a pointer to the next and previous faces in the
  87. * circular list, and a pointer to a half-edge with this face as
  88. * the left face (NULL if this is the dummy header). There is also
  89. * a field "data" for client data.
  90. *
  91. * Note that what we call a "face" is really a loop; faces may consist
  92. * of more than one loop (ie. not simply connected), but there is no
  93. * record of this in the data structure. The mesh may consist of
  94. * several disconnected regions, so it may not be possible to visit
  95. * the entire mesh by starting at a half-edge and traversing the edge
  96. * structure.
  97. *
  98. * The mesh does NOT support isolated vertices; a vertex is deleted along
  99. * with its last edge. Similarly when two faces are merged, one of the
  100. * faces is deleted (see __gl_meshDelete below). For mesh operations,
  101. * all face (loop) and vertex pointers must not be NULL. However, once
  102. * mesh manipulation is finished, __gl_MeshZapFace can be used to delete
  103. * faces of the mesh, one at a time. All external faces can be "zapped"
  104. * before the mesh is returned to the client; then a NULL face indicates
  105. * a region which is not part of the output polygon.
  106. */
  107. struct GLUvertex {
  108. GLUvertex *next; /* next vertex (never NULL) */
  109. GLUvertex *prev; /* previous vertex (never NULL) */
  110. GLUhalfEdge *anEdge; /* a half-edge with this origin */
  111. void *data; /* client's data */
  112. /* Internal data (keep hidden) */
  113. GLdouble coords[3]; /* vertex location in 3D */
  114. GLdouble s, t; /* projection onto the sweep plane */
  115. long pqHandle; /* to allow deletion from priority queue */
  116. };
  117. struct GLUface {
  118. GLUface *next; /* next face (never NULL) */
  119. GLUface *prev; /* previous face (never NULL) */
  120. GLUhalfEdge *anEdge; /* a half edge with this left face */
  121. void *data; /* room for client's data */
  122. /* Internal data (keep hidden) */
  123. GLUface *trail; /* "stack" for conversion to strips */
  124. GLboolean marked; /* flag for conversion to strips */
  125. GLboolean inside; /* this face is in the polygon interior */
  126. };
  127. struct GLUhalfEdge {
  128. GLUhalfEdge *next; /* doubly-linked list (prev==Sym->next) */
  129. GLUhalfEdge *Sym; /* same edge, opposite direction */
  130. GLUhalfEdge *Onext; /* next edge CCW around origin */
  131. GLUhalfEdge *Lnext; /* next edge CCW around left face */
  132. GLUvertex *Org; /* origin vertex (Overtex too long) */
  133. GLUface *Lface; /* left face */
  134. /* Internal data (keep hidden) */
  135. ActiveRegion *activeRegion; /* a region with this upper edge (sweep.c) */
  136. int winding; /* change in winding number when crossing
  137. from the right face to the left face */
  138. };
  139. #define Rface Sym->Lface
  140. #define Dst Sym->Org
  141. #define Oprev Sym->Lnext
  142. #define Lprev Onext->Sym
  143. #define Dprev Lnext->Sym
  144. #define Rprev Sym->Onext
  145. #define Dnext Rprev->Sym /* 3 pointers */
  146. #define Rnext Oprev->Sym /* 3 pointers */
  147. struct GLUmesh {
  148. GLUvertex vHead; /* dummy header for vertex list */
  149. GLUface fHead; /* dummy header for face list */
  150. GLUhalfEdge eHead; /* dummy header for edge list */
  151. GLUhalfEdge eHeadSym; /* and its symmetric counterpart */
  152. };
  153. /* The mesh operations below have three motivations: completeness,
  154. * convenience, and efficiency. The basic mesh operations are MakeEdge,
  155. * Splice, and Delete. All the other edge operations can be implemented
  156. * in terms of these. The other operations are provided for convenience
  157. * and/or efficiency.
  158. *
  159. * When a face is split or a vertex is added, they are inserted into the
  160. * global list *before* the existing vertex or face (ie. e->Org or e->Lface).
  161. * This makes it easier to process all vertices or faces in the global lists
  162. * without worrying about processing the same data twice. As a convenience,
  163. * when a face is split, the "inside" flag is copied from the old face.
  164. * Other internal data (v->data, v->activeRegion, f->data, f->marked,
  165. * f->trail, e->winding) is set to zero.
  166. *
  167. * ********************** Basic Edge Operations **************************
  168. *
  169. * __gl_meshMakeEdge( mesh ) creates one edge, two vertices, and a loop.
  170. * The loop (face) consists of the two new half-edges.
  171. *
  172. * __gl_meshSplice( eOrg, eDst ) is the basic operation for changing the
  173. * mesh connectivity and topology. It changes the mesh so that
  174. * eOrg->Onext <- OLD( eDst->Onext )
  175. * eDst->Onext <- OLD( eOrg->Onext )
  176. * where OLD(...) means the value before the meshSplice operation.
  177. *
  178. * This can have two effects on the vertex structure:
  179. * - if eOrg->Org != eDst->Org, the two vertices are merged together
  180. * - if eOrg->Org == eDst->Org, the origin is split into two vertices
  181. * In both cases, eDst->Org is changed and eOrg->Org is untouched.
  182. *
  183. * Similarly (and independently) for the face structure,
  184. * - if eOrg->Lface == eDst->Lface, one loop is split into two
  185. * - if eOrg->Lface != eDst->Lface, two distinct loops are joined into one
  186. * In both cases, eDst->Lface is changed and eOrg->Lface is unaffected.
  187. *
  188. * __gl_meshDelete( eDel ) removes the edge eDel. There are several cases:
  189. * if (eDel->Lface != eDel->Rface), we join two loops into one; the loop
  190. * eDel->Lface is deleted. Otherwise, we are splitting one loop into two;
  191. * the newly created loop will contain eDel->Dst. If the deletion of eDel
  192. * would create isolated vertices, those are deleted as well.
  193. *
  194. * ********************** Other Edge Operations **************************
  195. *
  196. * __gl_meshAddEdgeVertex( eOrg ) creates a new edge eNew such that
  197. * eNew == eOrg->Lnext, and eNew->Dst is a newly created vertex.
  198. * eOrg and eNew will have the same left face.
  199. *
  200. * __gl_meshSplitEdge( eOrg ) splits eOrg into two edges eOrg and eNew,
  201. * such that eNew == eOrg->Lnext. The new vertex is eOrg->Dst == eNew->Org.
  202. * eOrg and eNew will have the same left face.
  203. *
  204. * __gl_meshConnect( eOrg, eDst ) creates a new edge from eOrg->Dst
  205. * to eDst->Org, and returns the corresponding half-edge eNew.
  206. * If eOrg->Lface == eDst->Lface, this splits one loop into two,
  207. * and the newly created loop is eNew->Lface. Otherwise, two disjoint
  208. * loops are merged into one, and the loop eDst->Lface is destroyed.
  209. *
  210. * ************************ Other Operations *****************************
  211. *
  212. * __gl_meshNewMesh() creates a new mesh with no edges, no vertices,
  213. * and no loops (what we usually call a "face").
  214. *
  215. * __gl_meshUnion( mesh1, mesh2 ) forms the union of all structures in
  216. * both meshes, and returns the new mesh (the old meshes are destroyed).
  217. *
  218. * __gl_meshDeleteMesh( mesh ) will free all storage for any valid mesh.
  219. *
  220. * __gl_meshZapFace( fZap ) destroys a face and removes it from the
  221. * global face list. All edges of fZap will have a NULL pointer as their
  222. * left face. Any edges which also have a NULL pointer as their right face
  223. * are deleted entirely (along with any isolated vertices this produces).
  224. * An entire mesh can be deleted by zapping its faces, one at a time,
  225. * in any order. Zapped faces cannot be used in further mesh operations!
  226. *
  227. * __gl_meshCheckMesh( mesh ) checks a mesh for self-consistency.
  228. */
  229. GLUhalfEdge *__gl_meshMakeEdge( GLUmesh *mesh );
  230. int __gl_meshSplice( GLUhalfEdge *eOrg, GLUhalfEdge *eDst );
  231. int __gl_meshDelete( GLUhalfEdge *eDel );
  232. GLUhalfEdge *__gl_meshAddEdgeVertex( GLUhalfEdge *eOrg );
  233. GLUhalfEdge *__gl_meshSplitEdge( GLUhalfEdge *eOrg );
  234. GLUhalfEdge *__gl_meshConnect( GLUhalfEdge *eOrg, GLUhalfEdge *eDst );
  235. GLUmesh *__gl_meshNewMesh( void );
  236. GLUmesh *__gl_meshUnion( GLUmesh *mesh1, GLUmesh *mesh2 );
  237. void __gl_meshDeleteMesh( GLUmesh *mesh );
  238. void __gl_meshZapFace( GLUface *fZap );
  239. #ifdef NDEBUG
  240. #define __gl_meshCheckMesh( mesh )
  241. #else
  242. void __gl_meshCheckMesh( GLUmesh *mesh );
  243. #endif
  244. #endif