aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/glu/sgi/libnurbs/nurbtess/sampleMonoPoly.cc
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/glu/sgi/libnurbs/nurbtess/sampleMonoPoly.cc')
-rw-r--r--mesalib/src/glu/sgi/libnurbs/nurbtess/sampleMonoPoly.cc2427
1 files changed, 0 insertions, 2427 deletions
diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/sampleMonoPoly.cc b/mesalib/src/glu/sgi/libnurbs/nurbtess/sampleMonoPoly.cc
deleted file mode 100644
index 051f24108..000000000
--- a/mesalib/src/glu/sgi/libnurbs/nurbtess/sampleMonoPoly.cc
+++ /dev/null
@@ -1,2427 +0,0 @@
-/*
-** License Applicability. Except to the extent portions of this file are
-** made subject to an alternative license as permitted in the SGI Free
-** Software License B, Version 1.1 (the "License"), the contents of this
-** file are subject only to the provisions of the License. You may not use
-** this file except in compliance with the License. You may obtain a copy
-** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
-** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
-**
-** http://oss.sgi.com/projects/FreeB
-**
-** Note that, as provided in the License, the Software is distributed on an
-** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
-** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
-** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
-** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
-**
-** Original Code. The Original Code is: OpenGL Sample Implementation,
-** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
-** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
-** Copyright in any portions created by third parties is as indicated
-** elsewhere herein. All Rights Reserved.
-**
-** Additional Notice Provisions: The application programming interfaces
-** established by SGI in conjunction with the Original Code are The
-** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
-** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
-** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
-** Window System(R) (Version 1.3), released October 19, 1998. This software
-** was created using the OpenGL(R) version 1.2.1 Sample Implementation
-** published by SGI, but has not been independently verified as being
-** compliant with the OpenGL(R) version 1.2.1 Specification.
-**
-*/
-/*
-*/
-
-#include "gluos.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <math.h>
-
-#ifndef max
-#define max(a,b) ((a>b)? a:b)
-#endif
-#ifndef min
-#define min(a,b) ((a>b)? b:a)
-#endif
-
-#include <GL/gl.h>
-
-#include "glimports.h"
-#include "zlassert.h"
-#include "sampleMonoPoly.h"
-#include "sampleComp.h"
-#include "polyDBG.h"
-#include "partitionX.h"
-
-
-#define ZERO 0.00001
-
-//#define MYDEBUG
-
-//#define SHORTEN_GRID_LINE
-//see work/newtess/internal/test/problems
-
-
-/*split a polygon so that each vertex correcpond to one edge
- *the head of the first edge of the returned plygon must be the head of the first
- *edge of the origianl polygon. This is crucial for the code in sampleMonoPoly function
- */
- directedLine* polygonConvert(directedLine* polygon)
-{
- int i;
- directedLine* ret;
- sampledLine* sline;
- sline = new sampledLine(2);
- sline->setPoint(0, polygon->getVertex(0));
- sline->setPoint(1, polygon->getVertex(1));
- ret=new directedLine(INCREASING, sline);
- for(i=1; i<= polygon->get_npoints()-2; i++)
- {
- sline = new sampledLine(2);
- sline->setPoint(0, polygon->getVertex(i));
- sline->setPoint(1, polygon->getVertex(i+1));
- ret->insert(new directedLine(INCREASING, sline));
- }
-
- for(directedLine *temp = polygon->getNext(); temp != polygon; temp = temp->getNext())
- {
- for(i=0; i<= temp->get_npoints()-2; i++)
- {
- sline = new sampledLine(2);
- sline->setPoint(0, temp->getVertex(i));
- sline->setPoint(1, temp->getVertex(i+1));
- ret->insert(new directedLine(INCREASING, sline));
- }
- }
- return ret;
-}
-
-void triangulateConvexPolyVertical(directedLine* topV, directedLine* botV, primStream *pStream)
-{
- Int i,j;
- Int n_leftVerts;
- Int n_rightVerts;
- Real** leftVerts;
- Real** rightVerts;
- directedLine* tempV;
- n_leftVerts = 0;
- for(tempV = topV; tempV != botV; tempV = tempV->getNext())
- {
- n_leftVerts += tempV->get_npoints();
- }
- n_rightVerts=0;
- for(tempV = botV; tempV != topV; tempV = tempV->getNext())
- {
- n_rightVerts += tempV->get_npoints();
- }
-
- Real2* temp_leftVerts = (Real2 *) malloc(sizeof(Real2) * n_leftVerts);
- assert(temp_leftVerts);
- Real2* temp_rightVerts = (Real2 *) malloc(sizeof(Real2) * n_rightVerts);
- assert(temp_rightVerts);
-
- leftVerts = (Real**) malloc(sizeof(Real2*) * n_leftVerts);
- assert(leftVerts);
- rightVerts = (Real**) malloc(sizeof(Real2*) * n_rightVerts);
- assert(rightVerts);
- for(i=0; i<n_leftVerts; i++)
- leftVerts[i] = temp_leftVerts[i];
- for(i=0; i<n_rightVerts; i++)
- rightVerts[i] = temp_rightVerts[i];
-
- i=0;
- for(tempV = topV; tempV != botV; tempV = tempV->getNext())
- {
- for(j=1; j<tempV->get_npoints(); j++)
- {
- leftVerts[i][0] = tempV->getVertex(j)[0];
- leftVerts[i][1] = tempV->getVertex(j)[1];
- i++;
- }
- }
- n_leftVerts = i;
- i=0;
- for(tempV = topV->getPrev(); tempV != botV->getPrev(); tempV = tempV->getPrev())
- {
- for(j=tempV->get_npoints()-1; j>=1; j--)
- {
- rightVerts[i][0] = tempV->getVertex(j)[0];
- rightVerts[i][1] = tempV->getVertex(j)[1];
- i++;
- }
- }
- n_rightVerts = i;
- triangulateXYMonoTB(n_leftVerts, leftVerts, n_rightVerts, rightVerts, pStream);
- free(leftVerts);
- free(rightVerts);
- free(temp_leftVerts);
- free(temp_rightVerts);
-}
-
-void triangulateConvexPolyHoriz(directedLine* leftV, directedLine* rightV, primStream *pStream)
-{
- Int i,j;
- Int n_lowerVerts;
- Int n_upperVerts;
- Real2 *lowerVerts;
- Real2 *upperVerts;
- directedLine* tempV;
- n_lowerVerts=0;
- for(tempV = leftV; tempV != rightV; tempV = tempV->getNext())
- {
- n_lowerVerts += tempV->get_npoints();
- }
- n_upperVerts=0;
- for(tempV = rightV; tempV != leftV; tempV = tempV->getNext())
- {
- n_upperVerts += tempV->get_npoints();
- }
- lowerVerts = (Real2 *) malloc(sizeof(Real2) * n_lowerVerts);
- assert(n_lowerVerts);
- upperVerts = (Real2 *) malloc(sizeof(Real2) * n_upperVerts);
- assert(n_upperVerts);
- i=0;
- for(tempV = leftV; tempV != rightV; tempV = tempV->getNext())
- {
- for(j=0; j<tempV->get_npoints(); j++)
- {
- lowerVerts[i][0] = tempV->getVertex(j)[0];
- lowerVerts[i][1] = tempV->getVertex(j)[1];
- i++;
- }
- }
- i=0;
- for(tempV = leftV->getPrev(); tempV != rightV->getPrev(); tempV = tempV->getPrev())
- {
- for(j=tempV->get_npoints()-1; j>=0; j--)
- {
- upperVerts[i][0] = tempV->getVertex(j)[0];
- upperVerts[i][1] = tempV->getVertex(j)[1];
- i++;
- }
- }
- triangulateXYMono(n_upperVerts, upperVerts, n_lowerVerts, lowerVerts, pStream);
- free(lowerVerts);
- free(upperVerts);
-}
-void triangulateConvexPoly(directedLine* polygon, Int ulinear, Int vlinear, primStream* pStream)
-{
- /*find left, right, top , bot
- */
- directedLine* tempV;
- directedLine* topV;
- directedLine* botV;
- directedLine* leftV;
- directedLine* rightV;
- topV = botV = polygon;
-
- for(tempV = polygon->getNext(); tempV != polygon; tempV = tempV->getNext())
- {
- if(compV2InY(topV->head(), tempV->head())<0) {
-
- topV = tempV;
- }
- if(compV2InY(botV->head(), tempV->head())>0) {
-
- botV = tempV;
- }
- }
- //find leftV
- for(tempV = topV; tempV != botV; tempV = tempV->getNext())
- {
- if(tempV->tail()[0] >= tempV->head()[0])
- break;
- }
- leftV = tempV;
- //find rightV
- for(tempV = botV; tempV != topV; tempV = tempV->getNext())
- {
- if(tempV->tail()[0] <= tempV->head()[0])
- break;
- }
- rightV = tempV;
- if(vlinear)
- {
- triangulateConvexPolyHoriz( leftV, rightV, pStream);
- }
- else if(ulinear)
- {
- triangulateConvexPolyVertical(topV, botV, pStream);
- }
- else
- {
- if(DBG_is_U_direction(polygon))
- {
- triangulateConvexPolyHoriz( leftV, rightV, pStream);
- }
- else
- triangulateConvexPolyVertical(topV, botV, pStream);
- }
-}
-
-/*for debug purpose*/
-void drawCorners(
- Real* topV, Real* botV,
- vertexArray* leftChain,
- vertexArray* rightChain,
- gridBoundaryChain* leftGridChain,
- gridBoundaryChain* rightGridChain,
- Int gridIndex1,
- Int gridIndex2,
- Int leftCornerWhere,
- Int leftCornerIndex,
- Int rightCornerWhere,
- Int rightCornerIndex,
- Int bot_leftCornerWhere,
- Int bot_leftCornerIndex,
- Int bot_rightCornerWhere,
- Int bot_rightCornerIndex)
-{
- Real* leftCornerV;
- Real* rightCornerV;
- Real* bot_leftCornerV;
- Real* bot_rightCornerV;
-
- if(leftCornerWhere == 1)
- leftCornerV = topV;
- else if(leftCornerWhere == 0)
- leftCornerV = leftChain->getVertex(leftCornerIndex);
- else
- leftCornerV = rightChain->getVertex(leftCornerIndex);
-
- if(rightCornerWhere == 1)
- rightCornerV = topV;
- else if(rightCornerWhere == 0)
- rightCornerV = leftChain->getVertex(rightCornerIndex);
- else
- rightCornerV = rightChain->getVertex(rightCornerIndex);
-
- if(bot_leftCornerWhere == 1)
- bot_leftCornerV = botV;
- else if(bot_leftCornerWhere == 0)
- bot_leftCornerV = leftChain->getVertex(bot_leftCornerIndex);
- else
- bot_leftCornerV = rightChain->getVertex(bot_leftCornerIndex);
-
- if(bot_rightCornerWhere == 1)
- bot_rightCornerV = botV;
- else if(bot_rightCornerWhere == 0)
- bot_rightCornerV = leftChain->getVertex(bot_rightCornerIndex);
- else
- bot_rightCornerV = rightChain->getVertex(bot_rightCornerIndex);
-
- Real topGridV = leftGridChain->get_v_value(gridIndex1);
- Real topGridU1 = leftGridChain->get_u_value(gridIndex1);
- Real topGridU2 = rightGridChain->get_u_value(gridIndex1);
- Real botGridV = leftGridChain->get_v_value(gridIndex2);
- Real botGridU1 = leftGridChain->get_u_value(gridIndex2);
- Real botGridU2 = rightGridChain->get_u_value(gridIndex2);
-
- glBegin(GL_LINE_STRIP);
- glVertex2fv(leftCornerV);
- glVertex2f(topGridU1, topGridV);
- glEnd();
-
- glBegin(GL_LINE_STRIP);
- glVertex2fv(rightCornerV);
- glVertex2f(topGridU2, topGridV);
- glEnd();
-
- glBegin(GL_LINE_STRIP);
- glVertex2fv(bot_leftCornerV);
- glVertex2f(botGridU1, botGridV);
- glEnd();
-
- glBegin(GL_LINE_STRIP);
- glVertex2fv(bot_rightCornerV);
- glVertex2f(botGridU2, botGridV);
- glEnd();
-
-
-}
-
-void toVertexArrays(directedLine* topV, directedLine* botV, vertexArray& leftChain, vertexArray& rightChain)
-{
- Int i;
- directedLine* tempV;
- for(i=1; i<=topV->get_npoints()-2; i++) { /*the first vertex is the top vertex which doesn't belong to inc_chain*/
- leftChain.appendVertex(topV->getVertex(i));
- }
- for(tempV = topV->getNext(); tempV != botV; tempV = tempV->getNext())
- {
- for(i=0; i<=tempV->get_npoints()-2; i++){
- leftChain.appendVertex(tempV->getVertex(i));
- }
- }
-
- for(tempV = topV->getPrev(); tempV != botV; tempV = tempV->getPrev())
- {
- for(i=tempV->get_npoints()-2; i>=0; i--){
- rightChain.appendVertex(tempV->getVertex(i));
- }
- }
- for(i=botV->get_npoints()-2; i>=1; i--){
- rightChain.appendVertex(tempV->getVertex(i));
- }
-}
-
-
-void findTopAndBot(directedLine* polygon, directedLine*& topV, directedLine*& botV)
-{
- assert(polygon);
- directedLine* tempV;
- topV = botV = polygon;
- for(tempV = polygon->getNext(); tempV != polygon; tempV = tempV->getNext())
- {
- if(compV2InY(topV->head(), tempV->head())<0) {
- topV = tempV;
- }
- if(compV2InY(botV->head(), tempV->head())>0) {
- botV = tempV;
- }
- }
-}
-
-void findGridChains(directedLine* topV, directedLine* botV,
- gridWrap* grid,
- gridBoundaryChain*& leftGridChain,
- gridBoundaryChain*& rightGridChain)
-{
- /*find the first(top) and the last (bottom) grid line which intersect the
- *this polygon
- */
- Int firstGridIndex; /*the index in the grid*/
- Int lastGridIndex;
-
- firstGridIndex = (Int) ((topV->head()[1] - grid->get_v_min()) / (grid->get_v_max() - grid->get_v_min()) * (grid->get_n_vlines()-1));
-
- if(botV->head()[1] < grid->get_v_min())
- lastGridIndex = 0;
- else
- lastGridIndex = (Int) ((botV->head()[1] - grid->get_v_min()) / (grid->get_v_max() - grid->get_v_min()) * (grid->get_n_vlines()-1)) + 1;
-
- /*find the interval inside the polygon for each gridline*/
- Int *leftGridIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1));
- assert(leftGridIndices);
- Int *rightGridIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1));
- assert(rightGridIndices);
- Int *leftGridInnerIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1));
- assert(leftGridInnerIndices);
- Int *rightGridInnerIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1));
- assert(rightGridInnerIndices);
-
- findLeftGridIndices(topV, firstGridIndex, lastGridIndex, grid, leftGridIndices, leftGridInnerIndices);
-
- findRightGridIndices(topV, firstGridIndex, lastGridIndex, grid, rightGridIndices, rightGridInnerIndices);
-
- leftGridChain = new gridBoundaryChain(grid, firstGridIndex, firstGridIndex-lastGridIndex+1, leftGridIndices, leftGridInnerIndices);
-
- rightGridChain = new gridBoundaryChain(grid, firstGridIndex, firstGridIndex-lastGridIndex+1, rightGridIndices, rightGridInnerIndices);
-
- free(leftGridIndices);
- free(rightGridIndices);
- free(leftGridInnerIndices);
- free(rightGridInnerIndices);
-}
-
-void findDownCorners(Real *botVertex,
- vertexArray *leftChain, Int leftChainStartIndex, Int leftChainEndIndex,
- vertexArray *rightChain, Int rightChainStartIndex, Int rightChainEndIndex,
- Real v,
- Real uleft,
- Real uright,
- Int& ret_leftCornerWhere, /*0: left chain, 1: topvertex, 2: rightchain*/
- Int& ret_leftCornerIndex, /*useful when ret_leftCornerWhere == 0 or 2*/
- Int& ret_rightCornerWhere, /*0: left chain, 1: topvertex, 2: rightchain*/
- Int& ret_rightCornerIndex /*useful when ret_leftCornerWhere == 0 or 2*/
- )
-{
-#ifdef MYDEBUG
-printf("*************enter find donw corner\n");
-printf("finddownCorner: v=%f, uleft=%f, uright=%f\n", v, uleft, uright);
-printf("(%i,%i,%i,%i)\n", leftChainStartIndex, leftChainEndIndex,rightChainStartIndex, rightChainEndIndex);
-printf("left chain is\n");
-leftChain->print();
-printf("right chain is\n");
-rightChain->print();
-#endif
-
- assert(v > botVertex[1]);
- Real leftGridPoint[2];
- leftGridPoint[0] = uleft;
- leftGridPoint[1] = v;
- Real rightGridPoint[2];
- rightGridPoint[0] = uright;
- rightGridPoint[1] = v;
-
- Int i;
- Int index1, index2;
-
- index1 = leftChain->findIndexBelowGen(v, leftChainStartIndex, leftChainEndIndex);
- index2 = rightChain->findIndexBelowGen(v, rightChainStartIndex, rightChainEndIndex);
-
- if(index2 <= rightChainEndIndex) //index2 was found above
- index2 = rightChain->skipEqualityFromStart(v, index2, rightChainEndIndex);
-
- if(index1>leftChainEndIndex && index2 > rightChainEndIndex) /*no point below v on left chain or right chain*/
- {
-
- /*the botVertex is the only vertex below v*/
- ret_leftCornerWhere = 1;
- ret_rightCornerWhere = 1;
- }
- else if(index1>leftChainEndIndex ) /*index2 <= rightChainEndIndex*/
- {
-
- ret_rightCornerWhere = 2; /*on right chain*/
- ret_rightCornerIndex = index2;
-
-
- Real tempMin = rightChain->getVertex(index2)[0];
- Int tempI = index2;
- for(i=index2+1; i<= rightChainEndIndex; i++)
- if(rightChain->getVertex(i)[0] < tempMin)
- {
- tempI = i;
- tempMin = rightChain->getVertex(i)[0];
- }
-
-
- //we consider whether we can use botVertex as left corner. First check
- //if (leftGirdPoint, botVertex) interesects right chian or not.
- if(DBG_intersectChain(rightChain, rightChainStartIndex,rightChainEndIndex,
- leftGridPoint, botVertex))
- {
- ret_leftCornerWhere = 2;//right
- ret_leftCornerIndex = index2; //should use tempI???
- }
- else if(botVertex[0] < tempMin)
- ret_leftCornerWhere = 1; //bot
- else
- {
- ret_leftCornerWhere = 2; //right
- ret_leftCornerIndex = tempI;
- }
- }
- else if(index2> rightChainEndIndex) /*index1<=leftChainEndIndex*/
- {
- ret_leftCornerWhere = 0; /*left chain*/
- ret_leftCornerIndex = index1;
-
- /*find the vertex on the left chain with the maximum u,
- *either this vertex or the botvertex can be used as the right corner
- */
-
- Int tempI;
- //skip those points which are equal to v. (avoid degeneratcy)
- for(tempI = index1; tempI <= leftChainEndIndex; tempI++)
- if(leftChain->getVertex(tempI)[1] < v)
- break;
- if(tempI > leftChainEndIndex)
- ret_rightCornerWhere = 1;
- else
- {
- Real tempMax = leftChain->getVertex(tempI)[0];
- for(i=tempI; i<= leftChainEndIndex; i++)
- if(leftChain->getVertex(i)[0] > tempMax)
- {
- tempI = i;
- tempMax = leftChain->getVertex(i)[0];
- }
-
-
-
- //we consider whether we can use botVertex as a corner. So first we check
- //whether (rightGridPoint, botVertex) interescts the left chain or not.
- if(DBG_intersectChain(leftChain, leftChainStartIndex,leftChainEndIndex,
- rightGridPoint, botVertex))
- {
- ret_rightCornerWhere = 0;
- ret_rightCornerIndex = index1; //should use tempI???
- }
- else if(botVertex[0] > tempMax)
- {
-
- ret_rightCornerWhere = 1;
- }
- else
- {
- ret_rightCornerWhere = 0;
- ret_rightCornerIndex = tempI;
- }
- }
-
- }
- else /*index1<=leftChainEndIndex and index2 <=rightChainEndIndex*/
- {
- if(leftChain->getVertex(index1)[1] >= rightChain->getVertex(index2)[1]) /*left point above right point*/
- {
- ret_leftCornerWhere = 0; /*on left chain*/
- ret_leftCornerIndex = index1;
-
- Real tempMax;
- Int tempI;
-
- tempI = index1;
- tempMax = leftChain->getVertex(index1)[0];
-
- /*find the maximum u for all the points on the left above the right point index2*/
- for(i=index1+1; i<= leftChainEndIndex; i++)
- {
- if(leftChain->getVertex(i)[1] < rightChain->getVertex(index2)[1])
- break;
-
- if(leftChain->getVertex(i)[0]>tempMax)
- {
- tempI = i;
- tempMax = leftChain->getVertex(i)[0];
- }
- }
- //we consider if we can use rightChain(index2) as right corner
- //we check if (rightChain(index2), rightGidPoint) intersecs left chain or not.
- if(DBG_intersectChain(leftChain, leftChainStartIndex,leftChainEndIndex, rightGridPoint, rightChain->getVertex(index2)))
- {
- ret_rightCornerWhere = 0;
- ret_rightCornerIndex = index1; //should use tempI???
- }
- else if(tempMax >= rightChain->getVertex(index2)[0] ||
- tempMax >= uright
- )
- {
-
- ret_rightCornerWhere = 0; /*on left Chain*/
- ret_rightCornerIndex = tempI;
- }
- else
- {
- ret_rightCornerWhere = 2; /*on right chain*/
- ret_rightCornerIndex = index2;
- }
- }
- else /*left below right*/
- {
- ret_rightCornerWhere = 2; /*on the right*/
- ret_rightCornerIndex = index2;
-
- Real tempMin;
- Int tempI;
-
- tempI = index2;
- tempMin = rightChain->getVertex(index2)[0];
-
- /*find the minimum u for all the points on the right above the left poitn index1*/
- for(i=index2+1; i<= rightChainEndIndex; i++)
- {
- if( rightChain->getVertex(i)[1] < leftChain->getVertex(index1)[1])
- break;
- if(rightChain->getVertex(i)[0] < tempMin)
- {
- tempI = i;
- tempMin = rightChain->getVertex(i)[0];
- }
- }
-
- //we consider if we can use leftchain(index1) as left corner.
- //we check if (leftChain(index1) intersects right chian or not
- if(DBG_intersectChain(rightChain, rightChainStartIndex, rightChainEndIndex, leftGridPoint, leftChain->getVertex(index1)))
- {
- ret_leftCornerWhere = 2;
- ret_leftCornerIndex = index2; //should use tempI???
- }
- else if(tempMin <= leftChain->getVertex(index1)[0] ||
- tempMin <= uleft)
- {
- ret_leftCornerWhere = 2; /* on right chain*/
- ret_leftCornerIndex = tempI;
- }
- else
- {
- ret_leftCornerWhere = 0; /*on left chain*/
- ret_leftCornerIndex = index1;
- }
- }
- }
-
-}
-
-
-void findUpCorners(Real *topVertex,
- vertexArray *leftChain, Int leftChainStartIndex, Int leftChainEndIndex,
- vertexArray *rightChain, Int rightChainStartIndex, Int rightChainEndIndex,
- Real v,
- Real uleft,
- Real uright,
- Int& ret_leftCornerWhere, /*0: left chain, 1: topvertex, 2: rightchain*/
- Int& ret_leftCornerIndex, /*useful when ret_leftCornerWhere == 0 or 2*/
- Int& ret_rightCornerWhere, /*0: left chain, 1: topvertex, 2: rightchain*/
- Int& ret_rightCornerIndex /*useful when ret_leftCornerWhere == 0 or 2*/
- )
-{
-#ifdef MYDEBUG
-printf("***********enter findUpCorners\n");
-#endif
-
- assert(v < topVertex[1]);
- Real leftGridPoint[2];
- leftGridPoint[0] = uleft;
- leftGridPoint[1] = v;
- Real rightGridPoint[2];
- rightGridPoint[0] = uright;
- rightGridPoint[1] = v;
-
- Int i;
- Int index1, index2;
-
- index1 = leftChain->findIndexFirstAboveEqualGen(v, leftChainStartIndex, leftChainEndIndex);
-
-
- index2 = rightChain->findIndexFirstAboveEqualGen(v, rightChainStartIndex, rightChainEndIndex);
-
- if(index2>= leftChainStartIndex) //index2 was found above
- index2 = rightChain->skipEqualityFromStart(v, index2, rightChainEndIndex);
-
- if(index1<leftChainStartIndex && index2 <rightChainStartIndex) /*no point above v on left chain or right chain*/
- {
- /*the topVertex is the only vertex above v*/
- ret_leftCornerWhere = 1;
- ret_rightCornerWhere = 1;
- }
- else if(index1<leftChainStartIndex ) /*index2 >= rightChainStartIndex*/
- {
- ret_rightCornerWhere = 2; /*on right chain*/
- ret_rightCornerIndex = index2;
-
- //find the minimum u on right top, either that, or top, or right[index2] is the left corner
- Real tempMin = rightChain->getVertex(index2)[0];
- Int tempI = index2;
- for(i=index2-1; i>=rightChainStartIndex; i--)
- if(rightChain->getVertex(i)[0] < tempMin)
- {
- tempMin = rightChain->getVertex(i)[0];
- tempI = i;
- }
- //chech whether (leftGridPoint, top) intersects rightchai,
- //if yes, use right corner as left corner
- //if not, use top or right[tempI] as left corner
- if(DBG_intersectChain(rightChain, rightChainStartIndex, rightChainEndIndex,
- leftGridPoint, topVertex))
- {
- ret_leftCornerWhere = 2; //rightChain
- ret_leftCornerIndex = index2;
- }
- else if(topVertex[0] < tempMin)
- ret_leftCornerWhere = 1; /*topvertex*/
- else
- {
- ret_leftCornerWhere = 2; //right chain
- ret_leftCornerIndex = tempI;
- }
-
- }
- else if(index2< rightChainStartIndex) /*index1>=leftChainStartIndex*/
- {
- ret_leftCornerWhere = 0; /*left chain*/
- ret_leftCornerIndex = index1;
-
- //find the maximum u on the left top section. either that or topvertex, or left[index1] is the right corner
- Real tempMax = leftChain->getVertex(index1)[0];
- Int tempI = index1;
-
- for(i=index1-1; i>=leftChainStartIndex; i--){
-
- if(leftChain->getVertex(i)[0] > tempMax)
- {
-
- tempMax = leftChain->getVertex(i)[0];
- tempI = i;
- }
- }
- //check whether (rightGridPoint, top) intersects leftChain or not
- //if yes, we use leftCorner as the right corner
- //if not, we use either top or left[tempI] as the right corner
- if(DBG_intersectChain(leftChain, leftChainStartIndex,leftChainEndIndex,
- rightGridPoint, topVertex))
- {
- ret_rightCornerWhere = 0; //left chan
- ret_rightCornerIndex = index1;
- }
- else if(topVertex[0] > tempMax)
- ret_rightCornerWhere = 1;//topVertex
- else
- {
- ret_rightCornerWhere = 0;//left chain
- ret_rightCornerIndex = tempI;
- }
- }
- else /*index1>=leftChainStartIndex and index2 >=rightChainStartIndex*/
- {
- if(leftChain->getVertex(index1)[1] <= rightChain->getVertex(index2)[1]) /*left point below right point*/
- {
- ret_leftCornerWhere = 0; /*on left chain*/
- ret_leftCornerIndex = index1;
-
- Real tempMax;
- Int tempI;
-
- tempI = index1;
- tempMax = leftChain->getVertex(index1)[0];
-
- /*find the maximum u for all the points on the left below the right point index2*/
- for(i=index1-1; i>= leftChainStartIndex; i--)
- {
- if(leftChain->getVertex(i)[1] > rightChain->getVertex(index2)[1])
- break;
-
- if(leftChain->getVertex(i)[0]>tempMax)
- {
- tempI = i;
- tempMax = leftChain->getVertex(i)[0];
- }
- }
- //chek whether (rightChain(index2), rightGridPoint) intersects leftchian or not
- if(DBG_intersectChain(leftChain, leftChainStartIndex, leftChainEndIndex, rightGridPoint, rightChain->getVertex(index2)))
- {
- ret_rightCornerWhere = 0;
- ret_rightCornerIndex = index1;
- }
- else if(tempMax >= rightChain->getVertex(index2)[0] ||
- tempMax >= uright)
- {
- ret_rightCornerWhere = 0; /*on left Chain*/
- ret_rightCornerIndex = tempI;
- }
- else
- {
- ret_rightCornerWhere = 2; /*on right chain*/
- ret_rightCornerIndex = index2;
- }
- }
- else /*left above right*/
- {
- ret_rightCornerWhere = 2; /*on the right*/
- ret_rightCornerIndex = index2;
-
- Real tempMin;
- Int tempI;
-
- tempI = index2;
- tempMin = rightChain->getVertex(index2)[0];
-
- /*find the minimum u for all the points on the right below the left poitn index1*/
- for(i=index2-1; i>= rightChainStartIndex; i--)
- {
- if( rightChain->getVertex(i)[1] > leftChain->getVertex(index1)[1])
- break;
- if(rightChain->getVertex(i)[0] < tempMin)
- {
- tempI = i;
- tempMin = rightChain->getVertex(i)[0];
- }
- }
- //check whether (leftGRidPoint,left(index1)) interesect right chain
- if(DBG_intersectChain(rightChain, rightChainStartIndex, rightChainEndIndex,
- leftGridPoint, leftChain->getVertex(index1)))
- {
- ret_leftCornerWhere = 2; //right
- ret_leftCornerIndex = index2;
- }
- else if(tempMin <= leftChain->getVertex(index1)[0] ||
- tempMin <= uleft)
- {
- ret_leftCornerWhere = 2; /* on right chain*/
- ret_leftCornerIndex = tempI;
- }
- else
- {
- ret_leftCornerWhere = 0; /*on left chain*/
- ret_leftCornerIndex = index1;
- }
- }
- }
-#ifdef MYDEBUG
-printf("***********leave findUpCorners\n");
-#endif
-}
-
-//return 1 if neck exists, 0 othewise
-Int findNeckF(vertexArray *leftChain, Int botLeftIndex,
- vertexArray *rightChain, Int botRightIndex,
- gridBoundaryChain* leftGridChain,
- gridBoundaryChain* rightGridChain,
- Int gridStartIndex,
- Int& neckLeft,
- Int& neckRight)
-{
-/*
-printf("enter findNeckF, botleft, botright=%i,%i,gstartindex=%i\n",botLeftIndex,botRightIndex,gridStartIndex);
-printf("leftChain is\n");
-leftChain->print();
-printf("rightChain is\n");
-rightChain->print();
-*/
-
- Int lowerGridIndex; //the grid below leftChain and rightChian vertices
- Int i;
- Int n_vlines = leftGridChain->get_nVlines();
- Real v;
- if(botLeftIndex >= leftChain->getNumElements() ||
- botRightIndex >= rightChain->getNumElements())
- return 0; //no neck exists
-
- v=min(leftChain->getVertex(botLeftIndex)[1], rightChain->getVertex(botRightIndex)[1]);
-
-
-
-
- for(i=gridStartIndex; i<n_vlines; i++)
- if(leftGridChain->get_v_value(i) <= v &&
- leftGridChain->getUlineIndex(i)<= rightGridChain->getUlineIndex(i))
- break;
-
- lowerGridIndex = i;
-
- if(lowerGridIndex == n_vlines) //the two trm vertex are higher than all gridlines
- return 0;
- else
- {
- Int botLeft2, botRight2;
-/*
-printf("leftGridChain->get_v_)value=%f\n",leftGridChain->get_v_value(lowerGridIndex), botLeftIndex);
-printf("leftChain->get_vertex(0)=(%f,%f)\n", leftChain->getVertex(0)[0],leftChain->getVertex(0)[1]);
-printf("leftChain->get_vertex(1)=(%f,%f)\n", leftChain->getVertex(1)[0],leftChain->getVertex(1)[1]);
-printf("leftChain->get_vertex(2)=(%f,%f)\n", leftChain->getVertex(2)[0],leftChain->getVertex(2)[1]);
-*/
- botLeft2 = leftChain->findIndexFirstAboveEqualGen(leftGridChain->get_v_value(lowerGridIndex), botLeftIndex, leftChain->getNumElements()-1) -1 ;
-
-/*
-printf("botLeft2=%i\n", botLeft2);
-printf("leftChain->getNumElements=%i\n", leftChain->getNumElements());
-*/
-
- botRight2 = rightChain->findIndexFirstAboveEqualGen(leftGridChain->get_v_value(lowerGridIndex), botRightIndex, rightChain->getNumElements()-1) -1;
- if(botRight2 < botRightIndex) botRight2=botRightIndex;
-
- if(botLeft2 < botLeftIndex) botLeft2 = botLeftIndex;
-
- assert(botLeft2 >= botLeftIndex);
- assert(botRight2 >= botRightIndex);
- //find nectLeft so that it is th erightmost vertex on letChain
-
- Int tempI = botLeftIndex;
- Real temp = leftChain->getVertex(tempI)[0];
- for(i=botLeftIndex+1; i<= botLeft2; i++)
- if(leftChain->getVertex(i)[0] > temp)
- {
- temp = leftChain->getVertex(i)[0];
- tempI = i;
- }
- neckLeft = tempI;
-
- tempI = botRightIndex;
- temp = rightChain->getVertex(tempI)[0];
- for(i=botRightIndex+1; i<= botRight2; i++)
- if(rightChain->getVertex(i)[0] < temp)
- {
- temp = rightChain->getVertex(i)[0];
- tempI = i;
- }
- neckRight = tempI;
- return 1;
- }
-}
-
-
-
-/*find i>=botLeftIndex,j>=botRightIndex so that
- *(leftChain[i], rightChain[j]) is a neck.
- */
-void findNeck(vertexArray *leftChain, Int botLeftIndex,
- vertexArray *rightChain, Int botRightIndex,
- Int& leftLastIndex, /*left point of the neck*/
- Int& rightLastIndex /*right point of the neck*/
- )
-{
- assert(botLeftIndex < leftChain->getNumElements() &&
- botRightIndex < rightChain->getNumElements());
-
- /*now the neck exists for sure*/
-
- if(leftChain->getVertex(botLeftIndex)[1] <= rightChain->getVertex(botRightIndex)[1]) //left below right
- {
-
- leftLastIndex = botLeftIndex;
-
- /*find i so that rightChain[i][1] >= leftchainbotverte[1], and i+1<
- */
- rightLastIndex=rightChain->findIndexAboveGen(leftChain->getVertex(botLeftIndex)[1], botRightIndex+1, rightChain->getNumElements()-1);
- }
- else //left above right
- {
-
- rightLastIndex = botRightIndex;
-
- leftLastIndex = leftChain->findIndexAboveGen(rightChain->getVertex(botRightIndex)[1],
- botLeftIndex+1,
- leftChain->getNumElements()-1);
- }
-}
-
-
-
-void findLeftGridIndices(directedLine* topEdge, Int firstGridIndex, Int lastGridIndex, gridWrap* grid, Int* ret_indices, Int* ret_innerIndices)
-{
-
- Int i,k,isHoriz = 0;
- Int n_ulines = grid->get_n_ulines();
- Real uMin = grid->get_u_min();
- Real uMax = grid->get_u_max();
- /*
- Real vMin = grid->get_v_min();
- Real vMax = grid->get_v_max();
- */
- Real slop = 0.0, uinterc;
-
-#ifdef SHORTEN_GRID_LINE
- //uintercBuf stores all the interction u value for each grid line
- //notice that lastGridIndex<= firstGridIndex
- Real *uintercBuf = (Real *) malloc (sizeof(Real) * (firstGridIndex-lastGridIndex+1));
- assert(uintercBuf);
-#endif
-
- /*initialization to make vtail bigger than grid->...*/
- directedLine* dLine = topEdge;
- Real vtail = grid->get_v_value(firstGridIndex) + 1.0;
- Real tempMaxU = grid->get_u_min();
-
-
- /*for each grid line*/
- for(k=0, i=firstGridIndex; i>=lastGridIndex; i--, k++)
- {
-
- Real grid_v_value = grid->get_v_value(i);
-
- /*check whether this grid line is below the current trim edge.*/
- if(vtail > grid_v_value)
- {
- /*since the grid line is below the trim edge, we
- *find the trim edge which will contain the trim line
- */
- while( (vtail=dLine->tail()[1]) > grid_v_value){
-
- tempMaxU = max(tempMaxU, dLine->tail()[0]);
- dLine = dLine -> getNext();
- }
-
- if( fabs(dLine->head()[1] - vtail) < ZERO)
- isHoriz = 1;
- else
- {
- isHoriz = 0;
- slop = (dLine->head()[0] - dLine->tail()[0]) / (dLine->head()[1]-vtail);
- }
- }
-
- if(isHoriz)
- {
- uinterc = max(dLine->head()[0], dLine->tail()[0]);
- }
- else
- {
- uinterc = slop * (grid_v_value - vtail) + dLine->tail()[0];
- }
-
- tempMaxU = max(tempMaxU, uinterc);
-
- if(uinterc < uMin && uinterc >= uMin - ZERO)
- uinterc = uMin;
- if(uinterc > uMax && uinterc <= uMax + ZERO)
- uinterc = uMax;
-
-#ifdef SHORTEN_GRID_LINE
- uintercBuf[k] = uinterc;
-#endif
-
- assert(uinterc >= uMin && uinterc <= uMax);
- if(uinterc == uMax)
- ret_indices[k] = n_ulines-1;
- else
- ret_indices[k] = (Int)(((uinterc-uMin)/(uMax - uMin)) * (n_ulines-1)) + 1;
- if(ret_indices[k] >= n_ulines)
- ret_indices[k] = n_ulines-1;
-
-
- ret_innerIndices[k] = (Int)(((tempMaxU-uMin)/(uMax - uMin)) * (n_ulines-1)) + 1;
-
- /*reinitialize tempMaxU for next grdiLine*/
- tempMaxU = uinterc;
- }
-#ifdef SHORTEN_GRID_LINE
- //for each grid line, compare the left grid point with the
- //intersection point. If the two points are too close, then
- //we should move the grid point one grid to the right
- //and accordingly we should update the inner index.
- for(k=0, i=firstGridIndex; i>=lastGridIndex; i--, k++)
- {
- //check gridLine i
- //check ret_indices[k]
- Real a = grid->get_u_value(ret_indices[k]-1);
- Real b = grid->get_u_value(ret_indices[k]);
- assert(uintercBuf[k] >= a && uintercBuf < b);
- if( (b-uintercBuf[k]) <= 0.2 * (b-a)) //interc is very close to b
- {
- ret_indices[k]++;
- }
-
- //check ret_innerIndices[k]
- if(k>0)
- {
- if(ret_innerIndices[k] < ret_indices[k-1])
- ret_innerIndices[k] = ret_indices[k-1];
- if(ret_innerIndices[k] < ret_indices[k])
- ret_innerIndices[k] = ret_indices[k];
- }
- }
- //clean up
- free(uintercBuf);
-#endif
-}
-
-void findRightGridIndices(directedLine* topEdge, Int firstGridIndex, Int lastGridIndex, gridWrap* grid, Int* ret_indices, Int* ret_innerIndices)
-{
-
- Int i,k;
- Int n_ulines = grid->get_n_ulines();
- Real uMin = grid->get_u_min();
- Real uMax = grid->get_u_max();
- /*
- Real vMin = grid->get_v_min();
- Real vMax = grid->get_v_max();
- */
- Real slop = 0.0, uinterc;
-
-#ifdef SHORTEN_GRID_LINE
- //uintercBuf stores all the interction u value for each grid line
- //notice that firstGridIndex >= lastGridIndex
- Real *uintercBuf = (Real *) malloc (sizeof(Real) * (firstGridIndex-lastGridIndex+1));
- assert(uintercBuf);
-#endif
-
- /*initialization to make vhead bigger than grid->v_value...*/
- directedLine* dLine = topEdge->getPrev();
- Real vhead = dLine->tail()[1];
- Real tempMinU = grid->get_u_max();
-
- /*for each grid line*/
- for(k=0, i=firstGridIndex; i>=lastGridIndex; i--, k++)
- {
-
- Real grid_v_value = grid->get_v_value(i);
-
-
- /*check whether this grid line is below the current trim edge.*/
- if(vhead >= grid_v_value)
- {
- /*since the grid line is below the tail of the trim edge, we
- *find the trim edge which will contain the trim line
- */
- while( (vhead=dLine->head()[1]) > grid_v_value){
- tempMinU = min(tempMinU, dLine->head()[0]);
- dLine = dLine -> getPrev();
- }
-
- /*skip the equality in the case of degenerat case: horizontal */
- while(dLine->head()[1] == grid_v_value)
- dLine = dLine->getPrev();
-
- assert( dLine->tail()[1] != dLine->head()[1]);
- slop = (dLine->tail()[0] - dLine->head()[0]) / (dLine->tail()[1]-dLine->head()[1]);
- /*
- if(dLine->tail()[1] == vhead)
- isHoriz = 1;
- else
- {
- isHoriz = 0;
- slop = (dLine->tail()[0] - dLine->head()[0]) / (dLine->tail()[1]-vhead);
- }
- */
- }
- uinterc = slop * (grid_v_value - dLine->head()[1]) + dLine->head()[0];
-
- //in case unterc is outside of the grid due to floating point
- if(uinterc < uMin)
- uinterc = uMin;
- else if(uinterc > uMax)
- uinterc = uMax;
-
-#ifdef SHORTEN_GRID_LINE
- uintercBuf[k] = uinterc;
-#endif
-
- tempMinU = min(tempMinU, uinterc);
-
- assert(uinterc >= uMin && uinterc <= uMax);
-
- if(uinterc == uMin)
- ret_indices[k] = 0;
- else
- ret_indices[k] = (int)ceil((((uinterc-uMin)/(uMax - uMin)) * (n_ulines-1))) -1;
-/*
-if(ret_indices[k] >= grid->get_n_ulines())
- {
- printf("ERROR3\n");
- exit(0);
-}
-if(ret_indices[k] < 0)
- {
- printf("ERROR4\n");
- exit(0);
-}
-*/
- ret_innerIndices[k] = (int)ceil ((((tempMinU-uMin)/(uMax - uMin)) * (n_ulines-1))) -1;
-
- tempMinU = uinterc;
- }
-#ifdef SHORTEN_GRID_LINE
- //for each grid line, compare the left grid point with the
- //intersection point. If the two points are too close, then
- //we should move the grid point one grid to the right
- //and accordingly we should update the inner index.
- for(k=0, i=firstGridIndex; i>=lastGridIndex; i--, k++)
- {
- //check gridLine i
- //check ret_indices[k]
- Real a = grid->get_u_value(ret_indices[k]);
- Real b = grid->get_u_value(ret_indices[k]+1);
- assert(uintercBuf[k] > a && uintercBuf <= b);
- if( (uintercBuf[k]-a) <= 0.2 * (b-a)) //interc is very close to a
- {
- ret_indices[k]--;
- }
-
- //check ret_innerIndices[k]
- if(k>0)
- {
- if(ret_innerIndices[k] > ret_indices[k-1])
- ret_innerIndices[k] = ret_indices[k-1];
- if(ret_innerIndices[k] > ret_indices[k])
- ret_innerIndices[k] = ret_indices[k];
- }
- }
- //clean up
- free(uintercBuf);
-#endif
-}
-
-
-void sampleMonoPoly(directedLine* polygon, gridWrap* grid, Int ulinear, Int vlinear, primStream* pStream, rectBlockArray* rbArray)
-{
-/*
-{
-grid->print();
-polygon->writeAllPolygons("zloutputFile");
-exit(0);
-}
-*/
-
-if(grid->get_n_ulines() == 2 ||
- grid->get_n_vlines() == 2)
-{
- if(ulinear && grid->get_n_ulines() == 2)
- {
- monoTriangulationFun(polygon, compV2InY, pStream);
- return;
- }
- else if(DBG_isConvex(polygon) && polygon->numEdges() >=4)
- {
- triangulateConvexPoly(polygon, ulinear, vlinear, pStream);
- return;
- }
- else if(vlinear || DBG_is_U_direction(polygon))
- {
- Int n_cusps;//num interior cusps
- Int n_edges = polygon->numEdges();
- directedLine** cusps = (directedLine**) malloc(sizeof(directedLine*) * n_edges);
- assert(cusps);
- findInteriorCuspsX(polygon, n_cusps, cusps);
-
- if(n_cusps == 0) //u_monotone
- {
-
- monoTriangulationFun(polygon, compV2InX, pStream);
-
- free(cusps);
- return;
- }
- else if(n_cusps == 1) //one interior cusp
- {
-
- directedLine* new_polygon = polygonConvert(cusps[0]);
-
- directedLine* other = findDiagonal_singleCuspX( new_polygon);
-
-
-
- //<other> should NOT be null unless there are self-intersecting
- //trim curves. In that case, we don't want to core dump, instead,
- //we triangulate anyway, and print out error message.
- if(other == NULL)
- {
- monoTriangulationFun(polygon, compV2InX, pStream);
- free(cusps);
- return;
- }
-
- directedLine* ret_p1;
- directedLine* ret_p2;
-
- new_polygon->connectDiagonal_2slines(new_polygon, other,
- &ret_p1,
- &ret_p2,
- new_polygon);
-
- monoTriangulationFun(ret_p1, compV2InX, pStream);
- monoTriangulationFun(ret_p2, compV2InX, pStream);
-
- ret_p1->deleteSinglePolygonWithSline();
- ret_p2->deleteSinglePolygonWithSline();
-
- free(cusps);
- return;
- }
- free(cusps);
- }
-}
-
- /*find the top and bottom of the polygon. It is supposed to be
- *a V-monotone polygon
- */
-
- directedLine* tempV;
- directedLine* topV;
- directedLine* botV;
- topV = botV = polygon;
-
- for(tempV = polygon->getNext(); tempV != polygon; tempV = tempV->getNext())
- {
- if(compV2InY(topV->head(), tempV->head())<0) {
-
- topV = tempV;
- }
- if(compV2InY(botV->head(), tempV->head())>0) {
-
- botV = tempV;
- }
- }
-
- /*find the first(top) and the last (bottom) grid line which intersect the
- *this polygon
- */
- Int firstGridIndex; /*the index in the grid*/
- Int lastGridIndex;
- firstGridIndex = (Int) ((topV->head()[1] - grid->get_v_min()) / (grid->get_v_max() - grid->get_v_min()) * (grid->get_n_vlines()-1));
- lastGridIndex = (Int) ((botV->head()[1] - grid->get_v_min()) / (grid->get_v_max() - grid->get_v_min()) * (grid->get_n_vlines()-1)) + 1;
-
-
- /*find the interval inside the polygon for each gridline*/
- Int *leftGridIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1));
- assert(leftGridIndices);
- Int *rightGridIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1));
- assert(rightGridIndices);
- Int *leftGridInnerIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1));
- assert(leftGridInnerIndices);
- Int *rightGridInnerIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1));
- assert(rightGridInnerIndices);
-
- findLeftGridIndices(topV, firstGridIndex, lastGridIndex, grid, leftGridIndices, leftGridInnerIndices);
-
- findRightGridIndices(topV, firstGridIndex, lastGridIndex, grid, rightGridIndices, rightGridInnerIndices);
-
- gridBoundaryChain leftGridChain(grid, firstGridIndex, firstGridIndex-lastGridIndex+1, leftGridIndices, leftGridInnerIndices);
-
- gridBoundaryChain rightGridChain(grid, firstGridIndex, firstGridIndex-lastGridIndex+1, rightGridIndices, rightGridInnerIndices);
-
-
-
-// leftGridChain.draw();
-// leftGridChain.drawInner();
-// rightGridChain.draw();
-// rightGridChain.drawInner();
- /*(1) determine the grid boundaries (left and right).
- *(2) process polygon into two monotone chaines: use vertexArray
- *(3) call sampleMonoPolyRec
- */
-
- /*copy the two chains into vertexArray datastructure*/
- Int i;
- vertexArray leftChain(20); /*this is a dynamic array*/
- for(i=1; i<=topV->get_npoints()-2; i++) { /*the first vertex is the top vertex which doesn't belong to inc_chain*/
- leftChain.appendVertex(topV->getVertex(i));
- }
- for(tempV = topV->getNext(); tempV != botV; tempV = tempV->getNext())
- {
- for(i=0; i<=tempV->get_npoints()-2; i++){
- leftChain.appendVertex(tempV->getVertex(i));
- }
- }
-
- vertexArray rightChain(20);
- for(tempV = topV->getPrev(); tempV != botV; tempV = tempV->getPrev())
- {
- for(i=tempV->get_npoints()-2; i>=0; i--){
- rightChain.appendVertex(tempV->getVertex(i));
- }
- }
- for(i=botV->get_npoints()-2; i>=1; i--){
- rightChain.appendVertex(tempV->getVertex(i));
- }
-
- sampleMonoPolyRec(topV->head(),
- botV->head(),
- &leftChain,
- 0,
- &rightChain,
- 0,
- &leftGridChain,
- &rightGridChain,
- 0,
- pStream,
- rbArray);
-
-
- /*cleanup space*/
- free(leftGridIndices);
- free(rightGridIndices);
- free(leftGridInnerIndices);
- free(rightGridInnerIndices);
-}
-
-void sampleMonoPolyRec(
- Real* topVertex,
- Real* botVertex,
- vertexArray* leftChain,
- Int leftStartIndex,
- vertexArray* rightChain,
- Int rightStartIndex,
- gridBoundaryChain* leftGridChain,
- gridBoundaryChain* rightGridChain,
- Int gridStartIndex,
- primStream* pStream,
- rectBlockArray* rbArray)
-{
-
- /*find the first connected component, and the four corners.
- */
- Int index1, index2; /*the first and last grid line of the first connected component*/
-
- if(topVertex[1] <= botVertex[1])
- return;
-
- /*find i so that the grid line is below the top vertex*/
- Int i=gridStartIndex;
- while (i < leftGridChain->get_nVlines())
- {
- if(leftGridChain->get_v_value(i) < topVertex[1])
- break;
- i++;
- }
-
- /*find the first connected component starting with i*/
- /*find index1 so that left_uline_index <= right_uline_index, that is, this
- *grid line contains at least one inner grid point
- */
- index1=i;
- int num_skipped_grid_lines=0;
- while(index1 < leftGridChain->get_nVlines())
- {
- if(leftGridChain->getUlineIndex(index1) <= rightGridChain->getUlineIndex(index1))
- break;
- num_skipped_grid_lines++;
- index1++;
- }
-
-
-
- if(index1 >= leftGridChain->get_nVlines()) /*no grid line exists which has inner point*/
- {
- /*stop recursion, ...*/
- /*monotone triangulate it...*/
-// printf("no grid line exists\n");
-/*
- monoTriangulationRecOpt(topVertex, botVertex, leftChain, leftStartIndex,
- rightChain, rightStartIndex, pStream);
-*/
-
-if(num_skipped_grid_lines <2)
- {
- monoTriangulationRecGenOpt(topVertex, botVertex, leftChain, leftStartIndex,
- leftChain->getNumElements()-1,
- rightChain, rightStartIndex,
- rightChain->getNumElements()-1,
- pStream);
- }
-else
- {
- //the optimum way to triangulate is top-down since this polygon
- //is narrow-long.
- monoTriangulationRec(topVertex, botVertex, leftChain, leftStartIndex,
- rightChain, rightStartIndex, pStream);
- }
-
-/*
- monoTriangulationRec(topVertex, botVertex, leftChain, leftStartIndex,
- rightChain, rightStartIndex, pStream);
-*/
-
-/* monoTriangulationRecGenTBOpt(topVertex, botVertex,
- leftChain, leftStartIndex, leftChain->getNumElements()-1,
- rightChain, rightStartIndex, rightChain->getNumElements()-1,
- pStream);*/
-
-
-
- }
- else
- {
-
- /*find index2 so that left_inner_index <= right_inner_index holds until index2*/
- index2=index1+1;
- if(index2 < leftGridChain->get_nVlines())
- while(leftGridChain->getInnerIndex(index2) <= rightGridChain->getInnerIndex(index2))
- {
- index2++;
- if(index2 >= leftGridChain->get_nVlines())
- break;
- }
-
- index2--;
-
-
-
- /*the neck*/
- Int neckLeftIndex;
- Int neckRightIndex;
-
- /*the four corners*/
- Int up_leftCornerWhere;
- Int up_leftCornerIndex;
- Int up_rightCornerWhere;
- Int up_rightCornerIndex;
- Int down_leftCornerWhere;
- Int down_leftCornerIndex;
- Int down_rightCornerWhere;
- Int down_rightCornerIndex;
-
- Real* tempBotVertex; /*the bottom vertex for this component*/
- Real* nextTopVertex=NULL; /*for the recursion*/
- Int nextLeftStartIndex=0;
- Int nextRightStartIndex=0;
-
- /*find the points below the grid line index2 on both chains*/
- Int botLeftIndex = leftChain->findIndexStrictBelowGen(
- leftGridChain->get_v_value(index2),
- leftStartIndex,
- leftChain->getNumElements()-1);
- Int botRightIndex = rightChain->findIndexStrictBelowGen(
- rightGridChain->get_v_value(index2),
- rightStartIndex,
- rightChain->getNumElements()-1);
- /*if either botLeftIndex>= numelements,
- * or botRightIndex >= numelemnet,
- *then there is no neck exists. the bottom vertex is botVertex,
- */
- if(! findNeckF(leftChain, botLeftIndex, rightChain, botRightIndex,
- leftGridChain, rightGridChain, index2, neckLeftIndex, neckRightIndex))
- /*
- if(botLeftIndex == leftChain->getNumElements() ||
- botRightIndex == rightChain->getNumElements())
- */
- {
-#ifdef MYDEBUG
- printf("neck NOT exists, botRightIndex=%i\n", botRightIndex);
-#endif
-
- tempBotVertex = botVertex;
- nextTopVertex = botVertex;
- botLeftIndex = leftChain->getNumElements()-1;
- botRightIndex = rightChain->getNumElements()-1;
- }
- else /*neck exists*/
- {
-#ifdef MYDEBUG
- printf("neck exists\n");
-#endif
-
- /*
- findNeck(leftChain, botLeftIndex,
- rightChain, botRightIndex,
- neckLeftIndex,
- neckRightIndex);
- */
-#ifdef MYDEBUG
-printf("neck is found, neckLeftIndex=%i, neckRightIndex=%i\n", neckLeftIndex, neckRightIndex);
-glBegin(GL_LINES);
-glVertex2fv(leftChain->getVertex(neckLeftIndex));
-glVertex2fv(rightChain->getVertex(neckRightIndex));
-glEnd();
-#endif
-
- if(leftChain->getVertex(neckLeftIndex)[1] <= rightChain->getVertex(neckRightIndex)[1])
- {
- tempBotVertex = leftChain->getVertex(neckLeftIndex);
- botLeftIndex = neckLeftIndex-1;
- botRightIndex = neckRightIndex;
- nextTopVertex = rightChain->getVertex(neckRightIndex);
- nextLeftStartIndex = neckLeftIndex;
- nextRightStartIndex = neckRightIndex+1;
- }
- else
- {
- tempBotVertex = rightChain->getVertex(neckRightIndex);
- botLeftIndex = neckLeftIndex;
- botRightIndex = neckRightIndex-1;
- nextTopVertex = leftChain->getVertex(neckLeftIndex);
- nextLeftStartIndex = neckLeftIndex+1;
- nextRightStartIndex = neckRightIndex;
- }
- }
-
- findUpCorners(topVertex,
- leftChain,
- leftStartIndex, botLeftIndex,
- rightChain,
- rightStartIndex, botRightIndex,
- leftGridChain->get_v_value(index1),
- leftGridChain->get_u_value(index1),
- rightGridChain->get_u_value(index1),
- up_leftCornerWhere,
- up_leftCornerIndex,
- up_rightCornerWhere,
- up_rightCornerIndex);
-
- findDownCorners(tempBotVertex,
- leftChain,
- leftStartIndex, botLeftIndex,
- rightChain,
- rightStartIndex, botRightIndex,
- leftGridChain->get_v_value(index2),
- leftGridChain->get_u_value(index2),
- rightGridChain->get_u_value(index2),
- down_leftCornerWhere,
- down_leftCornerIndex,
- down_rightCornerWhere,
- down_rightCornerIndex);
-#ifdef MYDEBUG
- printf("find corners done, down_leftwhere=%i, down_righwhere=%i,\n",down_leftCornerWhere, down_rightCornerWhere );
- printf("find corners done, up_leftwhere=%i, up_righwhere=%i,\n",up_leftCornerWhere, up_rightCornerWhere );
- printf("find corners done, up_leftindex=%i, up_righindex=%i,\n",up_leftCornerIndex, up_rightCornerIndex );
- printf("find corners done, down_leftindex=%i, down_righindex=%i,\n",down_leftCornerIndex, down_rightCornerIndex );
-#endif
-
-/*
- drawCorners(topVertex,
- tempBotVertex,
- leftChain,
- rightChain,
- leftGridChain,
- rightGridChain,
- index1,
- index2,
- up_leftCornerWhere,
- up_leftCornerIndex,
- up_rightCornerWhere,
- up_rightCornerIndex,
- down_leftCornerWhere,
- down_leftCornerIndex,
- down_rightCornerWhere,
- down_rightCornerIndex);
-*/
-
-
- sampleConnectedComp(topVertex, tempBotVertex,
- leftChain,
- leftStartIndex, botLeftIndex,
- rightChain,
- rightStartIndex, botRightIndex,
- leftGridChain,
- rightGridChain,
- index1, index2,
- up_leftCornerWhere,
- up_leftCornerIndex,
- up_rightCornerWhere,
- up_rightCornerIndex,
- down_leftCornerWhere,
- down_leftCornerIndex,
- down_rightCornerWhere,
- down_rightCornerIndex,
- pStream,
- rbArray
- );
-
- /*recursion*/
-
- sampleMonoPolyRec(
- nextTopVertex,
- botVertex,
- leftChain,
- nextLeftStartIndex,
- rightChain,
- nextRightStartIndex,
- leftGridChain,
- rightGridChain,
- index2+1,
- pStream, rbArray);
-
-
- }
-
-}
-
-void sampleLeftStrip(vertexArray* leftChain,
- Int topLeftIndex,
- Int botLeftIndex,
- gridBoundaryChain* leftGridChain,
- Int leftGridChainStartIndex,
- Int leftGridChainEndIndex,
- primStream* pStream
- )
-{
- assert(leftChain->getVertex(topLeftIndex)[1] > leftGridChain->get_v_value(leftGridChainStartIndex));
- assert(leftChain->getVertex(topLeftIndex+1)[1] <= leftGridChain->get_v_value(leftGridChainStartIndex));
- assert(leftChain->getVertex(botLeftIndex)[1] <= leftGridChain->get_v_value(leftGridChainEndIndex));
- assert(leftChain->getVertex(botLeftIndex-1)[1] > leftGridChain->get_v_value(leftGridChainEndIndex));
-
- /*
- *(1)find the last grid line which doesn'; pass below
- * this first edge, sample this region: one trim edge and
- * possily multiple grid lines.
- */
- Real *upperVert, *lowerVert; /*the end points of the first trim edge*/
- upperVert = leftChain->getVertex(topLeftIndex);
- lowerVert = leftChain->getVertex(topLeftIndex+1);
-
- Int index = leftGridChainStartIndex;
- while(leftGridChain->get_v_value(index) >= lowerVert[1]){
- index++;
- if(index > leftGridChainEndIndex)
- break;
- }
- index--;
-
- sampleLeftSingleTrimEdgeRegion(upperVert, lowerVert,
- leftGridChain,
- leftGridChainStartIndex,
- index,
- pStream);
- sampleLeftStripRec(leftChain, topLeftIndex+1, botLeftIndex,
- leftGridChain, index, leftGridChainEndIndex,
- pStream);
-
-}
-
-void sampleLeftStripRec(vertexArray* leftChain,
- Int topLeftIndex,
- Int botLeftIndex,
- gridBoundaryChain* leftGridChain,
- Int leftGridChainStartIndex,
- Int leftGridChainEndIndex,
- primStream* pStream
- )
-{
- /*now top left trim vertex is below the top grid line.
- */
- /*stop condition: if topLeftIndex >= botLeftIndex, then stop.
- */
- if(topLeftIndex >= botLeftIndex)
- return;
-
- /*find the last trim vertex which is above the second top grid line:
- * index1.
- *and sampleLeftOneGridStep(leftchain, topLeftIndex, index1, leftGridChain,
- * leftGridChainStartIndex).
- * index1 could be equal to topLeftIndex.
- */
- Real secondGridChainV = leftGridChain->get_v_value(leftGridChainStartIndex+1);
- assert(leftGridChainStartIndex < leftGridChainEndIndex);
- Int index1 = topLeftIndex;
- while(leftChain->getVertex(index1)[1] > secondGridChainV)
- index1++;
- index1--;
-
- sampleLeftOneGridStep(leftChain, topLeftIndex, index1, leftGridChain, leftGridChainStartIndex, pStream);
-
-
- /*
- * Let the next trim vertex be nextTrimVertIndex (which should be
- * below the second grid line).
- * Find the last grid line index2 which is above nextTrimVert.
- * sampleLeftSingleTrimEdgeRegion(uppervert[2], lowervert[2],
- * leftGridChain, leftGridChainStartIndex+1, index2).
- */
- Real *uppervert, *lowervert;
- uppervert = leftChain->getVertex(index1);
- lowervert = leftChain->getVertex(index1+1);
- Int index2 = leftGridChainStartIndex+1;
-
- while(leftGridChain->get_v_value(index2) >= lowervert[1])
- {
- index2++;
- if(index2 > leftGridChainEndIndex)
- break;
- }
- index2--;
- sampleLeftSingleTrimEdgeRegion(uppervert, lowervert, leftGridChain, leftGridChainStartIndex+1, index2, pStream);
-
- /* sampleLeftStripRec(leftChain,
- nextTrimVertIndex,
- botLeftIndex,
- leftGridChain,
- index2,
- leftGridChainEndIndex
- )
- *
- */
- sampleLeftStripRec(leftChain, index1+1, botLeftIndex, leftGridChain, index2, leftGridChainEndIndex, pStream);
-
-}
-
-
-/***************begin RecF***********************/
-/* the gridlines from leftGridChainStartIndex to
- * leftGridChainEndIndex are assumed to form a
- * connected component.
- * the trim vertex of topLeftIndex is assumed to
- * be below the first gridline, and the tim vertex
- * of botLeftIndex is assumed to be above the last
- * grid line.
- * If botLeftIndex < topLeftIndex, then no connected componeent exists, and this funcion returns without
- * outputing any triangles.
- * Otherwise botLeftIndex >= topLeftIndex, there is at least one triangle to output.
- */
-void sampleLeftStripRecF(vertexArray* leftChain,
- Int topLeftIndex,
- Int botLeftIndex,
- gridBoundaryChain* leftGridChain,
- Int leftGridChainStartIndex,
- Int leftGridChainEndIndex,
- primStream* pStream
- )
-{
- /*now top left trim vertex is below the top grid line.
- */
- /*stop condition: if topLeftIndex > botLeftIndex, then stop.
- */
- if(topLeftIndex > botLeftIndex)
- return;
-
- /*if there is only one grid Line, return.*/
-
- if(leftGridChainStartIndex>=leftGridChainEndIndex)
- return;
-
-
- assert(leftChain->getVertex(topLeftIndex)[1] <= leftGridChain->get_v_value(leftGridChainStartIndex) &&
- leftChain->getVertex(botLeftIndex)[1] >= leftGridChain->get_v_value(leftGridChainEndIndex));
-
- /*firs find the first trim vertex which is below or equal to the second top grid line:
- * index1.
- */
- Real secondGridChainV = leftGridChain->get_v_value(leftGridChainStartIndex+1);
-
-
- Int index1 = topLeftIndex;
-
- while(leftChain->getVertex(index1)[1] > secondGridChainV){
- index1++;
- if(index1>botLeftIndex)
- break;
- }
-
- /*now leftChain->getVertex(index-1)[1] > secondGridChainV and
- * leftChain->getVertex(index)[1] <= secondGridChainV
- *If equality holds, then we should include the vertex index1, otherwise we include only index1-1, to
- *perform sampleOneGridStep.
- */
- if(index1>botLeftIndex)
- index1--;
- else if(leftChain->getVertex(index1)[1] < secondGridChainV)
- index1--;
-
- /*now we have leftChain->getVertex(index1)[1] >= secondGridChainV, and
- * leftChain->getVertex(index1+1)[1] <= secondGridChainV
- */
-
-
- sampleLeftOneGridStep(leftChain, topLeftIndex, index1, leftGridChain, leftGridChainStartIndex, pStream);
-
-
- /*if leftChain->getVertex(index1)[1] == secondGridChainV, then we can recursively do the rest.
- */
- if(leftChain->getVertex(index1)[1] == secondGridChainV)
- {
-
- sampleLeftStripRecF(leftChain, index1, botLeftIndex,leftGridChain, leftGridChainStartIndex+1, leftGridChainEndIndex, pStream);
- }
- else if(index1 < botLeftIndex)
- {
-
- /* Otherwise, we have leftChain->getVertex(index1)[1] > secondGridChainV,
- * let the next trim vertex be nextTrimVertIndex (which should be strictly
- * below the second grid line).
- * Find the last grid line index2 which is above nextTrimVert.
- * sampleLeftSingleTrimEdgeRegion(uppervert[2], lowervert[2],
- * leftGridChain, leftGridChainStartIndex+1, index2).
- */
- Real *uppervert, *lowervert;
- uppervert = leftChain->getVertex(index1);
- lowervert = leftChain->getVertex(index1+1); //okay since index1<botLeftIndex
- Int index2 = leftGridChainStartIndex+1;
-
-
- while(leftGridChain->get_v_value(index2) >= lowervert[1])
- {
- index2++;
- if(index2 > leftGridChainEndIndex)
- break;
- }
- index2--;
-
-
- sampleLeftSingleTrimEdgeRegion(uppervert, lowervert, leftGridChain, leftGridChainStartIndex+1, index2, pStream);
-
- /*recursion*/
-
- sampleLeftStripRecF(leftChain, index1+1, botLeftIndex, leftGridChain, index2, leftGridChainEndIndex, pStream);
- }
-
-}
-
-/***************End RecF***********************/
-
-/*sample the left area in between one trim edge and multiple grid lines.
- * all the grid lines should be in between the two end poins of the
- *trim edge.
- */
-void sampleLeftSingleTrimEdgeRegion(Real upperVert[2], Real lowerVert[2],
- gridBoundaryChain* gridChain,
- Int beginIndex,
- Int endIndex,
- primStream* pStream)
-{
- Int i,j,k;
-
- vertexArray vArray(endIndex-beginIndex+1);
- vArray.appendVertex(gridChain->get_vertex(beginIndex));
-
- for(k=1, i=beginIndex+1; i<=endIndex; i++, k++)
- {
- vArray.appendVertex(gridChain->get_vertex(i));
-
- /*output the fan of the grid points of the (i)th and (i-1)th grid line.
- */
- if(gridChain->getUlineIndex(i) < gridChain->getUlineIndex(i-1))
- {
- pStream->begin();
- pStream->insert(gridChain->get_vertex(i-1));
- for(j=gridChain->getUlineIndex(i); j<= gridChain->getUlineIndex(i-1); j++)
- pStream->insert(gridChain->getGrid()->get_u_value(j), gridChain->get_v_value(i));
- pStream->end(PRIMITIVE_STREAM_FAN);
- }
- else if(gridChain->getUlineIndex(i) > gridChain->getUlineIndex(i-1))
- {
- pStream->begin();
- pStream->insert(gridChain->get_vertex(i));
- for(j=gridChain->getUlineIndex(i); j>= gridChain->getUlineIndex(i-1); j--)
- pStream->insert(gridChain->getGrid()->get_u_value(j), gridChain->get_v_value(i-1));
- pStream->end(PRIMITIVE_STREAM_FAN);
- }
- /*otherwisem, the two are equal, so there is no fan to outout*/
- }
-
- monoTriangulation2(upperVert, lowerVert, &vArray, 0, endIndex-beginIndex,
- 0, /*decreasing chain*/
- pStream);
-}
-
-/*return i, such that from begin to i-1 the chain is strictly u-monotone.
- */
-Int findIncreaseChainFromBegin(vertexArray* chain, Int begin ,Int end)
-{
- Int i=begin;
- Real prevU = chain->getVertex(i)[0];
- Real thisU;
- for(i=begin+1; i<=end; i++){
- thisU = chain->getVertex(i)[0];
-
- if(prevU < thisU){
- prevU = thisU;
- }
- else
- break;
- }
- return i;
-}
-
-/*check whether there is a vertex whose v value is strictly
- *inbetween vup vbelow
- *if no middle exists return -1, else return the idnex.
- */
-Int checkMiddle(vertexArray* chain, Int begin, Int end,
- Real vup, Real vbelow)
-{
- Int i;
- for(i=begin; i<=end; i++)
- {
- if(chain->getVertex(i)[1] < vup && chain->getVertex(i)[1]>vbelow)
- return i;
- }
- return -1;
-}
-
-/*the degenerat case of sampleLeftOneGridStep*/
-void sampleLeftOneGridStepNoMiddle(vertexArray* leftChain,
- Int beginLeftIndex,
- Int endLeftIndex,
- gridBoundaryChain* leftGridChain,
- Int leftGridChainStartIndex,
- primStream* pStream)
-{
- /*since there is no middle, there is at most one point which is on the
- *second grid line, there could be multiple points on the first (top)
- *grid line.
- */
-
- leftGridChain->leftEndFan(leftGridChainStartIndex+1, pStream);
-
- monoTriangulation2(leftGridChain->get_vertex(leftGridChainStartIndex),
- leftGridChain->get_vertex(leftGridChainStartIndex+1),
- leftChain,
- beginLeftIndex,
- endLeftIndex,
- 1, //is increase chain.
- pStream);
-}
-
-
-
-/*sampling the left area in between two grid lines.
- */
-void sampleLeftOneGridStep(vertexArray* leftChain,
- Int beginLeftIndex,
- Int endLeftIndex,
- gridBoundaryChain* leftGridChain,
- Int leftGridChainStartIndex,
- primStream* pStream
- )
-{
- if(checkMiddle(leftChain, beginLeftIndex, endLeftIndex,
- leftGridChain->get_v_value(leftGridChainStartIndex),
- leftGridChain->get_v_value(leftGridChainStartIndex+1))<0)
-
- {
-
- sampleLeftOneGridStepNoMiddle(leftChain, beginLeftIndex, endLeftIndex, leftGridChain, leftGridChainStartIndex, pStream);
- return;
- }
-
- //copy into a polygon
- {
- directedLine* poly = NULL;
- sampledLine* sline;
- directedLine* dline;
- gridWrap* grid = leftGridChain->getGrid();
- Real vert1[2];
- Real vert2[2];
- Int i;
-
- Int innerInd = leftGridChain->getInnerIndex(leftGridChainStartIndex+1);
- Int upperInd = leftGridChain->getUlineIndex(leftGridChainStartIndex);
- Int lowerInd = leftGridChain->getUlineIndex(leftGridChainStartIndex+1);
- Real upperV = leftGridChain->get_v_value(leftGridChainStartIndex);
- Real lowerV = leftGridChain->get_v_value(leftGridChainStartIndex+1);
-
- //the upper gridline
- vert1[1] = vert2[1] = upperV;
- for(i=innerInd; i>upperInd; i--)
- {
- vert1[0]=grid->get_u_value(i);
- vert2[0]=grid->get_u_value(i-1);
- sline = new sampledLine(vert1, vert2);
- dline = new directedLine(INCREASING, sline);
- if(poly == NULL)
- poly = dline;
- else
- poly->insert(dline);
- }
-
- //the edge connecting upper grid with left chain
- vert1[0] = grid->get_u_value(upperInd);
- vert1[1] = upperV;
- sline = new sampledLine(vert1, leftChain->getVertex(beginLeftIndex));
- dline = new directedLine(INCREASING, sline);
- if(poly == NULL)
- poly = dline;
- else
- poly->insert(dline);
-
- //the left chain
- for(i=beginLeftIndex; i<endLeftIndex; i++)
- {
- sline = new sampledLine(leftChain->getVertex(i), leftChain->getVertex(i+1));
- dline = new directedLine(INCREASING, sline);
- poly->insert(dline);
- }
-
- //the edge connecting left chain with lower gridline
- vert2[0] = grid->get_u_value(lowerInd);
- vert2[1] = lowerV;
- sline = new sampledLine(leftChain->getVertex(endLeftIndex), vert2);
- dline = new directedLine(INCREASING, sline);
- poly->insert(dline);
-
- //the lower grid line
- vert1[1] = vert2[1] = lowerV;
- for(i=lowerInd; i<innerInd; i++)
- {
- vert1[0] = grid->get_u_value(i);
- vert2[0] = grid->get_u_value(i+1);
- sline = new sampledLine(vert1, vert2);
- dline = new directedLine(INCREASING, sline);
- poly->insert(dline);
- }
-
- //the vertical grid line segement
- vert1[0]=vert2[0] = grid->get_u_value(innerInd);
- vert2[1]=upperV;
- vert1[1]=lowerV;
- sline=new sampledLine(vert1, vert2);
- dline=new directedLine(INCREASING, sline);
- poly->insert(dline);
- monoTriangulationOpt(poly, pStream);
- //cleanup
- poly->deleteSinglePolygonWithSline();
- return;
- }
-
-
-
-
-
- Int i;
- if(1/*leftGridChain->getUlineIndex(leftGridChainStartIndex) >=
- leftGridChain->getUlineIndex(leftGridChainStartIndex+1)*/
- ) /*the second grid line is beyond the first one to the left*/
- {
- /*find the maximal U-monotone chain
- * of endLeftIndex, endLeftIndex-1, ...,
- */
- i=endLeftIndex;
- Real prevU = leftChain->getVertex(i)[0];
- for(i=endLeftIndex-1; i>=beginLeftIndex; i--){
- Real thisU = leftChain->getVertex(i)[0];
- if( prevU < thisU){
- prevU = thisU;
- }
- else
- break;
- }
- /*from endLeftIndex to i+1 is strictly U- monotone */
- /*if i+1==endLeftIndex and the vertex and leftchain is on the second gridline, then
- *we should use 2 vertices on the leftchain. If we only use one (endLeftIndex), then we
- *we would output degenerate triangles
- */
- if(i+1 == endLeftIndex && leftChain->getVertex(endLeftIndex)[1] == leftGridChain->get_v_value(1+leftGridChainStartIndex))
- i--;
-
- Int j = beginLeftIndex/*endLeftIndex*/+1;
-
-
- if(leftGridChain->getInnerIndex(leftGridChainStartIndex+1) > leftGridChain->getUlineIndex(leftGridChainStartIndex))
- {
- j = findIncreaseChainFromBegin(leftChain, beginLeftIndex, i+1/*endLeftIndex*/);
-
- Int temp = beginLeftIndex;
- /*now from begin to j-1 is strictly u-monotone*/
- /*if j-1 is on the first grid line, then we want to skip to the vertex which is strictly
- *below the grid line. This vertexmust exist since there is a 'corner turn' inbetween the two grid lines
- */
- if(j-1 == beginLeftIndex)
- {
- while(leftChain->getVertex(j-1)[1] == leftGridChain->get_v_value(leftGridChainStartIndex))
- j++;
-
- Real vert[2];
- vert[0] = leftGridChain->get_u_value(leftGridChainStartIndex);
- vert[1] = leftGridChain->get_v_value(leftGridChainStartIndex);
-
- monoTriangulation2(
- vert/*leftChain->getVertex(beginLeftIndex)*/,
- leftChain->getVertex(j-1),
- leftChain,
- beginLeftIndex,
- j-2,
- 1,
- pStream //increase chain
- );
-
- temp = j-1;
- }
-
- stripOfFanLeft(leftChain, j-1, temp/*beginLeftIndex*/, leftGridChain->getGrid(),
- leftGridChain->getVlineIndex(leftGridChainStartIndex),
- leftGridChain->getUlineIndex(leftGridChainStartIndex),
- leftGridChain->getInnerIndex(leftGridChainStartIndex+1),
- pStream,
- 1 /*the grid line is above the trim line*/
- );
- }
-
- stripOfFanLeft(leftChain, endLeftIndex, i+1, leftGridChain->getGrid(),
- leftGridChain->getVlineIndex(leftGridChainStartIndex+1),
- leftGridChain->getUlineIndex(leftGridChainStartIndex+1),
- leftGridChain->getInnerIndex(leftGridChainStartIndex+1),
- pStream,
- 0 /*the grid line is below the trim lines*/
- );
-
- /*monotone triangulate the remaining left chain togther with the
- *two vertices on the two grid v-lines.
- */
- Real vert[2][2];
- vert[0][0]=vert[1][0] = leftGridChain->getInner_u_value(leftGridChainStartIndex+1);
- vert[0][1] = leftGridChain->get_v_value(leftGridChainStartIndex);
- vert[1][1] = leftGridChain->get_v_value(leftGridChainStartIndex+1);
-
-// vertexArray right(vert, 2);
-
- monoTriangulation2(
- &vert[0][0], /*top vertex */
- &vert[1][0], /*bottom vertex*/
- leftChain,
- /*beginLeftIndex*/j-1,
- i+1,
- 1, /*an increasing chain*/
- pStream);
- }
- else /*the second one is shorter than the first one to the left*/
- {
- /*find the maximal U-monotone chain of beginLeftIndex, beginLeftIndex+1,...,
- */
- i=beginLeftIndex;
- Real prevU = leftChain->getVertex(i)[0];
- for(i=beginLeftIndex+1; i<=endLeftIndex; i++){
- Real thisU = leftChain->getVertex(i)[0];
-
- if(prevU < thisU){
- prevU = thisU;
- }
- else
- break;
- }
- /*from beginLeftIndex to i-1 is strictly U-monotone*/
-
-
- stripOfFanLeft(leftChain, i-1, beginLeftIndex, leftGridChain->getGrid(),
- leftGridChain->getVlineIndex(leftGridChainStartIndex),
- leftGridChain->getUlineIndex(leftGridChainStartIndex),
- leftGridChain->getUlineIndex(leftGridChainStartIndex+1),
- pStream,
- 1 /*the grid line is above the trim lines*/
- );
- /*monotone triangulate the remaining left chain together with the
- *two vertices on the two grid v-lines.
- */
- Real vert[2][2];
- vert[0][0]=vert[1][0] = leftGridChain->get_u_value(leftGridChainStartIndex+1);
- vert[0][1] = leftGridChain->get_v_value(leftGridChainStartIndex);
- vert[1][1] = leftGridChain->get_v_value(leftGridChainStartIndex+1);
-
- vertexArray right(vert, 2);
-
- monoTriangulation2(
- &vert[0][0], //top vertex
- &vert[1][0], //bottom vertex
- leftChain,
- i-1,
- endLeftIndex,
- 1, /*an increase chain*/
- pStream);
-
- }
-}
-
-/*n_upper>=1
- *n_lower>=1
- */
-void triangulateXYMono(Int n_upper, Real upperVerts[][2],
- Int n_lower, Real lowerVerts[][2],
- primStream* pStream)
-{
- Int i,j,k,l;
- Real* leftMostV;
-
- assert(n_upper>=1 && n_lower>=1);
- if(upperVerts[0][0] <= lowerVerts[0][0])
- {
- i=1;
- j=0;
- leftMostV = upperVerts[0];
- }
- else
- {
- i=0;
- j=1;
- leftMostV = lowerVerts[0];
- }
-
- while(1)
- {
- if(i >= n_upper) /*case1: no more in upper*/
- {
-
- if(j<n_lower-1) /*at least two vertices in lower*/
- {
- pStream->begin();
- pStream->insert(leftMostV);
- while(j<n_lower){
- pStream->insert(lowerVerts[j]);
- j++;
- }
- pStream->end(PRIMITIVE_STREAM_FAN);
- }
-
- break;
- }
- else if(j>= n_lower) /*case2: no more in lower*/
- {
-
- if(i<n_upper-1) /*at least two vertices in upper*/
- {
- pStream->begin();
- pStream->insert(leftMostV);
-
- for(k=n_upper-1; k>=i; k--)
- pStream->insert(upperVerts[k]);
-
- pStream->end(PRIMITIVE_STREAM_FAN);
- }
-
- break;
- }
- else /* case3: neither is empty, plus the leftMostV, there is at least one triangle to output*/
- {
-
- if(upperVerts[i][0] <= lowerVerts[j][0])
- {
- pStream->begin();
- pStream->insert(lowerVerts[j]); /*the origin of this fan*/
-
- /*find the last k>=i such that
- *upperverts[k][0] <= lowerverts[j][0]
- */
- k=i;
- while(k<n_upper)
- {
- if(upperVerts[k][0] > lowerVerts[j][0])
- break;
- k++;
- }
- k--;
- for(l=k; l>=i; l--)/*the reverse is for two-face lighting*/
- {
- pStream->insert(upperVerts[l]);
- }
- pStream->insert(leftMostV);
-
- pStream->end(PRIMITIVE_STREAM_FAN);
- //update i for next loop
- i = k+1;
- leftMostV = upperVerts[k];
-
- }
- else /*upperVerts[i][0] > lowerVerts[j][0]*/
- {
- pStream->begin();
- pStream->insert(upperVerts[i]);/*the origion of this fan*/
- pStream->insert(leftMostV);
- /*find the last k>=j such that
- *lowerverts[k][0] < upperverts[i][0]*/
- k=j;
- while(k< n_lower)
- {
- if(lowerVerts[k][0] >= upperVerts[i][0])
- break;
- pStream->insert(lowerVerts[k]);
- k++;
- }
- pStream->end(PRIMITIVE_STREAM_FAN);
- j=k;
- leftMostV = lowerVerts[j-1];
- }
- }
- }
-}
-
-
-void stripOfFanLeft(vertexArray* leftChain,
- Int largeIndex,
- Int smallIndex,
- gridWrap* grid,
- Int vlineIndex,
- Int ulineSmallIndex,
- Int ulineLargeIndex,
- primStream* pStream,
- Int gridLineUp /*1 if the grid line is above the trim lines*/
- )
-{
- assert(largeIndex >= smallIndex);
-
- Real grid_v_value;
- grid_v_value = grid->get_v_value(vlineIndex);
-
- Real2* trimVerts=(Real2*) malloc(sizeof(Real2)* (largeIndex-smallIndex+1));
- assert(trimVerts);
-
-
- Real2* gridVerts=(Real2*) malloc(sizeof(Real2)* (ulineLargeIndex-ulineSmallIndex+1));
- assert(gridVerts);
-
- Int k,i;
- if(gridLineUp) /*trim line is below grid line, so trim vertices are going right when index increases*/
- for(k=0, i=smallIndex; i<=largeIndex; i++, k++)
- {
- trimVerts[k][0] = leftChain->getVertex(i)[0];
- trimVerts[k][1] = leftChain->getVertex(i)[1];
- }
- else
- for(k=0, i=largeIndex; i>=smallIndex; i--, k++)
- {
- trimVerts[k][0] = leftChain->getVertex(i)[0];
- trimVerts[k][1] = leftChain->getVertex(i)[1];
- }
-
- for(k=0, i=ulineSmallIndex; i<= ulineLargeIndex; i++, k++)
- {
- gridVerts[k][0] = grid->get_u_value(i);
- gridVerts[k][1] = grid_v_value;
- }
-
- if(gridLineUp)
- triangulateXYMono(
- ulineLargeIndex-ulineSmallIndex+1, gridVerts,
- largeIndex-smallIndex+1, trimVerts,
- pStream);
- else
- triangulateXYMono(largeIndex-smallIndex+1, trimVerts,
- ulineLargeIndex-ulineSmallIndex+1, gridVerts,
- pStream);
- free(trimVerts);
- free(gridVerts);
-}
-
-
-
-
-