1f220fa62Smrg/* 2f220fa62Smrg** License Applicability. Except to the extent portions of this file are 3f220fa62Smrg** made subject to an alternative license as permitted in the SGI Free 4f220fa62Smrg** Software License B, Version 1.1 (the "License"), the contents of this 5f220fa62Smrg** file are subject only to the provisions of the License. You may not use 6f220fa62Smrg** this file except in compliance with the License. You may obtain a copy 7f220fa62Smrg** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 8f220fa62Smrg** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: 9f220fa62Smrg** 10f220fa62Smrg** http://oss.sgi.com/projects/FreeB 11f220fa62Smrg** 12f220fa62Smrg** Note that, as provided in the License, the Software is distributed on an 13f220fa62Smrg** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS 14f220fa62Smrg** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND 15f220fa62Smrg** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A 16f220fa62Smrg** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. 17f220fa62Smrg** 18f220fa62Smrg** Original Code. The Original Code is: OpenGL Sample Implementation, 19f220fa62Smrg** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, 20f220fa62Smrg** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. 21f220fa62Smrg** Copyright in any portions created by third parties is as indicated 22f220fa62Smrg** elsewhere herein. All Rights Reserved. 23f220fa62Smrg** 24f220fa62Smrg** Additional Notice Provisions: The application programming interfaces 25f220fa62Smrg** established by SGI in conjunction with the Original Code are The 26f220fa62Smrg** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released 27f220fa62Smrg** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version 28f220fa62Smrg** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X 29f220fa62Smrg** Window System(R) (Version 1.3), released October 19, 1998. This software 30f220fa62Smrg** was created using the OpenGL(R) version 1.2.1 Sample Implementation 31f220fa62Smrg** published by SGI, but has not been independently verified as being 32f220fa62Smrg** compliant with the OpenGL(R) version 1.2.1 Specification. 33f220fa62Smrg** 34f220fa62Smrg*/ 35f220fa62Smrg/* 36f220fa62Smrg*/ 37f220fa62Smrg 38f220fa62Smrg#include "gluos.h" 39f220fa62Smrg#include <stdlib.h> 40f220fa62Smrg#include <stdio.h> 41f220fa62Smrg#include <math.h> 42f220fa62Smrg 43f220fa62Smrg#ifndef max 44f220fa62Smrg#define max(a,b) ((a>b)? a:b) 45f220fa62Smrg#endif 46f220fa62Smrg#ifndef min 47f220fa62Smrg#define min(a,b) ((a>b)? b:a) 48f220fa62Smrg#endif 49f220fa62Smrg 50f220fa62Smrg#include <GL/gl.h> 51f220fa62Smrg 52f220fa62Smrg#include "glimports.h" 53f220fa62Smrg#include "zlassert.h" 54f220fa62Smrg#include "sampleMonoPoly.h" 55f220fa62Smrg#include "sampleComp.h" 56f220fa62Smrg#include "polyDBG.h" 57f220fa62Smrg#include "partitionX.h" 58f220fa62Smrg 59f220fa62Smrg 60f220fa62Smrg#define ZERO 0.00001 61f220fa62Smrg 62f220fa62Smrg//#define MYDEBUG 63f220fa62Smrg 64f220fa62Smrg//#define SHORTEN_GRID_LINE 65f220fa62Smrg//see work/newtess/internal/test/problems 66f220fa62Smrg 67f220fa62Smrg 68f220fa62Smrg/*split a polygon so that each vertex correcpond to one edge 69f220fa62Smrg *the head of the first edge of the returned plygon must be the head of the first 70f220fa62Smrg *edge of the origianl polygon. This is crucial for the code in sampleMonoPoly function 71f220fa62Smrg */ 72f220fa62Smrg directedLine* polygonConvert(directedLine* polygon) 73f220fa62Smrg{ 74f220fa62Smrg int i; 75f220fa62Smrg directedLine* ret; 76f220fa62Smrg sampledLine* sline; 77f220fa62Smrg sline = new sampledLine(2); 78f220fa62Smrg sline->setPoint(0, polygon->getVertex(0)); 79f220fa62Smrg sline->setPoint(1, polygon->getVertex(1)); 80f220fa62Smrg ret=new directedLine(INCREASING, sline); 81f220fa62Smrg for(i=1; i<= polygon->get_npoints()-2; i++) 82f220fa62Smrg { 83f220fa62Smrg sline = new sampledLine(2); 84f220fa62Smrg sline->setPoint(0, polygon->getVertex(i)); 85f220fa62Smrg sline->setPoint(1, polygon->getVertex(i+1)); 86f220fa62Smrg ret->insert(new directedLine(INCREASING, sline)); 87f220fa62Smrg } 88f220fa62Smrg 89f220fa62Smrg for(directedLine *temp = polygon->getNext(); temp != polygon; temp = temp->getNext()) 90f220fa62Smrg { 91f220fa62Smrg for(i=0; i<= temp->get_npoints()-2; i++) 92f220fa62Smrg { 93f220fa62Smrg sline = new sampledLine(2); 94f220fa62Smrg sline->setPoint(0, temp->getVertex(i)); 95f220fa62Smrg sline->setPoint(1, temp->getVertex(i+1)); 96f220fa62Smrg ret->insert(new directedLine(INCREASING, sline)); 97f220fa62Smrg } 98f220fa62Smrg } 99f220fa62Smrg return ret; 100f220fa62Smrg} 101f220fa62Smrg 102f220fa62Smrgvoid triangulateConvexPolyVertical(directedLine* topV, directedLine* botV, primStream *pStream) 103f220fa62Smrg{ 104f220fa62Smrg Int i,j; 105f220fa62Smrg Int n_leftVerts; 106f220fa62Smrg Int n_rightVerts; 107f220fa62Smrg Real** leftVerts; 108f220fa62Smrg Real** rightVerts; 109f220fa62Smrg directedLine* tempV; 110f220fa62Smrg n_leftVerts = 0; 111f220fa62Smrg for(tempV = topV; tempV != botV; tempV = tempV->getNext()) 112f220fa62Smrg { 113f220fa62Smrg n_leftVerts += tempV->get_npoints(); 114f220fa62Smrg } 115f220fa62Smrg n_rightVerts=0; 116f220fa62Smrg for(tempV = botV; tempV != topV; tempV = tempV->getNext()) 117f220fa62Smrg { 118f220fa62Smrg n_rightVerts += tempV->get_npoints(); 119f220fa62Smrg } 120f220fa62Smrg 121f220fa62Smrg Real2* temp_leftVerts = (Real2 *) malloc(sizeof(Real2) * n_leftVerts); 122f220fa62Smrg assert(temp_leftVerts); 123f220fa62Smrg Real2* temp_rightVerts = (Real2 *) malloc(sizeof(Real2) * n_rightVerts); 124f220fa62Smrg assert(temp_rightVerts); 125f220fa62Smrg 126f220fa62Smrg leftVerts = (Real**) malloc(sizeof(Real2*) * n_leftVerts); 127f220fa62Smrg assert(leftVerts); 128f220fa62Smrg rightVerts = (Real**) malloc(sizeof(Real2*) * n_rightVerts); 129f220fa62Smrg assert(rightVerts); 130f220fa62Smrg for(i=0; i<n_leftVerts; i++) 131f220fa62Smrg leftVerts[i] = temp_leftVerts[i]; 132f220fa62Smrg for(i=0; i<n_rightVerts; i++) 133f220fa62Smrg rightVerts[i] = temp_rightVerts[i]; 134f220fa62Smrg 135f220fa62Smrg i=0; 136f220fa62Smrg for(tempV = topV; tempV != botV; tempV = tempV->getNext()) 137f220fa62Smrg { 138f220fa62Smrg for(j=1; j<tempV->get_npoints(); j++) 139f220fa62Smrg { 140f220fa62Smrg leftVerts[i][0] = tempV->getVertex(j)[0]; 141f220fa62Smrg leftVerts[i][1] = tempV->getVertex(j)[1]; 142f220fa62Smrg i++; 143f220fa62Smrg } 144f220fa62Smrg } 145f220fa62Smrg n_leftVerts = i; 146f220fa62Smrg i=0; 147f220fa62Smrg for(tempV = topV->getPrev(); tempV != botV->getPrev(); tempV = tempV->getPrev()) 148f220fa62Smrg { 149f220fa62Smrg for(j=tempV->get_npoints()-1; j>=1; j--) 150f220fa62Smrg { 151f220fa62Smrg rightVerts[i][0] = tempV->getVertex(j)[0]; 152f220fa62Smrg rightVerts[i][1] = tempV->getVertex(j)[1]; 153f220fa62Smrg i++; 154f220fa62Smrg } 155f220fa62Smrg } 156f220fa62Smrg n_rightVerts = i; 157f220fa62Smrg triangulateXYMonoTB(n_leftVerts, leftVerts, n_rightVerts, rightVerts, pStream); 158f220fa62Smrg free(leftVerts); 159f220fa62Smrg free(rightVerts); 160f220fa62Smrg free(temp_leftVerts); 161f220fa62Smrg free(temp_rightVerts); 162f220fa62Smrg} 163f220fa62Smrg 164f220fa62Smrgvoid triangulateConvexPolyHoriz(directedLine* leftV, directedLine* rightV, primStream *pStream) 165f220fa62Smrg{ 166f220fa62Smrg Int i,j; 167f220fa62Smrg Int n_lowerVerts; 168f220fa62Smrg Int n_upperVerts; 169f220fa62Smrg Real2 *lowerVerts; 170f220fa62Smrg Real2 *upperVerts; 171f220fa62Smrg directedLine* tempV; 172f220fa62Smrg n_lowerVerts=0; 173f220fa62Smrg for(tempV = leftV; tempV != rightV; tempV = tempV->getNext()) 174f220fa62Smrg { 175f220fa62Smrg n_lowerVerts += tempV->get_npoints(); 176f220fa62Smrg } 177f220fa62Smrg n_upperVerts=0; 178f220fa62Smrg for(tempV = rightV; tempV != leftV; tempV = tempV->getNext()) 179f220fa62Smrg { 180f220fa62Smrg n_upperVerts += tempV->get_npoints(); 181f220fa62Smrg } 182f220fa62Smrg lowerVerts = (Real2 *) malloc(sizeof(Real2) * n_lowerVerts); 183f220fa62Smrg assert(n_lowerVerts); 184f220fa62Smrg upperVerts = (Real2 *) malloc(sizeof(Real2) * n_upperVerts); 185f220fa62Smrg assert(n_upperVerts); 186f220fa62Smrg i=0; 187f220fa62Smrg for(tempV = leftV; tempV != rightV; tempV = tempV->getNext()) 188f220fa62Smrg { 189f220fa62Smrg for(j=0; j<tempV->get_npoints(); j++) 190f220fa62Smrg { 191f220fa62Smrg lowerVerts[i][0] = tempV->getVertex(j)[0]; 192f220fa62Smrg lowerVerts[i][1] = tempV->getVertex(j)[1]; 193f220fa62Smrg i++; 194f220fa62Smrg } 195f220fa62Smrg } 196f220fa62Smrg i=0; 197f220fa62Smrg for(tempV = leftV->getPrev(); tempV != rightV->getPrev(); tempV = tempV->getPrev()) 198f220fa62Smrg { 199f220fa62Smrg for(j=tempV->get_npoints()-1; j>=0; j--) 200f220fa62Smrg { 201f220fa62Smrg upperVerts[i][0] = tempV->getVertex(j)[0]; 202f220fa62Smrg upperVerts[i][1] = tempV->getVertex(j)[1]; 203f220fa62Smrg i++; 204f220fa62Smrg } 205f220fa62Smrg } 206f220fa62Smrg triangulateXYMono(n_upperVerts, upperVerts, n_lowerVerts, lowerVerts, pStream); 207f220fa62Smrg free(lowerVerts); 208f220fa62Smrg free(upperVerts); 209f220fa62Smrg} 210f220fa62Smrgvoid triangulateConvexPoly(directedLine* polygon, Int ulinear, Int vlinear, primStream* pStream) 211f220fa62Smrg{ 212f220fa62Smrg /*find left, right, top , bot 213f220fa62Smrg */ 214f220fa62Smrg directedLine* tempV; 215f220fa62Smrg directedLine* topV; 216f220fa62Smrg directedLine* botV; 217f220fa62Smrg directedLine* leftV; 218f220fa62Smrg directedLine* rightV; 219f220fa62Smrg topV = botV = polygon; 220f220fa62Smrg 221f220fa62Smrg for(tempV = polygon->getNext(); tempV != polygon; tempV = tempV->getNext()) 222f220fa62Smrg { 223f220fa62Smrg if(compV2InY(topV->head(), tempV->head())<0) { 224f220fa62Smrg 225f220fa62Smrg topV = tempV; 226f220fa62Smrg } 227f220fa62Smrg if(compV2InY(botV->head(), tempV->head())>0) { 228f220fa62Smrg 229f220fa62Smrg botV = tempV; 230f220fa62Smrg } 231f220fa62Smrg } 232f220fa62Smrg //find leftV 233f220fa62Smrg for(tempV = topV; tempV != botV; tempV = tempV->getNext()) 234f220fa62Smrg { 235f220fa62Smrg if(tempV->tail()[0] >= tempV->head()[0]) 236f220fa62Smrg break; 237f220fa62Smrg } 238f220fa62Smrg leftV = tempV; 239f220fa62Smrg //find rightV 240f220fa62Smrg for(tempV = botV; tempV != topV; tempV = tempV->getNext()) 241f220fa62Smrg { 242f220fa62Smrg if(tempV->tail()[0] <= tempV->head()[0]) 243f220fa62Smrg break; 244f220fa62Smrg } 245f220fa62Smrg rightV = tempV; 246f220fa62Smrg if(vlinear) 247f220fa62Smrg { 248f220fa62Smrg triangulateConvexPolyHoriz( leftV, rightV, pStream); 249f220fa62Smrg } 250f220fa62Smrg else if(ulinear) 251f220fa62Smrg { 252f220fa62Smrg triangulateConvexPolyVertical(topV, botV, pStream); 253f220fa62Smrg } 254f220fa62Smrg else 255f220fa62Smrg { 256f220fa62Smrg if(DBG_is_U_direction(polygon)) 257f220fa62Smrg { 258f220fa62Smrg triangulateConvexPolyHoriz( leftV, rightV, pStream); 259f220fa62Smrg } 260f220fa62Smrg else 261f220fa62Smrg triangulateConvexPolyVertical(topV, botV, pStream); 262f220fa62Smrg } 263f220fa62Smrg} 264f220fa62Smrg 265f220fa62Smrg/*for debug purpose*/ 266f220fa62Smrgvoid drawCorners( 267f220fa62Smrg Real* topV, Real* botV, 268f220fa62Smrg vertexArray* leftChain, 269f220fa62Smrg vertexArray* rightChain, 270f220fa62Smrg gridBoundaryChain* leftGridChain, 271f220fa62Smrg gridBoundaryChain* rightGridChain, 272f220fa62Smrg Int gridIndex1, 273f220fa62Smrg Int gridIndex2, 274f220fa62Smrg Int leftCornerWhere, 275f220fa62Smrg Int leftCornerIndex, 276f220fa62Smrg Int rightCornerWhere, 277f220fa62Smrg Int rightCornerIndex, 278f220fa62Smrg Int bot_leftCornerWhere, 279f220fa62Smrg Int bot_leftCornerIndex, 280f220fa62Smrg Int bot_rightCornerWhere, 281f220fa62Smrg Int bot_rightCornerIndex) 282f220fa62Smrg{ 283f220fa62Smrg Real* leftCornerV; 284f220fa62Smrg Real* rightCornerV; 285f220fa62Smrg Real* bot_leftCornerV; 286f220fa62Smrg Real* bot_rightCornerV; 287f220fa62Smrg 288f220fa62Smrg if(leftCornerWhere == 1) 289f220fa62Smrg leftCornerV = topV; 290f220fa62Smrg else if(leftCornerWhere == 0) 291f220fa62Smrg leftCornerV = leftChain->getVertex(leftCornerIndex); 292f220fa62Smrg else 293f220fa62Smrg leftCornerV = rightChain->getVertex(leftCornerIndex); 294f220fa62Smrg 295f220fa62Smrg if(rightCornerWhere == 1) 296f220fa62Smrg rightCornerV = topV; 297f220fa62Smrg else if(rightCornerWhere == 0) 298f220fa62Smrg rightCornerV = leftChain->getVertex(rightCornerIndex); 299f220fa62Smrg else 300f220fa62Smrg rightCornerV = rightChain->getVertex(rightCornerIndex); 301f220fa62Smrg 302f220fa62Smrg if(bot_leftCornerWhere == 1) 303f220fa62Smrg bot_leftCornerV = botV; 304f220fa62Smrg else if(bot_leftCornerWhere == 0) 305f220fa62Smrg bot_leftCornerV = leftChain->getVertex(bot_leftCornerIndex); 306f220fa62Smrg else 307f220fa62Smrg bot_leftCornerV = rightChain->getVertex(bot_leftCornerIndex); 308f220fa62Smrg 309f220fa62Smrg if(bot_rightCornerWhere == 1) 310f220fa62Smrg bot_rightCornerV = botV; 311f220fa62Smrg else if(bot_rightCornerWhere == 0) 312f220fa62Smrg bot_rightCornerV = leftChain->getVertex(bot_rightCornerIndex); 313f220fa62Smrg else 314f220fa62Smrg bot_rightCornerV = rightChain->getVertex(bot_rightCornerIndex); 315f220fa62Smrg 316f220fa62Smrg Real topGridV = leftGridChain->get_v_value(gridIndex1); 317f220fa62Smrg Real topGridU1 = leftGridChain->get_u_value(gridIndex1); 318f220fa62Smrg Real topGridU2 = rightGridChain->get_u_value(gridIndex1); 319f220fa62Smrg Real botGridV = leftGridChain->get_v_value(gridIndex2); 320f220fa62Smrg Real botGridU1 = leftGridChain->get_u_value(gridIndex2); 321f220fa62Smrg Real botGridU2 = rightGridChain->get_u_value(gridIndex2); 322f220fa62Smrg 323f220fa62Smrg glBegin(GL_LINE_STRIP); 324f220fa62Smrg glVertex2fv(leftCornerV); 325f220fa62Smrg glVertex2f(topGridU1, topGridV); 326f220fa62Smrg glEnd(); 327f220fa62Smrg 328f220fa62Smrg glBegin(GL_LINE_STRIP); 329f220fa62Smrg glVertex2fv(rightCornerV); 330f220fa62Smrg glVertex2f(topGridU2, topGridV); 331f220fa62Smrg glEnd(); 332f220fa62Smrg 333f220fa62Smrg glBegin(GL_LINE_STRIP); 334f220fa62Smrg glVertex2fv(bot_leftCornerV); 335f220fa62Smrg glVertex2f(botGridU1, botGridV); 336f220fa62Smrg glEnd(); 337f220fa62Smrg 338f220fa62Smrg glBegin(GL_LINE_STRIP); 339f220fa62Smrg glVertex2fv(bot_rightCornerV); 340f220fa62Smrg glVertex2f(botGridU2, botGridV); 341f220fa62Smrg glEnd(); 342f220fa62Smrg 343f220fa62Smrg 344f220fa62Smrg} 345f220fa62Smrg 346f220fa62Smrgvoid toVertexArrays(directedLine* topV, directedLine* botV, vertexArray& leftChain, vertexArray& rightChain) 347f220fa62Smrg{ 348f220fa62Smrg Int i; 349f220fa62Smrg directedLine* tempV; 350f220fa62Smrg for(i=1; i<=topV->get_npoints()-2; i++) { /*the first vertex is the top vertex which doesn't belong to inc_chain*/ 351f220fa62Smrg leftChain.appendVertex(topV->getVertex(i)); 352f220fa62Smrg } 353f220fa62Smrg for(tempV = topV->getNext(); tempV != botV; tempV = tempV->getNext()) 354f220fa62Smrg { 355f220fa62Smrg for(i=0; i<=tempV->get_npoints()-2; i++){ 356f220fa62Smrg leftChain.appendVertex(tempV->getVertex(i)); 357f220fa62Smrg } 358f220fa62Smrg } 359f220fa62Smrg 360f220fa62Smrg for(tempV = topV->getPrev(); tempV != botV; tempV = tempV->getPrev()) 361f220fa62Smrg { 362f220fa62Smrg for(i=tempV->get_npoints()-2; i>=0; i--){ 363f220fa62Smrg rightChain.appendVertex(tempV->getVertex(i)); 364f220fa62Smrg } 365f220fa62Smrg } 366f220fa62Smrg for(i=botV->get_npoints()-2; i>=1; i--){ 367f220fa62Smrg rightChain.appendVertex(tempV->getVertex(i)); 368f220fa62Smrg } 369f220fa62Smrg} 370f220fa62Smrg 371f220fa62Smrg 372f220fa62Smrgvoid findTopAndBot(directedLine* polygon, directedLine*& topV, directedLine*& botV) 373f220fa62Smrg{ 374f220fa62Smrg assert(polygon); 375f220fa62Smrg directedLine* tempV; 376f220fa62Smrg topV = botV = polygon; 377f220fa62Smrg for(tempV = polygon->getNext(); tempV != polygon; tempV = tempV->getNext()) 378f220fa62Smrg { 379f220fa62Smrg if(compV2InY(topV->head(), tempV->head())<0) { 380f220fa62Smrg topV = tempV; 381f220fa62Smrg } 382f220fa62Smrg if(compV2InY(botV->head(), tempV->head())>0) { 383f220fa62Smrg botV = tempV; 384f220fa62Smrg } 385f220fa62Smrg } 386f220fa62Smrg} 387f220fa62Smrg 388f220fa62Smrgvoid findGridChains(directedLine* topV, directedLine* botV, 389f220fa62Smrg gridWrap* grid, 390f220fa62Smrg gridBoundaryChain*& leftGridChain, 391f220fa62Smrg gridBoundaryChain*& rightGridChain) 392f220fa62Smrg{ 393f220fa62Smrg /*find the first(top) and the last (bottom) grid line which intersect the 394f220fa62Smrg *this polygon 395f220fa62Smrg */ 396f220fa62Smrg Int firstGridIndex; /*the index in the grid*/ 397f220fa62Smrg Int lastGridIndex; 398f220fa62Smrg 399f220fa62Smrg firstGridIndex = (Int) ((topV->head()[1] - grid->get_v_min()) / (grid->get_v_max() - grid->get_v_min()) * (grid->get_n_vlines()-1)); 400f220fa62Smrg 401f220fa62Smrg if(botV->head()[1] < grid->get_v_min()) 402f220fa62Smrg lastGridIndex = 0; 403f220fa62Smrg else 404f220fa62Smrg lastGridIndex = (Int) ((botV->head()[1] - grid->get_v_min()) / (grid->get_v_max() - grid->get_v_min()) * (grid->get_n_vlines()-1)) + 1; 405f220fa62Smrg 406f220fa62Smrg /*find the interval inside the polygon for each gridline*/ 407f220fa62Smrg Int *leftGridIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1)); 408f220fa62Smrg assert(leftGridIndices); 409f220fa62Smrg Int *rightGridIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1)); 410f220fa62Smrg assert(rightGridIndices); 411f220fa62Smrg Int *leftGridInnerIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1)); 412f220fa62Smrg assert(leftGridInnerIndices); 413f220fa62Smrg Int *rightGridInnerIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1)); 414f220fa62Smrg assert(rightGridInnerIndices); 415f220fa62Smrg 416f220fa62Smrg findLeftGridIndices(topV, firstGridIndex, lastGridIndex, grid, leftGridIndices, leftGridInnerIndices); 417f220fa62Smrg 418f220fa62Smrg findRightGridIndices(topV, firstGridIndex, lastGridIndex, grid, rightGridIndices, rightGridInnerIndices); 419f220fa62Smrg 420f220fa62Smrg leftGridChain = new gridBoundaryChain(grid, firstGridIndex, firstGridIndex-lastGridIndex+1, leftGridIndices, leftGridInnerIndices); 421f220fa62Smrg 422f220fa62Smrg rightGridChain = new gridBoundaryChain(grid, firstGridIndex, firstGridIndex-lastGridIndex+1, rightGridIndices, rightGridInnerIndices); 423f220fa62Smrg 424f220fa62Smrg free(leftGridIndices); 425f220fa62Smrg free(rightGridIndices); 426f220fa62Smrg free(leftGridInnerIndices); 427f220fa62Smrg free(rightGridInnerIndices); 428f220fa62Smrg} 429f220fa62Smrg 430f220fa62Smrgvoid findDownCorners(Real *botVertex, 431f220fa62Smrg vertexArray *leftChain, Int leftChainStartIndex, Int leftChainEndIndex, 432f220fa62Smrg vertexArray *rightChain, Int rightChainStartIndex, Int rightChainEndIndex, 433f220fa62Smrg Real v, 434f220fa62Smrg Real uleft, 435f220fa62Smrg Real uright, 436f220fa62Smrg Int& ret_leftCornerWhere, /*0: left chain, 1: topvertex, 2: rightchain*/ 437f220fa62Smrg Int& ret_leftCornerIndex, /*useful when ret_leftCornerWhere == 0 or 2*/ 438f220fa62Smrg Int& ret_rightCornerWhere, /*0: left chain, 1: topvertex, 2: rightchain*/ 439f220fa62Smrg Int& ret_rightCornerIndex /*useful when ret_leftCornerWhere == 0 or 2*/ 440f220fa62Smrg ) 441f220fa62Smrg{ 442f220fa62Smrg#ifdef MYDEBUG 443f220fa62Smrgprintf("*************enter find donw corner\n"); 444f220fa62Smrgprintf("finddownCorner: v=%f, uleft=%f, uright=%f\n", v, uleft, uright); 445f220fa62Smrgprintf("(%i,%i,%i,%i)\n", leftChainStartIndex, leftChainEndIndex,rightChainStartIndex, rightChainEndIndex); 446f220fa62Smrgprintf("left chain is\n"); 447f220fa62SmrgleftChain->print(); 448f220fa62Smrgprintf("right chain is\n"); 449f220fa62SmrgrightChain->print(); 450f220fa62Smrg#endif 451f220fa62Smrg 452f220fa62Smrg assert(v > botVertex[1]); 453f220fa62Smrg Real leftGridPoint[2]; 454f220fa62Smrg leftGridPoint[0] = uleft; 455f220fa62Smrg leftGridPoint[1] = v; 456f220fa62Smrg Real rightGridPoint[2]; 457f220fa62Smrg rightGridPoint[0] = uright; 458f220fa62Smrg rightGridPoint[1] = v; 459f220fa62Smrg 460f220fa62Smrg Int i; 461f220fa62Smrg Int index1, index2; 462f220fa62Smrg 463f220fa62Smrg index1 = leftChain->findIndexBelowGen(v, leftChainStartIndex, leftChainEndIndex); 464f220fa62Smrg index2 = rightChain->findIndexBelowGen(v, rightChainStartIndex, rightChainEndIndex); 465f220fa62Smrg 466f220fa62Smrg if(index2 <= rightChainEndIndex) //index2 was found above 467f220fa62Smrg index2 = rightChain->skipEqualityFromStart(v, index2, rightChainEndIndex); 468f220fa62Smrg 469f220fa62Smrg if(index1>leftChainEndIndex && index2 > rightChainEndIndex) /*no point below v on left chain or right chain*/ 470f220fa62Smrg { 471f220fa62Smrg 472f220fa62Smrg /*the botVertex is the only vertex below v*/ 473f220fa62Smrg ret_leftCornerWhere = 1; 474f220fa62Smrg ret_rightCornerWhere = 1; 475f220fa62Smrg } 476f220fa62Smrg else if(index1>leftChainEndIndex ) /*index2 <= rightChainEndIndex*/ 477f220fa62Smrg { 478f220fa62Smrg 479f220fa62Smrg ret_rightCornerWhere = 2; /*on right chain*/ 480f220fa62Smrg ret_rightCornerIndex = index2; 481f220fa62Smrg 482f220fa62Smrg 483f220fa62Smrg Real tempMin = rightChain->getVertex(index2)[0]; 484f220fa62Smrg Int tempI = index2; 485f220fa62Smrg for(i=index2+1; i<= rightChainEndIndex; i++) 486f220fa62Smrg if(rightChain->getVertex(i)[0] < tempMin) 487f220fa62Smrg { 488f220fa62Smrg tempI = i; 489f220fa62Smrg tempMin = rightChain->getVertex(i)[0]; 490f220fa62Smrg } 491f220fa62Smrg 492f220fa62Smrg 493f220fa62Smrg //we consider whether we can use botVertex as left corner. First check 494f220fa62Smrg //if (leftGirdPoint, botVertex) interesects right chian or not. 495f220fa62Smrg if(DBG_intersectChain(rightChain, rightChainStartIndex,rightChainEndIndex, 496f220fa62Smrg leftGridPoint, botVertex)) 497f220fa62Smrg { 498f220fa62Smrg ret_leftCornerWhere = 2;//right 499f220fa62Smrg ret_leftCornerIndex = index2; //should use tempI??? 500f220fa62Smrg } 501f220fa62Smrg else if(botVertex[0] < tempMin) 502f220fa62Smrg ret_leftCornerWhere = 1; //bot 503f220fa62Smrg else 504f220fa62Smrg { 505f220fa62Smrg ret_leftCornerWhere = 2; //right 506f220fa62Smrg ret_leftCornerIndex = tempI; 507f220fa62Smrg } 508f220fa62Smrg } 509f220fa62Smrg else if(index2> rightChainEndIndex) /*index1<=leftChainEndIndex*/ 510f220fa62Smrg { 511f220fa62Smrg ret_leftCornerWhere = 0; /*left chain*/ 512f220fa62Smrg ret_leftCornerIndex = index1; 513f220fa62Smrg 514f220fa62Smrg /*find the vertex on the left chain with the maximum u, 515f220fa62Smrg *either this vertex or the botvertex can be used as the right corner 516f220fa62Smrg */ 517f220fa62Smrg 518f220fa62Smrg Int tempI; 519f220fa62Smrg //skip those points which are equal to v. (avoid degeneratcy) 520f220fa62Smrg for(tempI = index1; tempI <= leftChainEndIndex; tempI++) 521f220fa62Smrg if(leftChain->getVertex(tempI)[1] < v) 522f220fa62Smrg break; 523f220fa62Smrg if(tempI > leftChainEndIndex) 524f220fa62Smrg ret_rightCornerWhere = 1; 525f220fa62Smrg else 526f220fa62Smrg { 527f220fa62Smrg Real tempMax = leftChain->getVertex(tempI)[0]; 528f220fa62Smrg for(i=tempI; i<= leftChainEndIndex; i++) 529f220fa62Smrg if(leftChain->getVertex(i)[0] > tempMax) 530f220fa62Smrg { 531f220fa62Smrg tempI = i; 532f220fa62Smrg tempMax = leftChain->getVertex(i)[0]; 533f220fa62Smrg } 534f220fa62Smrg 535f220fa62Smrg 536f220fa62Smrg 537f220fa62Smrg //we consider whether we can use botVertex as a corner. So first we check 538f220fa62Smrg //whether (rightGridPoint, botVertex) interescts the left chain or not. 539f220fa62Smrg if(DBG_intersectChain(leftChain, leftChainStartIndex,leftChainEndIndex, 540f220fa62Smrg rightGridPoint, botVertex)) 541f220fa62Smrg { 542f220fa62Smrg ret_rightCornerWhere = 0; 543f220fa62Smrg ret_rightCornerIndex = index1; //should use tempI??? 544f220fa62Smrg } 545f220fa62Smrg else if(botVertex[0] > tempMax) 546f220fa62Smrg { 547f220fa62Smrg 548f220fa62Smrg ret_rightCornerWhere = 1; 549f220fa62Smrg } 550f220fa62Smrg else 551f220fa62Smrg { 552f220fa62Smrg ret_rightCornerWhere = 0; 553f220fa62Smrg ret_rightCornerIndex = tempI; 554f220fa62Smrg } 555f220fa62Smrg } 556f220fa62Smrg 557f220fa62Smrg } 558f220fa62Smrg else /*index1<=leftChainEndIndex and index2 <=rightChainEndIndex*/ 559f220fa62Smrg { 560f220fa62Smrg if(leftChain->getVertex(index1)[1] >= rightChain->getVertex(index2)[1]) /*left point above right point*/ 561f220fa62Smrg { 562f220fa62Smrg ret_leftCornerWhere = 0; /*on left chain*/ 563f220fa62Smrg ret_leftCornerIndex = index1; 564f220fa62Smrg 565f220fa62Smrg Real tempMax; 566f220fa62Smrg Int tempI; 567f220fa62Smrg 568f220fa62Smrg tempI = index1; 569f220fa62Smrg tempMax = leftChain->getVertex(index1)[0]; 570f220fa62Smrg 571f220fa62Smrg /*find the maximum u for all the points on the left above the right point index2*/ 572f220fa62Smrg for(i=index1+1; i<= leftChainEndIndex; i++) 573f220fa62Smrg { 574f220fa62Smrg if(leftChain->getVertex(i)[1] < rightChain->getVertex(index2)[1]) 575f220fa62Smrg break; 576f220fa62Smrg 577f220fa62Smrg if(leftChain->getVertex(i)[0]>tempMax) 578f220fa62Smrg { 579f220fa62Smrg tempI = i; 580f220fa62Smrg tempMax = leftChain->getVertex(i)[0]; 581f220fa62Smrg } 582f220fa62Smrg } 583f220fa62Smrg //we consider if we can use rightChain(index2) as right corner 584f220fa62Smrg //we check if (rightChain(index2), rightGidPoint) intersecs left chain or not. 585f220fa62Smrg if(DBG_intersectChain(leftChain, leftChainStartIndex,leftChainEndIndex, rightGridPoint, rightChain->getVertex(index2))) 586f220fa62Smrg { 587f220fa62Smrg ret_rightCornerWhere = 0; 588f220fa62Smrg ret_rightCornerIndex = index1; //should use tempI??? 589f220fa62Smrg } 590f220fa62Smrg else if(tempMax >= rightChain->getVertex(index2)[0] || 591f220fa62Smrg tempMax >= uright 592f220fa62Smrg ) 593f220fa62Smrg { 594f220fa62Smrg 595f220fa62Smrg ret_rightCornerWhere = 0; /*on left Chain*/ 596f220fa62Smrg ret_rightCornerIndex = tempI; 597f220fa62Smrg } 598f220fa62Smrg else 599f220fa62Smrg { 600f220fa62Smrg ret_rightCornerWhere = 2; /*on right chain*/ 601f220fa62Smrg ret_rightCornerIndex = index2; 602f220fa62Smrg } 603f220fa62Smrg } 604f220fa62Smrg else /*left below right*/ 605f220fa62Smrg { 606f220fa62Smrg ret_rightCornerWhere = 2; /*on the right*/ 607f220fa62Smrg ret_rightCornerIndex = index2; 608f220fa62Smrg 609f220fa62Smrg Real tempMin; 610f220fa62Smrg Int tempI; 611f220fa62Smrg 612f220fa62Smrg tempI = index2; 613f220fa62Smrg tempMin = rightChain->getVertex(index2)[0]; 614f220fa62Smrg 615f220fa62Smrg /*find the minimum u for all the points on the right above the left poitn index1*/ 616f220fa62Smrg for(i=index2+1; i<= rightChainEndIndex; i++) 617f220fa62Smrg { 618f220fa62Smrg if( rightChain->getVertex(i)[1] < leftChain->getVertex(index1)[1]) 619f220fa62Smrg break; 620f220fa62Smrg if(rightChain->getVertex(i)[0] < tempMin) 621f220fa62Smrg { 622f220fa62Smrg tempI = i; 623f220fa62Smrg tempMin = rightChain->getVertex(i)[0]; 624f220fa62Smrg } 625f220fa62Smrg } 626f220fa62Smrg 627f220fa62Smrg //we consider if we can use leftchain(index1) as left corner. 628f220fa62Smrg //we check if (leftChain(index1) intersects right chian or not 629f220fa62Smrg if(DBG_intersectChain(rightChain, rightChainStartIndex, rightChainEndIndex, leftGridPoint, leftChain->getVertex(index1))) 630f220fa62Smrg { 631f220fa62Smrg ret_leftCornerWhere = 2; 632f220fa62Smrg ret_leftCornerIndex = index2; //should use tempI??? 633f220fa62Smrg } 634f220fa62Smrg else if(tempMin <= leftChain->getVertex(index1)[0] || 635f220fa62Smrg tempMin <= uleft) 636f220fa62Smrg { 637f220fa62Smrg ret_leftCornerWhere = 2; /* on right chain*/ 638f220fa62Smrg ret_leftCornerIndex = tempI; 639f220fa62Smrg } 640f220fa62Smrg else 641f220fa62Smrg { 642f220fa62Smrg ret_leftCornerWhere = 0; /*on left chain*/ 643f220fa62Smrg ret_leftCornerIndex = index1; 644f220fa62Smrg } 645f220fa62Smrg } 646f220fa62Smrg } 647f220fa62Smrg 648f220fa62Smrg} 649f220fa62Smrg 650f220fa62Smrg 651f220fa62Smrgvoid findUpCorners(Real *topVertex, 652f220fa62Smrg vertexArray *leftChain, Int leftChainStartIndex, Int leftChainEndIndex, 653f220fa62Smrg vertexArray *rightChain, Int rightChainStartIndex, Int rightChainEndIndex, 654f220fa62Smrg Real v, 655f220fa62Smrg Real uleft, 656f220fa62Smrg Real uright, 657f220fa62Smrg Int& ret_leftCornerWhere, /*0: left chain, 1: topvertex, 2: rightchain*/ 658f220fa62Smrg Int& ret_leftCornerIndex, /*useful when ret_leftCornerWhere == 0 or 2*/ 659f220fa62Smrg Int& ret_rightCornerWhere, /*0: left chain, 1: topvertex, 2: rightchain*/ 660f220fa62Smrg Int& ret_rightCornerIndex /*useful when ret_leftCornerWhere == 0 or 2*/ 661f220fa62Smrg ) 662f220fa62Smrg{ 663f220fa62Smrg#ifdef MYDEBUG 664f220fa62Smrgprintf("***********enter findUpCorners\n"); 665f220fa62Smrg#endif 666f220fa62Smrg 667f220fa62Smrg assert(v < topVertex[1]); 668f220fa62Smrg Real leftGridPoint[2]; 669f220fa62Smrg leftGridPoint[0] = uleft; 670f220fa62Smrg leftGridPoint[1] = v; 671f220fa62Smrg Real rightGridPoint[2]; 672f220fa62Smrg rightGridPoint[0] = uright; 673f220fa62Smrg rightGridPoint[1] = v; 674f220fa62Smrg 675f220fa62Smrg Int i; 676f220fa62Smrg Int index1, index2; 677f220fa62Smrg 678f220fa62Smrg index1 = leftChain->findIndexFirstAboveEqualGen(v, leftChainStartIndex, leftChainEndIndex); 679f220fa62Smrg 680f220fa62Smrg 681f220fa62Smrg index2 = rightChain->findIndexFirstAboveEqualGen(v, rightChainStartIndex, rightChainEndIndex); 682f220fa62Smrg 683f220fa62Smrg if(index2>= leftChainStartIndex) //index2 was found above 684f220fa62Smrg index2 = rightChain->skipEqualityFromStart(v, index2, rightChainEndIndex); 685f220fa62Smrg 686f220fa62Smrg if(index1<leftChainStartIndex && index2 <rightChainStartIndex) /*no point above v on left chain or right chain*/ 687f220fa62Smrg { 688f220fa62Smrg /*the topVertex is the only vertex above v*/ 689f220fa62Smrg ret_leftCornerWhere = 1; 690f220fa62Smrg ret_rightCornerWhere = 1; 691f220fa62Smrg } 692f220fa62Smrg else if(index1<leftChainStartIndex ) /*index2 >= rightChainStartIndex*/ 693f220fa62Smrg { 694f220fa62Smrg ret_rightCornerWhere = 2; /*on right chain*/ 695f220fa62Smrg ret_rightCornerIndex = index2; 696f220fa62Smrg 697f220fa62Smrg //find the minimum u on right top, either that, or top, or right[index2] is the left corner 698f220fa62Smrg Real tempMin = rightChain->getVertex(index2)[0]; 699f220fa62Smrg Int tempI = index2; 700f220fa62Smrg for(i=index2-1; i>=rightChainStartIndex; i--) 701f220fa62Smrg if(rightChain->getVertex(i)[0] < tempMin) 702f220fa62Smrg { 703f220fa62Smrg tempMin = rightChain->getVertex(i)[0]; 704f220fa62Smrg tempI = i; 705f220fa62Smrg } 706f220fa62Smrg //chech whether (leftGridPoint, top) intersects rightchai, 707f220fa62Smrg //if yes, use right corner as left corner 708f220fa62Smrg //if not, use top or right[tempI] as left corner 709f220fa62Smrg if(DBG_intersectChain(rightChain, rightChainStartIndex, rightChainEndIndex, 710f220fa62Smrg leftGridPoint, topVertex)) 711f220fa62Smrg { 712f220fa62Smrg ret_leftCornerWhere = 2; //rightChain 713f220fa62Smrg ret_leftCornerIndex = index2; 714f220fa62Smrg } 715f220fa62Smrg else if(topVertex[0] < tempMin) 716f220fa62Smrg ret_leftCornerWhere = 1; /*topvertex*/ 717f220fa62Smrg else 718f220fa62Smrg { 719f220fa62Smrg ret_leftCornerWhere = 2; //right chain 720f220fa62Smrg ret_leftCornerIndex = tempI; 721f220fa62Smrg } 722f220fa62Smrg 723f220fa62Smrg } 724f220fa62Smrg else if(index2< rightChainStartIndex) /*index1>=leftChainStartIndex*/ 725f220fa62Smrg { 726f220fa62Smrg ret_leftCornerWhere = 0; /*left chain*/ 727f220fa62Smrg ret_leftCornerIndex = index1; 728f220fa62Smrg 729f220fa62Smrg //find the maximum u on the left top section. either that or topvertex, or left[index1] is the right corner 730f220fa62Smrg Real tempMax = leftChain->getVertex(index1)[0]; 731f220fa62Smrg Int tempI = index1; 732f220fa62Smrg 733f220fa62Smrg for(i=index1-1; i>=leftChainStartIndex; i--){ 734f220fa62Smrg 735f220fa62Smrg if(leftChain->getVertex(i)[0] > tempMax) 736f220fa62Smrg { 737f220fa62Smrg 738f220fa62Smrg tempMax = leftChain->getVertex(i)[0]; 739f220fa62Smrg tempI = i; 740f220fa62Smrg } 741f220fa62Smrg } 742f220fa62Smrg //check whether (rightGridPoint, top) intersects leftChain or not 743f220fa62Smrg //if yes, we use leftCorner as the right corner 744f220fa62Smrg //if not, we use either top or left[tempI] as the right corner 745f220fa62Smrg if(DBG_intersectChain(leftChain, leftChainStartIndex,leftChainEndIndex, 746f220fa62Smrg rightGridPoint, topVertex)) 747f220fa62Smrg { 748f220fa62Smrg ret_rightCornerWhere = 0; //left chan 749f220fa62Smrg ret_rightCornerIndex = index1; 750f220fa62Smrg } 751f220fa62Smrg else if(topVertex[0] > tempMax) 752f220fa62Smrg ret_rightCornerWhere = 1;//topVertex 753f220fa62Smrg else 754f220fa62Smrg { 755f220fa62Smrg ret_rightCornerWhere = 0;//left chain 756f220fa62Smrg ret_rightCornerIndex = tempI; 757f220fa62Smrg } 758f220fa62Smrg } 759f220fa62Smrg else /*index1>=leftChainStartIndex and index2 >=rightChainStartIndex*/ 760f220fa62Smrg { 761f220fa62Smrg if(leftChain->getVertex(index1)[1] <= rightChain->getVertex(index2)[1]) /*left point below right point*/ 762f220fa62Smrg { 763f220fa62Smrg ret_leftCornerWhere = 0; /*on left chain*/ 764f220fa62Smrg ret_leftCornerIndex = index1; 765f220fa62Smrg 766f220fa62Smrg Real tempMax; 767f220fa62Smrg Int tempI; 768f220fa62Smrg 769f220fa62Smrg tempI = index1; 770f220fa62Smrg tempMax = leftChain->getVertex(index1)[0]; 771f220fa62Smrg 772f220fa62Smrg /*find the maximum u for all the points on the left below the right point index2*/ 773f220fa62Smrg for(i=index1-1; i>= leftChainStartIndex; i--) 774f220fa62Smrg { 775f220fa62Smrg if(leftChain->getVertex(i)[1] > rightChain->getVertex(index2)[1]) 776f220fa62Smrg break; 777f220fa62Smrg 778f220fa62Smrg if(leftChain->getVertex(i)[0]>tempMax) 779f220fa62Smrg { 780f220fa62Smrg tempI = i; 781f220fa62Smrg tempMax = leftChain->getVertex(i)[0]; 782f220fa62Smrg } 783f220fa62Smrg } 784f220fa62Smrg //chek whether (rightChain(index2), rightGridPoint) intersects leftchian or not 785f220fa62Smrg if(DBG_intersectChain(leftChain, leftChainStartIndex, leftChainEndIndex, rightGridPoint, rightChain->getVertex(index2))) 786f220fa62Smrg { 787f220fa62Smrg ret_rightCornerWhere = 0; 788f220fa62Smrg ret_rightCornerIndex = index1; 789f220fa62Smrg } 790f220fa62Smrg else if(tempMax >= rightChain->getVertex(index2)[0] || 791f220fa62Smrg tempMax >= uright) 792f220fa62Smrg { 793f220fa62Smrg ret_rightCornerWhere = 0; /*on left Chain*/ 794f220fa62Smrg ret_rightCornerIndex = tempI; 795f220fa62Smrg } 796f220fa62Smrg else 797f220fa62Smrg { 798f220fa62Smrg ret_rightCornerWhere = 2; /*on right chain*/ 799f220fa62Smrg ret_rightCornerIndex = index2; 800f220fa62Smrg } 801f220fa62Smrg } 802f220fa62Smrg else /*left above right*/ 803f220fa62Smrg { 804f220fa62Smrg ret_rightCornerWhere = 2; /*on the right*/ 805f220fa62Smrg ret_rightCornerIndex = index2; 806f220fa62Smrg 807f220fa62Smrg Real tempMin; 808f220fa62Smrg Int tempI; 809f220fa62Smrg 810f220fa62Smrg tempI = index2; 811f220fa62Smrg tempMin = rightChain->getVertex(index2)[0]; 812f220fa62Smrg 813f220fa62Smrg /*find the minimum u for all the points on the right below the left poitn index1*/ 814f220fa62Smrg for(i=index2-1; i>= rightChainStartIndex; i--) 815f220fa62Smrg { 816f220fa62Smrg if( rightChain->getVertex(i)[1] > leftChain->getVertex(index1)[1]) 817f220fa62Smrg break; 818f220fa62Smrg if(rightChain->getVertex(i)[0] < tempMin) 819f220fa62Smrg { 820f220fa62Smrg tempI = i; 821f220fa62Smrg tempMin = rightChain->getVertex(i)[0]; 822f220fa62Smrg } 823f220fa62Smrg } 824f220fa62Smrg //check whether (leftGRidPoint,left(index1)) interesect right chain 825f220fa62Smrg if(DBG_intersectChain(rightChain, rightChainStartIndex, rightChainEndIndex, 826f220fa62Smrg leftGridPoint, leftChain->getVertex(index1))) 827f220fa62Smrg { 828f220fa62Smrg ret_leftCornerWhere = 2; //right 829f220fa62Smrg ret_leftCornerIndex = index2; 830f220fa62Smrg } 831f220fa62Smrg else if(tempMin <= leftChain->getVertex(index1)[0] || 832f220fa62Smrg tempMin <= uleft) 833f220fa62Smrg { 834f220fa62Smrg ret_leftCornerWhere = 2; /* on right chain*/ 835f220fa62Smrg ret_leftCornerIndex = tempI; 836f220fa62Smrg } 837f220fa62Smrg else 838f220fa62Smrg { 839f220fa62Smrg ret_leftCornerWhere = 0; /*on left chain*/ 840f220fa62Smrg ret_leftCornerIndex = index1; 841f220fa62Smrg } 842f220fa62Smrg } 843f220fa62Smrg } 844f220fa62Smrg#ifdef MYDEBUG 845f220fa62Smrgprintf("***********leave findUpCorners\n"); 846f220fa62Smrg#endif 847f220fa62Smrg} 848f220fa62Smrg 849f220fa62Smrg//return 1 if neck exists, 0 othewise 850f220fa62SmrgInt findNeckF(vertexArray *leftChain, Int botLeftIndex, 851f220fa62Smrg vertexArray *rightChain, Int botRightIndex, 852f220fa62Smrg gridBoundaryChain* leftGridChain, 853f220fa62Smrg gridBoundaryChain* rightGridChain, 854f220fa62Smrg Int gridStartIndex, 855f220fa62Smrg Int& neckLeft, 856f220fa62Smrg Int& neckRight) 857f220fa62Smrg{ 858f220fa62Smrg/* 859f220fa62Smrgprintf("enter findNeckF, botleft, botright=%i,%i,gstartindex=%i\n",botLeftIndex,botRightIndex,gridStartIndex); 860f220fa62Smrgprintf("leftChain is\n"); 861f220fa62SmrgleftChain->print(); 862f220fa62Smrgprintf("rightChain is\n"); 863f220fa62SmrgrightChain->print(); 864f220fa62Smrg*/ 865f220fa62Smrg 866f220fa62Smrg Int lowerGridIndex; //the grid below leftChain and rightChian vertices 867f220fa62Smrg Int i; 868f220fa62Smrg Int n_vlines = leftGridChain->get_nVlines(); 869f220fa62Smrg Real v; 870f220fa62Smrg if(botLeftIndex >= leftChain->getNumElements() || 871f220fa62Smrg botRightIndex >= rightChain->getNumElements()) 872f220fa62Smrg return 0; //no neck exists 873f220fa62Smrg 874f220fa62Smrg v=min(leftChain->getVertex(botLeftIndex)[1], rightChain->getVertex(botRightIndex)[1]); 875f220fa62Smrg 876f220fa62Smrg 877f220fa62Smrg 878f220fa62Smrg 879f220fa62Smrg for(i=gridStartIndex; i<n_vlines; i++) 880f220fa62Smrg if(leftGridChain->get_v_value(i) <= v && 881f220fa62Smrg leftGridChain->getUlineIndex(i)<= rightGridChain->getUlineIndex(i)) 882f220fa62Smrg break; 883f220fa62Smrg 884f220fa62Smrg lowerGridIndex = i; 885f220fa62Smrg 886f220fa62Smrg if(lowerGridIndex == n_vlines) //the two trm vertex are higher than all gridlines 887f220fa62Smrg return 0; 888f220fa62Smrg else 889f220fa62Smrg { 890f220fa62Smrg Int botLeft2, botRight2; 891f220fa62Smrg/* 892f220fa62Smrgprintf("leftGridChain->get_v_)value=%f\n",leftGridChain->get_v_value(lowerGridIndex), botLeftIndex); 893f220fa62Smrgprintf("leftChain->get_vertex(0)=(%f,%f)\n", leftChain->getVertex(0)[0],leftChain->getVertex(0)[1]); 894f220fa62Smrgprintf("leftChain->get_vertex(1)=(%f,%f)\n", leftChain->getVertex(1)[0],leftChain->getVertex(1)[1]); 895f220fa62Smrgprintf("leftChain->get_vertex(2)=(%f,%f)\n", leftChain->getVertex(2)[0],leftChain->getVertex(2)[1]); 896f220fa62Smrg*/ 897f220fa62Smrg botLeft2 = leftChain->findIndexFirstAboveEqualGen(leftGridChain->get_v_value(lowerGridIndex), botLeftIndex, leftChain->getNumElements()-1) -1 ; 898f220fa62Smrg 899f220fa62Smrg/* 900f220fa62Smrgprintf("botLeft2=%i\n", botLeft2); 901f220fa62Smrgprintf("leftChain->getNumElements=%i\n", leftChain->getNumElements()); 902f220fa62Smrg*/ 903f220fa62Smrg 904f220fa62Smrg botRight2 = rightChain->findIndexFirstAboveEqualGen(leftGridChain->get_v_value(lowerGridIndex), botRightIndex, rightChain->getNumElements()-1) -1; 905f220fa62Smrg if(botRight2 < botRightIndex) botRight2=botRightIndex; 906f220fa62Smrg 907f220fa62Smrg if(botLeft2 < botLeftIndex) botLeft2 = botLeftIndex; 908f220fa62Smrg 909f220fa62Smrg assert(botLeft2 >= botLeftIndex); 910f220fa62Smrg assert(botRight2 >= botRightIndex); 911f220fa62Smrg //find nectLeft so that it is th erightmost vertex on letChain 912f220fa62Smrg 913f220fa62Smrg Int tempI = botLeftIndex; 914f220fa62Smrg Real temp = leftChain->getVertex(tempI)[0]; 915f220fa62Smrg for(i=botLeftIndex+1; i<= botLeft2; i++) 916f220fa62Smrg if(leftChain->getVertex(i)[0] > temp) 917f220fa62Smrg { 918f220fa62Smrg temp = leftChain->getVertex(i)[0]; 919f220fa62Smrg tempI = i; 920f220fa62Smrg } 921f220fa62Smrg neckLeft = tempI; 922f220fa62Smrg 923f220fa62Smrg tempI = botRightIndex; 924f220fa62Smrg temp = rightChain->getVertex(tempI)[0]; 925f220fa62Smrg for(i=botRightIndex+1; i<= botRight2; i++) 926f220fa62Smrg if(rightChain->getVertex(i)[0] < temp) 927f220fa62Smrg { 928f220fa62Smrg temp = rightChain->getVertex(i)[0]; 929f220fa62Smrg tempI = i; 930f220fa62Smrg } 931f220fa62Smrg neckRight = tempI; 932f220fa62Smrg return 1; 933f220fa62Smrg } 934f220fa62Smrg} 935f220fa62Smrg 936f220fa62Smrg 937f220fa62Smrg 938f220fa62Smrg/*find i>=botLeftIndex,j>=botRightIndex so that 939f220fa62Smrg *(leftChain[i], rightChain[j]) is a neck. 940f220fa62Smrg */ 941f220fa62Smrgvoid findNeck(vertexArray *leftChain, Int botLeftIndex, 942f220fa62Smrg vertexArray *rightChain, Int botRightIndex, 943f220fa62Smrg Int& leftLastIndex, /*left point of the neck*/ 944f220fa62Smrg Int& rightLastIndex /*right point of the neck*/ 945f220fa62Smrg ) 946f220fa62Smrg{ 947f220fa62Smrg assert(botLeftIndex < leftChain->getNumElements() && 948f220fa62Smrg botRightIndex < rightChain->getNumElements()); 949f220fa62Smrg 950f220fa62Smrg /*now the neck exists for sure*/ 951f220fa62Smrg 952f220fa62Smrg if(leftChain->getVertex(botLeftIndex)[1] <= rightChain->getVertex(botRightIndex)[1]) //left below right 953f220fa62Smrg { 954f220fa62Smrg 955f220fa62Smrg leftLastIndex = botLeftIndex; 956f220fa62Smrg 957f220fa62Smrg /*find i so that rightChain[i][1] >= leftchainbotverte[1], and i+1< 958f220fa62Smrg */ 959f220fa62Smrg rightLastIndex=rightChain->findIndexAboveGen(leftChain->getVertex(botLeftIndex)[1], botRightIndex+1, rightChain->getNumElements()-1); 960f220fa62Smrg } 961f220fa62Smrg else //left above right 962f220fa62Smrg { 963f220fa62Smrg 964f220fa62Smrg rightLastIndex = botRightIndex; 965f220fa62Smrg 966f220fa62Smrg leftLastIndex = leftChain->findIndexAboveGen(rightChain->getVertex(botRightIndex)[1], 967f220fa62Smrg botLeftIndex+1, 968f220fa62Smrg leftChain->getNumElements()-1); 969f220fa62Smrg } 970f220fa62Smrg} 971f220fa62Smrg 972f220fa62Smrg 973f220fa62Smrg 974f220fa62Smrgvoid findLeftGridIndices(directedLine* topEdge, Int firstGridIndex, Int lastGridIndex, gridWrap* grid, Int* ret_indices, Int* ret_innerIndices) 975f220fa62Smrg{ 976f220fa62Smrg 977f220fa62Smrg Int i,k,isHoriz = 0; 978f220fa62Smrg Int n_ulines = grid->get_n_ulines(); 979f220fa62Smrg Real uMin = grid->get_u_min(); 980f220fa62Smrg Real uMax = grid->get_u_max(); 981f220fa62Smrg /* 982f220fa62Smrg Real vMin = grid->get_v_min(); 983f220fa62Smrg Real vMax = grid->get_v_max(); 984f220fa62Smrg */ 985f220fa62Smrg Real slop = 0.0, uinterc; 986f220fa62Smrg 987f220fa62Smrg#ifdef SHORTEN_GRID_LINE 988f220fa62Smrg //uintercBuf stores all the interction u value for each grid line 989f220fa62Smrg //notice that lastGridIndex<= firstGridIndex 990f220fa62Smrg Real *uintercBuf = (Real *) malloc (sizeof(Real) * (firstGridIndex-lastGridIndex+1)); 991f220fa62Smrg assert(uintercBuf); 992f220fa62Smrg#endif 993f220fa62Smrg 994f220fa62Smrg /*initialization to make vtail bigger than grid->...*/ 995f220fa62Smrg directedLine* dLine = topEdge; 996f220fa62Smrg Real vtail = grid->get_v_value(firstGridIndex) + 1.0; 997f220fa62Smrg Real tempMaxU = grid->get_u_min(); 998f220fa62Smrg 999f220fa62Smrg 1000f220fa62Smrg /*for each grid line*/ 1001f220fa62Smrg for(k=0, i=firstGridIndex; i>=lastGridIndex; i--, k++) 1002f220fa62Smrg { 1003f220fa62Smrg 1004f220fa62Smrg Real grid_v_value = grid->get_v_value(i); 1005f220fa62Smrg 1006f220fa62Smrg /*check whether this grid line is below the current trim edge.*/ 1007f220fa62Smrg if(vtail > grid_v_value) 1008f220fa62Smrg { 1009f220fa62Smrg /*since the grid line is below the trim edge, we 1010f220fa62Smrg *find the trim edge which will contain the trim line 1011f220fa62Smrg */ 1012f220fa62Smrg while( (vtail=dLine->tail()[1]) > grid_v_value){ 1013f220fa62Smrg 1014f220fa62Smrg tempMaxU = max(tempMaxU, dLine->tail()[0]); 1015f220fa62Smrg dLine = dLine -> getNext(); 1016f220fa62Smrg } 1017f220fa62Smrg 1018f220fa62Smrg if( fabs(dLine->head()[1] - vtail) < ZERO) 1019f220fa62Smrg isHoriz = 1; 1020f220fa62Smrg else 1021f220fa62Smrg { 1022f220fa62Smrg isHoriz = 0; 1023f220fa62Smrg slop = (dLine->head()[0] - dLine->tail()[0]) / (dLine->head()[1]-vtail); 1024f220fa62Smrg } 1025f220fa62Smrg } 1026f220fa62Smrg 1027f220fa62Smrg if(isHoriz) 1028f220fa62Smrg { 1029f220fa62Smrg uinterc = max(dLine->head()[0], dLine->tail()[0]); 1030f220fa62Smrg } 1031f220fa62Smrg else 1032f220fa62Smrg { 1033f220fa62Smrg uinterc = slop * (grid_v_value - vtail) + dLine->tail()[0]; 1034f220fa62Smrg } 1035f220fa62Smrg 1036f220fa62Smrg tempMaxU = max(tempMaxU, uinterc); 1037f220fa62Smrg 1038f220fa62Smrg if(uinterc < uMin && uinterc >= uMin - ZERO) 1039f220fa62Smrg uinterc = uMin; 1040f220fa62Smrg if(uinterc > uMax && uinterc <= uMax + ZERO) 1041f220fa62Smrg uinterc = uMax; 1042f220fa62Smrg 1043f220fa62Smrg#ifdef SHORTEN_GRID_LINE 1044f220fa62Smrg uintercBuf[k] = uinterc; 1045f220fa62Smrg#endif 1046f220fa62Smrg 1047f220fa62Smrg assert(uinterc >= uMin && uinterc <= uMax); 1048f220fa62Smrg if(uinterc == uMax) 1049f220fa62Smrg ret_indices[k] = n_ulines-1; 1050f220fa62Smrg else 1051f220fa62Smrg ret_indices[k] = (Int)(((uinterc-uMin)/(uMax - uMin)) * (n_ulines-1)) + 1; 1052f220fa62Smrg if(ret_indices[k] >= n_ulines) 1053f220fa62Smrg ret_indices[k] = n_ulines-1; 1054f220fa62Smrg 1055f220fa62Smrg 1056f220fa62Smrg ret_innerIndices[k] = (Int)(((tempMaxU-uMin)/(uMax - uMin)) * (n_ulines-1)) + 1; 1057f220fa62Smrg 1058f220fa62Smrg /*reinitialize tempMaxU for next grdiLine*/ 1059f220fa62Smrg tempMaxU = uinterc; 1060f220fa62Smrg } 1061f220fa62Smrg#ifdef SHORTEN_GRID_LINE 1062f220fa62Smrg //for each grid line, compare the left grid point with the 1063f220fa62Smrg //intersection point. If the two points are too close, then 1064f220fa62Smrg //we should move the grid point one grid to the right 1065f220fa62Smrg //and accordingly we should update the inner index. 1066f220fa62Smrg for(k=0, i=firstGridIndex; i>=lastGridIndex; i--, k++) 1067f220fa62Smrg { 1068f220fa62Smrg //check gridLine i 1069f220fa62Smrg //check ret_indices[k] 1070f220fa62Smrg Real a = grid->get_u_value(ret_indices[k]-1); 1071f220fa62Smrg Real b = grid->get_u_value(ret_indices[k]); 1072f220fa62Smrg assert(uintercBuf[k] >= a && uintercBuf < b); 1073f220fa62Smrg if( (b-uintercBuf[k]) <= 0.2 * (b-a)) //interc is very close to b 1074f220fa62Smrg { 1075f220fa62Smrg ret_indices[k]++; 1076f220fa62Smrg } 1077f220fa62Smrg 1078f220fa62Smrg //check ret_innerIndices[k] 1079f220fa62Smrg if(k>0) 1080f220fa62Smrg { 1081f220fa62Smrg if(ret_innerIndices[k] < ret_indices[k-1]) 1082f220fa62Smrg ret_innerIndices[k] = ret_indices[k-1]; 1083f220fa62Smrg if(ret_innerIndices[k] < ret_indices[k]) 1084f220fa62Smrg ret_innerIndices[k] = ret_indices[k]; 1085f220fa62Smrg } 1086f220fa62Smrg } 1087f220fa62Smrg //clean up 1088f220fa62Smrg free(uintercBuf); 1089f220fa62Smrg#endif 1090f220fa62Smrg} 1091f220fa62Smrg 1092f220fa62Smrgvoid findRightGridIndices(directedLine* topEdge, Int firstGridIndex, Int lastGridIndex, gridWrap* grid, Int* ret_indices, Int* ret_innerIndices) 1093f220fa62Smrg{ 1094f220fa62Smrg 1095f220fa62Smrg Int i,k; 1096f220fa62Smrg Int n_ulines = grid->get_n_ulines(); 1097f220fa62Smrg Real uMin = grid->get_u_min(); 1098f220fa62Smrg Real uMax = grid->get_u_max(); 1099f220fa62Smrg /* 1100f220fa62Smrg Real vMin = grid->get_v_min(); 1101f220fa62Smrg Real vMax = grid->get_v_max(); 1102f220fa62Smrg */ 1103f220fa62Smrg Real slop = 0.0, uinterc; 1104f220fa62Smrg 1105f220fa62Smrg#ifdef SHORTEN_GRID_LINE 1106f220fa62Smrg //uintercBuf stores all the interction u value for each grid line 1107f220fa62Smrg //notice that firstGridIndex >= lastGridIndex 1108f220fa62Smrg Real *uintercBuf = (Real *) malloc (sizeof(Real) * (firstGridIndex-lastGridIndex+1)); 1109f220fa62Smrg assert(uintercBuf); 1110f220fa62Smrg#endif 1111f220fa62Smrg 1112f220fa62Smrg /*initialization to make vhead bigger than grid->v_value...*/ 1113f220fa62Smrg directedLine* dLine = topEdge->getPrev(); 1114f220fa62Smrg Real vhead = dLine->tail()[1]; 1115f220fa62Smrg Real tempMinU = grid->get_u_max(); 1116f220fa62Smrg 1117f220fa62Smrg /*for each grid line*/ 1118f220fa62Smrg for(k=0, i=firstGridIndex; i>=lastGridIndex; i--, k++) 1119f220fa62Smrg { 1120f220fa62Smrg 1121f220fa62Smrg Real grid_v_value = grid->get_v_value(i); 1122f220fa62Smrg 1123f220fa62Smrg 1124f220fa62Smrg /*check whether this grid line is below the current trim edge.*/ 1125f220fa62Smrg if(vhead >= grid_v_value) 1126f220fa62Smrg { 1127f220fa62Smrg /*since the grid line is below the tail of the trim edge, we 1128f220fa62Smrg *find the trim edge which will contain the trim line 1129f220fa62Smrg */ 1130f220fa62Smrg while( (vhead=dLine->head()[1]) > grid_v_value){ 1131f220fa62Smrg tempMinU = min(tempMinU, dLine->head()[0]); 1132f220fa62Smrg dLine = dLine -> getPrev(); 1133f220fa62Smrg } 1134f220fa62Smrg 1135f220fa62Smrg /*skip the equality in the case of degenerat case: horizontal */ 1136f220fa62Smrg while(dLine->head()[1] == grid_v_value) 1137f220fa62Smrg dLine = dLine->getPrev(); 1138f220fa62Smrg 1139f220fa62Smrg assert( dLine->tail()[1] != dLine->head()[1]); 1140f220fa62Smrg slop = (dLine->tail()[0] - dLine->head()[0]) / (dLine->tail()[1]-dLine->head()[1]); 1141f220fa62Smrg /* 1142f220fa62Smrg if(dLine->tail()[1] == vhead) 1143f220fa62Smrg isHoriz = 1; 1144f220fa62Smrg else 1145f220fa62Smrg { 1146f220fa62Smrg isHoriz = 0; 1147f220fa62Smrg slop = (dLine->tail()[0] - dLine->head()[0]) / (dLine->tail()[1]-vhead); 1148f220fa62Smrg } 1149f220fa62Smrg */ 1150f220fa62Smrg } 1151f220fa62Smrg uinterc = slop * (grid_v_value - dLine->head()[1]) + dLine->head()[0]; 1152f220fa62Smrg 1153f220fa62Smrg //in case unterc is outside of the grid due to floating point 1154f220fa62Smrg if(uinterc < uMin) 1155f220fa62Smrg uinterc = uMin; 1156f220fa62Smrg else if(uinterc > uMax) 1157f220fa62Smrg uinterc = uMax; 1158f220fa62Smrg 1159f220fa62Smrg#ifdef SHORTEN_GRID_LINE 1160f220fa62Smrg uintercBuf[k] = uinterc; 1161f220fa62Smrg#endif 1162f220fa62Smrg 1163f220fa62Smrg tempMinU = min(tempMinU, uinterc); 1164f220fa62Smrg 1165f220fa62Smrg assert(uinterc >= uMin && uinterc <= uMax); 1166f220fa62Smrg 1167f220fa62Smrg if(uinterc == uMin) 1168f220fa62Smrg ret_indices[k] = 0; 1169f220fa62Smrg else 1170f220fa62Smrg ret_indices[k] = (int)ceil((((uinterc-uMin)/(uMax - uMin)) * (n_ulines-1))) -1; 1171f220fa62Smrg/* 1172f220fa62Smrgif(ret_indices[k] >= grid->get_n_ulines()) 1173f220fa62Smrg { 1174f220fa62Smrg printf("ERROR3\n"); 1175f220fa62Smrg exit(0); 1176f220fa62Smrg} 1177f220fa62Smrgif(ret_indices[k] < 0) 1178f220fa62Smrg { 1179f220fa62Smrg printf("ERROR4\n"); 1180f220fa62Smrg exit(0); 1181f220fa62Smrg} 1182f220fa62Smrg*/ 1183f220fa62Smrg ret_innerIndices[k] = (int)ceil ((((tempMinU-uMin)/(uMax - uMin)) * (n_ulines-1))) -1; 1184f220fa62Smrg 1185f220fa62Smrg tempMinU = uinterc; 1186f220fa62Smrg } 1187f220fa62Smrg#ifdef SHORTEN_GRID_LINE 1188f220fa62Smrg //for each grid line, compare the left grid point with the 1189f220fa62Smrg //intersection point. If the two points are too close, then 1190f220fa62Smrg //we should move the grid point one grid to the right 1191f220fa62Smrg //and accordingly we should update the inner index. 1192f220fa62Smrg for(k=0, i=firstGridIndex; i>=lastGridIndex; i--, k++) 1193f220fa62Smrg { 1194f220fa62Smrg //check gridLine i 1195f220fa62Smrg //check ret_indices[k] 1196f220fa62Smrg Real a = grid->get_u_value(ret_indices[k]); 1197f220fa62Smrg Real b = grid->get_u_value(ret_indices[k]+1); 1198f220fa62Smrg assert(uintercBuf[k] > a && uintercBuf <= b); 1199f220fa62Smrg if( (uintercBuf[k]-a) <= 0.2 * (b-a)) //interc is very close to a 1200f220fa62Smrg { 1201f220fa62Smrg ret_indices[k]--; 1202f220fa62Smrg } 1203f220fa62Smrg 1204f220fa62Smrg //check ret_innerIndices[k] 1205f220fa62Smrg if(k>0) 1206f220fa62Smrg { 1207f220fa62Smrg if(ret_innerIndices[k] > ret_indices[k-1]) 1208f220fa62Smrg ret_innerIndices[k] = ret_indices[k-1]; 1209f220fa62Smrg if(ret_innerIndices[k] > ret_indices[k]) 1210f220fa62Smrg ret_innerIndices[k] = ret_indices[k]; 1211f220fa62Smrg } 1212f220fa62Smrg } 1213f220fa62Smrg //clean up 1214f220fa62Smrg free(uintercBuf); 1215f220fa62Smrg#endif 1216f220fa62Smrg} 1217f220fa62Smrg 1218f220fa62Smrg 1219f220fa62Smrgvoid sampleMonoPoly(directedLine* polygon, gridWrap* grid, Int ulinear, Int vlinear, primStream* pStream, rectBlockArray* rbArray) 1220f220fa62Smrg{ 1221f220fa62Smrg/* 1222f220fa62Smrg{ 1223f220fa62Smrggrid->print(); 1224f220fa62Smrgpolygon->writeAllPolygons("zloutputFile"); 1225f220fa62Smrgexit(0); 1226f220fa62Smrg} 1227f220fa62Smrg*/ 1228f220fa62Smrg 1229f220fa62Smrgif(grid->get_n_ulines() == 2 || 1230f220fa62Smrg grid->get_n_vlines() == 2) 1231f220fa62Smrg{ 1232f220fa62Smrg if(ulinear && grid->get_n_ulines() == 2) 1233f220fa62Smrg { 1234f220fa62Smrg monoTriangulationFun(polygon, compV2InY, pStream); 1235f220fa62Smrg return; 1236f220fa62Smrg } 1237f220fa62Smrg else if(DBG_isConvex(polygon) && polygon->numEdges() >=4) 1238f220fa62Smrg { 1239f220fa62Smrg triangulateConvexPoly(polygon, ulinear, vlinear, pStream); 1240f220fa62Smrg return; 1241f220fa62Smrg } 1242f220fa62Smrg else if(vlinear || DBG_is_U_direction(polygon)) 1243f220fa62Smrg { 1244f220fa62Smrg Int n_cusps;//num interior cusps 1245f220fa62Smrg Int n_edges = polygon->numEdges(); 1246f220fa62Smrg directedLine** cusps = (directedLine**) malloc(sizeof(directedLine*) * n_edges); 1247f220fa62Smrg assert(cusps); 1248f220fa62Smrg findInteriorCuspsX(polygon, n_cusps, cusps); 1249f220fa62Smrg 1250f220fa62Smrg if(n_cusps == 0) //u_monotone 1251f220fa62Smrg { 1252f220fa62Smrg 1253f220fa62Smrg monoTriangulationFun(polygon, compV2InX, pStream); 1254f220fa62Smrg 1255f220fa62Smrg free(cusps); 1256f220fa62Smrg return; 1257f220fa62Smrg } 1258f220fa62Smrg else if(n_cusps == 1) //one interior cusp 1259f220fa62Smrg { 1260f220fa62Smrg 1261f220fa62Smrg directedLine* new_polygon = polygonConvert(cusps[0]); 1262f220fa62Smrg 1263f220fa62Smrg directedLine* other = findDiagonal_singleCuspX( new_polygon); 1264f220fa62Smrg 1265f220fa62Smrg 1266f220fa62Smrg 1267f220fa62Smrg //<other> should NOT be null unless there are self-intersecting 1268f220fa62Smrg //trim curves. In that case, we don't want to core dump, instead, 1269f220fa62Smrg //we triangulate anyway, and print out error message. 1270f220fa62Smrg if(other == NULL) 1271f220fa62Smrg { 1272f220fa62Smrg monoTriangulationFun(polygon, compV2InX, pStream); 1273f220fa62Smrg free(cusps); 1274f220fa62Smrg return; 1275f220fa62Smrg } 1276f220fa62Smrg 1277f220fa62Smrg directedLine* ret_p1; 1278f220fa62Smrg directedLine* ret_p2; 1279f220fa62Smrg 1280f220fa62Smrg new_polygon->connectDiagonal_2slines(new_polygon, other, 1281f220fa62Smrg &ret_p1, 1282f220fa62Smrg &ret_p2, 1283f220fa62Smrg new_polygon); 1284f220fa62Smrg 1285f220fa62Smrg monoTriangulationFun(ret_p1, compV2InX, pStream); 1286f220fa62Smrg monoTriangulationFun(ret_p2, compV2InX, pStream); 1287f220fa62Smrg 1288f220fa62Smrg ret_p1->deleteSinglePolygonWithSline(); 1289f220fa62Smrg ret_p2->deleteSinglePolygonWithSline(); 1290f220fa62Smrg 1291f220fa62Smrg free(cusps); 1292f220fa62Smrg return; 1293f220fa62Smrg } 1294f220fa62Smrg free(cusps); 1295f220fa62Smrg } 1296f220fa62Smrg} 1297f220fa62Smrg 1298f220fa62Smrg /*find the top and bottom of the polygon. It is supposed to be 1299f220fa62Smrg *a V-monotone polygon 1300f220fa62Smrg */ 1301f220fa62Smrg 1302f220fa62Smrg directedLine* tempV; 1303f220fa62Smrg directedLine* topV; 1304f220fa62Smrg directedLine* botV; 1305f220fa62Smrg topV = botV = polygon; 1306f220fa62Smrg 1307f220fa62Smrg for(tempV = polygon->getNext(); tempV != polygon; tempV = tempV->getNext()) 1308f220fa62Smrg { 1309f220fa62Smrg if(compV2InY(topV->head(), tempV->head())<0) { 1310f220fa62Smrg 1311f220fa62Smrg topV = tempV; 1312f220fa62Smrg } 1313f220fa62Smrg if(compV2InY(botV->head(), tempV->head())>0) { 1314f220fa62Smrg 1315f220fa62Smrg botV = tempV; 1316f220fa62Smrg } 1317f220fa62Smrg } 1318f220fa62Smrg 1319f220fa62Smrg /*find the first(top) and the last (bottom) grid line which intersect the 1320f220fa62Smrg *this polygon 1321f220fa62Smrg */ 1322f220fa62Smrg Int firstGridIndex; /*the index in the grid*/ 1323f220fa62Smrg Int lastGridIndex; 1324f220fa62Smrg firstGridIndex = (Int) ((topV->head()[1] - grid->get_v_min()) / (grid->get_v_max() - grid->get_v_min()) * (grid->get_n_vlines()-1)); 1325f220fa62Smrg lastGridIndex = (Int) ((botV->head()[1] - grid->get_v_min()) / (grid->get_v_max() - grid->get_v_min()) * (grid->get_n_vlines()-1)) + 1; 1326f220fa62Smrg 1327f220fa62Smrg 1328f220fa62Smrg /*find the interval inside the polygon for each gridline*/ 1329f220fa62Smrg Int *leftGridIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1)); 1330f220fa62Smrg assert(leftGridIndices); 1331f220fa62Smrg Int *rightGridIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1)); 1332f220fa62Smrg assert(rightGridIndices); 1333f220fa62Smrg Int *leftGridInnerIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1)); 1334f220fa62Smrg assert(leftGridInnerIndices); 1335f220fa62Smrg Int *rightGridInnerIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1)); 1336f220fa62Smrg assert(rightGridInnerIndices); 1337f220fa62Smrg 1338f220fa62Smrg findLeftGridIndices(topV, firstGridIndex, lastGridIndex, grid, leftGridIndices, leftGridInnerIndices); 1339f220fa62Smrg 1340f220fa62Smrg findRightGridIndices(topV, firstGridIndex, lastGridIndex, grid, rightGridIndices, rightGridInnerIndices); 1341f220fa62Smrg 1342f220fa62Smrg gridBoundaryChain leftGridChain(grid, firstGridIndex, firstGridIndex-lastGridIndex+1, leftGridIndices, leftGridInnerIndices); 1343f220fa62Smrg 1344f220fa62Smrg gridBoundaryChain rightGridChain(grid, firstGridIndex, firstGridIndex-lastGridIndex+1, rightGridIndices, rightGridInnerIndices); 1345f220fa62Smrg 1346f220fa62Smrg 1347f220fa62Smrg 1348f220fa62Smrg// leftGridChain.draw(); 1349f220fa62Smrg// leftGridChain.drawInner(); 1350f220fa62Smrg// rightGridChain.draw(); 1351f220fa62Smrg// rightGridChain.drawInner(); 1352f220fa62Smrg /*(1) determine the grid boundaries (left and right). 1353f220fa62Smrg *(2) process polygon into two monotone chaines: use vertexArray 1354f220fa62Smrg *(3) call sampleMonoPolyRec 1355f220fa62Smrg */ 1356f220fa62Smrg 1357f220fa62Smrg /*copy the two chains into vertexArray datastructure*/ 1358f220fa62Smrg Int i; 1359f220fa62Smrg vertexArray leftChain(20); /*this is a dynamic array*/ 1360f220fa62Smrg for(i=1; i<=topV->get_npoints()-2; i++) { /*the first vertex is the top vertex which doesn't belong to inc_chain*/ 1361f220fa62Smrg leftChain.appendVertex(topV->getVertex(i)); 1362f220fa62Smrg } 1363f220fa62Smrg for(tempV = topV->getNext(); tempV != botV; tempV = tempV->getNext()) 1364f220fa62Smrg { 1365f220fa62Smrg for(i=0; i<=tempV->get_npoints()-2; i++){ 1366f220fa62Smrg leftChain.appendVertex(tempV->getVertex(i)); 1367f220fa62Smrg } 1368f220fa62Smrg } 1369f220fa62Smrg 1370f220fa62Smrg vertexArray rightChain(20); 1371f220fa62Smrg for(tempV = topV->getPrev(); tempV != botV; tempV = tempV->getPrev()) 1372f220fa62Smrg { 1373f220fa62Smrg for(i=tempV->get_npoints()-2; i>=0; i--){ 1374f220fa62Smrg rightChain.appendVertex(tempV->getVertex(i)); 1375f220fa62Smrg } 1376f220fa62Smrg } 1377f220fa62Smrg for(i=botV->get_npoints()-2; i>=1; i--){ 1378f220fa62Smrg rightChain.appendVertex(tempV->getVertex(i)); 1379f220fa62Smrg } 1380f220fa62Smrg 1381f220fa62Smrg sampleMonoPolyRec(topV->head(), 1382f220fa62Smrg botV->head(), 1383f220fa62Smrg &leftChain, 1384f220fa62Smrg 0, 1385f220fa62Smrg &rightChain, 1386f220fa62Smrg 0, 1387f220fa62Smrg &leftGridChain, 1388f220fa62Smrg &rightGridChain, 1389f220fa62Smrg 0, 1390f220fa62Smrg pStream, 1391f220fa62Smrg rbArray); 1392f220fa62Smrg 1393f220fa62Smrg 1394f220fa62Smrg /*cleanup space*/ 1395f220fa62Smrg free(leftGridIndices); 1396f220fa62Smrg free(rightGridIndices); 1397f220fa62Smrg free(leftGridInnerIndices); 1398f220fa62Smrg free(rightGridInnerIndices); 1399f220fa62Smrg} 1400f220fa62Smrg 1401f220fa62Smrgvoid sampleMonoPolyRec( 1402f220fa62Smrg Real* topVertex, 1403f220fa62Smrg Real* botVertex, 1404f220fa62Smrg vertexArray* leftChain, 1405f220fa62Smrg Int leftStartIndex, 1406f220fa62Smrg vertexArray* rightChain, 1407f220fa62Smrg Int rightStartIndex, 1408f220fa62Smrg gridBoundaryChain* leftGridChain, 1409f220fa62Smrg gridBoundaryChain* rightGridChain, 1410f220fa62Smrg Int gridStartIndex, 1411f220fa62Smrg primStream* pStream, 1412f220fa62Smrg rectBlockArray* rbArray) 1413f220fa62Smrg{ 1414f220fa62Smrg 1415f220fa62Smrg /*find the first connected component, and the four corners. 1416f220fa62Smrg */ 1417f220fa62Smrg Int index1, index2; /*the first and last grid line of the first connected component*/ 1418f220fa62Smrg 1419f220fa62Smrg if(topVertex[1] <= botVertex[1]) 1420f220fa62Smrg return; 1421f220fa62Smrg 1422f220fa62Smrg /*find i so that the grid line is below the top vertex*/ 1423f220fa62Smrg Int i=gridStartIndex; 1424f220fa62Smrg while (i < leftGridChain->get_nVlines()) 1425f220fa62Smrg { 1426f220fa62Smrg if(leftGridChain->get_v_value(i) < topVertex[1]) 1427f220fa62Smrg break; 1428f220fa62Smrg i++; 1429f220fa62Smrg } 1430f220fa62Smrg 1431f220fa62Smrg /*find the first connected component starting with i*/ 1432f220fa62Smrg /*find index1 so that left_uline_index <= right_uline_index, that is, this 1433f220fa62Smrg *grid line contains at least one inner grid point 1434f220fa62Smrg */ 1435f220fa62Smrg index1=i; 1436f220fa62Smrg int num_skipped_grid_lines=0; 1437f220fa62Smrg while(index1 < leftGridChain->get_nVlines()) 1438f220fa62Smrg { 1439f220fa62Smrg if(leftGridChain->getUlineIndex(index1) <= rightGridChain->getUlineIndex(index1)) 1440f220fa62Smrg break; 1441f220fa62Smrg num_skipped_grid_lines++; 1442f220fa62Smrg index1++; 1443f220fa62Smrg } 1444f220fa62Smrg 1445f220fa62Smrg 1446f220fa62Smrg 1447f220fa62Smrg if(index1 >= leftGridChain->get_nVlines()) /*no grid line exists which has inner point*/ 1448f220fa62Smrg { 1449f220fa62Smrg /*stop recursion, ...*/ 1450f220fa62Smrg /*monotone triangulate it...*/ 1451f220fa62Smrg// printf("no grid line exists\n"); 1452f220fa62Smrg/* 1453f220fa62Smrg monoTriangulationRecOpt(topVertex, botVertex, leftChain, leftStartIndex, 1454f220fa62Smrg rightChain, rightStartIndex, pStream); 1455f220fa62Smrg*/ 1456f220fa62Smrg 1457f220fa62Smrgif(num_skipped_grid_lines <2) 1458f220fa62Smrg { 1459f220fa62Smrg monoTriangulationRecGenOpt(topVertex, botVertex, leftChain, leftStartIndex, 1460f220fa62Smrg leftChain->getNumElements()-1, 1461f220fa62Smrg rightChain, rightStartIndex, 1462f220fa62Smrg rightChain->getNumElements()-1, 1463f220fa62Smrg pStream); 1464f220fa62Smrg } 1465f220fa62Smrgelse 1466f220fa62Smrg { 1467f220fa62Smrg //the optimum way to triangulate is top-down since this polygon 1468f220fa62Smrg //is narrow-long. 1469f220fa62Smrg monoTriangulationRec(topVertex, botVertex, leftChain, leftStartIndex, 1470f220fa62Smrg rightChain, rightStartIndex, pStream); 1471f220fa62Smrg } 1472f220fa62Smrg 1473f220fa62Smrg/* 1474f220fa62Smrg monoTriangulationRec(topVertex, botVertex, leftChain, leftStartIndex, 1475f220fa62Smrg rightChain, rightStartIndex, pStream); 1476f220fa62Smrg*/ 1477f220fa62Smrg 1478f220fa62Smrg/* monoTriangulationRecGenTBOpt(topVertex, botVertex, 1479f220fa62Smrg leftChain, leftStartIndex, leftChain->getNumElements()-1, 1480f220fa62Smrg rightChain, rightStartIndex, rightChain->getNumElements()-1, 1481f220fa62Smrg pStream);*/ 1482f220fa62Smrg 1483f220fa62Smrg 1484f220fa62Smrg 1485f220fa62Smrg } 1486f220fa62Smrg else 1487f220fa62Smrg { 1488f220fa62Smrg 1489f220fa62Smrg /*find index2 so that left_inner_index <= right_inner_index holds until index2*/ 1490f220fa62Smrg index2=index1+1; 1491f220fa62Smrg if(index2 < leftGridChain->get_nVlines()) 1492f220fa62Smrg while(leftGridChain->getInnerIndex(index2) <= rightGridChain->getInnerIndex(index2)) 1493f220fa62Smrg { 1494f220fa62Smrg index2++; 1495f220fa62Smrg if(index2 >= leftGridChain->get_nVlines()) 1496f220fa62Smrg break; 1497f220fa62Smrg } 1498f220fa62Smrg 1499f220fa62Smrg index2--; 1500f220fa62Smrg 1501f220fa62Smrg 1502f220fa62Smrg 1503f220fa62Smrg /*the neck*/ 1504f220fa62Smrg Int neckLeftIndex; 1505f220fa62Smrg Int neckRightIndex; 1506f220fa62Smrg 1507f220fa62Smrg /*the four corners*/ 1508f220fa62Smrg Int up_leftCornerWhere; 1509f220fa62Smrg Int up_leftCornerIndex; 1510f220fa62Smrg Int up_rightCornerWhere; 1511f220fa62Smrg Int up_rightCornerIndex; 1512f220fa62Smrg Int down_leftCornerWhere; 1513f220fa62Smrg Int down_leftCornerIndex; 1514f220fa62Smrg Int down_rightCornerWhere; 1515f220fa62Smrg Int down_rightCornerIndex; 1516f220fa62Smrg 1517f220fa62Smrg Real* tempBotVertex; /*the bottom vertex for this component*/ 1518f220fa62Smrg Real* nextTopVertex=NULL; /*for the recursion*/ 1519f220fa62Smrg Int nextLeftStartIndex=0; 1520f220fa62Smrg Int nextRightStartIndex=0; 1521f220fa62Smrg 1522f220fa62Smrg /*find the points below the grid line index2 on both chains*/ 1523f220fa62Smrg Int botLeftIndex = leftChain->findIndexStrictBelowGen( 1524f220fa62Smrg leftGridChain->get_v_value(index2), 1525f220fa62Smrg leftStartIndex, 1526f220fa62Smrg leftChain->getNumElements()-1); 1527f220fa62Smrg Int botRightIndex = rightChain->findIndexStrictBelowGen( 1528f220fa62Smrg rightGridChain->get_v_value(index2), 1529f220fa62Smrg rightStartIndex, 1530f220fa62Smrg rightChain->getNumElements()-1); 1531f220fa62Smrg /*if either botLeftIndex>= numelements, 1532f220fa62Smrg * or botRightIndex >= numelemnet, 1533f220fa62Smrg *then there is no neck exists. the bottom vertex is botVertex, 1534f220fa62Smrg */ 1535f220fa62Smrg if(! findNeckF(leftChain, botLeftIndex, rightChain, botRightIndex, 1536f220fa62Smrg leftGridChain, rightGridChain, index2, neckLeftIndex, neckRightIndex)) 1537f220fa62Smrg /* 1538f220fa62Smrg if(botLeftIndex == leftChain->getNumElements() || 1539f220fa62Smrg botRightIndex == rightChain->getNumElements()) 1540f220fa62Smrg */ 1541f220fa62Smrg { 1542f220fa62Smrg#ifdef MYDEBUG 1543f220fa62Smrg printf("neck NOT exists, botRightIndex=%i\n", botRightIndex); 1544f220fa62Smrg#endif 1545f220fa62Smrg 1546f220fa62Smrg tempBotVertex = botVertex; 1547f220fa62Smrg nextTopVertex = botVertex; 1548f220fa62Smrg botLeftIndex = leftChain->getNumElements()-1; 1549f220fa62Smrg botRightIndex = rightChain->getNumElements()-1; 1550f220fa62Smrg } 1551f220fa62Smrg else /*neck exists*/ 1552f220fa62Smrg { 1553f220fa62Smrg#ifdef MYDEBUG 1554f220fa62Smrg printf("neck exists\n"); 1555f220fa62Smrg#endif 1556f220fa62Smrg 1557f220fa62Smrg /* 1558f220fa62Smrg findNeck(leftChain, botLeftIndex, 1559f220fa62Smrg rightChain, botRightIndex, 1560f220fa62Smrg neckLeftIndex, 1561f220fa62Smrg neckRightIndex); 1562f220fa62Smrg */ 1563f220fa62Smrg#ifdef MYDEBUG 1564f220fa62Smrgprintf("neck is found, neckLeftIndex=%i, neckRightIndex=%i\n", neckLeftIndex, neckRightIndex); 1565f220fa62SmrgglBegin(GL_LINES); 1566f220fa62SmrgglVertex2fv(leftChain->getVertex(neckLeftIndex)); 1567f220fa62SmrgglVertex2fv(rightChain->getVertex(neckRightIndex)); 1568f220fa62SmrgglEnd(); 1569f220fa62Smrg#endif 1570f220fa62Smrg 1571f220fa62Smrg if(leftChain->getVertex(neckLeftIndex)[1] <= rightChain->getVertex(neckRightIndex)[1]) 1572f220fa62Smrg { 1573f220fa62Smrg tempBotVertex = leftChain->getVertex(neckLeftIndex); 1574f220fa62Smrg botLeftIndex = neckLeftIndex-1; 1575f220fa62Smrg botRightIndex = neckRightIndex; 1576f220fa62Smrg nextTopVertex = rightChain->getVertex(neckRightIndex); 1577f220fa62Smrg nextLeftStartIndex = neckLeftIndex; 1578f220fa62Smrg nextRightStartIndex = neckRightIndex+1; 1579f220fa62Smrg } 1580f220fa62Smrg else 1581f220fa62Smrg { 1582f220fa62Smrg tempBotVertex = rightChain->getVertex(neckRightIndex); 1583f220fa62Smrg botLeftIndex = neckLeftIndex; 1584f220fa62Smrg botRightIndex = neckRightIndex-1; 1585f220fa62Smrg nextTopVertex = leftChain->getVertex(neckLeftIndex); 1586f220fa62Smrg nextLeftStartIndex = neckLeftIndex+1; 1587f220fa62Smrg nextRightStartIndex = neckRightIndex; 1588f220fa62Smrg } 1589f220fa62Smrg } 1590f220fa62Smrg 1591f220fa62Smrg findUpCorners(topVertex, 1592f220fa62Smrg leftChain, 1593f220fa62Smrg leftStartIndex, botLeftIndex, 1594f220fa62Smrg rightChain, 1595f220fa62Smrg rightStartIndex, botRightIndex, 1596f220fa62Smrg leftGridChain->get_v_value(index1), 1597f220fa62Smrg leftGridChain->get_u_value(index1), 1598f220fa62Smrg rightGridChain->get_u_value(index1), 1599f220fa62Smrg up_leftCornerWhere, 1600f220fa62Smrg up_leftCornerIndex, 1601f220fa62Smrg up_rightCornerWhere, 1602f220fa62Smrg up_rightCornerIndex); 1603f220fa62Smrg 1604f220fa62Smrg findDownCorners(tempBotVertex, 1605f220fa62Smrg leftChain, 1606f220fa62Smrg leftStartIndex, botLeftIndex, 1607f220fa62Smrg rightChain, 1608f220fa62Smrg rightStartIndex, botRightIndex, 1609f220fa62Smrg leftGridChain->get_v_value(index2), 1610f220fa62Smrg leftGridChain->get_u_value(index2), 1611f220fa62Smrg rightGridChain->get_u_value(index2), 1612f220fa62Smrg down_leftCornerWhere, 1613f220fa62Smrg down_leftCornerIndex, 1614f220fa62Smrg down_rightCornerWhere, 1615f220fa62Smrg down_rightCornerIndex); 1616f220fa62Smrg#ifdef MYDEBUG 1617f220fa62Smrg printf("find corners done, down_leftwhere=%i, down_righwhere=%i,\n",down_leftCornerWhere, down_rightCornerWhere ); 1618f220fa62Smrg printf("find corners done, up_leftwhere=%i, up_righwhere=%i,\n",up_leftCornerWhere, up_rightCornerWhere ); 1619f220fa62Smrg printf("find corners done, up_leftindex=%i, up_righindex=%i,\n",up_leftCornerIndex, up_rightCornerIndex ); 1620f220fa62Smrg printf("find corners done, down_leftindex=%i, down_righindex=%i,\n",down_leftCornerIndex, down_rightCornerIndex ); 1621f220fa62Smrg#endif 1622f220fa62Smrg 1623f220fa62Smrg/* 1624f220fa62Smrg drawCorners(topVertex, 1625f220fa62Smrg tempBotVertex, 1626f220fa62Smrg leftChain, 1627f220fa62Smrg rightChain, 1628f220fa62Smrg leftGridChain, 1629f220fa62Smrg rightGridChain, 1630f220fa62Smrg index1, 1631f220fa62Smrg index2, 1632f220fa62Smrg up_leftCornerWhere, 1633f220fa62Smrg up_leftCornerIndex, 1634f220fa62Smrg up_rightCornerWhere, 1635f220fa62Smrg up_rightCornerIndex, 1636f220fa62Smrg down_leftCornerWhere, 1637f220fa62Smrg down_leftCornerIndex, 1638f220fa62Smrg down_rightCornerWhere, 1639f220fa62Smrg down_rightCornerIndex); 1640f220fa62Smrg*/ 1641f220fa62Smrg 1642f220fa62Smrg 1643f220fa62Smrg sampleConnectedComp(topVertex, tempBotVertex, 1644f220fa62Smrg leftChain, 1645f220fa62Smrg leftStartIndex, botLeftIndex, 1646f220fa62Smrg rightChain, 1647f220fa62Smrg rightStartIndex, botRightIndex, 1648f220fa62Smrg leftGridChain, 1649f220fa62Smrg rightGridChain, 1650f220fa62Smrg index1, index2, 1651f220fa62Smrg up_leftCornerWhere, 1652f220fa62Smrg up_leftCornerIndex, 1653f220fa62Smrg up_rightCornerWhere, 1654f220fa62Smrg up_rightCornerIndex, 1655f220fa62Smrg down_leftCornerWhere, 1656f220fa62Smrg down_leftCornerIndex, 1657f220fa62Smrg down_rightCornerWhere, 1658f220fa62Smrg down_rightCornerIndex, 1659f220fa62Smrg pStream, 1660f220fa62Smrg rbArray 1661f220fa62Smrg ); 1662f220fa62Smrg 1663f220fa62Smrg /*recursion*/ 1664f220fa62Smrg 1665f220fa62Smrg sampleMonoPolyRec( 1666f220fa62Smrg nextTopVertex, 1667f220fa62Smrg botVertex, 1668f220fa62Smrg leftChain, 1669f220fa62Smrg nextLeftStartIndex, 1670f220fa62Smrg rightChain, 1671f220fa62Smrg nextRightStartIndex, 1672f220fa62Smrg leftGridChain, 1673f220fa62Smrg rightGridChain, 1674f220fa62Smrg index2+1, 1675f220fa62Smrg pStream, rbArray); 1676f220fa62Smrg 1677f220fa62Smrg 1678f220fa62Smrg } 1679f220fa62Smrg 1680f220fa62Smrg} 1681f220fa62Smrg 1682f220fa62Smrgvoid sampleLeftStrip(vertexArray* leftChain, 1683f220fa62Smrg Int topLeftIndex, 1684f220fa62Smrg Int botLeftIndex, 1685f220fa62Smrg gridBoundaryChain* leftGridChain, 1686f220fa62Smrg Int leftGridChainStartIndex, 1687f220fa62Smrg Int leftGridChainEndIndex, 1688f220fa62Smrg primStream* pStream 1689f220fa62Smrg ) 1690f220fa62Smrg{ 1691f220fa62Smrg assert(leftChain->getVertex(topLeftIndex)[1] > leftGridChain->get_v_value(leftGridChainStartIndex)); 1692f220fa62Smrg assert(leftChain->getVertex(topLeftIndex+1)[1] <= leftGridChain->get_v_value(leftGridChainStartIndex)); 1693f220fa62Smrg assert(leftChain->getVertex(botLeftIndex)[1] <= leftGridChain->get_v_value(leftGridChainEndIndex)); 1694f220fa62Smrg assert(leftChain->getVertex(botLeftIndex-1)[1] > leftGridChain->get_v_value(leftGridChainEndIndex)); 1695f220fa62Smrg 1696f220fa62Smrg /* 1697f220fa62Smrg *(1)find the last grid line which doesn'; pass below 1698f220fa62Smrg * this first edge, sample this region: one trim edge and 1699f220fa62Smrg * possily multiple grid lines. 1700f220fa62Smrg */ 1701f220fa62Smrg Real *upperVert, *lowerVert; /*the end points of the first trim edge*/ 1702f220fa62Smrg upperVert = leftChain->getVertex(topLeftIndex); 1703f220fa62Smrg lowerVert = leftChain->getVertex(topLeftIndex+1); 1704f220fa62Smrg 1705f220fa62Smrg Int index = leftGridChainStartIndex; 1706f220fa62Smrg while(leftGridChain->get_v_value(index) >= lowerVert[1]){ 1707f220fa62Smrg index++; 1708f220fa62Smrg if(index > leftGridChainEndIndex) 1709f220fa62Smrg break; 1710f220fa62Smrg } 1711f220fa62Smrg index--; 1712f220fa62Smrg 1713f220fa62Smrg sampleLeftSingleTrimEdgeRegion(upperVert, lowerVert, 1714f220fa62Smrg leftGridChain, 1715f220fa62Smrg leftGridChainStartIndex, 1716f220fa62Smrg index, 1717f220fa62Smrg pStream); 1718f220fa62Smrg sampleLeftStripRec(leftChain, topLeftIndex+1, botLeftIndex, 1719f220fa62Smrg leftGridChain, index, leftGridChainEndIndex, 1720f220fa62Smrg pStream); 1721f220fa62Smrg 1722f220fa62Smrg} 1723f220fa62Smrg 1724f220fa62Smrgvoid sampleLeftStripRec(vertexArray* leftChain, 1725f220fa62Smrg Int topLeftIndex, 1726f220fa62Smrg Int botLeftIndex, 1727f220fa62Smrg gridBoundaryChain* leftGridChain, 1728f220fa62Smrg Int leftGridChainStartIndex, 1729f220fa62Smrg Int leftGridChainEndIndex, 1730f220fa62Smrg primStream* pStream 1731f220fa62Smrg ) 1732f220fa62Smrg{ 1733f220fa62Smrg /*now top left trim vertex is below the top grid line. 1734f220fa62Smrg */ 1735f220fa62Smrg /*stop condition: if topLeftIndex >= botLeftIndex, then stop. 1736f220fa62Smrg */ 1737f220fa62Smrg if(topLeftIndex >= botLeftIndex) 1738f220fa62Smrg return; 1739f220fa62Smrg 1740f220fa62Smrg /*find the last trim vertex which is above the second top grid line: 1741f220fa62Smrg * index1. 1742f220fa62Smrg *and sampleLeftOneGridStep(leftchain, topLeftIndex, index1, leftGridChain, 1743f220fa62Smrg * leftGridChainStartIndex). 1744f220fa62Smrg * index1 could be equal to topLeftIndex. 1745f220fa62Smrg */ 1746f220fa62Smrg Real secondGridChainV = leftGridChain->get_v_value(leftGridChainStartIndex+1); 1747f220fa62Smrg assert(leftGridChainStartIndex < leftGridChainEndIndex); 1748f220fa62Smrg Int index1 = topLeftIndex; 1749f220fa62Smrg while(leftChain->getVertex(index1)[1] > secondGridChainV) 1750f220fa62Smrg index1++; 1751f220fa62Smrg index1--; 1752f220fa62Smrg 1753f220fa62Smrg sampleLeftOneGridStep(leftChain, topLeftIndex, index1, leftGridChain, leftGridChainStartIndex, pStream); 1754f220fa62Smrg 1755f220fa62Smrg 1756f220fa62Smrg /* 1757f220fa62Smrg * Let the next trim vertex be nextTrimVertIndex (which should be 1758f220fa62Smrg * below the second grid line). 1759f220fa62Smrg * Find the last grid line index2 which is above nextTrimVert. 1760f220fa62Smrg * sampleLeftSingleTrimEdgeRegion(uppervert[2], lowervert[2], 1761f220fa62Smrg * leftGridChain, leftGridChainStartIndex+1, index2). 1762f220fa62Smrg */ 1763f220fa62Smrg Real *uppervert, *lowervert; 1764f220fa62Smrg uppervert = leftChain->getVertex(index1); 1765f220fa62Smrg lowervert = leftChain->getVertex(index1+1); 1766f220fa62Smrg Int index2 = leftGridChainStartIndex+1; 1767f220fa62Smrg 1768f220fa62Smrg while(leftGridChain->get_v_value(index2) >= lowervert[1]) 1769f220fa62Smrg { 1770f220fa62Smrg index2++; 1771f220fa62Smrg if(index2 > leftGridChainEndIndex) 1772f220fa62Smrg break; 1773f220fa62Smrg } 1774f220fa62Smrg index2--; 1775f220fa62Smrg sampleLeftSingleTrimEdgeRegion(uppervert, lowervert, leftGridChain, leftGridChainStartIndex+1, index2, pStream); 1776f220fa62Smrg 1777f220fa62Smrg /* sampleLeftStripRec(leftChain, 1778f220fa62Smrg nextTrimVertIndex, 1779f220fa62Smrg botLeftIndex, 1780f220fa62Smrg leftGridChain, 1781f220fa62Smrg index2, 1782f220fa62Smrg leftGridChainEndIndex 1783f220fa62Smrg ) 1784f220fa62Smrg * 1785f220fa62Smrg */ 1786f220fa62Smrg sampleLeftStripRec(leftChain, index1+1, botLeftIndex, leftGridChain, index2, leftGridChainEndIndex, pStream); 1787f220fa62Smrg 1788f220fa62Smrg} 1789f220fa62Smrg 1790f220fa62Smrg 1791f220fa62Smrg/***************begin RecF***********************/ 1792f220fa62Smrg/* the gridlines from leftGridChainStartIndex to 1793f220fa62Smrg * leftGridChainEndIndex are assumed to form a 1794f220fa62Smrg * connected component. 1795f220fa62Smrg * the trim vertex of topLeftIndex is assumed to 1796f220fa62Smrg * be below the first gridline, and the tim vertex 1797f220fa62Smrg * of botLeftIndex is assumed to be above the last 1798f220fa62Smrg * grid line. 1799f220fa62Smrg * If botLeftIndex < topLeftIndex, then no connected componeent exists, and this funcion returns without 1800f220fa62Smrg * outputing any triangles. 1801f220fa62Smrg * Otherwise botLeftIndex >= topLeftIndex, there is at least one triangle to output. 1802f220fa62Smrg */ 1803f220fa62Smrgvoid sampleLeftStripRecF(vertexArray* leftChain, 1804f220fa62Smrg Int topLeftIndex, 1805f220fa62Smrg Int botLeftIndex, 1806f220fa62Smrg gridBoundaryChain* leftGridChain, 1807f220fa62Smrg Int leftGridChainStartIndex, 1808f220fa62Smrg Int leftGridChainEndIndex, 1809f220fa62Smrg primStream* pStream 1810f220fa62Smrg ) 1811f220fa62Smrg{ 1812f220fa62Smrg /*now top left trim vertex is below the top grid line. 1813f220fa62Smrg */ 1814f220fa62Smrg /*stop condition: if topLeftIndex > botLeftIndex, then stop. 1815f220fa62Smrg */ 1816f220fa62Smrg if(topLeftIndex > botLeftIndex) 1817f220fa62Smrg return; 1818f220fa62Smrg 1819f220fa62Smrg /*if there is only one grid Line, return.*/ 1820f220fa62Smrg 1821f220fa62Smrg if(leftGridChainStartIndex>=leftGridChainEndIndex) 1822f220fa62Smrg return; 1823f220fa62Smrg 1824f220fa62Smrg 1825f220fa62Smrg assert(leftChain->getVertex(topLeftIndex)[1] <= leftGridChain->get_v_value(leftGridChainStartIndex) && 1826f220fa62Smrg leftChain->getVertex(botLeftIndex)[1] >= leftGridChain->get_v_value(leftGridChainEndIndex)); 1827f220fa62Smrg 1828f220fa62Smrg /*firs find the first trim vertex which is below or equal to the second top grid line: 1829f220fa62Smrg * index1. 1830f220fa62Smrg */ 1831f220fa62Smrg Real secondGridChainV = leftGridChain->get_v_value(leftGridChainStartIndex+1); 1832f220fa62Smrg 1833f220fa62Smrg 1834f220fa62Smrg Int index1 = topLeftIndex; 1835f220fa62Smrg 1836f220fa62Smrg while(leftChain->getVertex(index1)[1] > secondGridChainV){ 1837f220fa62Smrg index1++; 1838f220fa62Smrg if(index1>botLeftIndex) 1839f220fa62Smrg break; 1840f220fa62Smrg } 1841f220fa62Smrg 1842f220fa62Smrg /*now leftChain->getVertex(index-1)[1] > secondGridChainV and 1843f220fa62Smrg * leftChain->getVertex(index)[1] <= secondGridChainV 1844f220fa62Smrg *If equality holds, then we should include the vertex index1, otherwise we include only index1-1, to 1845f220fa62Smrg *perform sampleOneGridStep. 1846f220fa62Smrg */ 1847f220fa62Smrg if(index1>botLeftIndex) 1848f220fa62Smrg index1--; 1849f220fa62Smrg else if(leftChain->getVertex(index1)[1] < secondGridChainV) 1850f220fa62Smrg index1--; 1851f220fa62Smrg 1852f220fa62Smrg /*now we have leftChain->getVertex(index1)[1] >= secondGridChainV, and 1853f220fa62Smrg * leftChain->getVertex(index1+1)[1] <= secondGridChainV 1854f220fa62Smrg */ 1855f220fa62Smrg 1856f220fa62Smrg 1857f220fa62Smrg sampleLeftOneGridStep(leftChain, topLeftIndex, index1, leftGridChain, leftGridChainStartIndex, pStream); 1858f220fa62Smrg 1859f220fa62Smrg 1860f220fa62Smrg /*if leftChain->getVertex(index1)[1] == secondGridChainV, then we can recursively do the rest. 1861f220fa62Smrg */ 1862f220fa62Smrg if(leftChain->getVertex(index1)[1] == secondGridChainV) 1863f220fa62Smrg { 1864f220fa62Smrg 1865f220fa62Smrg sampleLeftStripRecF(leftChain, index1, botLeftIndex,leftGridChain, leftGridChainStartIndex+1, leftGridChainEndIndex, pStream); 1866f220fa62Smrg } 1867f220fa62Smrg else if(index1 < botLeftIndex) 1868f220fa62Smrg { 1869f220fa62Smrg 1870f220fa62Smrg /* Otherwise, we have leftChain->getVertex(index1)[1] > secondGridChainV, 1871f220fa62Smrg * let the next trim vertex be nextTrimVertIndex (which should be strictly 1872f220fa62Smrg * below the second grid line). 1873f220fa62Smrg * Find the last grid line index2 which is above nextTrimVert. 1874f220fa62Smrg * sampleLeftSingleTrimEdgeRegion(uppervert[2], lowervert[2], 1875f220fa62Smrg * leftGridChain, leftGridChainStartIndex+1, index2). 1876f220fa62Smrg */ 1877f220fa62Smrg Real *uppervert, *lowervert; 1878f220fa62Smrg uppervert = leftChain->getVertex(index1); 1879f220fa62Smrg lowervert = leftChain->getVertex(index1+1); //okay since index1<botLeftIndex 1880f220fa62Smrg Int index2 = leftGridChainStartIndex+1; 1881f220fa62Smrg 1882f220fa62Smrg 1883f220fa62Smrg while(leftGridChain->get_v_value(index2) >= lowervert[1]) 1884f220fa62Smrg { 1885f220fa62Smrg index2++; 1886f220fa62Smrg if(index2 > leftGridChainEndIndex) 1887f220fa62Smrg break; 1888f220fa62Smrg } 1889f220fa62Smrg index2--; 1890f220fa62Smrg 1891f220fa62Smrg 1892f220fa62Smrg sampleLeftSingleTrimEdgeRegion(uppervert, lowervert, leftGridChain, leftGridChainStartIndex+1, index2, pStream); 1893f220fa62Smrg 1894f220fa62Smrg /*recursion*/ 1895f220fa62Smrg 1896f220fa62Smrg sampleLeftStripRecF(leftChain, index1+1, botLeftIndex, leftGridChain, index2, leftGridChainEndIndex, pStream); 1897f220fa62Smrg } 1898f220fa62Smrg 1899f220fa62Smrg} 1900f220fa62Smrg 1901f220fa62Smrg/***************End RecF***********************/ 1902f220fa62Smrg 1903f220fa62Smrg/*sample the left area in between one trim edge and multiple grid lines. 1904f220fa62Smrg * all the grid lines should be in between the two end poins of the 1905f220fa62Smrg *trim edge. 1906f220fa62Smrg */ 1907f220fa62Smrgvoid sampleLeftSingleTrimEdgeRegion(Real upperVert[2], Real lowerVert[2], 1908f220fa62Smrg gridBoundaryChain* gridChain, 1909f220fa62Smrg Int beginIndex, 1910f220fa62Smrg Int endIndex, 1911f220fa62Smrg primStream* pStream) 1912f220fa62Smrg{ 1913f220fa62Smrg Int i,j,k; 1914f220fa62Smrg 1915f220fa62Smrg vertexArray vArray(endIndex-beginIndex+1); 1916f220fa62Smrg vArray.appendVertex(gridChain->get_vertex(beginIndex)); 1917f220fa62Smrg 1918f220fa62Smrg for(k=1, i=beginIndex+1; i<=endIndex; i++, k++) 1919f220fa62Smrg { 1920f220fa62Smrg vArray.appendVertex(gridChain->get_vertex(i)); 1921f220fa62Smrg 1922f220fa62Smrg /*output the fan of the grid points of the (i)th and (i-1)th grid line. 1923f220fa62Smrg */ 1924f220fa62Smrg if(gridChain->getUlineIndex(i) < gridChain->getUlineIndex(i-1)) 1925f220fa62Smrg { 1926f220fa62Smrg pStream->begin(); 1927f220fa62Smrg pStream->insert(gridChain->get_vertex(i-1)); 1928f220fa62Smrg for(j=gridChain->getUlineIndex(i); j<= gridChain->getUlineIndex(i-1); j++) 1929f220fa62Smrg pStream->insert(gridChain->getGrid()->get_u_value(j), gridChain->get_v_value(i)); 1930f220fa62Smrg pStream->end(PRIMITIVE_STREAM_FAN); 1931f220fa62Smrg } 1932f220fa62Smrg else if(gridChain->getUlineIndex(i) > gridChain->getUlineIndex(i-1)) 1933f220fa62Smrg { 1934f220fa62Smrg pStream->begin(); 1935f220fa62Smrg pStream->insert(gridChain->get_vertex(i)); 1936f220fa62Smrg for(j=gridChain->getUlineIndex(i); j>= gridChain->getUlineIndex(i-1); j--) 1937f220fa62Smrg pStream->insert(gridChain->getGrid()->get_u_value(j), gridChain->get_v_value(i-1)); 1938f220fa62Smrg pStream->end(PRIMITIVE_STREAM_FAN); 1939f220fa62Smrg } 1940f220fa62Smrg /*otherwisem, the two are equal, so there is no fan to outout*/ 1941f220fa62Smrg } 1942f220fa62Smrg 1943f220fa62Smrg monoTriangulation2(upperVert, lowerVert, &vArray, 0, endIndex-beginIndex, 1944f220fa62Smrg 0, /*decreasing chain*/ 1945f220fa62Smrg pStream); 1946f220fa62Smrg} 1947f220fa62Smrg 1948f220fa62Smrg/*return i, such that from begin to i-1 the chain is strictly u-monotone. 1949f220fa62Smrg */ 1950f220fa62SmrgInt findIncreaseChainFromBegin(vertexArray* chain, Int begin ,Int end) 1951f220fa62Smrg{ 1952f220fa62Smrg Int i=begin; 1953f220fa62Smrg Real prevU = chain->getVertex(i)[0]; 1954f220fa62Smrg Real thisU; 1955f220fa62Smrg for(i=begin+1; i<=end; i++){ 1956f220fa62Smrg thisU = chain->getVertex(i)[0]; 1957f220fa62Smrg 1958f220fa62Smrg if(prevU < thisU){ 1959f220fa62Smrg prevU = thisU; 1960f220fa62Smrg } 1961f220fa62Smrg else 1962f220fa62Smrg break; 1963f220fa62Smrg } 1964f220fa62Smrg return i; 1965f220fa62Smrg} 1966f220fa62Smrg 1967f220fa62Smrg/*check whether there is a vertex whose v value is strictly 1968f220fa62Smrg *inbetween vup vbelow 1969f220fa62Smrg *if no middle exists return -1, else return the idnex. 1970f220fa62Smrg */ 1971f220fa62SmrgInt checkMiddle(vertexArray* chain, Int begin, Int end, 1972f220fa62Smrg Real vup, Real vbelow) 1973f220fa62Smrg{ 1974f220fa62Smrg Int i; 1975f220fa62Smrg for(i=begin; i<=end; i++) 1976f220fa62Smrg { 1977f220fa62Smrg if(chain->getVertex(i)[1] < vup && chain->getVertex(i)[1]>vbelow) 1978f220fa62Smrg return i; 1979f220fa62Smrg } 1980f220fa62Smrg return -1; 1981f220fa62Smrg} 1982f220fa62Smrg 1983f220fa62Smrg/*the degenerat case of sampleLeftOneGridStep*/ 1984f220fa62Smrgvoid sampleLeftOneGridStepNoMiddle(vertexArray* leftChain, 1985f220fa62Smrg Int beginLeftIndex, 1986f220fa62Smrg Int endLeftIndex, 1987f220fa62Smrg gridBoundaryChain* leftGridChain, 1988f220fa62Smrg Int leftGridChainStartIndex, 1989f220fa62Smrg primStream* pStream) 1990f220fa62Smrg{ 1991f220fa62Smrg /*since there is no middle, there is at most one point which is on the 1992f220fa62Smrg *second grid line, there could be multiple points on the first (top) 1993f220fa62Smrg *grid line. 1994f220fa62Smrg */ 1995f220fa62Smrg 1996f220fa62Smrg leftGridChain->leftEndFan(leftGridChainStartIndex+1, pStream); 1997f220fa62Smrg 1998f220fa62Smrg monoTriangulation2(leftGridChain->get_vertex(leftGridChainStartIndex), 1999f220fa62Smrg leftGridChain->get_vertex(leftGridChainStartIndex+1), 2000f220fa62Smrg leftChain, 2001f220fa62Smrg beginLeftIndex, 2002f220fa62Smrg endLeftIndex, 2003f220fa62Smrg 1, //is increase chain. 2004f220fa62Smrg pStream); 2005f220fa62Smrg} 2006f220fa62Smrg 2007f220fa62Smrg 2008f220fa62Smrg 2009f220fa62Smrg/*sampling the left area in between two grid lines. 2010f220fa62Smrg */ 2011f220fa62Smrgvoid sampleLeftOneGridStep(vertexArray* leftChain, 2012f220fa62Smrg Int beginLeftIndex, 2013f220fa62Smrg Int endLeftIndex, 2014f220fa62Smrg gridBoundaryChain* leftGridChain, 2015f220fa62Smrg Int leftGridChainStartIndex, 2016f220fa62Smrg primStream* pStream 2017f220fa62Smrg ) 2018f220fa62Smrg{ 2019f220fa62Smrg if(checkMiddle(leftChain, beginLeftIndex, endLeftIndex, 2020f220fa62Smrg leftGridChain->get_v_value(leftGridChainStartIndex), 2021f220fa62Smrg leftGridChain->get_v_value(leftGridChainStartIndex+1))<0) 2022f220fa62Smrg 2023f220fa62Smrg { 2024f220fa62Smrg 2025f220fa62Smrg sampleLeftOneGridStepNoMiddle(leftChain, beginLeftIndex, endLeftIndex, leftGridChain, leftGridChainStartIndex, pStream); 2026f220fa62Smrg return; 2027f220fa62Smrg } 2028f220fa62Smrg 2029f220fa62Smrg //copy into a polygon 2030f220fa62Smrg { 2031f220fa62Smrg directedLine* poly = NULL; 2032f220fa62Smrg sampledLine* sline; 2033f220fa62Smrg directedLine* dline; 2034f220fa62Smrg gridWrap* grid = leftGridChain->getGrid(); 2035f220fa62Smrg Real vert1[2]; 2036f220fa62Smrg Real vert2[2]; 2037f220fa62Smrg Int i; 2038f220fa62Smrg 2039f220fa62Smrg Int innerInd = leftGridChain->getInnerIndex(leftGridChainStartIndex+1); 2040f220fa62Smrg Int upperInd = leftGridChain->getUlineIndex(leftGridChainStartIndex); 2041f220fa62Smrg Int lowerInd = leftGridChain->getUlineIndex(leftGridChainStartIndex+1); 2042f220fa62Smrg Real upperV = leftGridChain->get_v_value(leftGridChainStartIndex); 2043f220fa62Smrg Real lowerV = leftGridChain->get_v_value(leftGridChainStartIndex+1); 2044f220fa62Smrg 2045f220fa62Smrg //the upper gridline 2046f220fa62Smrg vert1[1] = vert2[1] = upperV; 2047f220fa62Smrg for(i=innerInd; i>upperInd; i--) 2048f220fa62Smrg { 2049f220fa62Smrg vert1[0]=grid->get_u_value(i); 2050f220fa62Smrg vert2[0]=grid->get_u_value(i-1); 2051f220fa62Smrg sline = new sampledLine(vert1, vert2); 2052f220fa62Smrg dline = new directedLine(INCREASING, sline); 2053f220fa62Smrg if(poly == NULL) 2054f220fa62Smrg poly = dline; 2055f220fa62Smrg else 2056f220fa62Smrg poly->insert(dline); 2057f220fa62Smrg } 2058f220fa62Smrg 2059f220fa62Smrg //the edge connecting upper grid with left chain 2060f220fa62Smrg vert1[0] = grid->get_u_value(upperInd); 2061f220fa62Smrg vert1[1] = upperV; 2062f220fa62Smrg sline = new sampledLine(vert1, leftChain->getVertex(beginLeftIndex)); 2063f220fa62Smrg dline = new directedLine(INCREASING, sline); 2064f220fa62Smrg if(poly == NULL) 2065f220fa62Smrg poly = dline; 2066f220fa62Smrg else 2067f220fa62Smrg poly->insert(dline); 2068f220fa62Smrg 2069f220fa62Smrg //the left chain 2070f220fa62Smrg for(i=beginLeftIndex; i<endLeftIndex; i++) 2071f220fa62Smrg { 2072f220fa62Smrg sline = new sampledLine(leftChain->getVertex(i), leftChain->getVertex(i+1)); 2073f220fa62Smrg dline = new directedLine(INCREASING, sline); 2074f220fa62Smrg poly->insert(dline); 2075f220fa62Smrg } 2076f220fa62Smrg 2077f220fa62Smrg //the edge connecting left chain with lower gridline 2078f220fa62Smrg vert2[0] = grid->get_u_value(lowerInd); 2079f220fa62Smrg vert2[1] = lowerV; 2080f220fa62Smrg sline = new sampledLine(leftChain->getVertex(endLeftIndex), vert2); 2081f220fa62Smrg dline = new directedLine(INCREASING, sline); 2082f220fa62Smrg poly->insert(dline); 2083f220fa62Smrg 2084f220fa62Smrg //the lower grid line 2085f220fa62Smrg vert1[1] = vert2[1] = lowerV; 2086f220fa62Smrg for(i=lowerInd; i<innerInd; i++) 2087f220fa62Smrg { 2088f220fa62Smrg vert1[0] = grid->get_u_value(i); 2089f220fa62Smrg vert2[0] = grid->get_u_value(i+1); 2090f220fa62Smrg sline = new sampledLine(vert1, vert2); 2091f220fa62Smrg dline = new directedLine(INCREASING, sline); 2092f220fa62Smrg poly->insert(dline); 2093f220fa62Smrg } 2094f220fa62Smrg 2095f220fa62Smrg //the vertical grid line segement 2096f220fa62Smrg vert1[0]=vert2[0] = grid->get_u_value(innerInd); 2097f220fa62Smrg vert2[1]=upperV; 2098f220fa62Smrg vert1[1]=lowerV; 2099f220fa62Smrg sline=new sampledLine(vert1, vert2); 2100f220fa62Smrg dline=new directedLine(INCREASING, sline); 2101f220fa62Smrg poly->insert(dline); 2102f220fa62Smrg monoTriangulationOpt(poly, pStream); 2103f220fa62Smrg //cleanup 2104f220fa62Smrg poly->deleteSinglePolygonWithSline(); 2105f220fa62Smrg return; 2106f220fa62Smrg } 2107f220fa62Smrg 2108f220fa62Smrg 2109f220fa62Smrg 2110f220fa62Smrg 2111f220fa62Smrg 2112f220fa62Smrg Int i; 2113f220fa62Smrg if(1/*leftGridChain->getUlineIndex(leftGridChainStartIndex) >= 2114f220fa62Smrg leftGridChain->getUlineIndex(leftGridChainStartIndex+1)*/ 2115f220fa62Smrg ) /*the second grid line is beyond the first one to the left*/ 2116f220fa62Smrg { 2117f220fa62Smrg /*find the maximal U-monotone chain 2118f220fa62Smrg * of endLeftIndex, endLeftIndex-1, ..., 2119f220fa62Smrg */ 2120f220fa62Smrg i=endLeftIndex; 2121f220fa62Smrg Real prevU = leftChain->getVertex(i)[0]; 2122f220fa62Smrg for(i=endLeftIndex-1; i>=beginLeftIndex; i--){ 2123f220fa62Smrg Real thisU = leftChain->getVertex(i)[0]; 2124f220fa62Smrg if( prevU < thisU){ 2125f220fa62Smrg prevU = thisU; 2126f220fa62Smrg } 2127f220fa62Smrg else 2128f220fa62Smrg break; 2129f220fa62Smrg } 2130f220fa62Smrg /*from endLeftIndex to i+1 is strictly U- monotone */ 2131f220fa62Smrg /*if i+1==endLeftIndex and the vertex and leftchain is on the second gridline, then 2132f220fa62Smrg *we should use 2 vertices on the leftchain. If we only use one (endLeftIndex), then we 2133f220fa62Smrg *we would output degenerate triangles 2134f220fa62Smrg */ 2135f220fa62Smrg if(i+1 == endLeftIndex && leftChain->getVertex(endLeftIndex)[1] == leftGridChain->get_v_value(1+leftGridChainStartIndex)) 2136f220fa62Smrg i--; 2137f220fa62Smrg 2138f220fa62Smrg Int j = beginLeftIndex/*endLeftIndex*/+1; 2139f220fa62Smrg 2140f220fa62Smrg 2141f220fa62Smrg if(leftGridChain->getInnerIndex(leftGridChainStartIndex+1) > leftGridChain->getUlineIndex(leftGridChainStartIndex)) 2142f220fa62Smrg { 2143f220fa62Smrg j = findIncreaseChainFromBegin(leftChain, beginLeftIndex, i+1/*endLeftIndex*/); 2144f220fa62Smrg 2145f220fa62Smrg Int temp = beginLeftIndex; 2146f220fa62Smrg /*now from begin to j-1 is strictly u-monotone*/ 2147f220fa62Smrg /*if j-1 is on the first grid line, then we want to skip to the vertex which is strictly 2148f220fa62Smrg *below the grid line. This vertexmust exist since there is a 'corner turn' inbetween the two grid lines 2149f220fa62Smrg */ 2150f220fa62Smrg if(j-1 == beginLeftIndex) 2151f220fa62Smrg { 2152f220fa62Smrg while(leftChain->getVertex(j-1)[1] == leftGridChain->get_v_value(leftGridChainStartIndex)) 2153f220fa62Smrg j++; 2154f220fa62Smrg 2155f220fa62Smrg Real vert[2]; 2156f220fa62Smrg vert[0] = leftGridChain->get_u_value(leftGridChainStartIndex); 2157f220fa62Smrg vert[1] = leftGridChain->get_v_value(leftGridChainStartIndex); 2158f220fa62Smrg 2159f220fa62Smrg monoTriangulation2( 2160f220fa62Smrg vert/*leftChain->getVertex(beginLeftIndex)*/, 2161f220fa62Smrg leftChain->getVertex(j-1), 2162f220fa62Smrg leftChain, 2163f220fa62Smrg beginLeftIndex, 2164f220fa62Smrg j-2, 2165f220fa62Smrg 1, 2166f220fa62Smrg pStream //increase chain 2167f220fa62Smrg ); 2168f220fa62Smrg 2169f220fa62Smrg temp = j-1; 2170f220fa62Smrg } 2171f220fa62Smrg 2172f220fa62Smrg stripOfFanLeft(leftChain, j-1, temp/*beginLeftIndex*/, leftGridChain->getGrid(), 2173f220fa62Smrg leftGridChain->getVlineIndex(leftGridChainStartIndex), 2174f220fa62Smrg leftGridChain->getUlineIndex(leftGridChainStartIndex), 2175f220fa62Smrg leftGridChain->getInnerIndex(leftGridChainStartIndex+1), 2176f220fa62Smrg pStream, 2177f220fa62Smrg 1 /*the grid line is above the trim line*/ 2178f220fa62Smrg ); 2179f220fa62Smrg } 2180f220fa62Smrg 2181f220fa62Smrg stripOfFanLeft(leftChain, endLeftIndex, i+1, leftGridChain->getGrid(), 2182f220fa62Smrg leftGridChain->getVlineIndex(leftGridChainStartIndex+1), 2183f220fa62Smrg leftGridChain->getUlineIndex(leftGridChainStartIndex+1), 2184f220fa62Smrg leftGridChain->getInnerIndex(leftGridChainStartIndex+1), 2185f220fa62Smrg pStream, 2186f220fa62Smrg 0 /*the grid line is below the trim lines*/ 2187f220fa62Smrg ); 2188f220fa62Smrg 2189f220fa62Smrg /*monotone triangulate the remaining left chain togther with the 2190f220fa62Smrg *two vertices on the two grid v-lines. 2191f220fa62Smrg */ 2192f220fa62Smrg Real vert[2][2]; 2193f220fa62Smrg vert[0][0]=vert[1][0] = leftGridChain->getInner_u_value(leftGridChainStartIndex+1); 2194f220fa62Smrg vert[0][1] = leftGridChain->get_v_value(leftGridChainStartIndex); 2195f220fa62Smrg vert[1][1] = leftGridChain->get_v_value(leftGridChainStartIndex+1); 2196f220fa62Smrg 2197f220fa62Smrg// vertexArray right(vert, 2); 2198f220fa62Smrg 2199f220fa62Smrg monoTriangulation2( 2200f220fa62Smrg &vert[0][0], /*top vertex */ 2201f220fa62Smrg &vert[1][0], /*bottom vertex*/ 2202f220fa62Smrg leftChain, 2203f220fa62Smrg /*beginLeftIndex*/j-1, 2204f220fa62Smrg i+1, 2205f220fa62Smrg 1, /*an increasing chain*/ 2206f220fa62Smrg pStream); 2207f220fa62Smrg } 2208f220fa62Smrg else /*the second one is shorter than the first one to the left*/ 2209f220fa62Smrg { 2210f220fa62Smrg /*find the maximal U-monotone chain of beginLeftIndex, beginLeftIndex+1,..., 2211f220fa62Smrg */ 2212f220fa62Smrg i=beginLeftIndex; 2213f220fa62Smrg Real prevU = leftChain->getVertex(i)[0]; 2214f220fa62Smrg for(i=beginLeftIndex+1; i<=endLeftIndex; i++){ 2215f220fa62Smrg Real thisU = leftChain->getVertex(i)[0]; 2216f220fa62Smrg 2217f220fa62Smrg if(prevU < thisU){ 2218f220fa62Smrg prevU = thisU; 2219f220fa62Smrg } 2220f220fa62Smrg else 2221f220fa62Smrg break; 2222f220fa62Smrg } 2223f220fa62Smrg /*from beginLeftIndex to i-1 is strictly U-monotone*/ 2224f220fa62Smrg 2225f220fa62Smrg 2226f220fa62Smrg stripOfFanLeft(leftChain, i-1, beginLeftIndex, leftGridChain->getGrid(), 2227f220fa62Smrg leftGridChain->getVlineIndex(leftGridChainStartIndex), 2228f220fa62Smrg leftGridChain->getUlineIndex(leftGridChainStartIndex), 2229f220fa62Smrg leftGridChain->getUlineIndex(leftGridChainStartIndex+1), 2230f220fa62Smrg pStream, 2231f220fa62Smrg 1 /*the grid line is above the trim lines*/ 2232f220fa62Smrg ); 2233f220fa62Smrg /*monotone triangulate the remaining left chain together with the 2234f220fa62Smrg *two vertices on the two grid v-lines. 2235f220fa62Smrg */ 2236f220fa62Smrg Real vert[2][2]; 2237f220fa62Smrg vert[0][0]=vert[1][0] = leftGridChain->get_u_value(leftGridChainStartIndex+1); 2238f220fa62Smrg vert[0][1] = leftGridChain->get_v_value(leftGridChainStartIndex); 2239f220fa62Smrg vert[1][1] = leftGridChain->get_v_value(leftGridChainStartIndex+1); 2240f220fa62Smrg 2241f220fa62Smrg vertexArray right(vert, 2); 2242f220fa62Smrg 2243f220fa62Smrg monoTriangulation2( 2244f220fa62Smrg &vert[0][0], //top vertex 2245f220fa62Smrg &vert[1][0], //bottom vertex 2246f220fa62Smrg leftChain, 2247f220fa62Smrg i-1, 2248f220fa62Smrg endLeftIndex, 2249f220fa62Smrg 1, /*an increase chain*/ 2250f220fa62Smrg pStream); 2251f220fa62Smrg 2252f220fa62Smrg } 2253f220fa62Smrg} 2254f220fa62Smrg 2255f220fa62Smrg/*n_upper>=1 2256f220fa62Smrg *n_lower>=1 2257f220fa62Smrg */ 2258f220fa62Smrgvoid triangulateXYMono(Int n_upper, Real upperVerts[][2], 2259f220fa62Smrg Int n_lower, Real lowerVerts[][2], 2260f220fa62Smrg primStream* pStream) 2261f220fa62Smrg{ 2262f220fa62Smrg Int i,j,k,l; 2263f220fa62Smrg Real* leftMostV; 2264f220fa62Smrg 2265f220fa62Smrg assert(n_upper>=1 && n_lower>=1); 2266f220fa62Smrg if(upperVerts[0][0] <= lowerVerts[0][0]) 2267f220fa62Smrg { 2268f220fa62Smrg i=1; 2269f220fa62Smrg j=0; 2270f220fa62Smrg leftMostV = upperVerts[0]; 2271f220fa62Smrg } 2272f220fa62Smrg else 2273f220fa62Smrg { 2274f220fa62Smrg i=0; 2275f220fa62Smrg j=1; 2276f220fa62Smrg leftMostV = lowerVerts[0]; 2277f220fa62Smrg } 2278f220fa62Smrg 2279f220fa62Smrg while(1) 2280f220fa62Smrg { 2281f220fa62Smrg if(i >= n_upper) /*case1: no more in upper*/ 2282f220fa62Smrg { 2283f220fa62Smrg 2284f220fa62Smrg if(j<n_lower-1) /*at least two vertices in lower*/ 2285f220fa62Smrg { 2286f220fa62Smrg pStream->begin(); 2287f220fa62Smrg pStream->insert(leftMostV); 2288f220fa62Smrg while(j<n_lower){ 2289f220fa62Smrg pStream->insert(lowerVerts[j]); 2290f220fa62Smrg j++; 2291f220fa62Smrg } 2292f220fa62Smrg pStream->end(PRIMITIVE_STREAM_FAN); 2293f220fa62Smrg } 2294f220fa62Smrg 2295f220fa62Smrg break; 2296f220fa62Smrg } 2297f220fa62Smrg else if(j>= n_lower) /*case2: no more in lower*/ 2298f220fa62Smrg { 2299f220fa62Smrg 2300f220fa62Smrg if(i<n_upper-1) /*at least two vertices in upper*/ 2301f220fa62Smrg { 2302f220fa62Smrg pStream->begin(); 2303f220fa62Smrg pStream->insert(leftMostV); 2304f220fa62Smrg 2305f220fa62Smrg for(k=n_upper-1; k>=i; k--) 2306f220fa62Smrg pStream->insert(upperVerts[k]); 2307f220fa62Smrg 2308f220fa62Smrg pStream->end(PRIMITIVE_STREAM_FAN); 2309f220fa62Smrg } 2310f220fa62Smrg 2311f220fa62Smrg break; 2312f220fa62Smrg } 2313f220fa62Smrg else /* case3: neither is empty, plus the leftMostV, there is at least one triangle to output*/ 2314f220fa62Smrg { 2315f220fa62Smrg 2316f220fa62Smrg if(upperVerts[i][0] <= lowerVerts[j][0]) 2317f220fa62Smrg { 2318f220fa62Smrg pStream->begin(); 2319f220fa62Smrg pStream->insert(lowerVerts[j]); /*the origin of this fan*/ 2320f220fa62Smrg 2321f220fa62Smrg /*find the last k>=i such that 2322f220fa62Smrg *upperverts[k][0] <= lowerverts[j][0] 2323f220fa62Smrg */ 2324f220fa62Smrg k=i; 2325f220fa62Smrg while(k<n_upper) 2326f220fa62Smrg { 2327f220fa62Smrg if(upperVerts[k][0] > lowerVerts[j][0]) 2328f220fa62Smrg break; 2329f220fa62Smrg k++; 2330f220fa62Smrg } 2331f220fa62Smrg k--; 2332f220fa62Smrg for(l=k; l>=i; l--)/*the reverse is for two-face lighting*/ 2333f220fa62Smrg { 2334f220fa62Smrg pStream->insert(upperVerts[l]); 2335f220fa62Smrg } 2336f220fa62Smrg pStream->insert(leftMostV); 2337f220fa62Smrg 2338f220fa62Smrg pStream->end(PRIMITIVE_STREAM_FAN); 2339f220fa62Smrg //update i for next loop 2340f220fa62Smrg i = k+1; 2341f220fa62Smrg leftMostV = upperVerts[k]; 2342f220fa62Smrg 2343f220fa62Smrg } 2344f220fa62Smrg else /*upperVerts[i][0] > lowerVerts[j][0]*/ 2345f220fa62Smrg { 2346f220fa62Smrg pStream->begin(); 2347f220fa62Smrg pStream->insert(upperVerts[i]);/*the origion of this fan*/ 2348f220fa62Smrg pStream->insert(leftMostV); 2349f220fa62Smrg /*find the last k>=j such that 2350f220fa62Smrg *lowerverts[k][0] < upperverts[i][0]*/ 2351f220fa62Smrg k=j; 2352f220fa62Smrg while(k< n_lower) 2353f220fa62Smrg { 2354f220fa62Smrg if(lowerVerts[k][0] >= upperVerts[i][0]) 2355f220fa62Smrg break; 2356f220fa62Smrg pStream->insert(lowerVerts[k]); 2357f220fa62Smrg k++; 2358f220fa62Smrg } 2359f220fa62Smrg pStream->end(PRIMITIVE_STREAM_FAN); 2360f220fa62Smrg j=k; 2361f220fa62Smrg leftMostV = lowerVerts[j-1]; 2362f220fa62Smrg } 2363f220fa62Smrg } 2364f220fa62Smrg } 2365f220fa62Smrg} 2366f220fa62Smrg 2367f220fa62Smrg 2368f220fa62Smrgvoid stripOfFanLeft(vertexArray* leftChain, 2369f220fa62Smrg Int largeIndex, 2370f220fa62Smrg Int smallIndex, 2371f220fa62Smrg gridWrap* grid, 2372f220fa62Smrg Int vlineIndex, 2373f220fa62Smrg Int ulineSmallIndex, 2374f220fa62Smrg Int ulineLargeIndex, 2375f220fa62Smrg primStream* pStream, 2376f220fa62Smrg Int gridLineUp /*1 if the grid line is above the trim lines*/ 2377f220fa62Smrg ) 2378f220fa62Smrg{ 2379f220fa62Smrg assert(largeIndex >= smallIndex); 2380f220fa62Smrg 2381f220fa62Smrg Real grid_v_value; 2382f220fa62Smrg grid_v_value = grid->get_v_value(vlineIndex); 2383f220fa62Smrg 2384f220fa62Smrg Real2* trimVerts=(Real2*) malloc(sizeof(Real2)* (largeIndex-smallIndex+1)); 2385f220fa62Smrg assert(trimVerts); 2386f220fa62Smrg 2387f220fa62Smrg 2388f220fa62Smrg Real2* gridVerts=(Real2*) malloc(sizeof(Real2)* (ulineLargeIndex-ulineSmallIndex+1)); 2389f220fa62Smrg assert(gridVerts); 2390f220fa62Smrg 2391f220fa62Smrg Int k,i; 2392f220fa62Smrg if(gridLineUp) /*trim line is below grid line, so trim vertices are going right when index increases*/ 2393f220fa62Smrg for(k=0, i=smallIndex; i<=largeIndex; i++, k++) 2394f220fa62Smrg { 2395f220fa62Smrg trimVerts[k][0] = leftChain->getVertex(i)[0]; 2396f220fa62Smrg trimVerts[k][1] = leftChain->getVertex(i)[1]; 2397f220fa62Smrg } 2398f220fa62Smrg else 2399f220fa62Smrg for(k=0, i=largeIndex; i>=smallIndex; i--, k++) 2400f220fa62Smrg { 2401f220fa62Smrg trimVerts[k][0] = leftChain->getVertex(i)[0]; 2402f220fa62Smrg trimVerts[k][1] = leftChain->getVertex(i)[1]; 2403f220fa62Smrg } 2404f220fa62Smrg 2405f220fa62Smrg for(k=0, i=ulineSmallIndex; i<= ulineLargeIndex; i++, k++) 2406f220fa62Smrg { 2407f220fa62Smrg gridVerts[k][0] = grid->get_u_value(i); 2408f220fa62Smrg gridVerts[k][1] = grid_v_value; 2409f220fa62Smrg } 2410f220fa62Smrg 2411f220fa62Smrg if(gridLineUp) 2412f220fa62Smrg triangulateXYMono( 2413f220fa62Smrg ulineLargeIndex-ulineSmallIndex+1, gridVerts, 2414f220fa62Smrg largeIndex-smallIndex+1, trimVerts, 2415f220fa62Smrg pStream); 2416f220fa62Smrg else 2417f220fa62Smrg triangulateXYMono(largeIndex-smallIndex+1, trimVerts, 2418f220fa62Smrg ulineLargeIndex-ulineSmallIndex+1, gridVerts, 2419f220fa62Smrg pStream); 2420f220fa62Smrg free(trimVerts); 2421f220fa62Smrg free(gridVerts); 2422f220fa62Smrg} 2423f220fa62Smrg 2424f220fa62Smrg 2425f220fa62Smrg 2426f220fa62Smrg 2427f220fa62Smrg 2428