Prusa Slicer 2.6.0
Loading...
Searching...
No Matches
tess.c File Reference
#include "gluos.h"
#include <stddef.h>
#include <assert.h>
#include <setjmp.h>
#include "memalloc.h"
#include "tess.h"
#include "mesh.h"
#include "normal.h"
#include "sweep.h"
#include "tessmono.h"
#include "render.h"
+ Include dependency graph for tess.c:

Go to the source code of this file.

Classes

struct  EdgePair
 

Macros

#define GLU_TESS_DEFAULT_TOLERANCE   0.0
 
#define GLU_TESS_MESH   100112 /* void (*)(GLUmesh *mesh) */
 
#define TRUE   1
 
#define FALSE   0
 
#define MAX(a, b)   ((a) > (b) ? (a) : (b))
 
#define MAX_FAST_ALLOC
 
#define RequireState(tess, s)   if( tess->state != s ) GotoState(tess,s)
 

Functions

static void GLAPIENTRY noBegin (GLenum type)
 
static void GLAPIENTRY noEdgeFlag (GLboolean boundaryEdge)
 
static void GLAPIENTRY noVertex (void *data)
 
static void GLAPIENTRY noEnd (void)
 
static void GLAPIENTRY noError (GLenum errnum)
 
static void GLAPIENTRY noCombine (GLdouble coords[3], void *data[4], GLfloat weight[4], void **dataOut)
 
static void GLAPIENTRY noMesh (GLUmesh *mesh)
 
void GLAPIENTRY __gl_noBeginData (GLenum type, void *polygonData)
 
void GLAPIENTRY __gl_noEdgeFlagData (GLboolean boundaryEdge, void *polygonData)
 
void GLAPIENTRY __gl_noVertexData (void *data, void *polygonData)
 
void GLAPIENTRY __gl_noEndData (void *polygonData)
 
void GLAPIENTRY __gl_noErrorData (GLenum errnum, void *polygonData)
 
void GLAPIENTRY __gl_noCombineData (GLdouble coords[3], void *data[4], GLfloat weight[4], void **outData, void *polygonData)
 
GLUtesselator *GLAPIENTRY gluNewTess (void)
 
static void MakeDormant (GLUtesselator *tess)
 
static void GotoState (GLUtesselator *tess, enum TessState newState)
 
void GLAPIENTRY gluDeleteTess (GLUtesselator *tess)
 
void GLAPIENTRY gluTessProperty (GLUtesselator *tess, GLenum which, GLdouble value)
 
void GLAPIENTRY gluGetTessProperty (GLUtesselator *tess, GLenum which, GLdouble *value)
 
void GLAPIENTRY gluTessNormal (GLUtesselator *tess, GLdouble x, GLdouble y, GLdouble z)
 
void GLAPIENTRY gluTessCallback (GLUtesselator *tess, GLenum which, _GLUfuncptr fn)
 
static int AddVertex (GLUtesselator *tess, GLdouble coords[3], void *data)
 
static void CacheVertex (GLUtesselator *tess, GLdouble coords[3], void *data)
 
static int EmptyCache (GLUtesselator *tess)
 
void GLAPIENTRY gluTessVertex (GLUtesselator *tess, GLdouble coords[3], void *data)
 
void GLAPIENTRY gluTessBeginPolygon (GLUtesselator *tess, void *data)
 
void GLAPIENTRY gluTessBeginContour (GLUtesselator *tess)
 
void GLAPIENTRY gluTessEndContour (GLUtesselator *tess)
 
void GLAPIENTRY gluTessEndPolygon (GLUtesselator *tess)
 
void GLAPIENTRY gluBeginPolygon (GLUtesselator *tess)
 
void GLAPIENTRY gluNextContour (GLUtesselator *tess, GLenum type)
 
void GLAPIENTRY gluEndPolygon (GLUtesselator *tess)
 

Class Documentation

◆ EdgePair

struct EdgePair
+ Collaboration diagram for EdgePair:
Class Members
GLUhalfEdge e
GLUhalfEdge eSym

Macro Definition Documentation

◆ FALSE

#define FALSE   0

◆ GLU_TESS_DEFAULT_TOLERANCE

#define GLU_TESS_DEFAULT_TOLERANCE   0.0

◆ GLU_TESS_MESH

#define GLU_TESS_MESH   100112 /* void (*)(GLUmesh *mesh) */

◆ MAX

#define MAX (   a,
 
)    ((a) > (b) ? (a) : (b))

◆ MAX_FAST_ALLOC

#define MAX_FAST_ALLOC
Value:
(MAX(sizeof(EdgePair), \
MAX(sizeof(GLUvertex),sizeof(GLUface))))
Definition mesh.h:114
Definition mesh.h:126
#define MAX(a, b)
Definition tess.c:86
Definition mesh.c:63

◆ RequireState

#define RequireState (   tess,
 
)    if( tess->state != s ) GotoState(tess,s)

◆ TRUE

#define TRUE   1

Function Documentation

◆ __gl_noBeginData()

void GLAPIENTRY __gl_noBeginData ( GLenum  type,
void polygonData 
)
68 {}

Referenced by gluNewTess(), gluTessCallback(), and gluTessEndPolygon().

+ Here is the caller graph for this function:

◆ __gl_noCombineData()

void GLAPIENTRY __gl_noCombineData ( GLdouble  coords[3],
void data[4],
GLfloat  weight[4],
void **  outData,
void polygonData 
)
80 {}

Referenced by gluNewTess(), and gluTessCallback().

+ Here is the caller graph for this function:

◆ __gl_noEdgeFlagData()

void GLAPIENTRY __gl_noEdgeFlagData ( GLboolean  boundaryEdge,
void polygonData 
)
70 {}

Referenced by gluNewTess(), gluTessCallback(), and gluTessEndPolygon().

+ Here is the caller graph for this function:

◆ __gl_noEndData()

void GLAPIENTRY __gl_noEndData ( void polygonData)
73{}

Referenced by gluNewTess(), gluTessCallback(), and gluTessEndPolygon().

+ Here is the caller graph for this function:

◆ __gl_noErrorData()

void GLAPIENTRY __gl_noErrorData ( GLenum  errnum,
void polygonData 
)
75 {}

Referenced by gluNewTess(), and gluTessCallback().

+ Here is the caller graph for this function:

◆ __gl_noVertexData()

void GLAPIENTRY __gl_noVertexData ( void data,
void polygonData 
)
72 {}

Referenced by gluNewTess(), gluTessCallback(), and gluTessEndPolygon().

+ Here is the caller graph for this function:

◆ AddVertex()

static int AddVertex ( GLUtesselator tess,
GLdouble  coords[3],
void data 
)
static
346{
347 GLUhalfEdge *e;
348
349 e = tess->lastEdge;
350 if( e == NULL ) {
351 /* Make a self-loop (one vertex, one edge). */
352
353 e = __gl_meshMakeEdge( tess->mesh );
354 if (e == NULL) return 0;
355 if ( !__gl_meshSplice( e, e->Sym ) ) return 0;
356 } else {
357 /* Create a new vertex and edge which immediately follow e
358 * in the ordering around the left face.
359 */
360 if (__gl_meshSplitEdge( e ) == NULL) return 0;
361 e = e->Lnext;
362 }
363
364 /* The new vertex is now e->Org. */
365 e->Org->data = data;
366 e->Org->coords[0] = coords[0];
367 e->Org->coords[1] = coords[1];
368 e->Org->coords[2] = coords[2];
369
370 /* The winding of an edge says how the winding number changes as we
371 * cross from the edge''s right face to its left face. We add the
372 * vertices in such an order that a CCW contour will add +1 to
373 * the winding number of the region inside the contour.
374 */
375 e->winding = 1;
376 e->Sym->winding = -1;
377
378 tess->lastEdge = e;
379
380 return 1;
381}
GLUhalfEdge * __gl_meshMakeEdge(GLUmesh *mesh)
Definition mesh.c:275
GLUhalfEdge * __gl_meshSplitEdge(GLUhalfEdge *eOrg)
Definition mesh.c:475
int __gl_meshSplice(GLUhalfEdge *eOrg, GLUhalfEdge *eDst)
Definition mesh.c:328
GLUhalfEdge * Lnext
Definition mesh.h:142
GLUvertex * Org
Definition mesh.h:143
GLdouble coords[3]
Definition mesh.h:121
GLUhalfEdge * Sym
Definition mesh.h:140
int winding
Definition mesh.h:148
void * data
Definition mesh.h:118
Definition mesh.h:138
constexpr auto data(C &c) -> decltype(c.data())
Definition span.hpp:195
GLUhalfEdge * lastEdge
Definition tess.h:65
GLUmesh * mesh
Definition tess.h:66

References __gl_meshMakeEdge(), __gl_meshSplice(), __gl_meshSplitEdge(), GLUvertex::coords, GLUvertex::data, GLUtesselator::lastEdge, GLUhalfEdge::Lnext, GLUtesselator::mesh, GLUhalfEdge::Org, GLUhalfEdge::Sym, and GLUhalfEdge::winding.

Referenced by EmptyCache(), and gluTessVertex().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CacheVertex()

static void CacheVertex ( GLUtesselator tess,
GLdouble  coords[3],
void data 
)
static
385{
386 CachedVertex *v = &tess->cache[tess->cacheCount];
387
388 v->data = data;
389 v->coords[0] = coords[0];
390 v->coords[1] = coords[1];
391 v->coords[2] = coords[2];
392 ++tess->cacheCount;
393}
int cacheCount
Definition tess.h:107
CachedVertex cache[TESS_MAX_CACHE]
Definition tess.h:108
void * data
Definition tess.h:56
GLdouble coords[3]
Definition tess.h:55
Definition tess.h:54

References GLUtesselator::cache, GLUtesselator::cacheCount, CachedVertex::coords, and CachedVertex::data.

Referenced by gluTessVertex().

+ Here is the caller graph for this function:

◆ EmptyCache()

static int EmptyCache ( GLUtesselator tess)
static
397{
398 CachedVertex *v = tess->cache;
399 CachedVertex *vLast;
400
401 tess->mesh = __gl_meshNewMesh();
402 if (tess->mesh == NULL) return 0;
403
404 for( vLast = v + tess->cacheCount; v < vLast; ++v ) {
405 if ( !AddVertex( tess, v->coords, v->data ) ) return 0;
406 }
407 tess->cacheCount = 0;
408 tess->emptyCache = FALSE;
409
410 return 1;
411}
GLUmesh * __gl_meshNewMesh(void)
Definition mesh.c:603
GLboolean emptyCache
Definition tess.h:106
static int AddVertex(GLUtesselator *tess, GLdouble coords[3], void *data)
Definition tess.c:345
#define FALSE
Definition tess.c:54

References __gl_meshNewMesh(), AddVertex(), GLUtesselator::cache, GLUtesselator::cacheCount, CachedVertex::coords, CachedVertex::data, GLUtesselator::emptyCache, FALSE, and GLUtesselator::mesh.

Referenced by gluTessEndPolygon(), and gluTessVertex().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ gluBeginPolygon()

void GLAPIENTRY gluBeginPolygon ( GLUtesselator tess)
612{
613 gluTessBeginPolygon( tess, NULL );
614 gluTessBeginContour( tess );
615}
#define gluTessBeginContour
Definition glu-libtess.h:39
#define gluTessBeginPolygon
Definition glu-libtess.h:38

References gluTessBeginContour, and gluTessBeginPolygon.

◆ gluDeleteTess()

void GLAPIENTRY gluDeleteTess ( GLUtesselator tess)
194{
195 RequireState( tess, T_DORMANT );
196 memFree( tess );
197}
#define memFree
Definition memalloc.h:41
#define RequireState(tess, s)
Definition tess.c:152
@ T_DORMANT
Definition tess.h:47

References memFree, RequireState, and T_DORMANT.

◆ gluEndPolygon()

void GLAPIENTRY gluEndPolygon ( GLUtesselator tess)
629{
630 gluTessEndContour( tess );
631 gluTessEndPolygon( tess );
632}
#define gluTessEndPolygon
Definition glu-libtess.h:41
#define gluTessEndContour
Definition glu-libtess.h:42

References gluTessEndContour, and gluTessEndPolygon.

◆ gluGetTessProperty()

void GLAPIENTRY gluGetTessProperty ( GLUtesselator tess,
GLenum  which,
GLdouble value 
)
241{
242 switch (which) {
244 /* tolerance should be in range [0..1] */
245 assert(0.0 <= tess->relTolerance && tess->relTolerance <= 1.0);
246 *value= tess->relTolerance;
247 break;
249 assert(tess->windingRule == GLU_TESS_WINDING_ODD ||
254 *value= tess->windingRule;
255 break;
257 assert(tess->boundaryOnly == TRUE || tess->boundaryOnly == FALSE);
258 *value= tess->boundaryOnly;
259 break;
260 default:
261 *value= 0.0;
263 break;
264 }
265} /* gluGetTessProperty() */
#define GLU_TESS_WINDING_NONZERO
Definition glu-libtess.h:156
#define GLU_TESS_WINDING_POSITIVE
Definition glu-libtess.h:157
#define GLU_INVALID_ENUM
Definition glu-libtess.h:102
#define GLU_TESS_BOUNDARY_ONLY
Definition glu-libtess.h:135
#define GLU_TESS_WINDING_NEGATIVE
Definition glu-libtess.h:158
#define GLU_TESS_WINDING_RULE
Definition glu-libtess.h:134
#define GLU_TESS_TOLERANCE
Definition glu-libtess.h:136
#define GLU_TESS_WINDING_ODD
Definition glu-libtess.h:155
#define GLU_TESS_WINDING_ABS_GEQ_TWO
Definition glu-libtess.h:159
GLboolean boundaryOnly
Definition tess.h:93
GLdouble relTolerance
Definition tess.h:79
GLenum windingRule
Definition tess.h:80
#define TRUE
Definition tess.c:51
#define CALL_ERROR_OR_ERROR_DATA(a)
Definition tess.h:160

References GLUtesselator::boundaryOnly, CALL_ERROR_OR_ERROR_DATA, FALSE, GLU_INVALID_ENUM, GLU_TESS_BOUNDARY_ONLY, GLU_TESS_TOLERANCE, GLU_TESS_WINDING_ABS_GEQ_TWO, GLU_TESS_WINDING_NEGATIVE, GLU_TESS_WINDING_NONZERO, GLU_TESS_WINDING_ODD, GLU_TESS_WINDING_POSITIVE, GLU_TESS_WINDING_RULE, GLUtesselator::relTolerance, TRUE, and GLUtesselator::windingRule.

◆ gluNewTess()

GLUtesselator *GLAPIENTRY gluNewTess ( void  )
93{
94 GLUtesselator *tess;
95
96 /* Only initialize fields which can be changed by the api. Other fields
97 * are initialized where they are used.
98 */
99
100 if (memInit( MAX_FAST_ALLOC ) == 0) {
101 return 0; /* out of memory */
102 }
103 tess = (GLUtesselator *)memAlloc( sizeof( GLUtesselator ));
104 if (tess == NULL) {
105 return 0; /* out of memory */
106 }
107
108 tess->state = T_DORMANT;
109
110 tess->normal[0] = 0;
111 tess->normal[1] = 0;
112 tess->normal[2] = 0;
113
116 tess->flagBoundary = FALSE;
117 tess->boundaryOnly = FALSE;
118
119 tess->callBegin = &noBegin;
120 tess->callEdgeFlag = &noEdgeFlag;
121 tess->callVertex = &noVertex;
122 tess->callEnd = &noEnd;
123
124 tess->callError = &noError;
125 tess->callCombine = &noCombine;
126 tess->callMesh = &noMesh;
127
128 tess->callBeginData= &__gl_noBeginData;
129 tess->callEdgeFlagData= &__gl_noEdgeFlagData;
130 tess->callVertexData= &__gl_noVertexData;
131 tess->callEndData= &__gl_noEndData;
132 tess->callErrorData= &__gl_noErrorData;
133 tess->callCombineData= &__gl_noCombineData;
134
135 tess->polygonData= NULL;
136
137 return tess;
138}
#define memAlloc
Definition memalloc.h:48
#define memInit
Definition memalloc.h:43
Definition tess.h:59
GLboolean flagBoundary
Definition tess.h:92
enum TessState state
Definition tess.h:63
GLdouble normal[3]
Definition tess.h:73
void * polygonData
Definition tess.h:111
void GLAPIENTRY __gl_noErrorData(GLenum errnum, void *polygonData)
Definition tess.c:74
static void GLAPIENTRY noEdgeFlag(GLboolean boundaryEdge)
Definition tess.c:58
void GLAPIENTRY __gl_noEdgeFlagData(GLboolean boundaryEdge, void *polygonData)
Definition tess.c:69
#define MAX_FAST_ALLOC
Definition tess.c:87
static void GLAPIENTRY noBegin(GLenum type)
Definition tess.c:57
static void GLAPIENTRY noMesh(GLUmesh *mesh)
Definition tess.c:64
void GLAPIENTRY __gl_noEndData(void *polygonData)
Definition tess.c:73
#define GLU_TESS_DEFAULT_TOLERANCE
Definition tess.c:47
void GLAPIENTRY __gl_noVertexData(void *data, void *polygonData)
Definition tess.c:71
static void GLAPIENTRY noError(GLenum errnum)
Definition tess.c:61
static void GLAPIENTRY noEnd(void)
Definition tess.c:60
void GLAPIENTRY __gl_noCombineData(GLdouble coords[3], void *data[4], GLfloat weight[4], void **outData, void *polygonData)
Definition tess.c:76
static void GLAPIENTRY noCombine(GLdouble coords[3], void *data[4], GLfloat weight[4], void **dataOut)
Definition tess.c:62
static void GLAPIENTRY noVertex(void *data)
Definition tess.c:59
void GLAPIENTRY __gl_noBeginData(GLenum type, void *polygonData)
Definition tess.c:67

References __gl_noBeginData(), __gl_noCombineData(), __gl_noEdgeFlagData(), __gl_noEndData(), __gl_noErrorData(), __gl_noVertexData(), GLUtesselator::boundaryOnly, FALSE, GLUtesselator::flagBoundary, GLU_TESS_DEFAULT_TOLERANCE, GLU_TESS_WINDING_ODD, MAX_FAST_ALLOC, memAlloc, memInit, noBegin(), noCombine(), noEdgeFlag(), noEnd(), noError(), noMesh(), GLUtesselator::normal, noVertex(), GLUtesselator::polygonData, GLUtesselator::relTolerance, GLUtesselator::state, T_DORMANT, and GLUtesselator::windingRule.

+ Here is the call graph for this function:

◆ gluNextContour()

void GLAPIENTRY gluNextContour ( GLUtesselator tess,
GLenum  type 
)
621{
622 gluTessEndContour( tess );
623 gluTessBeginContour( tess );
624}

References gluTessBeginContour, and gluTessEndContour.

◆ gluTessBeginContour()

void GLAPIENTRY gluTessBeginContour ( GLUtesselator tess)
477{
478 RequireState( tess, T_IN_POLYGON );
479
480 tess->state = T_IN_CONTOUR;
481 tess->lastEdge = NULL;
482 if( tess->cacheCount > 0 ) {
483 /* Just set a flag so we don't get confused by empty contours
484 * -- these can be generated accidentally with the obsolete
485 * NextContour() interface.
486 */
487 tess->emptyCache = TRUE;
488 }
489}
@ T_IN_CONTOUR
Definition tess.h:47
@ T_IN_POLYGON
Definition tess.h:47

References GLUtesselator::cacheCount, GLUtesselator::emptyCache, GLUtesselator::lastEdge, RequireState, GLUtesselator::state, T_IN_CONTOUR, T_IN_POLYGON, and TRUE.

◆ gluTessBeginPolygon()

void GLAPIENTRY gluTessBeginPolygon ( GLUtesselator tess,
void data 
)

◆ gluTessCallback()

void GLAPIENTRY gluTessCallback ( GLUtesselator tess,
GLenum  which,
_GLUfuncptr  fn 
)
277{
278 switch( which ) {
279 case GLU_TESS_BEGIN:
280 tess->callBegin = (fn == NULL) ? &noBegin : (void (GLAPIENTRY *)(GLenum)) fn;
281 return;
283 tess->callBeginData = (fn == NULL) ?
285 return;
287 tess->callEdgeFlag = (fn == NULL) ? &noEdgeFlag :
288 (void (GLAPIENTRY *)(GLboolean)) fn;
289 /* If the client wants boundary edges to be flagged,
290 * we render everything as separate triangles (no strips or fans).
291 */
292 tess->flagBoundary = (fn != NULL);
293 return;
295 tess->callEdgeFlagData= (fn == NULL) ?
297 /* If the client wants boundary edges to be flagged,
298 * we render everything as separate triangles (no strips or fans).
299 */
300 tess->flagBoundary = (fn != NULL);
301 return;
302 case GLU_TESS_VERTEX:
303 tess->callVertex = (fn == NULL) ? &noVertex :
304 (void (GLAPIENTRY *)(void *)) fn;
305 return;
307 tess->callVertexData = (fn == NULL) ?
308 &__gl_noVertexData : (void (GLAPIENTRY *)(void *, void *)) fn;
309 return;
310 case GLU_TESS_END:
311 tess->callEnd = (fn == NULL) ? &noEnd : (void (GLAPIENTRY *)(void)) fn;
312 return;
314 tess->callEndData = (fn == NULL) ? &__gl_noEndData :
315 (void (GLAPIENTRY *)(void *)) fn;
316 return;
317 case GLU_TESS_ERROR:
318 tess->callError = (fn == NULL) ? &noError : (void (GLAPIENTRY *)(GLenum)) fn;
319 return;
321 tess->callErrorData = (fn == NULL) ?
323 return;
324 case GLU_TESS_COMBINE:
325 tess->callCombine = (fn == NULL) ? &noCombine :
326 (void (GLAPIENTRY *)(GLdouble [3],void *[4], GLfloat [4], void ** )) fn;
327 return;
329 tess->callCombineData = (fn == NULL) ? &__gl_noCombineData :
330 (void (GLAPIENTRY *)(GLdouble [3],
331 void *[4],
332 GLfloat [4],
333 void **,
334 void *)) fn;
335 return;
336 case GLU_TESS_MESH:
337 tess->callMesh = (fn == NULL) ? &noMesh : (void (GLAPIENTRY *)(GLUmesh *)) fn;
338 return;
339 default:
341 return;
342 }
343}
#define GLU_TESS_VERTEX
Definition glu-libtess.h:111
#define GLU_TESS_BEGIN_DATA
Definition glu-libtess.h:119
#define GLU_TESS_COMBINE_DATA
Definition glu-libtess.h:124
float GLfloat
Definition glu-libtess.h:63
typedef void(GLAPIENTRYP _GLUfuncptr)(void)
#define GLU_TESS_END_DATA
Definition glu-libtess.h:121
double GLdouble
Definition glu-libtess.h:65
#define GLU_TESS_END
Definition glu-libtess.h:113
#define GLU_TESS_EDGE_FLAG
Definition glu-libtess.h:116
unsigned int GLenum
Definition glu-libtess.h:53
#define GLU_TESS_EDGE_FLAG_DATA
Definition glu-libtess.h:123
unsigned char GLboolean
Definition glu-libtess.h:54
#define GLU_TESS_VERTEX_DATA
Definition glu-libtess.h:120
#define GLU_TESS_BEGIN
Definition glu-libtess.h:109
#define GLAPIENTRY
Definition glu-libtess.h:52
#define GLU_TESS_COMBINE
Definition glu-libtess.h:118
#define GLU_TESS_ERROR
Definition glu-libtess.h:115
#define GLU_TESS_ERROR_DATA
Definition glu-libtess.h:122
Definition mesh.h:163
#define GLU_TESS_MESH
Definition tess.c:48

References __gl_noBeginData(), __gl_noCombineData(), __gl_noEdgeFlagData(), __gl_noEndData(), __gl_noErrorData(), __gl_noVertexData(), CALL_ERROR_OR_ERROR_DATA, GLUtesselator::flagBoundary, GLAPIENTRY, GLU_INVALID_ENUM, GLU_TESS_BEGIN, GLU_TESS_BEGIN_DATA, GLU_TESS_COMBINE, GLU_TESS_COMBINE_DATA, GLU_TESS_EDGE_FLAG, GLU_TESS_EDGE_FLAG_DATA, GLU_TESS_END, GLU_TESS_END_DATA, GLU_TESS_ERROR, GLU_TESS_ERROR_DATA, GLU_TESS_MESH, GLU_TESS_VERTEX, GLU_TESS_VERTEX_DATA, noBegin(), noCombine(), noEdgeFlag(), noEnd(), noError(), noMesh(), noVertex(), and void().

+ Here is the call graph for this function:

◆ gluTessEndContour()

void GLAPIENTRY gluTessEndContour ( GLUtesselator tess)
494{
495 RequireState( tess, T_IN_CONTOUR );
496 tess->state = T_IN_POLYGON;
497}

References RequireState, GLUtesselator::state, T_IN_CONTOUR, and T_IN_POLYGON.

◆ gluTessEndPolygon()

void GLAPIENTRY gluTessEndPolygon ( GLUtesselator tess)
501{
502 GLUmesh *mesh;
503
504 if (setjmp(tess->env) != 0) {
505 /* come back here if out of memory */
507 return;
508 }
509
510 RequireState( tess, T_IN_POLYGON );
511 tess->state = T_DORMANT;
512
513 if( tess->mesh == NULL ) {
514 if( ! tess->flagBoundary && tess->callMesh == &noMesh ) {
515
516 /* Try some special code to make the easy cases go quickly
517 * (eg. convex polygons). This code does NOT handle multiple contours,
518 * intersections, edge flags, and of course it does not generate
519 * an explicit mesh either.
520 */
521 if( __gl_renderCache( tess )) {
522 tess->polygonData= NULL;
523 return;
524 }
525 }
526 if ( !EmptyCache( tess ) ) longjmp(tess->env,1); /* could've used a label*/
527 }
528
529 /* Determine the polygon normal and project vertices onto the plane
530 * of the polygon.
531 */
532 __gl_projectPolygon( tess );
533
534 /* __gl_computeInterior( tess ) computes the planar arrangement specified
535 * by the given contours, and further subdivides this arrangement
536 * into regions. Each region is marked "inside" if it belongs
537 * to the polygon, according to the rule given by tess->windingRule.
538 * Each interior region is guaranteed be monotone.
539 */
540 if ( !__gl_computeInterior( tess ) ) {
541 longjmp(tess->env,1); /* could've used a label */
542 }
543
544 mesh = tess->mesh;
545 if( ! tess->fatalError ) {
546 int rc = 1;
547
548 /* If the user wants only the boundary contours, we throw away all edges
549 * except those which separate the interior from the exterior.
550 * Otherwise we tessellate all the regions marked "inside".
551 */
552 if( tess->boundaryOnly ) {
553 rc = __gl_meshSetWindingNumber( mesh, 1, TRUE );
554 } else {
555 rc = __gl_meshTessellateInterior( mesh );
556 }
557 if (rc == 0) longjmp(tess->env,1); /* could've used a label */
558
559 __gl_meshCheckMesh( mesh );
560
561 if( tess->callBegin != &noBegin || tess->callEnd != &noEnd
562 || tess->callVertex != &noVertex || tess->callEdgeFlag != &noEdgeFlag
563 || tess->callBeginData != &__gl_noBeginData
564 || tess->callEndData != &__gl_noEndData
565 || tess->callVertexData != &__gl_noVertexData
566 || tess->callEdgeFlagData != &__gl_noEdgeFlagData )
567 {
568 if( tess->boundaryOnly ) {
569 __gl_renderBoundary( tess, mesh ); /* output boundary contours */
570 } else {
571 __gl_renderMesh( tess, mesh ); /* output strips and fans */
572 }
573 }
574 if( tess->callMesh != &noMesh ) {
575
576 /* Throw away the exterior faces, so that all faces are interior.
577 * This way the user doesn't have to check the "inside" flag,
578 * and we don't need to even reveal its existence. It also leaves
579 * the freedom for an implementation to not generate the exterior
580 * faces in the first place.
581 */
583 (*tess->callMesh)( mesh ); /* user wants the mesh itself */
584 tess->mesh = NULL;
585 tess->polygonData= NULL;
586 return;
587 }
588 }
589 __gl_meshDeleteMesh( mesh );
590 tess->polygonData= NULL;
591 tess->mesh = NULL;
592}
#define GLU_OUT_OF_MEMORY
Definition glu-libtess.h:104
void __gl_meshCheckMesh(GLUmesh *mesh)
Definition mesh.c:742
void __gl_meshDeleteMesh(GLUmesh *mesh)
Definition mesh.c:711
void __gl_projectPolygon(GLUtesselator *tess)
Definition normal.c:198
GLboolean __gl_renderCache(GLUtesselator *tess)
Definition render.c:441
void __gl_renderMesh(GLUtesselator *tess, GLUmesh *mesh)
Definition render.c:82
void __gl_renderBoundary(GLUtesselator *tess, GLUmesh *mesh)
Definition render.c:339
GLboolean fatalError
Definition tess.h:81
jmp_buf env
Definition tess.h:121
int __gl_computeInterior(GLUtesselator *tess)
Definition sweep.c:1301
static int EmptyCache(GLUtesselator *tess)
Definition tess.c:396
int __gl_meshSetWindingNumber(GLUmesh *mesh, int value, GLboolean keepOnlyBoundary)
Definition tessmono.c:179
void __gl_meshDiscardExterior(GLUmesh *mesh)
Definition tessmono.c:155
int __gl_meshTessellateInterior(GLUmesh *mesh)
Definition tessmono.c:133

References __gl_computeInterior(), __gl_meshCheckMesh(), __gl_meshDeleteMesh(), __gl_meshDiscardExterior(), __gl_meshSetWindingNumber(), __gl_meshTessellateInterior(), __gl_noBeginData(), __gl_noEdgeFlagData(), __gl_noEndData(), __gl_noVertexData(), __gl_projectPolygon(), __gl_renderBoundary(), __gl_renderCache(), __gl_renderMesh(), GLUtesselator::boundaryOnly, CALL_ERROR_OR_ERROR_DATA, EmptyCache(), GLUtesselator::env, GLUtesselator::fatalError, GLUtesselator::flagBoundary, GLU_OUT_OF_MEMORY, GLUtesselator::mesh, noBegin(), noEdgeFlag(), noEnd(), noMesh(), noVertex(), GLUtesselator::polygonData, RequireState, GLUtesselator::state, T_DORMANT, T_IN_POLYGON, and TRUE.

+ Here is the call graph for this function:

◆ gluTessNormal()

void GLAPIENTRY gluTessNormal ( GLUtesselator tess,
GLdouble  x,
GLdouble  y,
GLdouble  z 
)
269{
270 tess->normal[0] = x;
271 tess->normal[1] = y;
272 tess->normal[2] = z;
273}
const Scalar & y
Definition MathFunctions.h:552
TCoord< P > x(const P &p)
Definition geometry_traits.hpp:297

References GLUtesselator::normal.

◆ gluTessProperty()

void GLAPIENTRY gluTessProperty ( GLUtesselator tess,
GLenum  which,
GLdouble  value 
)
202{
203 GLenum windingRule;
204
205 switch( which ) {
207 if( value < 0.0 || value > 1.0 ) break;
208 tess->relTolerance = value;
209 return;
210
212 windingRule = (GLenum) value;
213 if( windingRule != value ) break; /* not an integer */
214
215 switch( windingRule ) {
221 tess->windingRule = windingRule;
222 return;
223 default:
224 break;
225 }
226
228 tess->boundaryOnly = (value != 0);
229 return;
230
231 default:
233 return;
234 }
236}
#define GLU_INVALID_VALUE
Definition glu-libtess.h:103

References GLUtesselator::boundaryOnly, CALL_ERROR_OR_ERROR_DATA, GLU_INVALID_ENUM, GLU_INVALID_VALUE, GLU_TESS_BOUNDARY_ONLY, GLU_TESS_TOLERANCE, GLU_TESS_WINDING_ABS_GEQ_TWO, GLU_TESS_WINDING_NEGATIVE, GLU_TESS_WINDING_NONZERO, GLU_TESS_WINDING_ODD, GLU_TESS_WINDING_POSITIVE, GLU_TESS_WINDING_RULE, GLUtesselator::relTolerance, and GLUtesselator::windingRule.

◆ gluTessVertex()

void GLAPIENTRY gluTessVertex ( GLUtesselator tess,
GLdouble  coords[3],
void data 
)
416{
417 int i, tooLarge = FALSE;
418 GLdouble x, clamped[3];
419
420 RequireState( tess, T_IN_CONTOUR );
421
422 if( tess->emptyCache ) {
423 if ( !EmptyCache( tess ) ) {
425 return;
426 }
427 tess->lastEdge = NULL;
428 }
429 for( i = 0; i < 3; ++i ) {
430 x = coords[i];
431 if( x < - GLU_TESS_MAX_COORD ) {
433 tooLarge = TRUE;
434 }
435 if( x > GLU_TESS_MAX_COORD ) {
437 tooLarge = TRUE;
438 }
439 clamped[i] = x;
440 }
441 if( tooLarge ) {
443 }
444
445 if( tess->mesh == NULL ) {
446 if( tess->cacheCount < TESS_MAX_CACHE ) {
447 CacheVertex( tess, clamped, data );
448 return;
449 }
450 if ( !EmptyCache( tess ) ) {
452 return;
453 }
454 }
455 if ( !AddVertex( tess, clamped, data ) ) {
457 }
458}
#define GLU_TESS_COORD_TOO_LARGE
Definition glu-libtess.h:151
#define GLU_TESS_MAX_COORD
Definition glu-libtess.h:173
static void CacheVertex(GLUtesselator *tess, GLdouble coords[3], void *data)
Definition tess.c:384
#define TESS_MAX_CACHE
Definition tess.h:52

References AddVertex(), GLUtesselator::cacheCount, CacheVertex(), CALL_ERROR_OR_ERROR_DATA, EmptyCache(), GLUtesselator::emptyCache, FALSE, GLU_OUT_OF_MEMORY, GLU_TESS_COORD_TOO_LARGE, GLU_TESS_MAX_COORD, GLUtesselator::lastEdge, GLUtesselator::mesh, RequireState, T_IN_CONTOUR, TESS_MAX_CACHE, and TRUE.

+ Here is the call graph for this function:

◆ GotoState()

static void GotoState ( GLUtesselator tess,
enum TessState  newState 
)
static
155{
156 while( tess->state != newState ) {
157 /* We change the current state one level at a time, to get to
158 * the desired state.
159 */
160 if( tess->state < newState ) {
161 switch( tess->state ) {
162 case T_DORMANT:
164 gluTessBeginPolygon( tess, NULL );
165 break;
166 case T_IN_POLYGON:
168 gluTessBeginContour( tess );
169 break;
170 default:
171 ;
172 }
173 } else {
174 switch( tess->state ) {
175 case T_IN_CONTOUR:
177 gluTessEndContour( tess );
178 break;
179 case T_IN_POLYGON:
181 /* gluTessEndPolygon( tess ) is too much work! */
182 MakeDormant( tess );
183 break;
184 default:
185 ;
186 }
187 }
188 }
189}
#define GLU_TESS_MISSING_BEGIN_CONTOUR
Definition glu-libtess.h:148
#define GLU_TESS_MISSING_END_CONTOUR
Definition glu-libtess.h:150
#define GLU_TESS_MISSING_BEGIN_POLYGON
Definition glu-libtess.h:147
#define GLU_TESS_MISSING_END_POLYGON
Definition glu-libtess.h:149
static void MakeDormant(GLUtesselator *tess)
Definition tess.c:140

References CALL_ERROR_OR_ERROR_DATA, GLU_TESS_MISSING_BEGIN_CONTOUR, GLU_TESS_MISSING_BEGIN_POLYGON, GLU_TESS_MISSING_END_CONTOUR, GLU_TESS_MISSING_END_POLYGON, gluTessBeginContour, gluTessBeginPolygon, gluTessEndContour, MakeDormant(), GLUtesselator::state, T_DORMANT, T_IN_CONTOUR, and T_IN_POLYGON.

+ Here is the call graph for this function:

◆ MakeDormant()

static void MakeDormant ( GLUtesselator tess)
static
141{
142 /* Return the tessellator to its original dormant state. */
143
144 if( tess->mesh != NULL ) {
145 __gl_meshDeleteMesh( tess->mesh );
146 }
147 tess->state = T_DORMANT;
148 tess->lastEdge = NULL;
149 tess->mesh = NULL;
150}

References __gl_meshDeleteMesh(), GLUtesselator::lastEdge, GLUtesselator::mesh, GLUtesselator::state, and T_DORMANT.

Referenced by GotoState().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ noBegin()

static void GLAPIENTRY noBegin ( GLenum  type)
static
57{}

Referenced by gluNewTess(), gluTessCallback(), and gluTessEndPolygon().

+ Here is the caller graph for this function:

◆ noCombine()

static void GLAPIENTRY noCombine ( GLdouble  coords[3],
void data[4],
GLfloat  weight[4],
void **  dataOut 
)
static
63 {}

Referenced by gluNewTess(), and gluTessCallback().

+ Here is the caller graph for this function:

◆ noEdgeFlag()

static void GLAPIENTRY noEdgeFlag ( GLboolean  boundaryEdge)
static
58{}

Referenced by gluNewTess(), gluTessCallback(), and gluTessEndPolygon().

+ Here is the caller graph for this function:

◆ noEnd()

static void GLAPIENTRY noEnd ( void  )
static
60{}

Referenced by gluNewTess(), gluTessCallback(), and gluTessEndPolygon().

+ Here is the caller graph for this function:

◆ noError()

static void GLAPIENTRY noError ( GLenum  errnum)
static
61{}

Referenced by gluNewTess(), and gluTessCallback().

+ Here is the caller graph for this function:

◆ noMesh()

static void GLAPIENTRY noMesh ( GLUmesh mesh)
static
64{}

Referenced by gluNewTess(), gluTessCallback(), and gluTessEndPolygon().

+ Here is the caller graph for this function:

◆ noVertex()

static void GLAPIENTRY noVertex ( void data)
static
59{}

Referenced by gluNewTess(), gluTessCallback(), and gluTessEndPolygon().

+ Here is the caller graph for this function: