11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* 21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** License Applicability. Except to the extent portions of this file are 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** made subject to an alternative license as permitted in the SGI Free 41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** Software License B, Version 1.1 (the "License"), the contents of this 51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** file are subject only to the provisions of the License. You may not use 61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** this file except in compliance with the License. You may obtain a copy 71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 81cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: 91cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** 101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** http://oss.sgi.com/projects/FreeB 111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** 121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** Note that, as provided in the License, the Software is distributed on an 131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS 141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND 151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A 161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. 171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** 181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** Original Code. The Original Code is: OpenGL Sample Implementation, 191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, 201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. 211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** Copyright in any portions created by third parties is as indicated 221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** elsewhere herein. All Rights Reserved. 231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** 241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** Additional Notice Provisions: The application programming interfaces 251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** established by SGI in conjunction with the Original Code are The 261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released 271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version 281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X 291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** Window System(R) (Version 1.3), released October 19, 1998. This software 301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** was created using the OpenGL(R) version 1.2.1 Sample Implementation 311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** published by SGI, but has not been independently verified as being 321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** compliant with the OpenGL(R) version 1.2.1 Specification. 331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** 341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger*/ 351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* 361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** Author: Eric Veach, July 1994. 371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** 381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** $Date$ $Revision$ 391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger** $Header: //depot/main/gfx/lib/glu/libtess/tess.c#7 $ 401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger*/ 411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "gluos.h" 431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include <stddef.h> 441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include <assert.h> 451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include <setjmp.h> 461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "memalloc.h" 471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "tess.h" 481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "mesh.h" 491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "normal.h" 501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "sweep.h" 511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "tessmono.h" 521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "render.h" 531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define GLU_TESS_DEFAULT_TOLERANCE 0.0 551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define GLU_TESS_MESH 100112 /* void (*)(GLUmesh *mesh) */ 561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define TRUE 1 581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define FALSE 0 591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*ARGSUSED*/ static void GLAPIENTRY noBegin( GLenum type ) {} 611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*ARGSUSED*/ static void GLAPIENTRY noEdgeFlag( GLboolean boundaryEdge ) {} 621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*ARGSUSED*/ static void GLAPIENTRY noVertex( void *data ) {} 631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*ARGSUSED*/ static void GLAPIENTRY noEnd( void ) {} 641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*ARGSUSED*/ static void GLAPIENTRY noError( GLenum errnum ) {} 651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*ARGSUSED*/ static void GLAPIENTRY noCombine( GLdouble coords[3], void *data[4], 661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GLfloat weight[4], void **dataOut ) {} 671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*ARGSUSED*/ static void GLAPIENTRY noMesh( GLUmesh *mesh ) {} 681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*ARGSUSED*/ void GLAPIENTRY __gl_noBeginData( GLenum type, 711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void *polygonData ) {} 721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*ARGSUSED*/ void GLAPIENTRY __gl_noEdgeFlagData( GLboolean boundaryEdge, 731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void *polygonData ) {} 741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*ARGSUSED*/ void GLAPIENTRY __gl_noVertexData( void *data, 751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void *polygonData ) {} 761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*ARGSUSED*/ void GLAPIENTRY __gl_noEndData( void *polygonData ) {} 771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*ARGSUSED*/ void GLAPIENTRY __gl_noErrorData( GLenum errnum, 781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void *polygonData ) {} 791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*ARGSUSED*/ void GLAPIENTRY __gl_noCombineData( GLdouble coords[3], 801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void *data[4], 811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GLfloat weight[4], 821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void **outData, 831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void *polygonData ) {} 841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* Half-edges are allocated in pairs (see mesh.c) */ 861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergertypedef struct { GLUhalfEdge e, eSym; } EdgePair; 871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define MAX(a,b) ((a) > (b) ? (a) : (b)) 891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define MAX_FAST_ALLOC (MAX(sizeof(EdgePair), \ 901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger MAX(sizeof(GLUvertex),sizeof(GLUface)))) 911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 931cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGLUtesselator * GLAPIENTRY 941cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergergluNewTess( void ) 951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger{ 961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GLUtesselator *tess; 971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /* Only initialize fields which can be changed by the api. Other fields 991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * are initialized where they are used. 1001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 1011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (memInit( MAX_FAST_ALLOC ) == 0) { 1031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return 0; /* out of memory */ 1041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess = (GLUtesselator *)memAlloc( sizeof( GLUtesselator )); 1061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (tess == NULL) { 1071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return 0; /* out of memory */ 1081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->state = T_DORMANT; 1111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->normal[0] = 0; 1131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->normal[1] = 0; 1141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->normal[2] = 0; 1151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->relTolerance = GLU_TESS_DEFAULT_TOLERANCE; 1171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->windingRule = GLU_TESS_WINDING_ODD; 1181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->flagBoundary = FALSE; 1191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->boundaryOnly = FALSE; 1201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->callBegin = &noBegin; 1221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->callEdgeFlag = &noEdgeFlag; 1231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->callVertex = &noVertex; 1241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->callEnd = &noEnd; 1251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->callError = &noError; 1271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->callCombine = &noCombine; 1281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->callMesh = &noMesh; 1291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->callBeginData= &__gl_noBeginData; 1311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->callEdgeFlagData= &__gl_noEdgeFlagData; 1321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->callVertexData= &__gl_noVertexData; 1331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->callEndData= &__gl_noEndData; 1341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->callErrorData= &__gl_noErrorData; 1351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->callCombineData= &__gl_noCombineData; 1361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->polygonData= NULL; 1381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return tess; 1401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void MakeDormant( GLUtesselator *tess ) 1431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger{ 1441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /* Return the tessellator to its original dormant state. */ 1451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if( tess->mesh != NULL ) { 1471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger __gl_meshDeleteMesh( tess->mesh ); 1481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->state = T_DORMANT; 1501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->lastEdge = NULL; 1511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->mesh = NULL; 1521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define RequireState( tess, s ) if( tess->state != s ) GotoState(tess,s) 1551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void GotoState( GLUtesselator *tess, enum TessState newState ) 1571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger{ 1581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger while( tess->state != newState ) { 1591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /* We change the current state one level at a time, to get to 1601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * the desired state. 1611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 1621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if( tess->state < newState ) { 1631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger switch( tess->state ) { 1641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case T_DORMANT: 1651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger CALL_ERROR_OR_ERROR_DATA( GLU_TESS_MISSING_BEGIN_POLYGON ); 1661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger gluTessBeginPolygon( tess, NULL ); 1671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 1681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case T_IN_POLYGON: 1691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger CALL_ERROR_OR_ERROR_DATA( GLU_TESS_MISSING_BEGIN_CONTOUR ); 1701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger gluTessBeginContour( tess ); 1711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 1721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger default: 1731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger assert(0); 1741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 1751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 1771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger switch( tess->state ) { 1781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case T_IN_CONTOUR: 1791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger CALL_ERROR_OR_ERROR_DATA( GLU_TESS_MISSING_END_CONTOUR ); 1801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger gluTessEndContour( tess ); 1811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 1821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case T_IN_POLYGON: 1831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger CALL_ERROR_OR_ERROR_DATA( GLU_TESS_MISSING_END_POLYGON ); 1841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /* gluTessEndPolygon( tess ) is too much work! */ 1851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger MakeDormant( tess ); 1861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 1871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger default: 1881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger assert(0); 1891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 1901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GLAPIENTRY 1971cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergergluDeleteTess( GLUtesselator *tess ) 1981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger{ 1991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger RequireState( tess, T_DORMANT ); 2001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger memFree( tess ); 2011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GLAPIENTRY 2051cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergergluTessProperty( GLUtesselator *tess, GLenum which, GLdouble value ) 2061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger{ 2071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GLenum windingRule; 2081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger switch( which ) { 2101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case GLU_TESS_TOLERANCE: 2111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if( value < 0.0 || value > 1.0 ) break; 2121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->relTolerance = value; 2131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 2141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case GLU_TESS_WINDING_RULE: 2161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger windingRule = (GLenum) value; 2171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if( windingRule != value ) break; /* not an integer */ 2181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger switch( windingRule ) { 2201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case GLU_TESS_WINDING_ODD: 2211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case GLU_TESS_WINDING_NONZERO: 2221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case GLU_TESS_WINDING_POSITIVE: 2231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case GLU_TESS_WINDING_NEGATIVE: 2241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case GLU_TESS_WINDING_ABS_GEQ_TWO: 2251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->windingRule = windingRule; 2261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 2271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger default: 2281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 2291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case GLU_TESS_BOUNDARY_ONLY: 2321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->boundaryOnly = (value != 0); 2331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 2341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger default: 2361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger CALL_ERROR_OR_ERROR_DATA( GLU_INVALID_ENUM ); 2371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 2381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger CALL_ERROR_OR_ERROR_DATA( GLU_INVALID_VALUE ); 2401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* Returns tessellator property */ 2431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GLAPIENTRY 2441cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergergluGetTessProperty( GLUtesselator *tess, GLenum which, GLdouble *value ) 2451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger{ 2461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger switch (which) { 2471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case GLU_TESS_TOLERANCE: 2481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /* tolerance should be in range [0..1] */ 2491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger assert(0.0 <= tess->relTolerance && tess->relTolerance <= 1.0); 2501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *value= tess->relTolerance; 2511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 2521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case GLU_TESS_WINDING_RULE: 2531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger assert(tess->windingRule == GLU_TESS_WINDING_ODD || 2541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->windingRule == GLU_TESS_WINDING_NONZERO || 2551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->windingRule == GLU_TESS_WINDING_POSITIVE || 2561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->windingRule == GLU_TESS_WINDING_NEGATIVE || 2571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->windingRule == GLU_TESS_WINDING_ABS_GEQ_TWO); 2581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *value= tess->windingRule; 2591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 2601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case GLU_TESS_BOUNDARY_ONLY: 2611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger assert(tess->boundaryOnly == TRUE || tess->boundaryOnly == FALSE); 2621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *value= tess->boundaryOnly; 2631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 2641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger default: 2651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *value= 0.0; 2661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger CALL_ERROR_OR_ERROR_DATA( GLU_INVALID_ENUM ); 2671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 2681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} /* gluGetTessProperty() */ 2701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GLAPIENTRY 2721cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergergluTessNormal( GLUtesselator *tess, GLdouble x, GLdouble y, GLdouble z ) 2731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger{ 2741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->normal[0] = x; 2751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->normal[1] = y; 2761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->normal[2] = z; 2771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GLAPIENTRY 2801cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergergluTessCallback( GLUtesselator *tess, GLenum which, void (GLAPIENTRY *fn)()) 2811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger{ 2821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger switch( which ) { 2831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case GLU_TESS_BEGIN: 2841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->callBegin = (fn == NULL) ? &noBegin : (void (GLAPIENTRY *)(GLenum)) fn; 2851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 2861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case GLU_TESS_BEGIN_DATA: 2871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->callBeginData = (fn == NULL) ? 2881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger &__gl_noBeginData : (void (GLAPIENTRY *)(GLenum, void *)) fn; 2891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 2901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case GLU_TESS_EDGE_FLAG: 2911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->callEdgeFlag = (fn == NULL) ? &noEdgeFlag : 2921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger (void (GLAPIENTRY *)(GLboolean)) fn; 2931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /* If the client wants boundary edges to be flagged, 2941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * we render everything as separate triangles (no strips or fans). 2951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 2961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->flagBoundary = (fn != NULL); 2971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 2981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case GLU_TESS_EDGE_FLAG_DATA: 2991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->callEdgeFlagData= (fn == NULL) ? 3001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger &__gl_noEdgeFlagData : (void (GLAPIENTRY *)(GLboolean, void *)) fn; 3011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /* If the client wants boundary edges to be flagged, 3021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * we render everything as separate triangles (no strips or fans). 3031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 3041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->flagBoundary = (fn != NULL); 3051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 3061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case GLU_TESS_VERTEX: 3071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->callVertex = (fn == NULL) ? &noVertex : 3081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger (void (GLAPIENTRY *)(void *)) fn; 3091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 3101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case GLU_TESS_VERTEX_DATA: 3111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->callVertexData = (fn == NULL) ? 3121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger &__gl_noVertexData : (void (GLAPIENTRY *)(void *, void *)) fn; 3131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 3141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case GLU_TESS_END: 3151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->callEnd = (fn == NULL) ? &noEnd : (void (GLAPIENTRY *)(void)) fn; 3161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 3171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case GLU_TESS_END_DATA: 3181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->callEndData = (fn == NULL) ? &__gl_noEndData : 3191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger (void (GLAPIENTRY *)(void *)) fn; 3201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 3211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case GLU_TESS_ERROR: 3221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->callError = (fn == NULL) ? &noError : (void (GLAPIENTRY *)(GLenum)) fn; 3231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 3241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case GLU_TESS_ERROR_DATA: 3251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->callErrorData = (fn == NULL) ? 3261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger &__gl_noErrorData : (void (GLAPIENTRY *)(GLenum, void *)) fn; 3271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 3281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case GLU_TESS_COMBINE: 3291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->callCombine = (fn == NULL) ? &noCombine : 3301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger (void (GLAPIENTRY *)(GLdouble [3],void *[4], GLfloat [4], void ** )) fn; 3311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 3321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case GLU_TESS_COMBINE_DATA: 3331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->callCombineData = (fn == NULL) ? &__gl_noCombineData : 3341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger (void (GLAPIENTRY *)(GLdouble [3], 3351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void *[4], 3361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GLfloat [4], 3371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void **, 3381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void *)) fn; 3391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 3401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case GLU_TESS_MESH: 3411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->callMesh = (fn == NULL) ? &noMesh : (void (GLAPIENTRY *)(GLUmesh *)) fn; 3421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 3431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger default: 3441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger CALL_ERROR_OR_ERROR_DATA( GLU_INVALID_ENUM ); 3451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 3461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 3471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 3481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic int AddVertex( GLUtesselator *tess, GLdouble coords[3], void *data ) 3501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger{ 3511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GLUhalfEdge *e; 3521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger e = tess->lastEdge; 3541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if( e == NULL ) { 3551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /* Make a self-loop (one vertex, one edge). */ 3561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger e = __gl_meshMakeEdge( tess->mesh ); 3581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (e == NULL) return 0; 3591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if ( !__gl_meshSplice( e, e->Sym ) ) return 0; 3601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 3611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /* Create a new vertex and edge which immediately follow e 3621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * in the ordering around the left face. 3631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 3641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (__gl_meshSplitEdge( e ) == NULL) return 0; 3651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger e = e->Lnext; 3661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 3671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /* The new vertex is now e->Org. */ 3691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger e->Org->data = data; 3701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger e->Org->coords[0] = coords[0]; 3711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger e->Org->coords[1] = coords[1]; 3721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger e->Org->coords[2] = coords[2]; 3731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /* The winding of an edge says how the winding number changes as we 3751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * cross from the edge''s right face to its left face. We add the 3761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * vertices in such an order that a CCW contour will add +1 to 3771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * the winding number of the region inside the contour. 3781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 3791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger e->winding = 1; 3801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger e->Sym->winding = -1; 3811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->lastEdge = e; 3831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return 1; 3851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 3861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void CacheVertex( GLUtesselator *tess, GLdouble coords[3], void *data ) 3891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger{ 3901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger CachedVertex *v = &tess->cache[tess->cacheCount]; 3911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger v->data = data; 3931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger v->coords[0] = coords[0]; 3941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger v->coords[1] = coords[1]; 3951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger v->coords[2] = coords[2]; 3961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ++tess->cacheCount; 3971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 3981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic int EmptyCache( GLUtesselator *tess ) 4011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger{ 4021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger CachedVertex *v = tess->cache; 4031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger CachedVertex *vLast; 4041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->mesh = __gl_meshNewMesh(); 4061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (tess->mesh == NULL) return 0; 4071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for( vLast = v + tess->cacheCount; v < vLast; ++v ) { 4091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if ( !AddVertex( tess, v->coords, v->data ) ) return 0; 4101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->cacheCount = 0; 4121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->emptyCache = FALSE; 4131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return 1; 4151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 4161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GLAPIENTRY 4191cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergergluTessVertex( GLUtesselator *tess, GLdouble coords[3], void *data ) 4201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger{ 4211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int i, tooLarge = FALSE; 4221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GLdouble x, clamped[3]; 4231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger RequireState( tess, T_IN_CONTOUR ); 4251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if( tess->emptyCache ) { 4271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if ( !EmptyCache( tess ) ) { 4281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger CALL_ERROR_OR_ERROR_DATA( GLU_OUT_OF_MEMORY ); 4291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 4301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->lastEdge = NULL; 4321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for( i = 0; i < 3; ++i ) { 4341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger x = coords[i]; 4351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if( x < - GLU_TESS_MAX_COORD ) { 4361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger x = - GLU_TESS_MAX_COORD; 4371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tooLarge = TRUE; 4381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if( x > GLU_TESS_MAX_COORD ) { 4401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger x = GLU_TESS_MAX_COORD; 4411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tooLarge = TRUE; 4421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger clamped[i] = x; 4441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if( tooLarge ) { 4461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger CALL_ERROR_OR_ERROR_DATA( GLU_TESS_COORD_TOO_LARGE ); 4471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if( tess->mesh == NULL ) { 4501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if( tess->cacheCount < TESS_MAX_CACHE ) { 4511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger CacheVertex( tess, clamped, data ); 4521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 4531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if ( !EmptyCache( tess ) ) { 4551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger CALL_ERROR_OR_ERROR_DATA( GLU_OUT_OF_MEMORY ); 4561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 4571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if ( !AddVertex( tess, clamped, data ) ) { 4601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger CALL_ERROR_OR_ERROR_DATA( GLU_OUT_OF_MEMORY ); 4611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 4631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GLAPIENTRY 4661cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergergluTessBeginPolygon( GLUtesselator *tess, void *data ) 4671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger{ 4681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger RequireState( tess, T_DORMANT ); 4691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->state = T_IN_POLYGON; 4711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->cacheCount = 0; 4721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->emptyCache = FALSE; 4731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->mesh = NULL; 4741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->polygonData= data; 4761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 4771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GLAPIENTRY 4801cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergergluTessBeginContour( GLUtesselator *tess ) 4811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger{ 4821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger RequireState( tess, T_IN_POLYGON ); 4831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->state = T_IN_CONTOUR; 4851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->lastEdge = NULL; 4861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if( tess->cacheCount > 0 ) { 4871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /* Just set a flag so we don't get confused by empty contours 4881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * -- these can be generated accidentally with the obsolete 4891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * NextContour() interface. 4901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 4911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->emptyCache = TRUE; 4921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 4941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GLAPIENTRY 4971cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergergluTessEndContour( GLUtesselator *tess ) 4981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger{ 4991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger RequireState( tess, T_IN_CONTOUR ); 5001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->state = T_IN_POLYGON; 5011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 5021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GLAPIENTRY 5041cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergergluTessEndPolygon( GLUtesselator *tess ) 5051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger{ 5061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GLUmesh *mesh; 5071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (setjmp(tess->env) != 0) { 5091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /* come back here if out of memory */ 5101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger CALL_ERROR_OR_ERROR_DATA( GLU_OUT_OF_MEMORY ); 5111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 5121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 5131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger RequireState( tess, T_IN_POLYGON ); 5151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->state = T_DORMANT; 5161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if( tess->mesh == NULL ) { 5181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if( ! tess->flagBoundary && tess->callMesh == &noMesh ) { 5191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /* Try some special code to make the easy cases go quickly 5211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * (eg. convex polygons). This code does NOT handle multiple contours, 5221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * intersections, edge flags, and of course it does not generate 5231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * an explicit mesh either. 5241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 5251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if( __gl_renderCache( tess )) { 5261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->polygonData= NULL; 5271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 5281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 5291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 5301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if ( !EmptyCache( tess ) ) longjmp(tess->env,1); /* could've used a label*/ 5311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 5321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /* Determine the polygon normal and project vertices onto the plane 5341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * of the polygon. 5351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 5361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger __gl_projectPolygon( tess ); 5371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /* __gl_computeInterior( tess ) computes the planar arrangement specified 5391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * by the given contours, and further subdivides this arrangement 5401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * into regions. Each region is marked "inside" if it belongs 5411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * to the polygon, according to the rule given by tess->windingRule. 5421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Each interior region is guaranteed be monotone. 5431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 5441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if ( !__gl_computeInterior( tess ) ) { 5451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger longjmp(tess->env,1); /* could've used a label */ 5461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 5471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger mesh = tess->mesh; 5491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if( ! tess->fatalError ) { 5501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int rc = 1; 5511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /* If the user wants only the boundary contours, we throw away all edges 5531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * except those which separate the interior from the exterior. 5541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Otherwise we tessellate all the regions marked "inside". 5551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 5561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if( tess->boundaryOnly ) { 5571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger rc = __gl_meshSetWindingNumber( mesh, 1, TRUE ); 5581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 5591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger rc = __gl_meshTessellateInterior( mesh ); 5601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 5611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (rc == 0) longjmp(tess->env,1); /* could've used a label */ 5621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger __gl_meshCheckMesh( mesh ); 5641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if( tess->callBegin != &noBegin || tess->callEnd != &noEnd 5661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger || tess->callVertex != &noVertex || tess->callEdgeFlag != &noEdgeFlag 5671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger || tess->callBeginData != &__gl_noBeginData 5681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger || tess->callEndData != &__gl_noEndData 5691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger || tess->callVertexData != &__gl_noVertexData 5701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger || tess->callEdgeFlagData != &__gl_noEdgeFlagData ) 5711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { 5721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if( tess->boundaryOnly ) { 5731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger __gl_renderBoundary( tess, mesh ); /* output boundary contours */ 5741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 5751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger __gl_renderMesh( tess, mesh ); /* output strips and fans */ 5761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 5771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 5781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if( tess->callMesh != &noMesh ) { 5791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /* Throw away the exterior faces, so that all faces are interior. 5811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * This way the user doesn't have to check the "inside" flag, 5821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * and we don't need to even reveal its existence. It also leaves 5831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * the freedom for an implementation to not generate the exterior 5841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * faces in the first place. 5851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 5861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger __gl_meshDiscardExterior( mesh ); 5871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger (*tess->callMesh)( mesh ); /* user wants the mesh itself */ 5881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->mesh = NULL; 5891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->polygonData= NULL; 5901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 5911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 5921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 5931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger __gl_meshDeleteMesh( mesh ); 5941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->polygonData= NULL; 5951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tess->mesh = NULL; 5961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 5971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*XXXblythe unused function*/ 6001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if 0 6011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GLAPIENTRY 6021cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergergluDeleteMesh( GLUmesh *mesh ) 6031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger{ 6041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger __gl_meshDeleteMesh( mesh ); 6051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 6061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 6071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 6081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 6091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 6101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*******************************************************/ 6111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 6121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* Obsolete calls -- for backward compatibility */ 6131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 6141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if 0 6151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GLAPIENTRY 6161cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergergluBeginPolygon( GLUtesselator *tess ) 6171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger{ 6181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger gluTessBeginPolygon( tess, NULL ); 6191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger gluTessBeginContour( tess ); 6201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 6211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 6221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 6231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*ARGSUSED*/ 6241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GLAPIENTRY 6251cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergergluNextContour( GLUtesselator *tess, GLenum type ) 6261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger{ 6271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger gluTessEndContour( tess ); 6281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger gluTessBeginContour( tess ); 6291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 6301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 6311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 6321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GLAPIENTRY 6331cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergergluEndPolygon( GLUtesselator *tess ) 6341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger{ 6351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger gluTessEndContour( tess ); 6361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger gluTessEndPolygon( tess ); 6371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 6381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 639