Home | History | Annotate | Line # | Download | only in libtess
      1 /*
      2  * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
      3  * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining a
      6  * copy of this software and associated documentation files (the "Software"),
      7  * to deal in the Software without restriction, including without limitation
      8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      9  * and/or sell copies of the Software, and to permit persons to whom the
     10  * Software is furnished to do so, subject to the following conditions:
     11  *
     12  * The above copyright notice including the dates of first publication and
     13  * either this permission notice or a reference to
     14  * http://oss.sgi.com/projects/FreeB/
     15  * shall be included in all copies or substantial portions of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     20  * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     21  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
     22  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     23  * SOFTWARE.
     24  *
     25  * Except as contained in this notice, the name of Silicon Graphics, Inc.
     26  * shall not be used in advertising or otherwise to promote the sale, use or
     27  * other dealings in this Software without prior written authorization from
     28  * Silicon Graphics, Inc.
     29  */
     30 /*
     31 ** Author: Eric Veach, July 1994.
     32 **
     33 */
     34 
     35 #ifndef __tess_h_
     36 #define __tess_h_
     37 
     38 #include <GL/glu.h>
     39 #include <setjmp.h>
     40 #include "mesh.h"
     41 #include "dict.h"
     42 #include "priorityq.h"
     43 
     44 /* The begin/end calls must be properly nested.  We keep track of
     45  * the current state to enforce the ordering.
     46  */
     47 enum TessState { T_DORMANT, T_IN_POLYGON, T_IN_CONTOUR };
     48 
     49 /* We cache vertex data for single-contour polygons so that we can
     50  * try a quick-and-dirty decomposition first.
     51  */
     52 #define TESS_MAX_CACHE	100
     53 
     54 typedef struct CachedVertex {
     55   GLdouble	coords[3];
     56   void		*data;
     57 } CachedVertex;
     58 
     59 struct GLUtesselator {
     60 
     61   /*** state needed for collecting the input data ***/
     62 
     63   enum TessState state;		/* what begin/end calls have we seen? */
     64 
     65   GLUhalfEdge	*lastEdge;	/* lastEdge->Org is the most recent vertex */
     66   GLUmesh	*mesh;		/* stores the input contours, and eventually
     67                                    the tessellation itself */
     68 
     69   void		(GLAPIENTRY *callError)( GLenum errnum );
     70 
     71   /*** state needed for projecting onto the sweep plane ***/
     72 
     73   GLdouble	normal[3];	/* user-specified normal (if provided) */
     74   GLdouble	sUnit[3];	/* unit vector in s-direction (debugging) */
     75   GLdouble	tUnit[3];	/* unit vector in t-direction (debugging) */
     76 
     77   /*** state needed for the line sweep ***/
     78 
     79   GLdouble	relTolerance;	/* tolerance for merging features */
     80   GLenum	windingRule;	/* rule for determining polygon interior */
     81   GLboolean	fatalError;	/* fatal error: needed combine callback */
     82 
     83   Dict		*dict;		/* edge dictionary for sweep line */
     84   PriorityQ	*pq;		/* priority queue of vertex events */
     85   GLUvertex	*event;		/* current sweep event being processed */
     86 
     87   void		(GLAPIENTRY *callCombine)( GLdouble coords[3], void *data[4],
     88 			        GLfloat weight[4], void **outData );
     89 
     90   /*** state needed for rendering callbacks (see render.c) ***/
     91 
     92   GLboolean	flagBoundary;	/* mark boundary edges (use EdgeFlag) */
     93   GLboolean	boundaryOnly;	/* Extract contours, not triangles */
     94   GLUface	*lonelyTriList;
     95     /* list of triangles which could not be rendered as strips or fans */
     96 
     97   void		(GLAPIENTRY *callBegin)( GLenum type );
     98   void		(GLAPIENTRY *callEdgeFlag)( GLboolean boundaryEdge );
     99   void		(GLAPIENTRY *callVertex)( void *data );
    100   void		(GLAPIENTRY *callEnd)( void );
    101   void		(GLAPIENTRY *callMesh)( GLUmesh *mesh );
    102 
    103 
    104   /*** state needed to cache single-contour polygons for renderCache() */
    105 
    106   GLboolean	emptyCache;		/* empty cache on next vertex() call */
    107   int		cacheCount;		/* number of cached vertices */
    108   CachedVertex	cache[TESS_MAX_CACHE];	/* the vertex data */
    109 
    110   /*** rendering callbacks that also pass polygon data  ***/
    111   void		(GLAPIENTRY *callBeginData)( GLenum type, void *polygonData );
    112   void		(GLAPIENTRY *callEdgeFlagData)( GLboolean boundaryEdge,
    113 				     void *polygonData );
    114   void		(GLAPIENTRY *callVertexData)( void *data, void *polygonData );
    115   void		(GLAPIENTRY *callEndData)( void *polygonData );
    116   void		(GLAPIENTRY *callErrorData)( GLenum errnum, void *polygonData );
    117   void		(GLAPIENTRY *callCombineData)( GLdouble coords[3], void *data[4],
    118 				    GLfloat weight[4], void **outData,
    119 				    void *polygonData );
    120 
    121   jmp_buf env;			/* place to jump to when memAllocs fail */
    122 
    123   void *polygonData;		/* client data for current polygon */
    124 };
    125 
    126 void GLAPIENTRY __gl_noBeginData( GLenum type, void *polygonData );
    127 void GLAPIENTRY __gl_noEdgeFlagData( GLboolean boundaryEdge, void *polygonData );
    128 void GLAPIENTRY __gl_noVertexData( void *data, void *polygonData );
    129 void GLAPIENTRY __gl_noEndData( void *polygonData );
    130 void GLAPIENTRY __gl_noErrorData( GLenum errnum, void *polygonData );
    131 void GLAPIENTRY __gl_noCombineData( GLdouble coords[3], void *data[4],
    132 			 GLfloat weight[4], void **outData,
    133 			 void *polygonData );
    134 
    135 #define CALL_BEGIN_OR_BEGIN_DATA(a) \
    136    if (tess->callBeginData != &__gl_noBeginData) \
    137       (*tess->callBeginData)((a),tess->polygonData); \
    138    else (*tess->callBegin)((a));
    139 
    140 #define CALL_VERTEX_OR_VERTEX_DATA(a) \
    141    if (tess->callVertexData != &__gl_noVertexData) \
    142       (*tess->callVertexData)((a),tess->polygonData); \
    143    else (*tess->callVertex)((a));
    144 
    145 #define CALL_EDGE_FLAG_OR_EDGE_FLAG_DATA(a) \
    146    if (tess->callEdgeFlagData != &__gl_noEdgeFlagData) \
    147       (*tess->callEdgeFlagData)((a),tess->polygonData); \
    148    else (*tess->callEdgeFlag)((a));
    149 
    150 #define CALL_END_OR_END_DATA() \
    151    if (tess->callEndData != &__gl_noEndData) \
    152       (*tess->callEndData)(tess->polygonData); \
    153    else (*tess->callEnd)();
    154 
    155 #define CALL_COMBINE_OR_COMBINE_DATA(a,b,c,d) \
    156    if (tess->callCombineData != &__gl_noCombineData) \
    157       (*tess->callCombineData)((a),(b),(c),(d),tess->polygonData); \
    158    else (*tess->callCombine)((a),(b),(c),(d));
    159 
    160 #define CALL_ERROR_OR_ERROR_DATA(a) \
    161    if (tess->callErrorData != &__gl_noErrorData) \
    162       (*tess->callErrorData)((a),tess->polygonData); \
    163    else (*tess->callError)((a));
    164 
    165 #endif
    166