Small tweaks to CDT

- added CDT support for demo
- added infinity-loop safety guard on CDT iteration count
- visit all 4 neighbours
- changed to options based API
diff --git a/Example/example.c b/Example/example.c
index acbc388..2d4e23b 100644
--- a/Example/example.c
+++ b/Example/example.c
@@ -56,6 +56,7 @@
 
 
 int run = 1;
+int cdt = 0;
 
 static void key(GLFWwindow* window, int key, int scancode, int action, int mods)
 {
@@ -65,6 +66,8 @@
 		glfwSetWindowShouldClose(window, GL_TRUE);
 	if (key == GLFW_KEY_SPACE && action == GLFW_PRESS)
 		run = !run;
+	if (key == GLFW_KEY_C && action == GLFW_PRESS)
+		cdt = !cdt;
 }
 
 int main(int argc, char *argv[])
@@ -79,14 +82,15 @@
 	float t = 0.0f, pt = 0.0f;
 	TESSalloc ma;
 	TESStesselator* tess = 0;
-	const int nvp = 6;
+	const int nvp = 3;
 	unsigned char* vflags = 0;
-	int nvflags = 0;
 #ifdef USE_POOL
 	struct MemPool pool;
 	unsigned char mem[1024*1024];
+	int nvflags = 0;
 #else
 	int allocated = 0;
+	double t0 = 0, t1 = 0;
 #endif
 	TESS_NOTUSED(argc);
 	TESS_NOTUSED(argv);
@@ -104,7 +108,7 @@
 	if (!fg) return -1;
 
 	printf("go...\n");
-	
+
 	// Flip y
 	for (it = bg; it != NULL; it = it->next)
 		for (i = 0; i < it->npts; ++i)
@@ -138,7 +142,7 @@
 			it->pts[i*2+1] -= cy;
 		}
 	}
-			
+
 	// Find BG bounds.
 	bounds[0] = bounds[2] = bg->pts[0];
 	bounds[1] = bounds[3] = bg->pts[1];
@@ -154,7 +158,7 @@
 			if (y > bounds[3]) bounds[3] = y;
 		}
 	}
-		
+
 #ifdef USE_POOL
 
 	pool.size = 0;
@@ -168,6 +172,8 @@
 
 #else
 
+	t0 = glfwGetTime();
+
 	memset(&ma, 0, sizeof(ma));
 	ma.memalloc = stdAlloc;
 	ma.memfree = stdFree;
@@ -178,6 +184,8 @@
 	if (!tess)
 		return -1;
 
+	tessSetOption(tess, TESS_CONSTRAINED_DELAUNAY_TRIANGULATION, 1);
+
 	// Offset the foreground shape to center of the bg.
 	offx = (bounds[2]+bounds[0])/2;
 	offy = (bounds[3]+bounds[1])/2;
@@ -189,7 +197,7 @@
 			it->pts[i*2+1] += offy;
 		}
 	}
-	
+
 	// Add contours.
 	for (it = bg; it != NULL; it = it->next)
 		tessAddContour(tess, 2, it->pts, sizeof(float)*2, it->npts);
@@ -197,10 +205,14 @@
 		tessAddContour(tess, 2, it->pts, sizeof(float)*2, it->npts);
 	if (!tessTesselate(tess, TESS_WINDING_POSITIVE, TESS_POLYGONS, nvp, 2, 0))
 		return -1;
+
+	t1 = glfwGetTime();
+
+	printf("Time: %.3f ms\n", (t1 - t0) * 1000.0f);
 	printf("Memory used: %.1f kB\n", allocated/1024.0f);
-	
+
 #endif
-	
+
 	mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
 	width = mode->width - 40;
 	height = mode->height - 80;
@@ -221,17 +233,27 @@
 	view[2] = cx + w*1.2f;
 	view[1] = cy - w*1.2f*(float)height/(float)width;
 	view[3] = cy + w*1.2f*(float)height/(float)width;
-		
+
 	glfwSetTime(0);
 
 	while (!glfwWindowShouldClose(window))
 	{
-		float ct = (float)glfwGetTime();
+		int winWidth, winHeight;
+		int fbWidth, fbHeight;
+		float pxr, ct;
+
+		glfwGetWindowSize(window, &winWidth, &winHeight);
+		glfwGetFramebufferSize(window, &fbWidth, &fbHeight);
+
+		// Calculate pixel ration for hi-dpi devices.
+		pxr = (float)fbWidth / (float)winWidth;
+
+		ct = (float)glfwGetTime();
 		if (run) t += ct - pt;
 		pt = ct;
-		
+
 		// Update and render
-		glViewport(0, 0, width, height);
+		glViewport(0, 0, fbWidth, fbHeight);
 		glClearColor(0.3f, 0.3f, 0.32f, 1.0f);
 		glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
 		glEnable(GL_BLEND);
@@ -251,9 +273,11 @@
 		tess = tessNewTess(&ma);
 		if (tess)
 		{
+			tessSetOption(tess, TESS_CONSTRAINED_DELAUNAY_TRIANGULATION, cdt);
+
 			offx = (view[2]+view[0])/2 + sinf(t) * (view[2]-view[0])/2;
 			offy = (view[3]+view[1])/2 + cosf(t*3.13f) * (view[3]-view[1])/6;
-			
+
 			for (it = fg; it != NULL; it = it->next)
 			{
 				for (i = 0; i < it->npts; ++i)
@@ -293,7 +317,7 @@
 					nvflags = nverts;
 					vflags = (unsigned char*)malloc(sizeof(unsigned char)*nvflags);
 				}
-				
+
 				if (vflags)
 				{
 					// Vertex indices describe the order the indices were added and can be used
@@ -303,7 +327,7 @@
 					for (i = 0; i < nverts; ++i)
 						vflags[i] = vinds[i] == TESS_UNDEF ? 1 : 0;
 				}
-				
+
 				for (i = 0; i < nelems; ++i)
 				{
 					int b = elems[i*2];
@@ -314,9 +338,9 @@
 					tess = 0;
 			}
 			else
-				tess = 0;				
+				tess = 0;
 		}
-#endif		
+#endif
 
 		// Draw tesselated pieces.
 		if (tess)
@@ -326,7 +350,7 @@
 			const int* elems = tessGetElements(tess);
 			const int nverts = tessGetVertexCount(tess);
 			const int nelems = tessGetElementCount(tess);
-			
+
 			// Draw polygons.
 			glColor4ub(255,255,255,128);
 			for (i = 0; i < nelems; ++i)
@@ -337,7 +361,10 @@
 					glVertex2f(verts[p[j]*2], verts[p[j]*2+1]);
 				glEnd();
 			}
-			
+
+			glLineWidth(1.0f * pxr);
+			glPointSize(3.0f * pxr);
+
 			glColor4ub(0,0,0,16);
 			for (i = 0; i < nelems; ++i)
 			{
@@ -347,9 +374,8 @@
 					glVertex2f(verts[p[j]*2], verts[p[j]*2+1]);
 				glEnd();
 			}
-			
+
 			glColor4ub(0,0,0,128);
-			glPointSize(3.0f);
 			glBegin(GL_POINTS);
 			for (i = 0; i < nverts; ++i)
 			{
@@ -360,21 +386,22 @@
 				glVertex2f(verts[i*2], verts[i*2+1]);
 			}
 			glEnd();
+
 			glPointSize(1.0f);
 		}
-		
+
 		glEnable(GL_DEPTH_TEST);
 		glfwSwapBuffers(window);
 		glfwPollEvents();
 	}
-	
+
 	if (tess) tessDeleteTess(tess);
-	
+
 	if (vflags)
 		free(vflags);
-	
-	svgDelete(bg);	
-	svgDelete(fg);	
+
+	svgDelete(bg);
+	svgDelete(fg);
 
 	glfwTerminate();
 	return 0;
diff --git a/Include/tesselator.h b/Include/tesselator.h
index 6e51e32..38e05f1 100755
--- a/Include/tesselator.h
+++ b/Include/tesselator.h
@@ -1,5 +1,5 @@
 /*
-** SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) 
+** SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
 ** Copyright (C) [dates of first publication] Silicon Graphics, Inc.
 ** All Rights Reserved.
 **
@@ -9,10 +9,10 @@
 ** 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 including the dates of first publication and either this
 ** permission notice or a reference to http://oss.sgi.com/projects/FreeB/ shall be
-** included in all copies or substantial portions of the Software. 
+** 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
@@ -20,7 +20,7 @@
 ** 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.
-** 
+**
 ** Except as contained in this notice, the name of Silicon Graphics, Inc. shall not
 ** be used in advertising or otherwise to promote the sale, use or other dealings in
 ** this Software without prior written authorization from Silicon Graphics, Inc.
@@ -106,17 +106,22 @@
 //         }
 //         glEnd();
 //     }
-//
-// TESS_CONSTRAINED_DELAUNAY_TRIANGLES
-//   Similar to TESS_POLYGONS, but we output only triangles and we attempt to provide a valid
-//   Constrained Delaunay triangulation.
 
 enum TessElementType
 {
 	TESS_POLYGONS,
 	TESS_CONNECTED_POLYGONS,
 	TESS_BOUNDARY_CONTOURS,
-	TESS_CONSTRAINED_DELAUNAY_TRIANGLES
+};
+
+
+// TESS_CONSTRAINED_DELAUNAY_TRIANGULATION
+//   If enabled, the initial triagulation is improved with non-robust Constrained Delayney triangulation.
+//   Disable by default.
+
+enum TessOption
+{
+	TESS_CONSTRAINED_DELAUNAY_TRIANGULATION,
 };
 
 typedef float TESSreal;
@@ -138,12 +143,12 @@
 // how often to allocate memory from the system versus how much extra space the system
 // should allocate. Reasonable defaults are show in commects below, they will be used if
 // the bucket sizes are zero.
-// 
+//
 // The use may left the memrealloc to be null. In that case, the tesselator will not try to
 // dynamically grow int's internal arrays. The tesselator only needs the reallocation when it
 // has found intersecting segments and needs to add new vertex. This defency can be cured by
 // allocating some extra vertices beforehand. The 'extraVertices' variable allows to specify
-// number of expected extra vertices.  
+// number of expected extra vertices.
 struct TESSalloc
 {
 	void *(*memalloc)( void *userData, unsigned int size );
@@ -189,12 +194,18 @@
 //   count - number of vertices in contour.
 void tessAddContour( TESStesselator *tess, int size, const void* pointer, int stride, int count );
 
+// tessSetOption() - Toggles optional tessellation parameters
+// Parameters:
+//  option - one of TessOption
+//  value - 1 if enabled, 0 if disabled.
+void tessSetOption( TESStesselator *tess, int option, int value );
+
 // tessTesselate() - tesselate contours.
 // Parameters:
 //   tess - pointer to tesselator object.
 //   windingRule - winding rules used for tesselation, must be one of TessWindingRule.
 //   elementType - defines the tesselation result element type, must be one of TessElementType.
-//   polySize - defines maximum vertices per polygons if output is polygons. If elementType is TESS_CONSTRAINED_DELAUNAY_TRIANGLES, this parameter is ignored.
+//   polySize - defines maximum vertices per polygons if output is polygons.
 //   vertexSize - defines the number of coordinates in tesselation result vertex, must be 2 or 3.
 //   normal - defines the normal of the input contours, of null the normal is calculated automatically.
 // Returns:
@@ -212,7 +223,7 @@
 // Every point added using tessAddContour() will get a new index starting at 0.
 // New vertices generated at the intersections of segments are assigned value TESS_UNDEF.
 const TESSindex* tessGetVertexIndices( TESStesselator *tess );
-	
+
 // tessGetElementCount() - Returns number of elements in the the tesselated output.
 int tessGetElementCount( TESStesselator *tess );
 
diff --git a/Source/geom.c b/Source/geom.c
index 00b307a..97a5046 100755
--- a/Source/geom.c
+++ b/Source/geom.c
@@ -1,5 +1,5 @@
 /*

-** SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) 

+** SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)

 ** Copyright (C) [dates of first publication] Silicon Graphics, Inc.

 ** All Rights Reserved.

 **

@@ -9,10 +9,10 @@
 ** 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 including the dates of first publication and either this

 ** permission notice or a reference to http://oss.sgi.com/projects/FreeB/ shall be

-** included in all copies or substantial portions of the Software. 

+** 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

@@ -20,7 +20,7 @@
 ** 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.

-** 

+**

 ** Except as contained in this notice, the name of Silicon Graphics, Inc. shall not

 ** be used in advertising or otherwise to promote the sale, use or other dealings in

 ** this Software without prior written authorization from Silicon Graphics, Inc.

@@ -266,16 +266,13 @@
  */

 TESSreal calcAngle( TESSvertex *v0, TESSvertex *v1, TESSvertex *v2 )

 {

-	TESSreal num;

-	TESSreal den;

-	TESSreal a[2];

-	TESSreal b[2];

-	a[0] = v2->s - v1->s;

-	a[1] = v2->t - v1->t;

-	b[0] = v0->s - v1->s;

-	b[1] = v0->t - v1->t;

-	num = a[0] * b[0] + a[1] * b[1];

-	den = sqrt( a[0] * a[0] + a[1] * a[1] ) * sqrt( b[0] * b[0] + b[1] * b[1] );

+	TESSreal num, den, ax, ay, bx, by;

+	ax = v2->s - v1->s;

+	ay = v2->t - v1->t;

+	bx = v0->s - v1->s;

+	by = v0->t - v1->t;

+	num = ax * bx + ay * by;

+	den = sqrt( ax * ax + ay * ay ) * sqrt( bx * bx + by * by );

 	if ( den > 0.0 ) num /= den;

 	if ( num < -1.0 ) num = -1.0;

 	if ( num >  1.0 ) num =  1.0;

@@ -288,5 +285,5 @@
 int tesedgeIsLocallyDelaunay( TESShalfEdge *e )

 {

 	return (calcAngle(e->Lnext->Org, e->Lnext->Lnext->Org, e->Org) +

-					calcAngle(e->Sym->Lnext->Org, e->Sym->Lnext->Lnext->Org, e->Sym->Org)) < (M_PI + 0.01);

+			calcAngle(e->Sym->Lnext->Org, e->Sym->Lnext->Lnext->Org, e->Sym->Org)) < (M_PI + 0.01);

 }

diff --git a/Source/tess.c b/Source/tess.c
index 5699b18..1233b6d 100755
--- a/Source/tess.c
+++ b/Source/tess.c
@@ -1,5 +1,5 @@
 /*
-** SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) 
+** SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
 ** Copyright (C) [dates of first publication] Silicon Graphics, Inc.
 ** All Rights Reserved.
 **
@@ -9,10 +9,10 @@
 ** 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 including the dates of first publication and either this
 ** permission notice or a reference to http://oss.sgi.com/projects/FreeB/ shall be
-** included in all copies or substantial portions of the Software. 
+** 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
@@ -20,7 +20,7 @@
 ** 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.
-** 
+**
 ** Except as contained in this notice, the name of Silicon Graphics, Inc. shall not
 ** be used in advertising or otherwise to promote the sale, use or other dealings in
 ** this Software without prior written authorization from Silicon Graphics, Inc.
@@ -177,7 +177,7 @@
 #define S_UNIT_X	(RandomSweep ? (2*drand48()-1) : 1.0)
 #define S_UNIT_Y	(RandomSweep ? (2*drand48()-1) : 0.0)
 #else
-#if defined(SLANTED_SWEEP) 
+#if defined(SLANTED_SWEEP)
 /* The "feature merging" is not intended to be complete.  There are
 * special cases where edges are nearly parallel to the sweep line
 * which are not implemented.  The algorithm should still behave
@@ -286,7 +286,7 @@
 * (what else would it do??)  The region must consist of a single
 * loop of half-edges (see mesh.h) oriented CCW.  "Monotone" in this
 * case means that any vertical line intersects the interior of the
-* region in a single interval.  
+* region in a single interval.
 *
 * Tessellation consists of adding interior edges (actually pairs of
 * half-edges), to split the region into non-overlapping triangles.
@@ -436,43 +436,49 @@
 	return e;
 }
 
-/*
-	Starting with a valid triangulation, uses the Edge Flip algorithm to
-	refine the triangulation into a Constrained Delaunay Triangulation.
-*/
-int tessMeshRefineDelaunay( TESSmesh *mesh, TESSalloc *alloc )
-{
-	/* At this point, we have a valid, but not optimal, triangulation.
-		 We refine the triangulation using the Edge Flip algorithm */
 
-/*
-	 1) Find all internal edges
-	 2) Mark all dual edges
-	 3) insert all dual edges into a queue
-*/
+//	Starting with a valid triangulation, uses the Edge Flip algorithm to
+//	refine the triangulation into a Constrained Delaunay Triangulation.
+void tessMeshRefineDelaunay( TESSmesh *mesh, TESSalloc *alloc )
+{
+	// At this point, we have a valid, but not optimal, triangulation.
+	// We refine the triangulation using the Edge Flip algorithm
+	//
+	//  1) Find all internal edges
+	//	2) Mark all dual edges
+	//	3) insert all dual edges into a queue
+
 	TESSface *f;
 	EdgeStack stack;
 	TESShalfEdge *e;
-	TESShalfEdge *edges[4];
+	int maxFaces = 0, maxIter = 0, iter = 0;
+
 	stackInit(&stack, alloc);
+
 	for( f = mesh->fHead.next; f != &mesh->fHead; f = f->next ) {
 		if ( f->inside) {
 			e = f->anEdge;
 			do {
-				e->mark = EdgeIsInternal(e); /* Mark internal edges */
-				if (e->mark && !e->Sym->mark) stackPush(&stack, e); /* Insert into queue */
+				e->mark = EdgeIsInternal(e); // Mark internal edges
+				if (e->mark && !e->Sym->mark) stackPush(&stack, e); // Insert into queue
 				e = e->Lnext;
 			} while (e != f->anEdge);
+			maxFaces++;
 		}
 	}
-	
+
+	// The algorithm should converge on O(n^2), since the predicate is not robust,
+	// we'll save guard against infinite loop.
+	maxIter = maxFaces * maxFaces;
+
 	// Pop stack until we find a reversed edge
 	// Flip the reversed edge, and insert any of the four opposite edges
 	// which are internal and not already in the stack (!marked)
-	while (!stackEmpty(&stack)) {
+	while (!stackEmpty(&stack) && iter < maxIter) {
 		e = stackPop(&stack);
 		e->mark = e->Sym->mark = 0;
 		if (!tesedgeIsLocallyDelaunay(e)) {
+			TESShalfEdge *edges[4];
 			int i;
 			tessMeshFlipEdge(mesh, e);
 			// for each opposite edge
@@ -480,18 +486,17 @@
 			edges[1] = e->Lprev;
 			edges[2] = e->Sym->Lnext;
 			edges[3] = e->Sym->Lprev;
-			for (i=0;i<3;i++) {
+			for (i = 0; i < 4; i++) {
 				if (!edges[i]->mark && EdgeIsInternal(edges[i])) {
 					edges[i]->mark = edges[i]->Sym->mark = 1;
 					stackPush(&stack, edges[i]);
 				}
 			}
 		}
+		iter++;
 	}
-	
-	stackDelete(&stack);
 
-	return 1;
+	stackDelete(&stack);
 }
 
 
@@ -584,7 +589,7 @@
 
 	if (alloc == NULL)
 		alloc = &defaulAlloc;
-	
+
 	/* Only initialize fields which can be changed by the api.  Other fields
 	* are initialized where they are used.
 	*/
@@ -605,7 +610,7 @@
 		tess->alloc.dictNodeBucketSize = 512;
 	if (tess->alloc.regionBucketSize == 0)
 		tess->alloc.regionBucketSize = 256;
-	
+
 	tess->normal[0] = 0;
 	tess->normal[1] = 0;
 	tess->normal[2] = 0;
@@ -629,7 +634,7 @@
 
 	tess->outOfMemory = 0;
 	tess->vertexIndexCounter = 0;
-	
+
 	tess->vertices = 0;
 	tess->vertexIndices = 0;
 	tess->vertexCount = 0;
@@ -641,9 +646,9 @@
 
 void tessDeleteTess( TESStesselator *tess )
 {
-	
+
 	struct TESSalloc alloc = tess->alloc;
-	
+
 	deleteBucketAlloc( tess->regionPool );
 
 	if( tess->mesh != NULL ) {
@@ -722,7 +727,7 @@
 			edge = edge->Lnext;
 		}
 		while (edge != f->anEdge);
-		
+
 		assert( faceVerts <= polySize );
 
 		f->n = maxFaceCount;
@@ -739,7 +744,7 @@
 		tess->outOfMemory = 1;
 		return;
 	}
-	
+
 	tess->vertexCount = maxVertexCount;
 	tess->vertices = (TESSreal*)tess->alloc.memalloc( tess->alloc.userData,
 													 sizeof(TESSreal) * tess->vertexCount * vertexSize );
@@ -756,7 +761,7 @@
 		tess->outOfMemory = 1;
 		return;
 	}
-	
+
 	// Output vertices.
 	for ( v = mesh->vHead.next; v != &mesh->vHead; v = v->next )
 	{
@@ -778,7 +783,7 @@
 	for ( f = mesh->fHead.next; f != &mesh->fHead; f = f->next )
 	{
 		if ( !f->inside ) continue;
-		
+
 		// Store polygon
 		edge = f->anEdge;
 		faceVerts = 0;
@@ -847,7 +852,7 @@
 		tess->outOfMemory = 1;
 		return;
 	}
-	
+
 	tess->vertices = (TESSreal*)tess->alloc.memalloc( tess->alloc.userData,
 													  sizeof(TESSreal) * tess->vertexCount * vertexSize );
 	if (!tess->vertices)
@@ -863,7 +868,7 @@
 		tess->outOfMemory = 1;
 		return;
 	}
-	
+
 	verts = tess->vertices;
 	elements = tess->elements;
 	vertInds = tess->vertexIndices;
@@ -964,6 +969,17 @@
 	}
 }
 
+void tessSetOption( TESStesselator *tess, int option, int value )
+{
+	switch(option)
+	{
+	case TESS_CONSTRAINED_DELAUNAY_TRIANGULATION:
+		tess->processCDT = value > 0 ? 1 : 0;
+		break;
+	}
+}
+
+
 int tessTesselate( TESStesselator *tess, int windingRule, int elementType,
 				  int polySize, int vertexSize, const TESSreal* normal )
 {
@@ -984,7 +1000,7 @@
 	}
 
 	tess->vertexIndexCounter = 0;
-	
+
 	if (normal)
 	{
 		tess->normal[0] = normal[0];
@@ -999,7 +1015,7 @@
 	if (vertexSize > 3)
 		vertexSize = 3;
 
-	if (setjmp(tess->env) != 0) { 
+	if (setjmp(tess->env) != 0) {
 		/* come back here if out of memory */
 		return 0;
 	}
@@ -1033,12 +1049,9 @@
 	if (elementType == TESS_BOUNDARY_CONTOURS) {
 		rc = tessMeshSetWindingNumber( mesh, 1, TRUE );
 	} else {
-		rc = tessMeshTessellateInterior( mesh ); 
-		if (elementType == TESS_CONSTRAINED_DELAUNAY_TRIANGLES) {
-			rc = tessMeshRefineDelaunay( mesh, &tess->alloc );
-			elementType = TESS_POLYGONS;
-			polySize = 3;
-		}
+		rc = tessMeshTessellateInterior( mesh );
+		if (rc != 0 && tess->processCDT != 0)
+			tessMeshRefineDelaunay( mesh, &tess->alloc );
 	}
 	if (rc == 0) longjmp(tess->env,1);  /* could've used a label */
 
diff --git a/Source/tess.h b/Source/tess.h
index c8c747b..c1f981f 100755
--- a/Source/tess.h
+++ b/Source/tess.h
@@ -1,5 +1,5 @@
 /*
-** SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) 
+** SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
 ** Copyright (C) [dates of first publication] Silicon Graphics, Inc.
 ** All Rights Reserved.
 **
@@ -9,10 +9,10 @@
 ** 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 including the dates of first publication and either this
 ** permission notice or a reference to http://oss.sgi.com/projects/FreeB/ shall be
-** included in all copies or substantial portions of the Software. 
+** 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
@@ -20,7 +20,7 @@
 ** 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.
-** 
+**
 ** Except as contained in this notice, the name of Silicon Graphics, Inc. shall not
 ** be used in advertising or otherwise to promote the sale, use or other dealings in
 ** this Software without prior written authorization from Silicon Graphics, Inc.
@@ -61,6 +61,8 @@
 	TESSreal bmin[2];
 	TESSreal bmax[2];
 
+	int processCDT;	/* option to run Constrained Delayney pass. */
+
 	/*** state needed for the line sweep ***/
 	int	windingRule;	/* rule for determining polygon interior */
 
@@ -71,7 +73,7 @@
 	struct BucketAlloc* regionPool;
 
 	TESSindex vertexIndexCounter;
-	
+
 	TESSreal *vertices;
 	TESSindex *vertexIndices;
 	int vertexCount;
@@ -79,7 +81,7 @@
 	int elementCount;
 
 	TESSalloc alloc;
-	
+
 	jmp_buf env;			/* place to jump to when memAllocs fail */
 };