Merge commit 'origin/master' into gallium-0.2
[mesa.git] / src / glu / mesa / tess.c
index c773fbaae4b2d3b62ebd82b79e2f69e7d322ab07..341d29bae3a8e8067cc3da1ece656fe9b33b20e1 100644 (file)
@@ -1,9 +1,8 @@
-/* $Id: tess.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.1
- * Copyright (C) 1995-1999  Brian Paul
+ * Version:  3.3
+ * Copyright (C) 1995-2000  Brian Paul
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
  */
 
 
-/*
- * $Log: tess.c,v $
- * Revision 1.1  1999/08/19 00:55:42  jtg
- * Initial revision
- *
- * Revision 1.11  1999/02/27 13:55:31  brianp
- * fixed BeOS-related GLU typedef problems
- *
- * Revision 1.10  1999/01/03 03:23:15  brianp
- * now using GLAPIENTRY and GLCALLBACK keywords (Ted Jump)
- *
- * Revision 1.9  1998/06/01 01:10:29  brianp
- * small update for Next/OpenStep from Alexander Mai
- *
- * Revision 1.8  1998/02/04 00:27:58  brianp
- * cygnus changes from Stephane Rehel
- *
- * Revision 1.7  1998/01/16 03:35:26  brianp
- * fixed Windows compilation warnings (Theodore Jump)
- *
- * Revision 1.6  1997/09/17 01:51:48  brianp
- * changed glu*Callback() functions to match prototype in glu.h
- *
- * Revision 1.5  1997/07/24 01:28:44  brianp
- * changed precompiled header symbol from PCH to PC_HEADER
- *
- * Revision 1.4  1997/05/28 02:29:38  brianp
- * added support for precompiled headers (PCH), inserted APIENTRY keyword
- *
- * Revision 1.3  1996/11/12 01:23:02  brianp
- * added test to prevent free(vertex) when vertex==NULL in delete_contours()
- *
- * Revision 1.2  1996/10/22 22:57:19  brianp
- * better error handling in gluBegin/EndPolygon() from Erich Eder
- *
- * Revision 1.1  1996/09/27 01:19:39  brianp
- * Initial revision
- *
- */
-
-
 /*
  * This file is part of the polygon tesselation code contributed by
  * Bogdan Sikorski
  * This is ugly, but seems the easiest way to do things to make the
  * code work under YellowBox for Windows
  */
-#if defined(OPENSTEP) && defined(GLCALLBACK)
-#undef GLCALLBACK
-#define GLCALLBACK
+#if defined(OPENSTEP) && defined(CALLBACK)
+#undef CALLBACK
+#define CALLBACK
 #endif
 
 
-extern void tess_test_polygon(GLUtriangulatorObj *);
-extern void tess_find_contour_hierarchies(GLUtriangulatorObj *);
-extern void tess_handle_holes(GLUtriangulatorObj *);
-extern void tess_tesselate(GLUtriangulatorObj *);
-extern void tess_tesselate_with_edge_flag(GLUtriangulatorObj *);
 static void delete_contours(GLUtriangulatorObj *);
 
 #ifdef __CYGWIN32__
@@ -100,270 +53,275 @@ static void delete_contours(GLUtriangulatorObj *);
 #define _CALLBACK GLCALLBACK
 #endif
 
-void init_callbacks(tess_callbacks *callbacks)
+
+static void
+init_callbacks(tess_callbacks * callbacks)
 {
-   callbacks->begin = ( void (_CALLBACK*)(GLenum) ) 0;
-   callbacks->edgeFlag = ( void (_CALLBACK*)(GLboolean) ) 0;
-   callbacks->vertex = ( void (_CALLBACK*)(void*) ) 0;
-   callbacks->end = ( void (_CALLBACK*)(void) ) 0;
-   callbacks->error = ( void (_CALLBACK*)(GLenum) ) 0;
+   callbacks->begin = (void (_CALLBACK *) (GLenum)) 0;
+   callbacks->edgeFlag = (void (_CALLBACK *) (GLboolean)) 0;
+   callbacks->vertex = (void (_CALLBACK *) (void *)) 0;
+   callbacks->end = (void (_CALLBACK *) (void)) 0;
+   callbacks->error = (void (_CALLBACK *) (GLenum)) 0;
 }
 
-void tess_call_user_error(GLUtriangulatorObj *tobj, GLenum gluerr)
+void
+tess_call_user_error(GLUtriangulatorObj * tobj, GLenum gluerr)
 {
-   if(tobj->error==GLU_NO_ERROR)
-      tobj->error=gluerr;
-   if(tobj->callbacks.error!=NULL)
-      (tobj->callbacks.error)(gluerr);
+   if (tobj->error == GLU_NO_ERROR)
+      tobj->error = gluerr;
+   if (tobj->callbacks.error != NULL)
+      (tobj->callbacks.error) (gluerr);
 }
 
-GLUtriangulatorObj* GLAPIENTRY gluNewTess( void )
+GLUtriangulatorObj *GLAPIENTRY
+gluNewTess(void)
 {
    GLUtriangulatorObj *tobj;
-   tobj = (GLUtriangulatorObj *) malloc(sizeof(struct GLUtesselator));
-   if (!tobj)
+
+   if ((tobj = (GLUtriangulatorObj *)
+       malloc(sizeof(struct GLUtesselator))) == NULL)
       return NULL;
-   tobj->contours=tobj->last_contour=NULL;
+   tobj->contours = tobj->last_contour = NULL;
    init_callbacks(&tobj->callbacks);
-   tobj->error=GLU_NO_ERROR;
-   tobj->current_polygon=NULL;
-   tobj->contour_cnt=0;
+   tobj->error = GLU_NO_ERROR;
+   tobj->current_polygon = NULL;
+   tobj->contour_cnt = 0;
    return tobj;
 }
 
 
-void GLAPIENTRY gluTessCallback( GLUtriangulatorObj *tobj, GLenum which,
-                               void (GLCALLBACK *fn)() )
+void GLAPIENTRY
+gluTessCallback(GLUtriangulatorObj * tobj, GLenum which,
+               void (GLCALLBACK * fn) ())
 {
-       switch(which)
-       {
-               case GLU_BEGIN:
-                       tobj->callbacks.begin = (void (_CALLBACK*)(GLenum)) fn;
-                       break;
-               case GLU_EDGE_FLAG:
-                       tobj->callbacks.edgeFlag = (void (_CALLBACK*)(GLboolean)) fn;
-                       break;
-               case GLU_VERTEX:
-                       tobj->callbacks.vertex = (void (_CALLBACK*)(void *)) fn;
-                       break;
-               case GLU_END:
-                       tobj->callbacks.end = (void (_CALLBACK*)(void)) fn;
-                       break;
-               case GLU_ERROR:
-                       tobj->callbacks.error = (void (_CALLBACK*)(GLenum)) fn;
-                       break;
-               default:
-                       tobj->error=GLU_INVALID_ENUM;
-                       break;
-       }
+   switch (which) {
+   case GLU_BEGIN:
+      tobj->callbacks.begin = (void (_CALLBACK *) (GLenum)) fn;
+      break;
+   case GLU_EDGE_FLAG:
+      tobj->callbacks.edgeFlag = (void (_CALLBACK *) (GLboolean)) fn;
+      break;
+   case GLU_VERTEX:
+      tobj->callbacks.vertex = (void (_CALLBACK *) (void *)) fn;
+      break;
+   case GLU_END:
+      tobj->callbacks.end = (void (_CALLBACK *) (void)) fn;
+      break;
+   case GLU_ERROR:
+      tobj->callbacks.error = (void (_CALLBACK *) (GLenum)) fn;
+      break;
+   default:
+      tobj->error = GLU_INVALID_ENUM;
+      break;
+   }
 }
 
 
 
-void GLAPIENTRY gluDeleteTess( GLUtriangulatorObj *tobj )
+void GLAPIENTRY
+gluDeleteTess(GLUtriangulatorObj * tobj)
 {
-       if(tobj->error==GLU_NO_ERROR && tobj->contour_cnt)
-               /* was gluEndPolygon called? */
-               tess_call_user_error(tobj,GLU_TESS_ERROR1);
-       /* delete all internal structures */
-       delete_contours(tobj);
-       free(tobj);
+   if (tobj->error == GLU_NO_ERROR && tobj->contour_cnt)
+      /* was gluEndPolygon called? */
+      tess_call_user_error(tobj, GLU_TESS_ERROR1);
+   /* delete all internal structures */
+   delete_contours(tobj);
+   free(tobj);
 }
 
 
-void GLAPIENTRY gluBeginPolygon( GLUtriangulatorObj *tobj )
+void GLAPIENTRY
+gluBeginPolygon(GLUtriangulatorObj * tobj)
 {
 /*
        if(tobj->error!=GLU_NO_ERROR)
                return;
 */
-        tobj->error = GLU_NO_ERROR;
-       if(tobj->current_polygon!=NULL)
-       {
-               /* gluEndPolygon was not called */
-               tess_call_user_error(tobj,GLU_TESS_ERROR1);
-               /* delete all internal structures */
-               delete_contours(tobj);
-       }
-       else
-       {
-               if((tobj->current_polygon=
-                       (tess_polygon *)malloc(sizeof(tess_polygon)))==NULL)
-               {
-                       tess_call_user_error(tobj,GLU_OUT_OF_MEMORY);
-                       return;
-               }
-               tobj->current_polygon->vertex_cnt=0;
-               tobj->current_polygon->vertices=
-                       tobj->current_polygon->last_vertex=NULL;
-       }
+   tobj->error = GLU_NO_ERROR;
+   if (tobj->current_polygon != NULL) {
+      /* gluEndPolygon was not called */
+      tess_call_user_error(tobj, GLU_TESS_ERROR1);
+      /* delete all internal structures */
+      delete_contours(tobj);
+   }
+   else {
+      if ((tobj->current_polygon =
+          (tess_polygon *) malloc(sizeof(tess_polygon))) == NULL) {
+        tess_call_user_error(tobj, GLU_OUT_OF_MEMORY);
+        return;
+      }
+      tobj->current_polygon->vertex_cnt = 0;
+      tobj->current_polygon->vertices =
+        tobj->current_polygon->last_vertex = NULL;
+   }
 }
 
 
-void GLAPIENTRY gluEndPolygon( GLUtriangulatorObj *tobj )
+void GLAPIENTRY
+gluEndPolygon(GLUtriangulatorObj * tobj)
 {
-       /*tess_contour *contour_ptr;*/
-
-       /* there was an error */
-       if(tobj->error!=GLU_NO_ERROR) goto end;
-
-       /* check if gluBeginPolygon was called */
-       if(tobj->current_polygon==NULL)
-       {
-               tess_call_user_error(tobj,GLU_TESS_ERROR2);
-               return;
-       }
-       tess_test_polygon(tobj);
-       /* there was an error */
-       if(tobj->error!=GLU_NO_ERROR) goto end;
-
-       /* any real contours? */
-       if(tobj->contour_cnt==0)
-       {
-               /* delete all internal structures */
-               delete_contours(tobj);
-               return;
-       }
-       tess_find_contour_hierarchies(tobj);
-       /* there was an error */
-       if(tobj->error!=GLU_NO_ERROR) goto end;
-
-       tess_handle_holes(tobj);
-       /* there was an error */
-       if(tobj->error!=GLU_NO_ERROR) goto end;
-
-       /* if no callbacks, nothing to do */
-       if(tobj->callbacks.begin!=NULL && tobj->callbacks.vertex!=NULL &&
-               tobj->callbacks.end!=NULL)
-       {
-               if(tobj->callbacks.edgeFlag==NULL)
-                       tess_tesselate(tobj);
-               else
-                       tess_tesselate_with_edge_flag(tobj);
-       }
-
-end:
-       /* delete all internal structures */
-       delete_contours(tobj);
+   /*tess_contour *contour_ptr; */
+
+   /* there was an error */
+   if (tobj->error != GLU_NO_ERROR)
+      goto end;
+
+   /* check if gluBeginPolygon was called */
+   if (tobj->current_polygon == NULL) {
+      tess_call_user_error(tobj, GLU_TESS_ERROR2);
+      return;
+   }
+   tess_test_polygon(tobj);
+   /* there was an error */
+   if (tobj->error != GLU_NO_ERROR)
+      goto end;
+
+   /* any real contours? */
+   if (tobj->contour_cnt == 0) {
+      /* delete all internal structures */
+      delete_contours(tobj);
+      return;
+   }
+   tess_find_contour_hierarchies(tobj);
+   /* there was an error */
+   if (tobj->error != GLU_NO_ERROR)
+      goto end;
+
+   tess_handle_holes(tobj);
+   /* there was an error */
+   if (tobj->error != GLU_NO_ERROR)
+      goto end;
+
+   /* if no callbacks, nothing to do */
+   if (tobj->callbacks.begin != NULL && tobj->callbacks.vertex != NULL &&
+       tobj->callbacks.end != NULL) {
+      if (tobj->callbacks.edgeFlag == NULL)
+        tess_tesselate(tobj);
+      else
+        tess_tesselate_with_edge_flag(tobj);
+   }
+
+ end:
+   /* delete all internal structures */
+   delete_contours(tobj);
 }
 
 
-void GLAPIENTRY gluNextContour( GLUtriangulatorObj *tobj, GLenum type )
+void GLAPIENTRY
+gluNextContour(GLUtriangulatorObj * tobj, GLenum type)
 {
-       if(tobj->error!=GLU_NO_ERROR)
-               return;
-       if(tobj->current_polygon==NULL)
-       {
-               tess_call_user_error(tobj,GLU_TESS_ERROR2);
-               return;
-       }
-       /* first contour? */
-       if(tobj->current_polygon->vertex_cnt)
-               tess_test_polygon(tobj);
+   if (tobj->error != GLU_NO_ERROR)
+      return;
+   if (tobj->current_polygon == NULL) {
+      tess_call_user_error(tobj, GLU_TESS_ERROR2);
+      return;
+   }
+   /* first contour? */
+   if (tobj->current_polygon->vertex_cnt)
+      tess_test_polygon(tobj);
 }
 
 
-void GLAPIENTRY gluTessVertex( GLUtriangulatorObj *tobj, GLdouble v[3], void *data )
+void GLAPIENTRY
+gluTessVertex(GLUtriangulatorObj * tobj, GLdouble v[3], void *data)
 {
-       tess_polygon *polygon=tobj->current_polygon;
-       tess_vertex *last_vertex_ptr;
-
-       if(tobj->error!=GLU_NO_ERROR)
-               return;
-       if(polygon==NULL)
-       {
-               tess_call_user_error(tobj,GLU_TESS_ERROR2);
-               return;
-       }
-       last_vertex_ptr=polygon->last_vertex;
-       if(last_vertex_ptr==NULL)
-       {
-               if((last_vertex_ptr=(tess_vertex *)
-                       malloc(sizeof(tess_vertex)))==NULL)
-               {
-                       tess_call_user_error(tobj,GLU_OUT_OF_MEMORY);
-                       return;
-               }
-               polygon->vertices=last_vertex_ptr;
-               polygon->last_vertex=last_vertex_ptr;
-               last_vertex_ptr->data=data;
-               last_vertex_ptr->location[0]=v[0];
-               last_vertex_ptr->location[1]=v[1];
-               last_vertex_ptr->location[2]=v[2];
-               last_vertex_ptr->next=NULL;
-               last_vertex_ptr->previous=NULL;
-               ++(polygon->vertex_cnt);
-       }
-       else
-       {
-               tess_vertex *vertex_ptr;
-
-               /* same point twice? */
-               if(fabs(last_vertex_ptr->location[0]-v[0]) < EPSILON &&
-                       fabs(last_vertex_ptr->location[1]-v[1]) < EPSILON &&
-                       fabs(last_vertex_ptr->location[2]-v[2]) < EPSILON)
-               {
-                       tess_call_user_error(tobj,GLU_TESS_ERROR6);
-                       return;
-               }
-               if((vertex_ptr=(tess_vertex *)
-                       malloc(sizeof(tess_vertex)))==NULL)
-               {
-                       tess_call_user_error(tobj,GLU_OUT_OF_MEMORY);
-                       return;
-               }
-               vertex_ptr->data=data;
-               vertex_ptr->location[0]=v[0];
-               vertex_ptr->location[1]=v[1];
-               vertex_ptr->location[2]=v[2];
-               vertex_ptr->next=NULL;
-               vertex_ptr->previous=last_vertex_ptr;
-               ++(polygon->vertex_cnt);
-               last_vertex_ptr->next=vertex_ptr;
-               polygon->last_vertex=vertex_ptr;
-       }
+   tess_polygon *polygon = tobj->current_polygon;
+   tess_vertex *last_vertex_ptr;
+
+   if (tobj->error != GLU_NO_ERROR)
+      return;
+   if (polygon == NULL) {
+      tess_call_user_error(tobj, GLU_TESS_ERROR2);
+      return;
+   }
+   last_vertex_ptr = polygon->last_vertex;
+   if (last_vertex_ptr == NULL) {
+      if ((last_vertex_ptr = (tess_vertex *)
+          malloc(sizeof(tess_vertex))) == NULL) {
+        tess_call_user_error(tobj, GLU_OUT_OF_MEMORY);
+        return;
+      }
+      polygon->vertices = last_vertex_ptr;
+      polygon->last_vertex = last_vertex_ptr;
+      last_vertex_ptr->data = data;
+      last_vertex_ptr->location[0] = v[0];
+      last_vertex_ptr->location[1] = v[1];
+      last_vertex_ptr->location[2] = v[2];
+      last_vertex_ptr->next = NULL;
+      last_vertex_ptr->previous = NULL;
+      ++(polygon->vertex_cnt);
+   }
+   else {
+      tess_vertex *vertex_ptr;
+
+      /* same point twice? */
+      if (fabs(last_vertex_ptr->location[0] - v[0]) < EPSILON &&
+         fabs(last_vertex_ptr->location[1] - v[1]) < EPSILON &&
+         fabs(last_vertex_ptr->location[2] - v[2]) < EPSILON) {
+        tess_call_user_error(tobj, GLU_TESS_ERROR6);
+        return;
+      }
+      if ((vertex_ptr = (tess_vertex *)
+          malloc(sizeof(tess_vertex))) == NULL) {
+        tess_call_user_error(tobj, GLU_OUT_OF_MEMORY);
+        return;
+      }
+      vertex_ptr->data = data;
+      vertex_ptr->location[0] = v[0];
+      vertex_ptr->location[1] = v[1];
+      vertex_ptr->location[2] = v[2];
+      vertex_ptr->next = NULL;
+      vertex_ptr->previous = last_vertex_ptr;
+      ++(polygon->vertex_cnt);
+      last_vertex_ptr->next = vertex_ptr;
+      polygon->last_vertex = vertex_ptr;
+   }
 }
 
 
-static void delete_contours(GLUtriangulatorObj *tobj)
+static void
+delete_contours(GLUtriangulatorObj * tobj)
 {
-       tess_polygon *polygon=tobj->current_polygon;
-       tess_contour *contour,*contour_tmp;
-       tess_vertex *vertex,*vertex_tmp;
-
-       /* remove current_polygon list - if exists due to detected error */
-       if(polygon!=NULL)
-       {
-               if (polygon->vertices)
-               {
-                       for(vertex=polygon->vertices;vertex!=polygon->last_vertex;)
-                       {
-                               vertex_tmp=vertex->next;
-                               free(vertex);
-                               vertex=vertex_tmp;
-                       }
-                       free(vertex);
-               }
-               free(polygon);
-               tobj->current_polygon=NULL;
-       }
-       /* remove all contour data */
-       for(contour=tobj->contours;contour!=NULL;)
-       {
-               for(vertex=contour->vertices;vertex!=contour->last_vertex;)
-               {
-                       vertex_tmp=vertex->next;
-                       free(vertex);
-                       vertex=vertex_tmp;
-               }
-               free(vertex);
-               contour_tmp=contour->next;
-               free(contour);
-               contour=contour_tmp;
-       }
-       tobj->contours=tobj->last_contour=NULL;
-       tobj->contour_cnt=0;
+   tess_polygon *polygon = tobj->current_polygon;
+   tess_contour *contour, *contour_tmp;
+   tess_vertex *vertex, *vertex_tmp;
+
+   /* remove current_polygon list - if exists due to detected error */
+   if (polygon != NULL) {
+      if (polygon->vertices) {
+        for (vertex = polygon->vertices; vertex != polygon->last_vertex;) {
+           vertex_tmp = vertex->next;
+           free(vertex);
+           vertex = vertex_tmp;
+        }
+        free(vertex);
+      }
+      free(polygon);
+      tobj->current_polygon = NULL;
+   }
+   /* remove all contour data */
+   for (contour = tobj->contours; contour != NULL;) {
+      for (vertex = contour->vertices; vertex != contour->last_vertex;) {
+        vertex_tmp = vertex->next;
+        free(vertex);
+        vertex = vertex_tmp;
+      }
+      free(vertex);
+      contour_tmp = contour->next;
+      free(contour);
+      contour = contour_tmp;
+   }
+   tobj->contours = tobj->last_contour = NULL;
+   tobj->contour_cnt = 0;
 }
 
 
-
+void GLAPIENTRY
+gluTessNormal(GLUtesselator *tess, GLdouble valueX, GLdouble valueY, GLdouble valueZ)
+{
+   /* dummy function */
+   (void) tess;
+   (void) valueX;
+   (void) valueY;
+   (void) valueZ;
+}