Home | History | Annotate | Download | only in libtess
      1 /*
      2 ** $Header: /cvs/projects/ogl-sample/main/gfx/lib/glu/libtess/README,v 1.1 2000/04/26 05:53:59 ljp Exp $
      3 */
      4 
      5 General Polygon Tesselation
      6 ---------------------------
      7 
      8   This note describes a tesselator for polygons consisting of one or
      9   more closed contours.  It is backward-compatible with the current
     10   OpenGL Utilities tesselator, and is intended to replace it.  Here is
     11   a summary of the major differences:
     12 
     13    - input contours can be intersecting, self-intersecting, or degenerate.
     14 
     15    - supports a choice of several winding rules for determining which parts
     16      of the polygon are on the "interior".  This makes it possible to do
     17      CSG operations on polygons.
     18 
     19    - boundary extraction: instead of tesselating the polygon, returns a
     20      set of closed contours which separate the interior from the exterior.
     21 
     22    - returns the output as a small number of triangle fans and strips,
     23      rather than a list of independent triangles (when possible).
     24 
     25    - output is available as an explicit mesh (a quad-edge structure),
     26      in addition to the normal callback interface.
     27 
     28    - the algorithm used is extremely robust.
     29 
     30 
     31 The interface
     32 -------------
     33 
     34   The tesselator state is maintained in a "tesselator object".
     35   These are allocated and destroyed using
     36 
     37      GLUtesselator *gluNewTess( void );
     38      void gluDeleteTess( GLUtesselator *tess );
     39 
     40   Several tesselator objects may be used simultaneously.
     41 
     42   Inputs
     43   ------
     44 
     45   The input contours are specified with the following routines:
     46 
     47      void gluTessBeginPolygon( GLUtesselator *tess );
     48      void gluTessBeginContour( GLUtesselator *tess );
     49      void gluTessVertex( GLUtesselator *tess, GLUcoord coords[3], void *data );
     50      void gluTessEndContour( GLUtesselator *tess );
     51      void gluTessEndPolygon( GLUtesselator *tess );
     52 
     53   Within each BeginPolygon/EndPolygon pair, there can be zero or more
     54   calls to BeginContour/EndContour.  Within each contour, there are zero
     55   or more calls to gluTessVertex().  The vertices specify a closed
     56   contour (the last vertex of each contour is automatically linked to
     57   the first).
     58 
     59   "coords" give the coordinates of the vertex in 3-space.  For useful
     60   results, all vertices should lie in some plane, since the vertices
     61   are projected onto a plane before tesselation.  "data" is a pointer
     62   to a user-defined vertex structure, which typically contains other
     63   information such as color, texture coordinates, normal, etc.  It is
     64   used to refer to the vertex during rendering.
     65 
     66   The library can be compiled in single- or double-precision; the type
     67   GLUcoord represents either "float" or "double" accordingly.  The GLU
     68   version will be available in double-precision only.  Compile with
     69   GLU_TESS_API_FLOAT defined to get the single-precision version.
     70 
     71   When EndPolygon is called, the tesselation algorithm determines
     72   which regions are interior to the given contours, according to one
     73   of several "winding rules" described below.  The interior regions
     74   are then tesselated, and the output is provided as callbacks.
     75 
     76 
     77   Rendering Callbacks
     78   -------------------
     79 
     80   Callbacks are specified by the client using
     81 
     82      void gluTessCallback( GLUtesselator *tess, GLenum which, void (*fn)());
     83 
     84   If "fn" is NULL, any previously defined callback is discarded.
     85 
     86   The callbacks used to provide output are:	/* which == */
     87 
     88      void begin( GLenum type );			/* GLU_TESS_BEGIN */
     89      void edgeFlag( GLboolean flag );		/* GLU_TESS_EDGE_FLAG */
     90      void vertex( void *data );			/* GLU_TESS_VERTEX */
     91      void end( void );				/* GLU_TESS_END */
     92 
     93   Any of the callbacks may be left undefined; if so, the corresponding
     94   information will not be supplied during rendering.
     95 
     96   The "begin" callback indicates the start of a primitive; type is one
     97   of GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, or GL_TRIANGLES (but see the
     98   notes on "boundary extraction" below).
     99 
    100   It is followed by any number of "vertex" callbacks, which supply the
    101   vertices in the same order as expected by the corresponding glBegin()
    102   call.  After the last vertex of a given primitive, there is a callback
    103   to "end".
    104 
    105   If the "edgeFlag" callback is provided, no triangle fans or strips
    106   will be used.  When edgeFlag is called, if "flag" is GL_TRUE then each
    107   vertex which follows begins an edge which lies on the polygon boundary
    108   (ie. an edge which separates an interior region from an exterior one).
    109   If "flag" is GL_FALSE, each vertex which follows begins an edge which lies
    110   in the polygon interior.  "edgeFlag" will be called before the first
    111   call to "vertex".
    112 
    113   Other Callbacks
    114   ---------------
    115 
    116    void mesh( GLUmesh *mesh );			/* GLU_TESS_MESH */
    117 
    118    - Returns an explicit mesh, represented using the quad-edge structure
    119      (Guibas/Stolfi '85).  Other implementations of this interface might
    120      use a different mesh structure, so this is available only only as an
    121      SGI extension.  When the mesh is no longer needed, it should be freed
    122      using
    123 
    124 	void gluDeleteMesh( GLUmesh *mesh );
    125 
    126      There is a brief description of this data structure in the include
    127      file "mesh.h".  For the full details, see L. Guibas and J. Stolfi,
    128      Primitives for the manipulation of general subdivisions and the
    129      computation of Voronoi diagrams, ACM Transactions on Graphics,
    130      4(2):74-123, April 1985.  For an introduction, see the course notes
    131      for CS348a, "Mathematical Foundations of Computer Graphics",
    132      available at the Stanford bookstore (and taught during the fall
    133      quarter).
    134 
    135    void error( GLenum errno );			/* GLU_TESS_ERROR */
    136 
    137    - errno is one of	GLU_TESS_MISSING_BEGIN_POLYGON,
    138 			GLU_TESS_MISSING_END_POLYGON,
    139 			GLU_TESS_MISSING_BEGIN_CONTOUR,
    140 			GLU_TESS_MISSING_END_CONTOUR,
    141 			GLU_TESS_COORD_TOO_LARGE,
    142 			GLU_TESS_NEED_COMBINE_CALLBACK
    143 
    144      The first four are obvious.  The interface recovers from these
    145      errors by inserting the missing call(s).
    146 
    147      GLU_TESS_COORD_TOO_LARGE says that some vertex coordinate exceeded
    148      the predefined constant GLU_TESS_MAX_COORD in absolute value, and
    149      that the value has been clamped.  (Coordinate values must be small
    150      enough so that two can be multiplied together without overflow.)
    151 
    152      GLU_TESS_NEED_COMBINE_CALLBACK says that the algorithm detected an
    153      intersection between two edges in the input data, and the "combine"
    154      callback (below) was not provided.  No output will be generated.
    155 
    156 
    157    void combine( GLUcoord coords[3], void *data[4],	/* GLU_TESS_COMBINE */
    158 		 GLUcoord weight[4], void **outData );
    159 
    160    - When the algorithm detects an intersection, or wishes to merge
    161      features, it needs to create a new vertex.  The vertex is defined
    162      as a linear combination of up to 4 existing vertices, referenced
    163      by data[0..3].  The coefficients of the linear combination are
    164      given by weight[0..3]; these weights always sum to 1.0.  All vertex
    165      pointers are valid even when some of the weights are zero.
    166      "coords" gives the location of the new vertex.
    167 
    168      The user must allocate another vertex, interpolate parameters
    169      using "data" and "weights", and return the new vertex pointer in
    170      "outData".  This handle is supplied during rendering callbacks.
    171      For example, if the polygon lies in an arbitrary plane in 3-space,
    172      and we associate a color with each vertex, the combine callback might
    173      look like this:
    174 
    175      void myCombine( GLUcoord coords[3], VERTEX *d[4],
    176                      GLUcoord w[4], VERTEX **dataOut )
    177      {
    178         VERTEX *new = new_vertex();
    179 
    180         new->x = coords[0];
    181         new->y = coords[1];
    182         new->z = coords[2];
    183         new->r = w[0]*d[0]->r + w[1]*d[1]->r + w[2]*d[2]->r + w[3]*d[3]->r;
    184         new->g = w[0]*d[0]->g + w[1]*d[1]->g + w[2]*d[2]->g + w[3]*d[3]->g;
    185         new->b = w[0]*d[0]->b + w[1]*d[1]->b + w[2]*d[2]->b + w[3]*d[3]->b;
    186         new->a = w[0]*d[0]->a + w[1]*d[1]->a + w[2]*d[2]->a + w[3]*d[3]->a;
    187         *dataOut = new;
    188      }
    189 
    190      If the algorithm detects an intersection, then the "combine" callback
    191      must be defined, and must write a non-NULL pointer into "dataOut".
    192      Otherwise the GLU_TESS_NEED_COMBINE_CALLBACK error occurs, and no
    193      output is generated.  This is the only error that can occur during
    194      tesselation and rendering.
    195 
    196 
    197   Control over Tesselation
    198   ------------------------
    199 
    200    void gluTessProperty( GLUtesselator *tess, GLenum which, GLUcoord value );
    201 
    202    Properties defined:
    203 
    204     - GLU_TESS_WINDING_RULE.  Possible values:
    205 
    206 	  GLU_TESS_WINDING_ODD
    207 	  GLU_TESS_WINDING_NONZERO
    208 	  GLU_TESS_WINDING_POSITIVE
    209 	  GLU_TESS_WINDING_NEGATIVE
    210 	  GLU_TESS_WINDING_ABS_GEQ_TWO
    211 
    212       The input contours parition the plane into regions.  A winding
    213       rule determines which of these regions are inside the polygon.
    214 
    215       For a single contour C, the winding number of a point x is simply
    216       the signed number of revolutions we make around x as we travel
    217       once around C (where CCW is positive).  When there are several
    218       contours, the individual winding numbers are summed.  This
    219       procedure associates a signed integer value with each point x in
    220       the plane.  Note that the winding number is the same for all
    221       points in a single region.
    222 
    223       The winding rule classifies a region as "inside" if its winding
    224       number belongs to the chosen category (odd, nonzero, positive,
    225       negative, or absolute value of at least two).  The current GLU
    226       tesselator implements the "odd" rule.  The "nonzero" rule is another
    227       common way to define the interior.  The other three rules are
    228       useful for polygon CSG operations (see below).
    229 
    230     - GLU_TESS_BOUNDARY_ONLY.  Values: TRUE (non-zero) or FALSE (zero).
    231 
    232       If TRUE, returns a set of closed contours which separate the
    233       polygon interior and exterior (rather than a tesselation).
    234       Exterior contours are oriented CCW with respect to the normal,
    235       interior contours are oriented CW.  The GLU_TESS_BEGIN callback
    236       uses the type GL_LINE_LOOP for each contour.
    237 
    238     - GLU_TESS_TOLERANCE.  Value: a real number between 0.0 and 1.0.
    239 
    240       This specifies a tolerance for merging features to reduce the size
    241       of the output.  For example, two vertices which are very close to
    242       each other might be replaced by a single vertex.  The tolerance
    243       is multiplied by the largest coordinate magnitude of any input vertex;
    244       this specifies the maximum distance that any feature can move as the
    245       result of a single merge operation.  If a single feature takes part
    246       in several merge operations, the total distance moved could be larger.
    247 
    248       Feature merging is completely optional; the tolerance is only a hint.
    249       The implementation is free to merge in some cases and not in others,
    250       or to never merge features at all.  The default tolerance is zero.
    251 
    252       The current implementation merges vertices only if they are exactly
    253       coincident, regardless of the current tolerance.  A vertex is
    254       spliced into an edge only if the implementation is unable to
    255       distinguish which side of the edge the vertex lies on.
    256       Two edges are merged only when both endpoints are identical.
    257 
    258 
    259    void gluTessNormal( GLUtesselator *tess,
    260 		      GLUcoord x, GLUcoord y, GLUcoord z )
    261 
    262     - Lets the user supply the polygon normal, if known.  All input data
    263       is projected into a plane perpendicular to the normal before
    264       tesselation.  All output triangles are oriented CCW with
    265       respect to the normal (CW orientation can be obtained by
    266       reversing the sign of the supplied normal).  For example, if
    267       you know that all polygons lie in the x-y plane, call
    268       "gluTessNormal(tess, 0.0, 0.0, 1.0)" before rendering any polygons.
    269 
    270     - If the supplied normal is (0,0,0) (the default value), the
    271       normal is determined as follows.  The direction of the normal,
    272       up to its sign, is found by fitting a plane to the vertices,
    273       without regard to how the vertices are connected.  It is
    274       expected that the input data lies approximately in plane;
    275       otherwise projection perpendicular to the computed normal may
    276       substantially change the geometry.  The sign of the normal is
    277       chosen so that the sum of the signed areas of all input contours
    278       is non-negative (where a CCW contour has positive area).
    279 
    280     - The supplied normal persists until it is changed by another
    281       call to gluTessNormal.
    282 
    283 
    284   Backward compatibility with the GLU tesselator
    285   ----------------------------------------------
    286 
    287   The preferred interface is the one described above.  The following
    288   routines are obsolete, and are provided only for backward compatibility:
    289 
    290     typedef GLUtesselator GLUtriangulatorObj;	/* obsolete name */
    291 
    292     void gluBeginPolygon( GLUtesselator *tess );
    293     void gluNextContour( GLUtesselator *tess, GLenum type );
    294     void gluEndPolygon( GLUtesselator *tess );
    295 
    296   "type" is one of GLU_EXTERIOR, GLU_INTERIOR, GLU_CCW, GLU_CW, or
    297   GLU_UNKNOWN.  It is ignored by the current GLU tesselator.
    298 
    299   GLU_BEGIN, GLU_VERTEX, GLU_END, GLU_ERROR, and GLU_EDGE_FLAG are defined
    300   as synonyms for GLU_TESS_BEGIN, GLU_TESS_VERTEX, GLU_TESS_END,
    301   GLU_TESS_ERROR, and GLU_TESS_EDGE_FLAG.
    302 
    303 
    304 Polygon CSG operations
    305 ----------------------
    306 
    307   The features of the tesselator make it easy to find the union, difference,
    308   or intersection of several polygons.
    309 
    310   First, assume that each polygon is defined so that the winding number
    311   is 0 for each exterior region, and 1 for each interior region.  Under
    312   this model, CCW contours define the outer boundary of the polygon, and
    313   CW contours define holes.  Contours may be nested, but a nested
    314   contour must be oriented oppositely from the contour that contains it.
    315 
    316   If the original polygons do not satisfy this description, they can be
    317   converted to this form by first running the tesselator with the
    318   GLU_TESS_BOUNDARY_ONLY property turned on.  This returns a list of
    319   contours satisfying the restriction above.  By allocating two
    320   tesselator objects, the callbacks from one tesselator can be fed
    321   directly to the input of another.
    322 
    323   Given two or more polygons of the form above, CSG operations can be
    324   implemented as follows:
    325 
    326   Union
    327      Draw all the input contours as a single polygon.  The winding number
    328      of each resulting region is the number of original polygons
    329      which cover it.  The union can be extracted using the
    330      GLU_TESS_WINDING_NONZERO or GLU_TESS_WINDING_POSITIVE winding rules.
    331      Note that with the nonzero rule, we would get the same result if
    332      all contour orientations were reversed.
    333 
    334   Intersection (two polygons at a time only)
    335      Draw a single polygon using the contours from both input polygons.
    336      Extract the result using GLU_TESS_WINDING_ABS_GEQ_TWO.  (Since this
    337      winding rule looks at the absolute value, reversing all contour
    338      orientations does not change the result.)
    339 
    340   Difference
    341 
    342      Suppose we want to compute A \ (B union C union D).  Draw a single
    343      polygon consisting of the unmodified contours from A, followed by
    344      the contours of B,C,D with the vertex order reversed (this changes
    345      the winding number of the interior regions to -1).  To extract the
    346      result, use the GLU_TESS_WINDING_POSITIVE rule.
    347 
    348      If B,C,D are the result of a GLU_TESS_BOUNDARY_ONLY call, an
    349      alternative to reversing the vertex order is to reverse the sign of
    350      the supplied normal.  For example in the x-y plane, call
    351      gluTessNormal( tess, 0.0, 0.0, -1.0 ).
    352 
    353 
    354 Performance
    355 -----------
    356 
    357   The tesselator is not intended for immediate-mode rendering; when
    358   possible the output should be cached in a user structure or display
    359   list.  General polygon tesselation is an inherently difficult problem,
    360   especially given the goal of extreme robustness.
    361 
    362   The implementation makes an effort to output a small number of fans
    363   and strips; this should improve the rendering performance when the
    364   output is used in a display list.
    365 
    366   Single-contour input polygons are first tested to see whether they can
    367   be rendered as a triangle fan with respect to the first vertex (to
    368   avoid running the full decomposition algorithm on convex polygons).
    369   Non-convex polygons may be rendered by this "fast path" as well, if
    370   the algorithm gets lucky in its choice of a starting vertex.
    371 
    372   For best performance follow these guidelines:
    373 
    374    - supply the polygon normal, if available, using gluTessNormal().
    375      This represents about 10% of the computation time.  For example,
    376      if all polygons lie in the x-y plane, use gluTessNormal(tess,0,0,1).
    377 
    378    - render many polygons using the same tesselator object, rather than
    379      allocating a new tesselator for each one.  (In a multi-threaded,
    380      multi-processor environment you may get better performance using
    381      several tesselators.)
    382 
    383 
    384 Comparison with the GLU tesselator
    385 ----------------------------------
    386 
    387   On polygons which make it through the "fast path", the tesselator is
    388   3 to 5 times faster than the GLU tesselator.
    389 
    390   On polygons which don't make it through the fast path (but which don't
    391   have self-intersections or degeneracies), it is about 2 times slower.
    392 
    393   On polygons with self-intersections or degeneraces, there is nothing
    394   to compare against.
    395 
    396   The new tesselator generates many more fans and strips, reducing the
    397   number of vertices that need to be sent to the hardware.
    398 
    399   Key to the statistics:
    400 
    401 	vert		number of input vertices on all contours
    402 	cntr		number of input contours
    403 	tri		number of triangles in all output primitives
    404 	strip		number of triangle strips
    405 	fan		number of triangle fans
    406 	ind		number of independent triangles
    407 	ms		number of milliseconds for tesselation
    408 			(on a 150MHz R4400 Indy)
    409 
    410   Convex polygon examples:
    411 
    412 New:     3 vert,   1 cntr,     1 tri,   0 strip,   0 fan,     1 ind,  0.0459 ms
    413 Old:     3 vert,   1 cntr,     1 tri,   0 strip,   0 fan,     1 ind,   0.149 ms
    414 New:     4 vert,   1 cntr,     2 tri,   0 strip,   1 fan,     0 ind,  0.0459 ms
    415 Old:     4 vert,   1 cntr,     2 tri,   0 strip,   0 fan,     2 ind,   0.161 ms
    416 New:    36 vert,   1 cntr,    34 tri,   0 strip,   1 fan,     0 ind,   0.153 ms
    417 Old:    36 vert,   1 cntr,    34 tri,   0 strip,   0 fan,    34 ind,   0.621 ms
    418 
    419   Concave single-contour polygons:
    420 
    421 New:     5 vert,   1 cntr,     3 tri,   0 strip,   1 fan,     0 ind,   0.052 ms
    422 Old:     5 vert,   1 cntr,     3 tri,   0 strip,   0 fan,     3 ind,   0.252 ms
    423 New:    19 vert,   1 cntr,    17 tri,   2 strip,   2 fan,     1 ind,   0.911 ms
    424 Old:    19 vert,   1 cntr,    17 tri,   0 strip,   0 fan,    17 ind,   0.529 ms
    425 New:   151 vert,   1 cntr,   149 tri,  13 strip,  18 fan,     3 ind,    6.82 ms
    426 Old:   151 vert,   1 cntr,   149 tri,   0 strip,   3 fan,   143 ind,     2.7 ms
    427 New:   574 vert,   1 cntr,   572 tri,  59 strip,  54 fan,    11 ind,    26.6 ms
    428 Old:   574 vert,   1 cntr,   572 tri,   0 strip,  31 fan,   499 ind,    12.4 ms
    429 
    430   Multiple contours, but no intersections:
    431 
    432 New:     7 vert,   2 cntr,     7 tri,   1 strip,   0 fan,     0 ind,   0.527 ms
    433 Old:     7 vert,   2 cntr,     7 tri,   0 strip,   0 fan,     7 ind,   0.274 ms
    434 New:    81 vert,   6 cntr,    89 tri,   9 strip,   7 fan,     6 ind,    3.88 ms
    435 Old:    81 vert,   6 cntr,    89 tri,   0 strip,  13 fan,    61 ind,     2.2 ms
    436 New:   391 vert,  19 cntr,   413 tri,  37 strip,  32 fan,    26 ind,    20.2 ms
    437 Old:   391 vert,  19 cntr,   413 tri,   0 strip,  25 fan,   363 ind,    8.68 ms
    438 
    439   Self-intersecting and degenerate examples:
    440 
    441 Bowtie:  4 vert,   1 cntr,     2 tri,   0 strip,   0 fan,     2 ind,   0.483 ms
    442 Star:    5 vert,   1 cntr,     5 tri,   0 strip,   0 fan,     5 ind,    0.91 ms
    443 Random: 24 vert,   7 cntr,    46 tri,   2 strip,  12 fan,     7 ind,    5.32 ms
    444 Font:  333 vert,   2 cntr,   331 tri,  32 strip,  16 fan,     3 ind,    14.1 ms
    445 :      167 vert,  35 cntr,   254 tri,   8 strip,  56 fan,    52 ind,    46.3 ms
    446 :       78 vert,   1 cntr,  2675 tri, 148 strip, 207 fan,   180 ind,     243 ms
    447 :    12480 vert,   2 cntr, 12478 tri, 736 strip,1275 fan,     5 ind,    1010 ms
    448