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