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 35 #ifndef __mesh_h_ 36 #define __mesh_h_ 37 38 // #include <GL/glu.h> 39 #include <osg/GLU> 40 41 typedef struct GLUmesh GLUmesh; 42 43 typedef struct GLUvertex GLUvertex; 44 typedef struct GLUface GLUface; 45 typedef struct GLUhalfEdge GLUhalfEdge; 46 47 typedef struct ActiveRegion ActiveRegion; /* Internal data */ 48 49 /* The mesh structure is similar in spirit, notation, and operations 50 * to the "quad-edge" structure (see L. Guibas and J. Stolfi, Primitives 51 * for the manipulation of general subdivisions and the computation of 52 * Voronoi diagrams, ACM Transactions on Graphics, 4(2):74-123, April 1985). 53 * For a simplified description, see the course notes for CS348a, 54 * "Mathematical Foundations of Computer Graphics", available at the 55 * Stanford bookstore (and taught during the fall quarter). 56 * The implementation also borrows a tiny subset of the graph-based approach 57 * use in Mantyla's Geometric Work Bench (see M. Mantyla, An Introduction 58 * to Sold Modeling, Computer Science Press, Rockville, Maryland, 1988). 59 * 60 * The fundamental data structure is the "half-edge". Two half-edges 61 * go together to make an edge, but they point in opposite directions. 62 * Each half-edge has a pointer to its mate (the "symmetric" half-edge Sym), 63 * its origin vertex (Org), the face on its left side (Lface), and the 64 * adjacent half-edges in the CCW direction around the origin vertex 65 * (Onext) and around the left face (Lnext). There is also a "next" 66 * pointer for the global edge list (see below). 67 * 68 * The notation used for mesh navigation: 69 * Sym = the mate of a half-edge (same edge, but opposite direction) 70 * Onext = edge CCW around origin vertex (keep same origin) 71 * Dnext = edge CCW around destination vertex (keep same dest) 72 * Lnext = edge CCW around left face (dest becomes new origin) 73 * Rnext = edge CCW around right face (origin becomes new dest) 74 * 75 * "prev" means to substitute CW for CCW in the definitions above. 76 * 77 * The mesh keeps global lists of all vertices, faces, and edges, 78 * stored as doubly-linked circular lists with a dummy header node. 79 * The mesh stores pointers to these dummy headers (vHead, fHead, eHead). 80 * 81 * The circular edge list is special; since half-edges always occur 82 * in pairs (e and e->Sym), each half-edge stores a pointer in only 83 * one direction. Starting at eHead and following the e->next pointers 84 * will visit each *edge* once (ie. e or e->Sym, but not both). 85 * e->Sym stores a pointer in the opposite direction, thus it is 86 * always true that e->Sym->next->Sym->next == e. 87 * 88 * Each vertex has a pointer to next and previous vertices in the 89 * circular list, and a pointer to a half-edge with this vertex as 90 * the origin (NULL if this is the dummy header). There is also a 91 * field "data" for client data. 92 * 93 * Each face has a pointer to the next and previous faces in the 94 * circular list, and a pointer to a half-edge with this face as 95 * the left face (NULL if this is the dummy header). There is also 96 * a field "data" for client data. 97 * 98 * Note that what we call a "face" is really a loop; faces may consist 99 * of more than one loop (ie. not simply connected), but there is no 100 * record of this in the data structure. The mesh may consist of 101 * several disconnected regions, so it may not be possible to visit 102 * the entire mesh by starting at a half-edge and traversing the edge 103 * structure. 104 * 105 * The mesh does NOT support isolated vertices; a vertex is deleted along 106 * with its last edge. Similarly when two faces are merged, one of the 107 * faces is deleted (see __gl_meshDelete below). For mesh operations, 108 * all face (loop) and vertex pointers must not be NULL. However, once 109 * mesh manipulation is finished, __gl_MeshZapFace can be used to delete 110 * faces of the mesh, one at a time. All external faces can be "zapped" 111 * before the mesh is returned to the client; then a NULL face indicates 112 * a region which is not part of the output polygon. 113 */ 114 115 struct GLUvertex { 116 GLUvertex *next; /* next vertex (never NULL) */ 117 GLUvertex *prev; /* previous vertex (never NULL) */ 118 GLUhalfEdge *anEdge; /* a half-edge with this origin */ 119 void *data; /* client's data */ 120 121 /* Internal data (keep hidden) */ 122 GLdouble coords[3]; /* vertex location in 3D */ 123 GLdouble s, t; /* projection onto the sweep plane */ 124 long pqHandle; /* to allow deletion from priority queue */ 125 }; 126 127 struct GLUface { 128 GLUface *next; /* next face (never NULL) */ 129 GLUface *prev; /* previous face (never NULL) */ 130 GLUhalfEdge *anEdge; /* a half edge with this left face */ 131 void *data; /* room for client's data */ 132 133 /* Internal data (keep hidden) */ 134 GLUface *trail; /* "stack" for conversion to strips */ 135 GLboolean marked; /* flag for conversion to strips */ 136 GLboolean inside; /* this face is in the polygon interior */ 137 }; 138 139 struct GLUhalfEdge { 140 GLUhalfEdge *next; /* doubly-linked list (prev==Sym->next) */ 141 GLUhalfEdge *Sym; /* same edge, opposite direction */ 142 GLUhalfEdge *Onext; /* next edge CCW around origin */ 143 GLUhalfEdge *Lnext; /* next edge CCW around left face */ 144 GLUvertex *Org; /* origin vertex (Overtex too long) */ 145 GLUface *Lface; /* left face */ 146 147 /* Internal data (keep hidden) */ 148 ActiveRegion *activeRegion; /* a region with this upper edge (sweep.c) */ 149 int winding; /* change in winding number when crossing 150 from the right face to the left face */ 151 }; 152 153 #define Rface Sym->Lface 154 #define Dst Sym->Org 155 156 #define Oprev Sym->Lnext 157 #define Lprev Onext->Sym 158 #define Dprev Lnext->Sym 159 #define Rprev Sym->Onext 160 #define Dnext Rprev->Sym /* 3 pointers */ 161 #define Rnext Oprev->Sym /* 3 pointers */ 162 163 164 struct GLUmesh { 165 GLUvertex vHead; /* dummy header for vertex list */ 166 GLUface fHead; /* dummy header for face list */ 167 GLUhalfEdge eHead; /* dummy header for edge list */ 168 GLUhalfEdge eHeadSym; /* and its symmetric counterpart */ 169 }; 170 171 /* The mesh operations below have three motivations: completeness, 172 * convenience, and efficiency. The basic mesh operations are MakeEdge, 173 * Splice, and Delete. All the other edge operations can be implemented 174 * in terms of these. The other operations are provided for convenience 175 * and/or efficiency. 176 * 177 * When a face is split or a vertex is added, they are inserted into the 178 * global list *before* the existing vertex or face (ie. e->Org or e->Lface). 179 * This makes it easier to process all vertices or faces in the global lists 180 * without worrying about processing the same data twice. As a convenience, 181 * when a face is split, the "inside" flag is copied from the old face. 182 * Other internal data (v->data, v->activeRegion, f->data, f->marked, 183 * f->trail, e->winding) is set to zero. 184 * 185 * ********************** Basic Edge Operations ************************** 186 * 187 * __gl_meshMakeEdge( mesh ) creates one edge, two vertices, and a loop. 188 * The loop (face) consists of the two new half-edges. 189 * 190 * __gl_meshSplice( eOrg, eDst ) is the basic operation for changing the 191 * mesh connectivity and topology. It changes the mesh so that 192 * eOrg->Onext <- OLD( eDst->Onext ) 193 * eDst->Onext <- OLD( eOrg->Onext ) 194 * where OLD(...) means the value before the meshSplice operation. 195 * 196 * This can have two effects on the vertex structure: 197 * - if eOrg->Org != eDst->Org, the two vertices are merged together 198 * - if eOrg->Org == eDst->Org, the origin is split into two vertices 199 * In both cases, eDst->Org is changed and eOrg->Org is untouched. 200 * 201 * Similarly (and independently) for the face structure, 202 * - if eOrg->Lface == eDst->Lface, one loop is split into two 203 * - if eOrg->Lface != eDst->Lface, two distinct loops are joined into one 204 * In both cases, eDst->Lface is changed and eOrg->Lface is unaffected. 205 * 206 * __gl_meshDelete( eDel ) removes the edge eDel. There are several cases: 207 * if (eDel->Lface != eDel->Rface), we join two loops into one; the loop 208 * eDel->Lface is deleted. Otherwise, we are splitting one loop into two; 209 * the newly created loop will contain eDel->Dst. If the deletion of eDel 210 * would create isolated vertices, those are deleted as well. 211 * 212 * ********************** Other Edge Operations ************************** 213 * 214 * __gl_meshAddEdgeVertex( eOrg ) creates a new edge eNew such that 215 * eNew == eOrg->Lnext, and eNew->Dst is a newly created vertex. 216 * eOrg and eNew will have the same left face. 217 * 218 * __gl_meshSplitEdge( eOrg ) splits eOrg into two edges eOrg and eNew, 219 * such that eNew == eOrg->Lnext. The new vertex is eOrg->Dst == eNew->Org. 220 * eOrg and eNew will have the same left face. 221 * 222 * __gl_meshConnect( eOrg, eDst ) creates a new edge from eOrg->Dst 223 * to eDst->Org, and returns the corresponding half-edge eNew. 224 * If eOrg->Lface == eDst->Lface, this splits one loop into two, 225 * and the newly created loop is eNew->Lface. Otherwise, two disjoint 226 * loops are merged into one, and the loop eDst->Lface is destroyed. 227 * 228 * ************************ Other Operations ***************************** 229 * 230 * __gl_meshNewMesh() creates a new mesh with no edges, no vertices, 231 * and no loops (what we usually call a "face"). 232 * 233 * __gl_meshUnion( mesh1, mesh2 ) forms the union of all structures in 234 * both meshes, and returns the new mesh (the old meshes are destroyed). 235 * 236 * __gl_meshDeleteMesh( mesh ) will free all storage for any valid mesh. 237 * 238 * __gl_meshZapFace( fZap ) destroys a face and removes it from the 239 * global face list. All edges of fZap will have a NULL pointer as their 240 * left face. Any edges which also have a NULL pointer as their right face 241 * are deleted entirely (along with any isolated vertices this produces). 242 * An entire mesh can be deleted by zapping its faces, one at a time, 243 * in any order. Zapped faces cannot be used in further mesh operations! 244 * 245 * __gl_meshCheckMesh( mesh ) checks a mesh for self-consistency. 246 */ 247 248 GLUhalfEdge *__gl_meshMakeEdge( GLUmesh *mesh ); 249 int __gl_meshSplice( GLUhalfEdge *eOrg, GLUhalfEdge *eDst ); 250 int __gl_meshDelete( GLUhalfEdge *eDel ); 251 252 GLUhalfEdge *__gl_meshAddEdgeVertex( GLUhalfEdge *eOrg ); 253 GLUhalfEdge *__gl_meshSplitEdge( GLUhalfEdge *eOrg ); 254 GLUhalfEdge *__gl_meshConnect( GLUhalfEdge *eOrg, GLUhalfEdge *eDst ); 255 256 GLUmesh *__gl_meshNewMesh( void ); 257 GLUmesh *__gl_meshUnion( GLUmesh *mesh1, GLUmesh *mesh2 ); 258 void __gl_meshDeleteMesh( GLUmesh *mesh ); 259 void __gl_meshZapFace( GLUface *fZap ); 260 261 #ifdef NDEBUG 262 #define __gl_meshCheckMesh( mesh ) 263 #else 264 void __gl_meshCheckMesh( GLUmesh *mesh ); 265 #endif 266 267 #endif 268