File indexing completed on 2024-04-14 14:11:11
0001 /* 0002 ** Author: Eric Veach, July 1994. 0003 ** 0004 */ 0005 0006 #ifndef __tess_h_ 0007 #define __tess_h_ 0008 0009 #include "glu.h" 0010 #include <setjmp.h> 0011 #include "mesh.h" 0012 #include "dict.h" 0013 #include "priorityq.h" 0014 0015 /* The begin/end calls must be properly nested. We keep track of 0016 * the current state to enforce the ordering. 0017 */ 0018 enum TessState 0019 { 0020 T_DORMANT, 0021 T_IN_POLYGON, 0022 T_IN_CONTOUR 0023 }; 0024 0025 /* We cache vertex data for single-contour polygons so that we can 0026 * try a quick-and-dirty decomposition first. 0027 */ 0028 #define TESS_MAX_CACHE 100 0029 0030 typedef struct CachedVertex 0031 { 0032 GLdouble coords[3]; 0033 void *data; 0034 } CachedVertex; 0035 0036 struct GLUtesselator 0037 { 0038 /*** state needed for collecting the input data ***/ 0039 0040 enum TessState state; /* what begin/end calls have we seen? */ 0041 0042 GLUhalfEdge *lastEdge; /* lastEdge->Org is the most recent vertex */ 0043 GLUmesh *mesh; /* stores the input contours, and eventually 0044 the tessellation itself */ 0045 0046 void(GLAPIENTRY *callError)(GLenum errnum); 0047 0048 /*** state needed for projecting onto the sweep plane ***/ 0049 0050 GLdouble normal[3]; /* user-specified normal (if provided) */ 0051 GLdouble sUnit[3]; /* unit vector in s-direction (debugging) */ 0052 GLdouble tUnit[3]; /* unit vector in t-direction (debugging) */ 0053 0054 /*** state needed for the line sweep ***/ 0055 0056 GLdouble relTolerance; /* tolerance for merging features */ 0057 GLenum windingRule; /* rule for determining polygon interior */ 0058 GLboolean fatalError; /* fatal error: needed combine callback */ 0059 0060 Dict *dict; /* edge dictionary for sweep line */ 0061 PriorityQ *pq; /* priority queue of vertex events */ 0062 GLUvertex *event; /* current sweep event being processed */ 0063 0064 void(GLAPIENTRY *callCombine)(GLdouble coords[3], void *data[4], GLfloat weight[4], void **outData); 0065 0066 /*** state needed for rendering callbacks (see render.c) ***/ 0067 0068 GLboolean flagBoundary; /* mark boundary edges (use EdgeFlag) */ 0069 GLboolean boundaryOnly; /* Extract contours, not triangles */ 0070 GLUface *lonelyTriList; 0071 /* list of triangles which could not be rendered as strips or fans */ 0072 0073 void(GLAPIENTRY *callBegin)(GLenum type); 0074 void(GLAPIENTRY *callEdgeFlag)(GLboolean boundaryEdge); 0075 void(GLAPIENTRY *callVertex)(void *data); 0076 void(GLAPIENTRY *callEnd)(void); 0077 void(GLAPIENTRY *callMesh)(GLUmesh *mesh); 0078 0079 /*** state needed to cache single-contour polygons for renderCache() */ 0080 0081 GLboolean emptyCache; /* empty cache on next vertex() call */ 0082 int cacheCount; /* number of cached vertices */ 0083 CachedVertex cache[TESS_MAX_CACHE]; /* the vertex data */ 0084 0085 /*** rendering callbacks that also pass polygon data ***/ 0086 void(GLAPIENTRY *callBeginData)(GLenum type, void *polygonData); 0087 void(GLAPIENTRY *callEdgeFlagData)(GLboolean boundaryEdge, void *polygonData); 0088 void(GLAPIENTRY *callVertexData)(void *data, void *polygonData); 0089 void(GLAPIENTRY *callEndData)(void *polygonData); 0090 void(GLAPIENTRY *callErrorData)(GLenum errnum, void *polygonData); 0091 void(GLAPIENTRY *callCombineData)(GLdouble coords[3], void *data[4], GLfloat weight[4], void **outData, 0092 void *polygonData); 0093 0094 jmp_buf env; /* place to jump to when memAllocs fail */ 0095 0096 void *polygonData; /* client data for current polygon */ 0097 }; 0098 0099 void GLAPIENTRY __gl_noBeginData(GLenum type, void *polygonData); 0100 void GLAPIENTRY __gl_noEdgeFlagData(GLboolean boundaryEdge, void *polygonData); 0101 void GLAPIENTRY __gl_noVertexData(void *data, void *polygonData); 0102 void GLAPIENTRY __gl_noEndData(void *polygonData); 0103 void GLAPIENTRY __gl_noErrorData(GLenum errnum, void *polygonData); 0104 void GLAPIENTRY __gl_noCombineData(GLdouble coords[3], void *data[4], GLfloat weight[4], void **outData, 0105 void *polygonData); 0106 0107 #define CALL_BEGIN_OR_BEGIN_DATA(a) \ 0108 if (tess->callBeginData != &__gl_noBeginData) \ 0109 (*tess->callBeginData)((a), tess->polygonData); \ 0110 else \ 0111 (*tess->callBegin)((a)); 0112 0113 #define CALL_VERTEX_OR_VERTEX_DATA(a) \ 0114 if (tess->callVertexData != &__gl_noVertexData) \ 0115 (*tess->callVertexData)((a), tess->polygonData); \ 0116 else \ 0117 (*tess->callVertex)((a)); 0118 0119 #define CALL_EDGE_FLAG_OR_EDGE_FLAG_DATA(a) \ 0120 if (tess->callEdgeFlagData != &__gl_noEdgeFlagData) \ 0121 (*tess->callEdgeFlagData)((a), tess->polygonData); \ 0122 else \ 0123 (*tess->callEdgeFlag)((a)); 0124 0125 #define CALL_END_OR_END_DATA() \ 0126 if (tess->callEndData != &__gl_noEndData) \ 0127 (*tess->callEndData)(tess->polygonData); \ 0128 else \ 0129 (*tess->callEnd)(); 0130 0131 #define CALL_COMBINE_OR_COMBINE_DATA(a, b, c, d) \ 0132 if (tess->callCombineData != &__gl_noCombineData) \ 0133 (*tess->callCombineData)((a), (b), (c), (d), tess->polygonData); \ 0134 else \ 0135 (*tess->callCombine)((a), (b), (c), (d)); 0136 0137 #define CALL_ERROR_OR_ERROR_DATA(a) \ 0138 if (tess->callErrorData != &__gl_noErrorData) \ 0139 (*tess->callErrorData)((a), tess->polygonData); \ 0140 else \ 0141 (*tess->callError)((a)); 0142 0143 #endif