source: trunk/src/opengl/glu/tess/mesh.h

Last change on this file was 2689, checked in by jeroen, 26 years ago

* empty log message *

File size: 12.2 KB
Line 
1/* $Id: mesh.h,v 1.1 2000-02-09 08:47:35 jeroen Exp $ */
2/*
3** License Applicability. Except to the extent portions of this file are
4** made subject to an alternative license as permitted in the SGI Free
5** Software License B, Version 1.0 (the "License"), the contents of this
6** file are subject only to the provisions of the License. You may not use
7** this file except in compliance with the License. You may obtain a copy
8** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
9** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
10**
11** http://oss.sgi.com/projects/FreeB
12**
13** Note that, as provided in the License, the Software is distributed on an
14** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
15** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
16** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
17** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
18**
19** Original Code. The Original Code is: OpenGL Sample Implementation,
20** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
21** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
22** Copyright in any portions created by third parties is as indicated
23** elsewhere herein. All Rights Reserved.
24**
25** Additional Notice Provisions: The application programming interfaces
26** established by SGI in conjunction with the Original Code are The
27** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
28** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
29** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
30** Window System(R) (Version 1.3), released October 19, 1998. This software
31** was created using the OpenGL(R) version 1.2.1 Sample Implementation
32** published by SGI, but has not been independently verified as being
33** compliant with the OpenGL(R) version 1.2.1 Specification.
34**
35*/
36/*
37** Author: Eric Veach, July 1994.
38**
39** $Date: 2000-02-09 08:47:35 $ $Revision: 1.1 $
40** $Header: /home/ktk/tmp/odin/2007/netlabs.cvs/odin32/src/opengl/glu/tess/mesh.h,v 1.1 2000-02-09 08:47:35 jeroen Exp $
41*/
42
43#ifndef __mesh_h_
44#define __mesh_h_
45
46#include "glu.h"
47
48typedef struct GLUmesh GLUmesh;
49
50typedef struct GLUvertex GLUvertex;
51typedef struct GLUface GLUface;
52typedef struct GLUhalfEdge GLUhalfEdge;
53
54typedef struct ActiveRegion ActiveRegion; /* Internal data */
55
56/* The mesh structure is similar in spirit, notation, and operations
57 * to the "quad-edge" structure (see L. Guibas and J. Stolfi, Primitives
58 * for the manipulation of general subdivisions and the computation of
59 * Voronoi diagrams, ACM Transactions on Graphics, 4(2):74-123, April 1985).
60 * For a simplified description, see the course notes for CS348a,
61 * "Mathematical Foundations of Computer Graphics", available at the
62 * Stanford bookstore (and taught during the fall quarter).
63 * The implementation also borrows a tiny subset of the graph-based approach
64 * use in Mantyla's Geometric Work Bench (see M. Mantyla, An Introduction
65 * to Sold Modeling, Computer Science Press, Rockville, Maryland, 1988).
66 *
67 * The fundamental data structure is the "half-edge". Two half-edges
68 * go together to make an edge, but they point in opposite directions.
69 * Each half-edge has a pointer to its mate (the "symmetric" half-edge Sym),
70 * its origin vertex (Org), the face on its left side (Lface), and the
71 * adjacent half-edges in the CCW direction around the origin vertex
72 * (Onext) and around the left face (Lnext). There is also a "next"
73 * pointer for the global edge list (see below).
74 *
75 * The notation used for mesh navigation:
76 * Sym = the mate of a half-edge (same edge, but opposite direction)
77 * Onext = edge CCW around origin vertex (keep same origin)
78 * Dnext = edge CCW around destination vertex (keep same dest)
79 * Lnext = edge CCW around left face (dest becomes new origin)
80 * Rnext = edge CCW around right face (origin becomes new dest)
81 *
82 * "prev" means to substitute CW for CCW in the definitions above.
83 *
84 * The mesh keeps global lists of all vertices, faces, and edges,
85 * stored as doubly-linked circular lists with a dummy header node.
86 * The mesh stores pointers to these dummy headers (vHead, fHead, eHead).
87 *
88 * The circular edge list is special; since half-edges always occur
89 * in pairs (e and e->Sym), each half-edge stores a pointer in only
90 * one direction. Starting at eHead and following the e->next pointers
91 * will visit each *edge* once (ie. e or e->Sym, but not both).
92 * e->Sym stores a pointer in the opposite direction, thus it is
93 * always true that e->Sym->next->Sym->next == e.
94 *
95 * Each vertex has a pointer to next and previous vertices in the
96 * circular list, and a pointer to a half-edge with this vertex as
97 * the origin (NULL if this is the dummy header). There is also a
98 * field "data" for client data.
99 *
100 * Each face has a pointer to the next and previous faces in the
101 * circular list, and a pointer to a half-edge with this face as
102 * the left face (NULL if this is the dummy header). There is also
103 * a field "data" for client data.
104 *
105 * Note that what we call a "face" is really a loop; faces may consist
106 * of more than one loop (ie. not simply connected), but there is no
107 * record of this in the data structure. The mesh may consist of
108 * several disconnected regions, so it may not be possible to visit
109 * the entire mesh by starting at a half-edge and traversing the edge
110 * structure.
111 *
112 * The mesh does NOT support isolated vertices; a vertex is deleted along
113 * with its last edge. Similarly when two faces are merged, one of the
114 * faces is deleted (see __gl_meshDelete below). For mesh operations,
115 * all face (loop) and vertex pointers must not be NULL. However, once
116 * mesh manipulation is finished, __gl_MeshZapFace can be used to delete
117 * faces of the mesh, one at a time. All external faces can be "zapped"
118 * before the mesh is returned to the client; then a NULL face indicates
119 * a region which is not part of the output polygon.
120 */
121
122struct GLUvertex {
123 GLUvertex *next; /* next vertex (never NULL) */
124 GLUvertex *prev; /* previous vertex (never NULL) */
125 GLUhalfEdge *anEdge; /* a half-edge with this origin */
126 void *data; /* client's data */
127
128 /* Internal data (keep hidden) */
129 GLdouble coords[3]; /* vertex location in 3D */
130 GLdouble s, t; /* projection onto the sweep plane */
131 long pqHandle; /* to allow deletion from priority queue */
132};
133
134struct GLUface {
135 GLUface *next; /* next face (never NULL) */
136 GLUface *prev; /* previous face (never NULL) */
137 GLUhalfEdge *anEdge; /* a half edge with this left face */
138 void *data; /* room for client's data */
139
140 /* Internal data (keep hidden) */
141 GLUface *trail; /* "stack" for conversion to strips */
142 GLboolean marked; /* flag for conversion to strips */
143 GLboolean inside; /* this face is in the polygon interior */
144};
145
146struct GLUhalfEdge {
147 GLUhalfEdge *next; /* doubly-linked list (prev==Sym->next) */
148 GLUhalfEdge *Sym; /* same edge, opposite direction */
149 GLUhalfEdge *Onext; /* next edge CCW around origin */
150 GLUhalfEdge *Lnext; /* next edge CCW around left face */
151 GLUvertex *Org; /* origin vertex (Overtex too long) */
152 GLUface *Lface; /* left face */
153
154 /* Internal data (keep hidden) */
155 ActiveRegion *activeRegion; /* a region with this upper edge (sweep.c) */
156 int winding; /* change in winding number when crossing
157 from the right face to the left face */
158};
159
160#define Rface Sym->Lface
161#define Dst Sym->Org
162
163#define Oprev Sym->Lnext
164#define Lprev Onext->Sym
165#define Dprev Lnext->Sym
166#define Rprev Sym->Onext
167#define Dnext Rprev->Sym /* 3 pointers */
168#define Rnext Oprev->Sym /* 3 pointers */
169
170
171struct GLUmesh {
172 GLUvertex vHead; /* dummy header for vertex list */
173 GLUface fHead; /* dummy header for face list */
174 GLUhalfEdge eHead; /* dummy header for edge list */
175 GLUhalfEdge eHeadSym; /* and its symmetric counterpart */
176};
177
178/* The mesh operations below have three motivations: completeness,
179 * convenience, and efficiency. The basic mesh operations are MakeEdge,
180 * Splice, and Delete. All the other edge operations can be implemented
181 * in terms of these. The other operations are provided for convenience
182 * and/or efficiency.
183 *
184 * When a face is split or a vertex is added, they are inserted into the
185 * global list *before* the existing vertex or face (ie. e->Org or e->Lface).
186 * This makes it easier to process all vertices or faces in the global lists
187 * without worrying about processing the same data twice. As a convenience,
188 * when a face is split, the "inside" flag is copied from the old face.
189 * Other internal data (v->data, v->activeRegion, f->data, f->marked,
190 * f->trail, e->winding) is set to zero.
191 *
192 * ********************** Basic Edge Operations **************************
193 *
194 * __gl_meshMakeEdge( mesh ) creates one edge, two vertices, and a loop.
195 * The loop (face) consists of the two new half-edges.
196 *
197 * __gl_meshSplice( eOrg, eDst ) is the basic operation for changing the
198 * mesh connectivity and topology. It changes the mesh so that
199 * eOrg->Onext <- OLD( eDst->Onext )
200 * eDst->Onext <- OLD( eOrg->Onext )
201 * where OLD(...) means the value before the meshSplice operation.
202 *
203 * This can have two effects on the vertex structure:
204 * - if eOrg->Org != eDst->Org, the two vertices are merged together
205 * - if eOrg->Org == eDst->Org, the origin is split into two vertices
206 * In both cases, eDst->Org is changed and eOrg->Org is untouched.
207 *
208 * Similarly (and independently) for the face structure,
209 * - if eOrg->Lface == eDst->Lface, one loop is split into two
210 * - if eOrg->Lface != eDst->Lface, two distinct loops are joined into one
211 * In both cases, eDst->Lface is changed and eOrg->Lface is unaffected.
212 *
213 * __gl_meshDelete( eDel ) removes the edge eDel. There are several cases:
214 * if (eDel->Lface != eDel->Rface), we join two loops into one; the loop
215 * eDel->Lface is deleted. Otherwise, we are splitting one loop into two;
216 * the newly created loop will contain eDel->Dst. If the deletion of eDel
217 * would create isolated vertices, those are deleted as well.
218 *
219 * ********************** Other Edge Operations **************************
220 *
221 * __gl_meshAddEdgeVertex( eOrg ) creates a new edge eNew such that
222 * eNew == eOrg->Lnext, and eNew->Dst is a newly created vertex.
223 * eOrg and eNew will have the same left face.
224 *
225 * __gl_meshSplitEdge( eOrg ) splits eOrg into two edges eOrg and eNew,
226 * such that eNew == eOrg->Lnext. The new vertex is eOrg->Dst == eNew->Org.
227 * eOrg and eNew will have the same left face.
228 *
229 * __gl_meshConnect( eOrg, eDst ) creates a new edge from eOrg->Dst
230 * to eDst->Org, and returns the corresponding half-edge eNew.
231 * If eOrg->Lface == eDst->Lface, this splits one loop into two,
232 * and the newly created loop is eNew->Lface. Otherwise, two disjoint
233 * loops are merged into one, and the loop eDst->Lface is destroyed.
234 *
235 * ************************ Other Operations *****************************
236 *
237 * __gl_meshNewMesh() creates a new mesh with no edges, no vertices,
238 * and no loops (what we usually call a "face").
239 *
240 * __gl_meshUnion( mesh1, mesh2 ) forms the union of all structures in
241 * both meshes, and returns the new mesh (the old meshes are destroyed).
242 *
243 * __gl_meshDeleteMesh( mesh ) will free all storage for any valid mesh.
244 *
245 * __gl_meshZapFace( fZap ) destroys a face and removes it from the
246 * global face list. All edges of fZap will have a NULL pointer as their
247 * left face. Any edges which also have a NULL pointer as their right face
248 * are deleted entirely (along with any isolated vertices this produces).
249 * An entire mesh can be deleted by zapping its faces, one at a time,
250 * in any order. Zapped faces cannot be used in further mesh operations!
251 *
252 * __gl_meshCheckMesh( mesh ) checks a mesh for self-consistency.
253 */
254
255GLUhalfEdge *__gl_meshMakeEdge( GLUmesh *mesh );
256int __gl_meshSplice( GLUhalfEdge *eOrg, GLUhalfEdge *eDst );
257int __gl_meshDelete( GLUhalfEdge *eDel );
258
259GLUhalfEdge *__gl_meshAddEdgeVertex( GLUhalfEdge *eOrg );
260GLUhalfEdge *__gl_meshSplitEdge( GLUhalfEdge *eOrg );
261GLUhalfEdge *__gl_meshConnect( GLUhalfEdge *eOrg, GLUhalfEdge *eDst );
262
263GLUmesh *__gl_meshNewMesh( void );
264GLUmesh *__gl_meshUnion( GLUmesh *mesh1, GLUmesh *mesh2 );
265void __gl_meshDeleteMesh( GLUmesh *mesh );
266void __gl_meshZapFace( GLUface *fZap );
267
268#ifdef NDEBUG
269#define __gl_meshCheckMesh( mesh )
270#else
271void __gl_meshCheckMesh( GLUmesh *mesh );
272#endif
273
274#endif
Note: See TracBrowser for help on using the repository browser.