83 tess->lonelyTriList = NULL;
85 for( f = mesh->fHead.next; f != &mesh->fHead; f = f->next ) {
88 for( f = mesh->fHead.next; f != &mesh->fHead; f = f->next ) {
94 if( f->inside && ! f->marked ) {
95 RenderMaximumFaceGroup( tess, f );
99 if( tess->lonelyTriList != NULL ) {
100 RenderLonelyTriangles( tess, tess->lonelyTriList );
101 tess->lonelyTriList = NULL;
120 max.render = &RenderTriangle;
122 if( ! tess->flagBoundary ) {
123 newFace = MaximumFan( e );
if( newFace.size > max.size ) { max = newFace; }
124 newFace = MaximumFan( e->Lnext );
if( newFace.size > max.size ) { max = newFace; }
125 newFace = MaximumFan( e->Lprev );
if( newFace.size > max.size ) { max = newFace; }
127 newFace = MaximumStrip( e );
if( newFace.size > max.size ) { max = newFace; }
128 newFace = MaximumStrip( e->Lnext );
if( newFace.size > max.size ) { max = newFace; }
129 newFace = MaximumStrip( e->Lprev );
if( newFace.size > max.size ) { max = newFace; }
131 (*(max.render))( tess, max.eStart, max.size );
142 #define Marked(f) (! (f)->inside || (f)->marked)
144 #define AddToTrail(f,t) ((f)->trail = (t), (t) = (f), (f)->marked = TRUE)
146 #define FreeTrail(t) if( 1 ) { \
147 while( (t) != NULL ) { \
148 (t)->marked = FALSE; t = (t)->trail; \
160 struct FaceCount newFace = { 0, NULL, &RenderFan };
164 for( e = eOrig; ! Marked( e->Lface ); e = e->Onext ) {
165 AddToTrail( e->Lface, trail );
168 for( e = eOrig; ! Marked( e->Rface ); e = e->Oprev ) {
169 AddToTrail( e->Rface, trail );
179 #define IsEven(n) (((n) & 1) == 0)
193 struct FaceCount newFace = { 0, NULL, &RenderStrip };
194 long headSize = 0, tailSize = 0;
198 for( e = eOrig; ! Marked( e->Lface ); ++tailSize, e = e->Onext ) {
199 AddToTrail( e->Lface, trail );
202 if( Marked( e->Lface ))
break;
203 AddToTrail( e->Lface, trail );
207 for( e = eOrig; ! Marked( e->Rface ); ++headSize, e = e->Dnext ) {
208 AddToTrail( e->Rface, trail );
211 if( Marked( e->Rface ))
break;
212 AddToTrail( e->Rface, trail );
216 newFace.size = tailSize + headSize;
217 if( IsEven( tailSize )) {
218 newFace.eStart = eTail->Sym;
219 }
else if( IsEven( headSize )) {
220 newFace.eStart = eHead;
226 newFace.eStart = eHead->Onext;
240 AddToTrail( e->Lface, tess->lonelyTriList );
253 CALL_BEGIN_OR_BEGIN_DATA( GL_TRIANGLES );
255 for( ; f != NULL; f = f->trail ) {
260 if( tess->flagBoundary ) {
264 newState = ! e->Rface->inside;
265 if( edgeState != newState ) {
266 edgeState = newState;
267 CALL_EDGE_FLAG_OR_EDGE_FLAG_DATA( edgeState );
270 CALL_VERTEX_OR_VERTEX_DATA( e->Org->data );
273 }
while( e != f->anEdge );
275 CALL_END_OR_END_DATA();
285 CALL_BEGIN_OR_BEGIN_DATA( GL_TRIANGLE_FAN );
286 CALL_VERTEX_OR_VERTEX_DATA( e->Org->data );
287 CALL_VERTEX_OR_VERTEX_DATA( e->Dst->data );
289 while( ! Marked( e->Lface )) {
290 e->Lface->marked = TRUE;
293 CALL_VERTEX_OR_VERTEX_DATA( e->Dst->data );
297 CALL_END_OR_END_DATA();
307 CALL_BEGIN_OR_BEGIN_DATA( GL_TRIANGLE_STRIP );
308 CALL_VERTEX_OR_VERTEX_DATA( e->Org->data );
309 CALL_VERTEX_OR_VERTEX_DATA( e->Dst->data );
311 while( ! Marked( e->Lface )) {
312 e->Lface->marked = TRUE;
315 CALL_VERTEX_OR_VERTEX_DATA( e->Org->data );
316 if( Marked( e->Lface ))
break;
318 e->Lface->marked = TRUE;
321 CALL_VERTEX_OR_VERTEX_DATA( e->Dst->data );
325 CALL_END_OR_END_DATA();
340 for( f = mesh->fHead.next; f != &mesh->fHead; f = f->next ) {
342 CALL_BEGIN_OR_BEGIN_DATA( GL_LINE_LOOP );
345 CALL_VERTEX_OR_VERTEX_DATA( e->Org->data );
347 }
while( e != f->anEdge );
348 CALL_END_OR_END_DATA();
356 #define SIGN_INCONSISTENT 2
358 static int ComputeNormal(
GLUtesselator *tess, GLdouble norm[3],
int check )
371 GLdouble dot, xc, yc, zc, xp, yp, zp, n[3];
388 norm[0] = norm[1] = norm[2] = 0.0;
392 xc = vc->coords[0] - v0->coords[0];
393 yc = vc->coords[1] - v0->coords[1];
394 zc = vc->coords[2] - v0->coords[2];
396 xp = xc; yp = yc; zp = zc;
397 xc = vc->coords[0] - v0->coords[0];
398 yc = vc->coords[1] - v0->coords[1];
399 zc = vc->coords[2] - v0->coords[2];
402 n[0] = yp*zc - zp*yc;
403 n[1] = zp*xc - xp*zc;
404 n[2] = xp*yc - yp*xc;
406 dot = n[0]*norm[0] + n[1]*norm[1] + n[2]*norm[2];
412 norm[0] += n[0]; norm[1] += n[1]; norm[2] += n[2];
414 norm[0] -= n[0]; norm[1] -= n[1]; norm[2] -= n[2];
416 }
else if( dot != 0 ) {
419 if( sign < 0 )
return SIGN_INCONSISTENT;
422 if( sign > 0 )
return SIGN_INCONSISTENT;
445 if( tess->cacheCount < 3 ) {
450 norm[0] = tess->normal[0];
451 norm[1] = tess->normal[1];
452 norm[2] = tess->normal[2];
453 if( norm[0] == 0 && norm[1] == 0 && norm[2] == 0 ) {
454 ComputeNormal( tess, norm, FALSE );
457 sign = ComputeNormal( tess, norm, TRUE );
458 if( sign == SIGN_INCONSISTENT ) {
468 switch( tess->windingRule ) {
469 case GLU_TESS_WINDING_ODD:
470 case GLU_TESS_WINDING_NONZERO:
472 case GLU_TESS_WINDING_POSITIVE:
473 if( sign < 0 )
return TRUE;
475 case GLU_TESS_WINDING_NEGATIVE:
476 if( sign > 0 )
return TRUE;
478 case GLU_TESS_WINDING_ABS_GEQ_TWO:
482 CALL_BEGIN_OR_BEGIN_DATA( tess->boundaryOnly ? GL_LINE_LOOP
483 : (tess->cacheCount > 3) ? GL_TRIANGLE_FAN
486 CALL_VERTEX_OR_VERTEX_DATA( v0->data );
488 for( vc = v0+1; vc < vn; ++vc ) {
489 CALL_VERTEX_OR_VERTEX_DATA( vc->data );
492 for( vc = vn-1; vc > v0; --vc ) {
493 CALL_VERTEX_OR_VERTEX_DATA( vc->data );
496 CALL_END_OR_END_DATA();