Added GLU 1.3 tessellation (except winding rule code).

This commit is contained in:
Gareth Hughes 1999-09-10 02:03:31 +00:00
parent 2ba7c1cbe4
commit 2856b53e03
13 changed files with 1142 additions and 1976 deletions

View File

@ -1,4 +1,4 @@
/* $Id: glu.h,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
/* $Id: glu.h,v 1.2 1999/09/10 02:08:18 gareth Exp $ */
/*
* Mesa 3-D graphics library
@ -23,8 +23,11 @@
/*
* $Log: glu.h,v $
* Revision 1.1 1999/08/19 00:55:40 jtg
* Initial revision
* Revision 1.2 1999/09/10 02:08:18 gareth
* Added GLU 1.3 tessellation (except winding rule code).
*
* Revision 1.1.1.1 1999/08/19 00:55:40 jtg
* Imported sources
*
* Revision 3.6 1999/02/14 03:39:45 brianp
* updated for BeOS R4
@ -88,6 +91,7 @@ extern "C" {
#define GLU_VERSION_1_1 1
#define GLU_VERSION_1_2 1
#define GLU_TRUE GL_TRUE
@ -110,30 +114,42 @@ enum {
GLU_OUTSIDE = 100020,
GLU_INSIDE = 100021,
/* Tesselator */
GLU_BEGIN = 100100,
GLU_VERTEX = 100101,
GLU_END = 100102,
GLU_ERROR = 100103,
GLU_EDGE_FLAG = 100104,
/* Tessellator */
GLU_TESS_BEGIN = 100100,
GLU_TESS_VERTEX = 100101,
GLU_TESS_END = 100102,
GLU_TESS_ERROR = 100103,
GLU_TESS_EDGE_FLAG = 100104,
GLU_TESS_COMBINE = 100105,
/* Contour types */
GLU_CW = 100120,
GLU_CCW = 100121,
GLU_INTERIOR = 100122,
GLU_EXTERIOR = 100123,
GLU_UNKNOWN = 100124,
GLU_TESS_BEGIN_DATA = 100106,
GLU_TESS_VERTEX_DATA = 100107,
GLU_TESS_END_DATA = 100108,
GLU_TESS_ERROR_DATA = 100109,
GLU_TESS_EDGE_FLAG_DATA = 100110,
GLU_TESS_COMBINE_DATA = 100111,
/* Tesselation errors */
GLU_TESS_ERROR1 = 100151, /* missing gluEndPolygon */
GLU_TESS_ERROR2 = 100152, /* missing gluBeginPolygon */
GLU_TESS_ERROR3 = 100153, /* misoriented contour */
GLU_TESS_ERROR4 = 100154, /* vertex/edge intersection */
GLU_TESS_ERROR5 = 100155, /* misoriented or self-intersecting loops */
GLU_TESS_ERROR6 = 100156, /* coincident vertices */
GLU_TESS_ERROR7 = 100157, /* all vertices collinear */
GLU_TESS_ERROR8 = 100158, /* intersecting edges */
GLU_TESS_ERROR9 = 100159, /* not coplanar contours */
/* Winding rules */
GLU_TESS_WINDING_ODD = 100130,
GLU_TESS_WINDING_NONZERO = 100131,
GLU_TESS_WINDING_POSITIVE = 100132,
GLU_TESS_WINDING_NEGATIVE = 100133,
GLU_TESS_WINDING_ABS_GEQ_TWO = 100134,
/* Tessellation properties */
GLU_TESS_WINDING_RULE = 100140,
GLU_TESS_BOUNDARY_ONLY = 100141,
GLU_TESS_TOLERANCE = 100142,
/* Tessellation errors */
GLU_TESS_ERROR1 = 100151, /* Missing gluBeginPolygon */
GLU_TESS_ERROR2 = 100152, /* Missing gluBeginContour */
GLU_TESS_ERROR3 = 100153, /* Missing gluEndPolygon */
GLU_TESS_ERROR4 = 100154, /* Missing gluEndContour */
GLU_TESS_ERROR5 = 100155, /* */
GLU_TESS_ERROR6 = 100156, /* */
GLU_TESS_ERROR7 = 100157, /* */
GLU_TESS_ERROR8 = 100158, /* */
/* NURBS */
GLU_AUTO_LOAD_MATRIX = 100200,
@ -201,21 +217,39 @@ enum {
/* New in GLU 1.1 */
GLU_VERSION = 100800,
GLU_EXTENSIONS = 100801
GLU_EXTENSIONS = 100801,
/*** GLU 1.0 tessellation - obsolete! ***/
/* Contour types */
GLU_CW = 100120,
GLU_CCW = 100121,
GLU_INTERIOR = 100122,
GLU_EXTERIOR = 100123,
GLU_UNKNOWN = 100124,
/* Tessellator */
GLU_BEGIN = GLU_TESS_BEGIN,
GLU_VERTEX = GLU_TESS_VERTEX,
GLU_END = GLU_TESS_END,
GLU_ERROR = GLU_TESS_ERROR,
GLU_EDGE_FLAG = GLU_TESS_EDGE_FLAG
};
/*
* These are the GLU 1.1 typedefs. GLU 1.2 has different ones!
* These are the GLU 1.1 typedefs. GLU 1.3 has different ones!
*/
#if defined(__BEOS__)
/* The BeOS does something funky and makes these typedefs in one
* of its system headers.
*/
/* The BeOS does something funky and makes these typedefs in one
* of its system headers.
*/
#else
typedef struct GLUquadric GLUquadricObj;
typedef struct GLUtesselator GLUtriangulatorObj;
typedef struct GLUnurbs GLUnurbsObj;
typedef struct GLUquadric GLUquadricObj;
typedef struct GLUnurbs GLUnurbsObj;
/* FIXME: We need to implement the other 1.3 typedefs - GH */
typedef struct GLUtesselator GLUtesselator;
#endif
@ -392,25 +426,49 @@ GLUAPI void GLAPIENTRY gluNurbsCallback( GLUnurbsObj *nobj, GLenum which,
/*
*
* Polygon tesselation
* Polygon tessellation
*
*/
GLUAPI GLUtriangulatorObj* GLAPIENTRY gluNewTess( void );
GLUAPI GLUtesselator* GLAPIENTRY gluNewTess( void );
GLUAPI void GLAPIENTRY gluTessCallback( GLUtriangulatorObj *tobj, GLenum which,
void (GLCALLBACK *fn)() );
GLUAPI void GLAPIENTRY gluDeleteTess( GLUtesselator *tobj );
GLUAPI void GLAPIENTRY gluDeleteTess( GLUtriangulatorObj *tobj );
GLUAPI void GLAPIENTRY gluTessBeginPolygon( GLUtesselator *tobj,
void *polygon_data );
GLUAPI void GLAPIENTRY gluBeginPolygon( GLUtriangulatorObj *tobj );
GLUAPI void GLAPIENTRY gluTessBeginContour( GLUtesselator *tobj );
GLUAPI void GLAPIENTRY gluEndPolygon( GLUtriangulatorObj *tobj );
GLUAPI void GLAPIENTRY gluTessVertex( GLUtesselator *tobj, GLdouble coords[3],
void *vertex_data );
GLUAPI void GLAPIENTRY gluNextContour( GLUtriangulatorObj *tobj, GLenum type );
GLUAPI void GLAPIENTRY gluTessEndContour( GLUtesselator *tobj );
GLUAPI void GLAPIENTRY gluTessVertex( GLUtriangulatorObj *tobj, GLdouble v[3],
void *data );
GLUAPI void GLAPIENTRY gluTessEndPolygon( GLUtesselator *tobj );
GLUAPI void GLAPIENTRY gluTessProperty( GLUtesselator *tobj, GLenum which,
GLdouble value );
GLUAPI void GLAPIENTRY gluTessNormal( GLUtesselator *tobj, GLdouble x,
GLdouble y, GLdouble z );
GLUAPI void GLAPIENTRY gluTessCallback( GLUtesselator *tobj, GLenum which,
void (GLCALLBACK *fn)() );
GLUAPI void GLAPIENTRY gluGetTessProperty( GLUtesselator *tobj, GLenum which,
GLdouble *value );
/*
*
* Obsolete 1.0 tessellation functions
*
*/
GLUAPI void GLAPIENTRY gluBeginPolygon( GLUtesselator *tobj );
GLUAPI void GLAPIENTRY gluNextContour( GLUtesselator *tobj, GLenum type );
GLUAPI void GLAPIENTRY gluEndPolygon( GLUtesselator *tobj );

View File

@ -1,4 +1,4 @@
/* $Id: glu_mangle.h,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
/* $Id: glu_mangle.h,v 1.2 1999/09/10 02:08:19 gareth Exp $ */
/*
* Mesa 3-D graphics library
@ -23,8 +23,11 @@
/*
* $Log: glu_mangle.h,v $
* Revision 1.1 1999/08/19 00:55:40 jtg
* Initial revision
* Revision 1.2 1999/09/10 02:08:19 gareth
* Added GLU 1.3 tessellation (except winding rule code).
*
* Revision 1.1.1.1 1999/08/19 00:55:40 jtg
* Imported sources
*
* Revision 3.1 1999/06/21 22:00:42 brianp
* added #ifndef GLU_MANGLE_H stuff
@ -75,12 +78,19 @@
#define gluPwlCurve mgluPwlCurve
#define gluNurbsCallback mgluNurbsCallback
#define gluNewTess mgluNewTess
#define gluTessCallback mgluTessCallback
#define gluDeleteTess mgluDeleteTess
#define gluBeginPolygon mgluBeginPolygon
#define gluEndPolygon mgluEndPolygon
#define gluNextContour mgluNextContour
#define gluTessBeginPolygon mgluTessBeginPolygon
#define gluTessBeginContour mgluTessBeginContour
#define gluTessVertex mgluTessVertex
#define gluTessEndPolygon mgluTessEndPolygon
#define gluTessEndContour mgluTessEndContour
#define gluTessProperty mgluTessProperty
#define gluTessNormal mgluTessNormal
#define gluTessCallback mgluTessCallback
#define gluGetTessProperty mgluGetTessProperty
#define gluBeginPolygon mgluBeginPolygon
#define gluNextContour mgluNextContour
#define gluEndPolygon mgluEndPolygon
#define gluGetString mgluGetString
#endif

View File

@ -29,7 +29,7 @@ INCDIR = ../include
LIBDIR = ../lib
SOURCES = glu.c mipmap.c nurbs.c nurbscrv.c nurbssrf.c nurbsutl.c \
project.c quadric.c tess.c tesselat.c polytest.c
project.c quadric.c tess.c tess_fist.c tess_hash.c tess_heap.c
OBJECTS = $(SOURCES:.c=.o)

View File

@ -19,11 +19,14 @@
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
# $Id: Makefile.BeOS-R4,v 1.1 1999/08/19 00:55:42 jtg Exp $
# $Id: Makefile.BeOS-R4,v 1.2 1999/09/10 02:03:31 gareth Exp $
# $Log: Makefile.BeOS-R4,v $
# Revision 1.1 1999/08/19 00:55:42 jtg
# Initial revision
# Revision 1.2 1999/09/10 02:03:31 gareth
# Added GLU 1.3 tessellation (except winding rule code).
#
# Revision 1.1.1.1 1999/08/19 00:55:42 jtg
# Imported sources
#
# Revision 1.2 1999/02/02 04:44:40 brianp
# fixed some problems
@ -42,7 +45,7 @@ INCDIR = ../include
LIBDIR = ../lib
SOURCES = glu.c mipmap.c nurbs.c nurbscrv.c nurbssrf.c nurbsutl.c \
project.c quadric.c tess.c tesselat.c polytest.c
project.c quadric.c tess.c tess_fist.c tess_hash.c tess_heap.c
OBJECTS = $(SOURCES:.c=.o)

View File

@ -1,4 +1,4 @@
# $Id: Makefile.X11,v 1.1 1999/08/19 00:55:42 jtg Exp $
# $Id: Makefile.X11,v 1.2 1999/09/10 02:03:31 gareth Exp $
# Mesa 3-D graphics library
# Version: 3.1
@ -15,7 +15,7 @@ INCDIR = ../include
LIBDIR = ../lib
SOURCES = glu.c mipmap.c nurbs.c nurbscrv.c nurbssrf.c nurbsutl.c \
project.c quadric.c tess.c tesselat.c polytest.c
project.c quadric.c tess.c tess_fist.c tess_hash.c tess_heap.c
OBJECTS = $(SOURCES:.c=.o)

View File

@ -45,10 +45,17 @@ EXPORTS
gluPwlCurve
gluNurbsCallback
gluNewTess
gluTessCallback
gluDeleteTess
gluBeginPolygon
gluEndPolygon
gluNextContour
gluTessBeginPolygon
gluTessBeginContour
gluTessVertex
gluTessEndContour
gluTessEndPolygon
gluTessProperty
gluTessNormal
gluTessCallback
gluGetTessProperty
gluBeginPolygon
gluNextContour
gluEndPolygon
gluGetString

View File

@ -15,10 +15,11 @@ LIBDIR = [-.lib]
CFLAGS = /include=$(INCDIR)/define=(FBIND=1)
SOURCES = glu.c mipmap.c nurbs.c nurbscrv.c nurbssrf.c nurbsutl.c \
project.c quadric.c tess.c tesselat.c polytest.c
project.c quadric.c tess.c tess_fist.c tess_hash.c tess_heap.c
OBJECTS =glu.obj,mipmap.obj,nurbs.obj,nurbscrv.obj,nurbssrf.obj,nurbsutl.obj,\
project.obj,quadric.obj,tess.obj,tesselat.obj,polytest.obj
project.obj,quadric.obj,tess.obj,tess_fist.obj,tess_hash.obj,\
tess_heap.obj

View File

@ -1,4 +1,4 @@
/* $Id: glu.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
/* $Id: glu.c,v 1.2 1999/09/10 02:03:31 gareth Exp $ */
/*
* Mesa 3-D graphics library
@ -23,8 +23,11 @@
/*
* $Log: glu.c,v $
* Revision 1.1 1999/08/19 00:55:42 jtg
* Initial revision
* Revision 1.2 1999/09/10 02:03:31 gareth
* Added GLU 1.3 tessellation (except winding rule code).
*
* Revision 1.1.1.1 1999/08/19 00:55:42 jtg
* Imported sources
*
* Revision 1.13 1999/03/31 19:07:28 brianp
* added GL_EXT_abgr to extensions
@ -220,8 +223,7 @@ const GLubyte* GLAPIENTRY gluErrorString( GLenum errorCode )
"misoriented or self-intersecting loops",
"coincident vertices",
"colinear vertices",
"intersecting edges",
"not coplanar contours"
"intersecting edges"
};
static char *nurbs_error[] = {
"spline order un-supported",
@ -301,7 +303,7 @@ const GLubyte* GLAPIENTRY gluErrorString( GLenum errorCode )
else if (errorCode==GLU_INCOMPATIBLE_GL_VERSION) {
return (GLubyte *) "incompatible GL version";
}
else if (errorCode>=GLU_TESS_ERROR1 && errorCode<=GLU_TESS_ERROR9) {
else if (errorCode>=GLU_TESS_ERROR1 && errorCode<=GLU_TESS_ERROR8) {
return (GLubyte *) tess_error[errorCode-GLU_TESS_ERROR1];
}
else if (errorCode>=GLU_NURBS_ERROR1 && errorCode<=GLU_NURBS_ERROR37) {

View File

@ -9,5 +9,6 @@ nurbsutl.obj : gluP.h [-.include.gl]gl.h [-.include.gl]glu.h nurbs.h
project.obj : gluP.h [-.include.gl]gl.h [-.include.gl]glu.h
quadric.obj : gluP.h [-.include.gl]gl.h [-.include.gl]glu.h
tess.obj : gluP.h [-.include.gl]gl.h [-.include.gl]glu.h tess.h
tesselat.obj : gluP.h [-.include.gl]gl.h [-.include.gl]glu.h tess.h
polytest.obj : gluP.h [-.include.gl]gl.h [-.include.gl]glu.h tess.h
tess_fist.obj : gluP.h [-.include.gl]gl.h [-.include.gl]glu.h tess.h
tess_hash.obj : gluP.h [-.include.gl]gl.h [-.include.gl]glu.h tess.h
tess_heap.obj : gluP.h [-.include.gl]gl.h [-.include.gl]glu.h tess.h

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,121 +1,108 @@
/* $Id: tess.h,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
/* $Id: tess.h,v 1.2 1999/09/10 02:03:31 gareth Exp $ */
/*
* Mesa 3-D graphics library
* Version: 3.1
* Copyright (C) 1995-1998 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Copyright (C) 1999 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* $Log: tess.h,v $
* Revision 1.1 1999/08/19 00:55:42 jtg
* Initial revision
/*****************************************************************************
*
* Revision 1.5 1999/02/27 13:55:31 brianp
* fixed BeOS-related GLU typedef problems
* GLU 1.3 Polygon Tessellation by Gareth Hughes <garethh@lucent.com>
*
* Revision 1.4 1999/01/03 03:23:15 brianp
* now using GLAPIENTRY and GLCALLBACK keywords (Ted Jump)
*
* Revision 1.3 1997/10/29 02:02:20 brianp
* various MS Windows compiler changes (David Bucciarelli, v20 3dfx driver)
*
* Revision 1.2 1997/05/24 13:30:58 brianp
* added TESS_H multi-inclusion prevention test
*
* Revision 1.1 1996/09/27 01:19:39 brianp
* Initial revision
*
*/
*****************************************************************************/
#ifndef __GLU_TESS_H__
#define __GLU_TESS_H__
/*
* This file is part of the polygon tesselation code contributed by
* Bogdan Sikorski
*/
#ifndef TESS_H
#define TESS_H
#include <stdarg.h>
#include <stdio.h>
#include "gluP.h"
#define EPSILON 1e-06 /* epsilon for double precision compares */
#include "tess_typedefs.h"
#include "tess_heap.h"
#if 0
#include "tess_grid.h"
#endif
typedef enum
{
OXY,
OYZ,
OXZ
} projection_type;
typedef struct callbacks_str
{
void (GLCALLBACK *begin)( GLenum mode );
void (GLCALLBACK *edgeFlag)( GLboolean flag );
void (GLCALLBACK *vertex)( GLvoid *v );
void (GLCALLBACK *end)( void );
void (GLCALLBACK *error)( GLenum err );
} tess_callbacks;
typedef struct vertex_str
{
void *data;
GLdouble location[3];
GLdouble x,y;
GLboolean edge_flag;
struct vertex_str *shadow_vertex;
struct vertex_str *next,*previous;
} tess_vertex;
typedef struct contour_str
{
GLenum type;
GLuint vertex_cnt;
GLdouble area;
GLenum orientation;
struct vertex_str *vertices,*last_vertex;
struct contour_str *next,*previous;
} tess_contour;
typedef struct polygon_str
{
GLuint vertex_cnt;
GLdouble A,B,C,D;
GLdouble area;
GLenum orientation;
struct vertex_str *vertices,*last_vertex;
} tess_polygon;
#ifdef __cplusplus
extern "C" {
#endif
/*****************************************************************************
* The GLUtesselator structure:
*****************************************************************************/
struct GLUtesselator
{
tess_contour *contours,*last_contour;
GLuint contour_cnt;
tess_callbacks callbacks;
tess_polygon *current_polygon;
GLenum error;
GLdouble A,B,C,D;
projection_type projection;
tess_callbacks_t callbacks;
GLboolean boundary_only;
GLenum winding_rule;
GLdouble tolerance;
tess_plane_t plane;
GLuint contour_count;
tess_contour_t *contours, *last_contour;
tess_contour_t *current_contour;
GLdouble mins[2], maxs[2];
GLuint vertex_count;
tess_vertex_t **sorted_vertices;
#if 0
tess_grid_t *grid; /* Not currently used... */
#endif
heap_t *heap;
GLenum error;
};
extern void tess_call_user_error(GLUtriangulatorObj *,GLenum);
/*****************************************************************************
* Tessellation error handler:
*****************************************************************************/
extern void tess_error_callback( GLUtesselator *, GLenum, void * );
/*****************************************************************************
* Debugging output: (to be removed...)
*****************************************************************************/
extern int tess_debug_level;
int vdebugstr( char *format_str, ... );
#ifdef _DEBUG
#define DEBUGP(level, body) \
do { \
if ( tess_debug_level >= level ) { \
vdebugstr( "%11.11s:%-5d ", __FILE__, __LINE__, level ); \
vdebugstr body; \
fflush ( stderr ); \
} \
} while ( 0 )
#define DEBUGIF(level) do { if ( tess_debug_level >= level ) {
#define DEBUGENDIF } } while ( 0 )
#else
#define DEBUGP(level, body)
#define DEBUGIF(level) while(0) {
#define DEBUGENDIF }
#endif
#ifdef __cplusplus
}
#endif
#endif // __GLU_TESS_H__

View File

@ -1,456 +0,0 @@
/* $Id: tesselat.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
/*
* Mesa 3-D graphics library
* Version: 2.4
* Copyright (C) 1995-1997 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* $Log: tesselat.c,v $
* Revision 1.1 1999/08/19 00:55:42 jtg
* Initial revision
*
* 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 1997/02/17 17:24:58 brianp
* more tesselation changes (Randy Frank)
*
* Revision 1.2 1997/02/13 18:31:57 brianp
* fixed some numerical precision problems (Randy Frank)
*
* 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
*/
#ifdef PC_HEADER
#include "all.h"
#else
#include <stdlib.h>
#include <math.h>
#include "tess.h"
#endif
static GLboolean edge_flag;
static void emit_triangle(GLUtriangulatorObj *, tess_vertex *,
tess_vertex *,tess_vertex *);
static void emit_triangle_with_edge_flag(GLUtriangulatorObj *,
tess_vertex *,GLboolean,tess_vertex *,GLboolean,
tess_vertex *,GLboolean);
static GLdouble twice_the_triangle_area(
tess_vertex *va,
tess_vertex *vb,
tess_vertex *vc)
{
return (vb->x - va->x)*(vc->y - va->y) - (vb->y - va->y)*(vc->x - va->x);
}
static GLboolean left(
GLdouble A,
GLdouble B,
GLdouble C,
GLdouble x,
GLdouble y)
{
if(A*x+B*y+C > -EPSILON)
return GL_TRUE;
else
return GL_FALSE;
}
static GLboolean right(
GLdouble A,
GLdouble B,
GLdouble C,
GLdouble x,
GLdouble y)
{
if(A*x+B*y+C < EPSILON)
return GL_TRUE;
else
return GL_FALSE;
}
static GLint convex_ccw(
tess_vertex *va,
tess_vertex *vb,
tess_vertex *vc,
GLUtriangulatorObj *tobj)
{
GLdouble d;
d = twice_the_triangle_area(va,vb,vc);
if (d > EPSILON ) {
return 1;
} else if (d < -EPSILON ) {
return 0;
} else {
return -1;
}
}
static GLint convex_cw(
tess_vertex *va,
tess_vertex *vb,
tess_vertex *vc,
GLUtriangulatorObj *tobj)
{
GLdouble d;
d = twice_the_triangle_area(va,vb,vc);
if (d < -EPSILON ) {
return 1;
} else if (d > EPSILON ) {
return 0;
} else {
return -1;
}
}
static GLboolean diagonal_ccw(
tess_vertex *va,
tess_vertex *vb,
GLUtriangulatorObj *tobj,
tess_contour *contour)
{
tess_vertex *vc=va->next , *vertex , *shadow_vertex;
struct
{
GLdouble A,B,C;
} ac,cb,ba;
GLdouble x,y;
GLint res = convex_ccw(va,vc,vb,tobj);
if (res == 0) return GL_FALSE;
if (res == -1) return GL_TRUE;
ba.A=vb->y - va->y;
ba.B=va->x - vb->x;
ba.C= -ba.A*va->x - ba.B*va->y;
ac.A=va->y - vc->y;
ac.B=vc->x - va->x;
ac.C= -ac.A*vc->x - ac.B*vc->y;
cb.A=vc->y - vb->y;
cb.B=vb->x - vc->x;
cb.C= -cb.A*vb->x - cb.B*vb->y;
for(vertex=vb->next;vertex!=va;vertex=vertex->next)
{
shadow_vertex=vertex->shadow_vertex;
if(shadow_vertex!=NULL &&
(shadow_vertex==va || shadow_vertex==vb || shadow_vertex==vc))
continue;
x=vertex->x;
y=vertex->y;
if(left(ba.A,ba.B,ba.C,x,y) &&
left(ac.A,ac.B,ac.C,x,y) &&
left(cb.A,cb.B,cb.C,x,y))
return GL_FALSE;
}
return GL_TRUE;
}
static GLboolean diagonal_cw(
tess_vertex *va,
tess_vertex *vb,
GLUtriangulatorObj *tobj,
tess_contour *contour)
{
tess_vertex *vc=va->next , *vertex , *shadow_vertex;
struct
{
GLdouble A,B,C;
} ac,cb,ba;
GLdouble x,y;
GLint res = convex_cw(va,vc,vb,tobj);
if (res == 0) return GL_FALSE;
if (res == -1) return GL_TRUE;
ba.A=vb->y - va->y;
ba.B=va->x - vb->x;
ba.C= -ba.A*va->x - ba.B*va->y;
ac.A=va->y - vc->y;
ac.B=vc->x - va->x;
ac.C= -ac.A*vc->x - ac.B*vc->y;
cb.A=vc->y - vb->y;
cb.B=vb->x - vc->x;
cb.C= -cb.A*vb->x - cb.B*vb->y;
for(vertex=vb->next;vertex!=va;vertex=vertex->next)
{
shadow_vertex=vertex->shadow_vertex;
if(shadow_vertex!=NULL &&
(shadow_vertex==va || shadow_vertex==vb || shadow_vertex==vc))
continue;
x=vertex->x;
y=vertex->y;
if(right(ba.A,ba.B,ba.C,x,y) &&
right(ac.A,ac.B,ac.C,x,y) &&
right(cb.A,cb.B,cb.C,x,y))
return GL_FALSE;
}
return GL_TRUE;
}
static void clip_ear(
GLUtriangulatorObj *tobj,
tess_vertex *v,
tess_contour *contour)
{
emit_triangle(tobj,v->previous,v,v->next);
/* the first in the list */
if(contour->vertices==v)
{
contour->vertices=v->next;
contour->last_vertex->next=v->next;
v->next->previous=contour->last_vertex;
}
else
/* the last ? */
if(contour->last_vertex==v)
{
contour->vertices->previous=v->previous;
v->previous->next=v->next;
contour->last_vertex=v->previous;
}
else
{
v->next->previous=v->previous;
v->previous->next=v->next;
}
free(v);
--(contour->vertex_cnt);
}
static void clip_ear_with_edge_flag(
GLUtriangulatorObj *tobj,
tess_vertex *v,
tess_contour *contour)
{
emit_triangle_with_edge_flag(tobj,v->previous,v->previous->edge_flag,
v,v->edge_flag,v->next,GL_FALSE);
v->previous->edge_flag=GL_FALSE;
/* the first in the list */
if(contour->vertices==v)
{
contour->vertices=v->next;
contour->last_vertex->next=v->next;
v->next->previous=contour->last_vertex;
}
else
/* the last ? */
if(contour->last_vertex==v)
{
contour->vertices->previous=v->previous;
v->previous->next=v->next;
contour->last_vertex=v->previous;
}
else
{
v->next->previous=v->previous;
v->previous->next=v->next;
}
free(v);
--(contour->vertex_cnt);
}
static void triangulate_ccw(
GLUtriangulatorObj *tobj,
tess_contour *contour)
{
tess_vertex *vertex;
GLuint vertex_cnt=contour->vertex_cnt;
while(vertex_cnt > 3)
{
vertex=contour->vertices;
while(diagonal_ccw(vertex,vertex->next->next,tobj,contour)==GL_FALSE &&
tobj->error==GLU_NO_ERROR)
vertex=vertex->next;
if(tobj->error!=GLU_NO_ERROR)
return;
clip_ear(tobj,vertex->next,contour);
--vertex_cnt;
}
}
static void triangulate_cw(
GLUtriangulatorObj *tobj,
tess_contour *contour)
{
tess_vertex *vertex;
GLuint vertex_cnt=contour->vertex_cnt;
while(vertex_cnt > 3)
{
vertex=contour->vertices;
while(diagonal_cw(vertex,vertex->next->next,tobj,contour)==GL_FALSE &&
tobj->error==GLU_NO_ERROR)
vertex=vertex->next;
if(tobj->error!=GLU_NO_ERROR)
return;
clip_ear(tobj,vertex->next,contour);
--vertex_cnt;
}
}
static void triangulate_ccw_with_edge_flag(
GLUtriangulatorObj *tobj,
tess_contour *contour)
{
tess_vertex *vertex;
GLuint vertex_cnt=contour->vertex_cnt;
while(vertex_cnt > 3)
{
vertex=contour->vertices;
while(diagonal_ccw(vertex,vertex->next->next,tobj,contour)==GL_FALSE &&
tobj->error==GLU_NO_ERROR)
vertex=vertex->next;
if(tobj->error!=GLU_NO_ERROR)
return;
clip_ear_with_edge_flag(tobj,vertex->next,contour);
--vertex_cnt;
}
}
static void triangulate_cw_with_edge_flag(
GLUtriangulatorObj *tobj,
tess_contour *contour)
{
tess_vertex *vertex;
GLuint vertex_cnt=contour->vertex_cnt;
while(vertex_cnt > 3)
{
vertex=contour->vertices;
while(diagonal_cw(vertex,vertex->next->next,tobj,contour)==GL_FALSE &&
tobj->error==GLU_NO_ERROR)
vertex=vertex->next;
if(tobj->error!=GLU_NO_ERROR)
return;
clip_ear_with_edge_flag(tobj,vertex->next,contour);
--vertex_cnt;
}
}
void tess_tesselate(GLUtriangulatorObj *tobj)
{
tess_contour *contour;
for(contour=tobj->contours;contour!=NULL;contour=contour->next)
{
if(contour->orientation==GLU_CCW) {
triangulate_ccw(tobj,contour);
} else {
triangulate_cw(tobj,contour);
}
if(tobj->error!=GLU_NO_ERROR)
return;
/* emit the last triangle */
emit_triangle(tobj,contour->vertices,contour->vertices->next,
contour->vertices->next->next);
}
}
void tess_tesselate_with_edge_flag(GLUtriangulatorObj *tobj)
{
tess_contour *contour;
edge_flag=GL_TRUE;
/* first callback with edgeFlag set to GL_TRUE */
(tobj->callbacks.edgeFlag)(GL_TRUE);
for(contour=tobj->contours;contour!=NULL;contour=contour->next)
{
if(contour->orientation==GLU_CCW)
triangulate_ccw_with_edge_flag(tobj,contour);
else
triangulate_cw_with_edge_flag(tobj,contour);
if(tobj->error!=GLU_NO_ERROR)
return;
/* emit the last triangle */
emit_triangle_with_edge_flag(tobj,contour->vertices,
contour->vertices->edge_flag,contour->vertices->next,
contour->vertices->next->edge_flag,contour->vertices->next->next,
contour->vertices->next->next->edge_flag);
}
}
static void emit_triangle(
GLUtriangulatorObj *tobj,
tess_vertex *v1,
tess_vertex *v2,
tess_vertex *v3)
{
(tobj->callbacks.begin)(GL_TRIANGLES);
(tobj->callbacks.vertex)(v1->data);
(tobj->callbacks.vertex)(v2->data);
(tobj->callbacks.vertex)(v3->data);
(tobj->callbacks.end)();
}
static void emit_triangle_with_edge_flag(
GLUtriangulatorObj *tobj,
tess_vertex *v1,
GLboolean edge_flag1,
tess_vertex *v2,
GLboolean edge_flag2,
tess_vertex *v3,
GLboolean edge_flag3)
{
(tobj->callbacks.begin)(GL_TRIANGLES);
if(edge_flag1!=edge_flag)
{
edge_flag = (edge_flag==GL_TRUE ? GL_FALSE : GL_TRUE);
(tobj->callbacks.edgeFlag)(edge_flag);
}
(tobj->callbacks.vertex)(v1->data);
if(edge_flag2!=edge_flag)
{
edge_flag = (edge_flag==GL_TRUE ? GL_FALSE : GL_TRUE);
(tobj->callbacks.edgeFlag)(edge_flag);
}
(tobj->callbacks.vertex)(v2->data);
if(edge_flag3!=edge_flag)
{
edge_flag = (edge_flag==GL_TRUE ? GL_FALSE : GL_TRUE);
(tobj->callbacks.edgeFlag)(edge_flag);
}
(tobj->callbacks.vertex)(v3->data);
(tobj->callbacks.end)();
}