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 <stdlib.h> 39f220fa62Smrg#include <stdio.h> 40f220fa62Smrg#include "gluos.h" 41f220fa62Smrg#include "glimports.h" 42f220fa62Smrg#include "zlassert.h" 43f220fa62Smrg#include "sampleCompRight.h" 44f220fa62Smrg 45f220fa62Smrg#define max(a,b) ((a>b)? a:b) 46f220fa62Smrg#define min(a,b) ((a>b)? b:a) 47f220fa62Smrg 48f220fa62Smrg 49f220fa62Smrg 50f220fa62Smrg#ifdef NOT_TAKEOUT 51f220fa62Smrg 52f220fa62Smrg/*notice that we need leftChain because the 53f220fa62Smrg *corners could be on the leftChain. 54f220fa62Smrg */ 55f220fa62Smrgvoid sampleCompRight(Real* topVertex, Real* botVertex, 56f220fa62Smrg vertexArray* leftChain, 57f220fa62Smrg Int leftStartIndex, Int leftEndIndex, 58f220fa62Smrg vertexArray* rightChain, 59f220fa62Smrg Int rightStartIndex, Int rightEndIndex, 60f220fa62Smrg gridBoundaryChain* rightGridChain, 61f220fa62Smrg Int gridIndex1, Int gridIndex2, 62f220fa62Smrg Int up_rightCornerWhere, 63f220fa62Smrg Int up_rightCornerIndex, 64f220fa62Smrg Int down_rightCornerWhere, 65f220fa62Smrg Int down_rightCornerIndex, 66f220fa62Smrg primStream* pStream) 67f220fa62Smrg{ 68f220fa62Smrg /*find out whether there is a trim vertex which is 69f220fa62Smrg *inbetween the top and bot grid lines or not. 70f220fa62Smrg */ 71f220fa62Smrg Int midIndex1; 72f220fa62Smrg Int midIndex2; 73f220fa62Smrg Int gridMidIndex1 = 0, gridMidIndex2 = 0; 74f220fa62Smrg //midIndex1: array[i] <= v, array[i+1] > v 75f220fa62Smrg //midIndex2: array[i] >= v, array[i+1] < v 76f220fa62Smrg midIndex1 = rightChain->findIndexBelowGen(rightGridChain->get_v_value(gridIndex1), 77f220fa62Smrg rightStartIndex, 78f220fa62Smrg rightEndIndex); 79f220fa62Smrg midIndex2 = -1; //initilization 80f220fa62Smrg if(midIndex1 <= rightEndIndex && gridIndex1 < gridIndex2) 81f220fa62Smrg if(rightChain->getVertex(midIndex1)[1] >= rightGridChain->get_v_value(gridIndex2)) 82f220fa62Smrg { 83f220fa62Smrg //midIndex2 must exist: 84f220fa62Smrg midIndex2 = rightChain->findIndexAboveGen(rightGridChain->get_v_value(gridIndex2), 85f220fa62Smrg midIndex1, //midIndex1<=midIndex2 86f220fa62Smrg rightEndIndex); 87f220fa62Smrg //find gridMidIndex1 so that either it=gridIndex1 when the gridline is 88f220fa62Smrg // at the same height as trim vertex midIndex1, or it is the last one 89f220fa62Smrg //which is strictly above midIndex1. 90f220fa62Smrg { 91f220fa62Smrg Real temp = rightChain->getVertex(midIndex1)[1]; 92f220fa62Smrg if(rightGridChain->get_v_value(gridIndex1) == temp) 93f220fa62Smrg gridMidIndex1 = gridIndex1; 94f220fa62Smrg else 95f220fa62Smrg { 96f220fa62Smrg gridMidIndex1 = gridIndex1; 97f220fa62Smrg while(rightGridChain->get_v_value(gridMidIndex1) > temp) 98f220fa62Smrg gridMidIndex1++; 99f220fa62Smrg gridMidIndex1--; 100f220fa62Smrg } 101f220fa62Smrg }//end of find gridMindIndex1 102f220fa62Smrg //find gridMidIndex2 so that it is the (first one below or equal 103f220fa62Smrg //midIndex) last one above or equal midIndex2 104f220fa62Smrg { 105f220fa62Smrg Real temp = rightChain->getVertex(midIndex2)[1]; 106f220fa62Smrg for(gridMidIndex2 = gridMidIndex1+1; gridMidIndex2 <= gridIndex2; gridMidIndex2++) 107f220fa62Smrg if(rightGridChain->get_v_value(gridMidIndex2) <= temp) 108f220fa62Smrg break; 109f220fa62Smrg 110f220fa62Smrg assert(gridMidIndex2 <= gridIndex2); 111f220fa62Smrg }//end of find gridMidIndex2 112f220fa62Smrg } 113f220fa62Smrg 114f220fa62Smrg 115f220fa62Smrg 116f220fa62Smrg //to interprete the corner information 117f220fa62Smrg Real* cornerTop; 118f220fa62Smrg Real* cornerBot; 119f220fa62Smrg Int cornerRightStart; 120f220fa62Smrg Int cornerRightEnd; 121f220fa62Smrg Int cornerLeftUpEnd; 122f220fa62Smrg Int cornerLeftDownStart; 123f220fa62Smrg if(up_rightCornerWhere == 2) //right corner is on right chain 124f220fa62Smrg { 125f220fa62Smrg cornerTop = rightChain->getVertex(up_rightCornerIndex); 126f220fa62Smrg cornerRightStart = up_rightCornerIndex+1; 127f220fa62Smrg cornerLeftUpEnd = -1; //no left 128f220fa62Smrg } 129f220fa62Smrg else if(up_rightCornerWhere == 1) //right corner is on top 130f220fa62Smrg { 131f220fa62Smrg cornerTop = topVertex; 132f220fa62Smrg cornerRightStart = rightStartIndex; 133f220fa62Smrg cornerLeftUpEnd = -1; //no left 134f220fa62Smrg } 135f220fa62Smrg else //right corner is on left chain 136f220fa62Smrg { 137f220fa62Smrg cornerTop = topVertex; 138f220fa62Smrg cornerRightStart = rightStartIndex; 139f220fa62Smrg cornerLeftUpEnd = up_rightCornerIndex; 140f220fa62Smrg } 141f220fa62Smrg 142f220fa62Smrg if(down_rightCornerWhere == 2) //right corner is on right chan 143f220fa62Smrg { 144f220fa62Smrg cornerBot = rightChain->getVertex(down_rightCornerIndex); 145f220fa62Smrg cornerRightEnd = down_rightCornerIndex-1; 146f220fa62Smrg cornerLeftDownStart = leftEndIndex+1; //no left 147f220fa62Smrg } 148f220fa62Smrg else if (down_rightCornerWhere == 1) //right corner is at bot 149f220fa62Smrg { 150f220fa62Smrg cornerBot = botVertex; 151f220fa62Smrg cornerRightEnd = rightEndIndex; 152f220fa62Smrg cornerLeftDownStart = leftEndIndex+1; //no left 153f220fa62Smrg } 154f220fa62Smrg else //right corner is on the left chain 155f220fa62Smrg { 156f220fa62Smrg cornerBot = botVertex; 157f220fa62Smrg cornerRightEnd = rightEndIndex; 158f220fa62Smrg cornerLeftDownStart = down_rightCornerIndex; 159f220fa62Smrg } 160f220fa62Smrg 161f220fa62Smrg //sample 162f220fa62Smrg if(midIndex2 >= 0) //there is a trm point between grid lines 163f220fa62Smrg { 164f220fa62Smrg 165f220fa62Smrg sampleRightSingleTrimEdgeRegionGen(cornerTop, rightChain->getVertex(midIndex1), 166f220fa62Smrg rightChain, 167f220fa62Smrg cornerRightStart, 168f220fa62Smrg midIndex1-1, 169f220fa62Smrg rightGridChain, 170f220fa62Smrg gridIndex1, 171f220fa62Smrg gridMidIndex1, 172f220fa62Smrg leftChain, 173f220fa62Smrg leftStartIndex, 174f220fa62Smrg cornerLeftUpEnd, 175f220fa62Smrg 0, //no left down section, 176f220fa62Smrg -1, 177f220fa62Smrg pStream); 178f220fa62Smrg 179f220fa62Smrg sampleRightSingleTrimEdgeRegionGen(rightChain->getVertex(midIndex2), 180f220fa62Smrg cornerBot, 181f220fa62Smrg rightChain, 182f220fa62Smrg midIndex2+1, 183f220fa62Smrg cornerRightEnd, 184f220fa62Smrg rightGridChain, 185f220fa62Smrg gridMidIndex2, 186f220fa62Smrg gridIndex2, 187f220fa62Smrg leftChain, 188f220fa62Smrg 0, //no left up section 189f220fa62Smrg -1, 190f220fa62Smrg cornerLeftDownStart, 191f220fa62Smrg leftEndIndex, 192f220fa62Smrg pStream); 193f220fa62Smrg 194f220fa62Smrg sampleRightStripRecF(rightChain, 195f220fa62Smrg midIndex1, 196f220fa62Smrg midIndex2, 197f220fa62Smrg rightGridChain, 198f220fa62Smrg gridMidIndex1, 199f220fa62Smrg gridMidIndex2, 200f220fa62Smrg pStream); 201f220fa62Smrg 202f220fa62Smrg } 203f220fa62Smrg else 204f220fa62Smrg { 205f220fa62Smrg sampleRightSingleTrimEdgeRegionGen(cornerTop, cornerBot, 206f220fa62Smrg rightChain, 207f220fa62Smrg cornerRightStart, 208f220fa62Smrg cornerRightEnd, 209f220fa62Smrg rightGridChain, 210f220fa62Smrg gridIndex1, 211f220fa62Smrg gridIndex2, 212f220fa62Smrg leftChain, 213f220fa62Smrg leftStartIndex, 214f220fa62Smrg cornerLeftUpEnd, 215f220fa62Smrg cornerLeftDownStart, 216f220fa62Smrg leftEndIndex, 217f220fa62Smrg pStream); 218f220fa62Smrg } 219f220fa62Smrg} 220f220fa62Smrg 221f220fa62Smrgvoid sampleRightSingleTrimEdgeRegionGen(Real topVertex[2], Real botVertex[2], 222f220fa62Smrg vertexArray* rightChain, 223f220fa62Smrg Int rightStart, 224f220fa62Smrg Int rightEnd, 225f220fa62Smrg gridBoundaryChain* gridChain, 226f220fa62Smrg Int gridBeginIndex, 227f220fa62Smrg Int gridEndIndex, 228f220fa62Smrg vertexArray* leftChain, 229f220fa62Smrg Int leftUpBegin, 230f220fa62Smrg Int leftUpEnd, 231f220fa62Smrg Int leftDownBegin, 232f220fa62Smrg Int leftDownEnd, 233f220fa62Smrg primStream* pStream) 234f220fa62Smrg{ 235f220fa62Smrg Int i,k; 236f220fa62Smrg /*creat an array to store all the up and down secments of the left chain, 237f220fa62Smrg *and the right end grid points 238f220fa62Smrg * 239f220fa62Smrg *although vertex array is a dynamic array, but to gain efficiency, 240f220fa62Smrg *it is better to initiliza the exact array size 241f220fa62Smrg */ 242f220fa62Smrg vertexArray vArray(gridEndIndex-gridBeginIndex+1 + 243f220fa62Smrg max(0,leftUpEnd - leftUpBegin+1)+ 244f220fa62Smrg max(0,leftDownEnd - leftDownBegin+1)); 245f220fa62Smrg //append the vertices on the up section of the left chain 246f220fa62Smrg for(i=leftUpBegin; i<= leftUpEnd; i++) 247f220fa62Smrg vArray.appendVertex(leftChain->getVertex(i)); 248f220fa62Smrg 249f220fa62Smrg //append the vertices of the right extremal grid points, 250f220fa62Smrg //and at the same time, perform triangulation for the stair cases 251f220fa62Smrg vArray.appendVertex(gridChain->get_vertex(gridBeginIndex)); 252f220fa62Smrg 253f220fa62Smrg for(k=1, i=gridBeginIndex+1; i<= gridEndIndex; i++, k++) 254f220fa62Smrg { 255f220fa62Smrg vArray.appendVertex(gridChain->get_vertex(i)); 256f220fa62Smrg 257f220fa62Smrg //output the fan of the grid points of the (i)th and (i-1)th grid line. 258f220fa62Smrg gridChain->rightEndFan(i, pStream); 259f220fa62Smrg } 260f220fa62Smrg 261f220fa62Smrg //append all the vertices on the down section of the left chain 262f220fa62Smrg for(i=leftDownBegin; i<= leftDownEnd; i++) 263f220fa62Smrg vArray.appendVertex(leftChain->getVertex(i)); 264f220fa62Smrg monoTriangulationRecGen(topVertex, botVertex, 265f220fa62Smrg &vArray, 0, vArray.getNumElements()-1, 266f220fa62Smrg rightChain, rightStart, rightEnd, 267f220fa62Smrg pStream); 268f220fa62Smrg} 269f220fa62Smrg 270f220fa62Smrgvoid sampleRightSingleTrimEdgeRegion(Real upperVert[2], Real lowerVert[2], 271f220fa62Smrg gridBoundaryChain* gridChain, 272f220fa62Smrg Int beginIndex, 273f220fa62Smrg Int endIndex, 274f220fa62Smrg primStream* pStream) 275f220fa62Smrg{ 276f220fa62Smrg Int i,k; 277f220fa62Smrg vertexArray vArray(endIndex-beginIndex+1); 278f220fa62Smrg vArray.appendVertex(gridChain->get_vertex(beginIndex)); 279f220fa62Smrg for(k=1, i=beginIndex+1; i<= endIndex; i++, k++) 280f220fa62Smrg { 281f220fa62Smrg vArray.appendVertex(gridChain->get_vertex(i)); 282f220fa62Smrg //output the fan of the grid points of the (i)_th and i-1th gridLine 283f220fa62Smrg gridChain->rightEndFan(i, pStream); 284f220fa62Smrg } 285f220fa62Smrg monoTriangulation2(upperVert, lowerVert, &vArray, 0, endIndex-beginIndex, 286f220fa62Smrg 1, //increase chain (to the left) 287f220fa62Smrg pStream); 288f220fa62Smrg} 289f220fa62Smrg 290f220fa62Smrg 291f220fa62Smrg/*the gridlines from rightGridChainStartIndex to 292f220fa62Smrg *rightGridChainEndIndex are assumed to form a 293f220fa62Smrg *connected componenet 294f220fa62Smrg *the trm vertex of topRightIndex is assumed to be below 295f220fa62Smrg *or equal the first gridLine, and the trm vertex of 296f220fa62Smrg *botRightIndex is assumed to be above or equal the last gridline 297f220fa62Smrg **there could be multipe trm vertices equal to the last gridline, but 298f220fa62Smrg **only one could be equal to top gridline. shape: ____| (recall that 299f220fa62Smrg **for left chain recF, we allow shape: |---- 300f220fa62Smrg *if botRightIndex<topRightIndex, then no connected componenet exists, and 301f220fa62Smrg *no triangles are generated. 302f220fa62Smrg *Othewise, botRightIndex>= topRightIndex, there is at least one triangles to 303f220fa62Smrg *output 304f220fa62Smrg */ 305f220fa62Smrgvoid sampleRightStripRecF(vertexArray* rightChain, 306f220fa62Smrg Int topRightIndex, 307f220fa62Smrg Int botRightIndex, 308f220fa62Smrg gridBoundaryChain* rightGridChain, 309f220fa62Smrg Int rightGridChainStartIndex, 310f220fa62Smrg Int rightGridChainEndIndex, 311f220fa62Smrg primStream* pStream 312f220fa62Smrg ) 313f220fa62Smrg{ 314f220fa62Smrg 315f220fa62Smrg //sstop conditionL: if topRightIndex > botRightIndex, then stop 316f220fa62Smrg if(topRightIndex > botRightIndex) 317f220fa62Smrg return; 318f220fa62Smrg 319f220fa62Smrg //if there is only one grid line, return 320f220fa62Smrg if(rightGridChainStartIndex >= rightGridChainEndIndex) 321f220fa62Smrg return; 322f220fa62Smrg 323f220fa62Smrg 324f220fa62Smrg assert(rightChain->getVertex(topRightIndex)[1] <= rightGridChain->get_v_value(rightGridChainStartIndex) && 325f220fa62Smrg rightChain->getVertex(botRightIndex)[1] >= rightGridChain->get_v_value(rightGridChainEndIndex)); 326f220fa62Smrg 327f220fa62Smrg //firstfind the first trim vertex which is strictly below the second top 328f220fa62Smrg //grid line: index1. 329f220fa62Smrg Real secondGridChainV = rightGridChain->get_v_value(rightGridChainStartIndex+1); 330f220fa62Smrg Int index1 = topRightIndex; 331f220fa62Smrg while(rightChain->getVertex(index1)[1] >= secondGridChainV){ 332f220fa62Smrg index1++; 333f220fa62Smrg if(index1 > botRightIndex) 334f220fa62Smrg break; 335f220fa62Smrg } 336f220fa62Smrg //now rightChain->getVertex(index1-1)[1] >= secondGridChainV and 337f220fa62Smrg //rightChain->getVertex(index1)[1] < secondGridChainV and 338f220fa62Smrg //we should include index1-1 to perform a gridStep 339f220fa62Smrg index1--; 340f220fa62Smrg 341f220fa62Smrg //now we have rightChain->getVertex(index1)[1] >= secondGridChainV, and 342f220fa62Smrg //rightChain->getVertex(index1+1)[1] < secondGridChainV 343f220fa62Smrg sampleRightOneGridStep(rightChain, topRightIndex, index1, rightGridChain, rightGridChainStartIndex, pStream); 344f220fa62Smrg 345f220fa62Smrg //if rightChain->getVertex(index1)[1] ==secondGridChainV then we can 346f220fa62Smrg //recurvesively to the rest 347f220fa62Smrg if(rightChain->getVertex(index1)[1] == secondGridChainV) 348f220fa62Smrg { 349f220fa62Smrg 350f220fa62Smrg 351f220fa62Smrg sampleRightStripRecF(rightChain, index1, botRightIndex, rightGridChain, rightGridChainStartIndex+1, rightGridChainEndIndex, pStream); 352f220fa62Smrg } 353f220fa62Smrg else if(index1 < botRightIndex) 354f220fa62Smrg { 355f220fa62Smrg //otherwise, we have rightChain->getVertex(index1)[1] > secondV 356f220fa62Smrg //let the next trim vertex be nextTrimVertex, (which should be strictly 357f220fa62Smrg //below the second grid line). Find the last grid line index2 which is STRICTLY ABOVE 358f220fa62Smrg //nextTrimVertex. 359f220fa62Smrg //sample one trm edge region. 360f220fa62Smrg Real *uppervert, *lowervert; 361f220fa62Smrg uppervert = rightChain->getVertex(index1); 362f220fa62Smrg lowervert = rightChain->getVertex(index1+1); //okay since index1<botRightindex 363f220fa62Smrg Int index2 = rightGridChainStartIndex+1; 364f220fa62Smrg while(rightGridChain->get_v_value(index2) > lowervert[1]) 365f220fa62Smrg { 366f220fa62Smrg index2++; 367f220fa62Smrg if(index2 > rightGridChainEndIndex) 368f220fa62Smrg break; 369f220fa62Smrg } 370f220fa62Smrg index2--; 371f220fa62Smrg 372f220fa62Smrg sampleRightSingleTrimEdgeRegion(uppervert, lowervert, rightGridChain, rightGridChainStartIndex+1, index2, pStream); 373f220fa62Smrg 374f220fa62Smrg //recursion 375f220fa62Smrg sampleRightStripRecF(rightChain, index1+1, botRightIndex, rightGridChain, index2, rightGridChainEndIndex, pStream); 376f220fa62Smrg } 377f220fa62Smrg} 378f220fa62Smrg 379f220fa62Smrg//the degenerate case of sampleRightOneGridStep 380f220fa62Smrgvoid sampleRightOneGridStepNoMiddle(vertexArray* rightChain, 381f220fa62Smrg Int beginRightIndex, 382f220fa62Smrg Int endRightIndex, 383f220fa62Smrg gridBoundaryChain* rightGridChain, 384f220fa62Smrg Int rightGridChainStartIndex, 385f220fa62Smrg primStream* pStream) 386f220fa62Smrg{ 387f220fa62Smrg /*since there is no middle, there is at most one point which is on the 388f220fa62Smrg *second grid line, there could be multiple points on the first (top) 389f220fa62Smrg *grid line. 390f220fa62Smrg */ 391f220fa62Smrg rightGridChain->rightEndFan(rightGridChainStartIndex+1, pStream); 392f220fa62Smrg monoTriangulation2(rightGridChain->get_vertex(rightGridChainStartIndex), 393f220fa62Smrg rightGridChain->get_vertex(rightGridChainStartIndex+1), 394f220fa62Smrg rightChain, 395f220fa62Smrg beginRightIndex, 396f220fa62Smrg endRightIndex, 397f220fa62Smrg 0, //decrease chain 398f220fa62Smrg pStream); 399f220fa62Smrg} 400f220fa62Smrg 401f220fa62Smrg//sampling the right area in between two grid lines 402f220fa62Smrg//shape: _________| 403f220fa62Smrgvoid sampleRightOneGridStep(vertexArray* rightChain, 404f220fa62Smrg Int beginRightIndex, 405f220fa62Smrg Int endRightIndex, 406f220fa62Smrg gridBoundaryChain* rightGridChain, 407f220fa62Smrg Int rightGridChainStartIndex, 408f220fa62Smrg primStream* pStream) 409f220fa62Smrg{ 410f220fa62Smrg if(checkMiddle(rightChain, beginRightIndex, endRightIndex, 411f220fa62Smrg rightGridChain->get_v_value(rightGridChainStartIndex), 412f220fa62Smrg rightGridChain->get_v_value(rightGridChainStartIndex+1))<0) 413f220fa62Smrg { 414f220fa62Smrg sampleRightOneGridStepNoMiddle(rightChain, beginRightIndex, endRightIndex, rightGridChain, rightGridChainStartIndex, pStream); 415f220fa62Smrg return; 416f220fa62Smrg } 417f220fa62Smrg 418f220fa62Smrg //copy into a polygn 419f220fa62Smrg { 420f220fa62Smrg directedLine* poly = NULL; 421f220fa62Smrg sampledLine* sline; 422f220fa62Smrg directedLine* dline; 423f220fa62Smrg gridWrap* grid = rightGridChain->getGrid(); 424f220fa62Smrg float vert1[2]; 425f220fa62Smrg float vert2[2]; 426f220fa62Smrg Int i; 427f220fa62Smrg 428f220fa62Smrg Int innerInd = rightGridChain->getInnerIndex(rightGridChainStartIndex+1); 429f220fa62Smrg Int upperInd = rightGridChain->getUlineIndex(rightGridChainStartIndex); 430f220fa62Smrg Int lowerInd = rightGridChain->getUlineIndex(rightGridChainStartIndex+1); 431f220fa62Smrg Real upperV = rightGridChain->get_v_value(rightGridChainStartIndex); 432f220fa62Smrg Real lowerV = rightGridChain->get_v_value(rightGridChainStartIndex+1); 433f220fa62Smrg 434f220fa62Smrg //the upper gridline 435f220fa62Smrg vert1[1]=vert2[1]=upperV; 436f220fa62Smrg for(i=upperInd; 437f220fa62Smrg i>innerInd; 438f220fa62Smrg i--) 439f220fa62Smrg { 440f220fa62Smrg vert1[0]=grid->get_u_value(i); 441f220fa62Smrg vert2[0]=grid->get_u_value(i-1); 442f220fa62Smrg sline = new sampledLine(vert1, vert2); 443f220fa62Smrg dline = new directedLine(INCREASING, sline); 444f220fa62Smrg if(poly == NULL) 445f220fa62Smrg poly = dline; 446f220fa62Smrg else 447f220fa62Smrg poly->insert(dline); 448f220fa62Smrg } 449f220fa62Smrg 450f220fa62Smrg //the vertical grid line segment 451f220fa62Smrg vert1[0]=vert2[0] = grid->get_u_value(innerInd); 452f220fa62Smrg vert1[1]=upperV; 453f220fa62Smrg vert2[1]=lowerV; 454f220fa62Smrg sline=new sampledLine(vert1, vert2); 455f220fa62Smrg dline=new directedLine(INCREASING, sline); 456f220fa62Smrg if(poly == NULL) 457f220fa62Smrg poly = dline; 458f220fa62Smrg else 459f220fa62Smrg poly->insert(dline); 460f220fa62Smrg 461f220fa62Smrg //the lower grid line 462f220fa62Smrg vert1[1]=vert2[1]=lowerV; 463f220fa62Smrg for(i=innerInd; i<lowerInd; i++) 464f220fa62Smrg { 465f220fa62Smrg vert1[0] = grid->get_u_value(i); 466f220fa62Smrg vert2[0] = grid->get_u_value(i+1); 467f220fa62Smrg sline = new sampledLine(vert1, vert2); 468f220fa62Smrg dline = new directedLine(INCREASING, sline); 469f220fa62Smrg poly->insert(dline); 470f220fa62Smrg } 471f220fa62Smrg 472f220fa62Smrg //the edge connecting lower grid to right chain 473f220fa62Smrg vert1[0]=grid->get_u_value(lowerInd); 474f220fa62Smrg sline = new sampledLine(vert1, rightChain->getVertex(endRightIndex)); 475f220fa62Smrg dline = new directedLine(INCREASING, sline); 476f220fa62Smrg poly->insert(dline); 477f220fa62Smrg 478f220fa62Smrg 479f220fa62Smrg //the right Chain 480f220fa62Smrg for(i=endRightIndex; i>beginRightIndex; i--) 481f220fa62Smrg { 482f220fa62Smrg sline = new sampledLine(rightChain->getVertex(i), rightChain->getVertex(i-1)); 483f220fa62Smrg dline = new directedLine(INCREASING, sline); 484f220fa62Smrg poly->insert(dline); 485f220fa62Smrg } 486f220fa62Smrg 487f220fa62Smrg //the edge connecting right chain with upper grid 488f220fa62Smrg vert2[1]=upperV; 489f220fa62Smrg vert2[0]=grid->get_u_value(upperInd); 490f220fa62Smrg sline = new sampledLine(rightChain->getVertex(beginRightIndex), vert2); 491f220fa62Smrg dline = new directedLine(INCREASING, sline); 492f220fa62Smrg poly->insert(dline); 493f220fa62Smrg monoTriangulationOpt(poly, pStream); 494f220fa62Smrg //clean up 495f220fa62Smrg poly->deleteSinglePolygonWithSline(); 496f220fa62Smrg 497f220fa62Smrg return; 498f220fa62Smrg } 499f220fa62Smrg 500f220fa62Smrg //this following code cannot be reached, but leave it for debuggig purpose. 501f220fa62Smrg Int i; 502f220fa62Smrg //find the maximal U-monotone chain of beginRightIndex, beginRightIndex+1,... 503f220fa62Smrg i=beginRightIndex; 504f220fa62Smrg Real prevU = rightChain->getVertex(i)[0]; 505f220fa62Smrg for(i=beginRightIndex+1; i<= endRightIndex; i++){ 506f220fa62Smrg Real thisU = rightChain->getVertex(i)[0]; 507f220fa62Smrg if(thisU < prevU) 508f220fa62Smrg prevU = thisU; 509f220fa62Smrg else 510f220fa62Smrg break; 511f220fa62Smrg } 512f220fa62Smrg //from beginRightIndex to i-1 is strictly U-monotne 513f220fa62Smrg //if(i-1==beginRightIndex and the vertex of rightchain is on the first 514f220fa62Smrg //gridline, then we should use 2 vertices on the right chain. Of we only 515f220fa62Smrg //use one (begin), we would output degenrate triangles. 516f220fa62Smrg if(i-1 == beginRightIndex && rightChain->getVertex(beginRightIndex)[1] == rightGridChain->get_v_value(rightGridChainStartIndex)) 517f220fa62Smrg i++; 518f220fa62Smrg 519f220fa62Smrg Int j = endRightIndex -1; 520f220fa62Smrg if(rightGridChain->getInnerIndex(rightGridChainStartIndex+1) < rightGridChain->getUlineIndex(rightGridChainStartIndex+1)) 521f220fa62Smrg { 522f220fa62Smrg j = rightChain->findDecreaseChainFromEnd(i-1/*beginRightIndex*/, endRightIndex); 523f220fa62Smrg Int temp = endRightIndex; 524f220fa62Smrg //now from j+1 to end is strictly U-monotone. 525f220fa62Smrg //if j+1 is on the last grid line, then we wat to skip to the vertex 526f220fa62Smrg //whcih is strictly above the second grid line. This vertex must exist 527f220fa62Smrg //since there is a middle vertex 528f220fa62Smrg if(j+1 == endRightIndex) 529f220fa62Smrg { 530f220fa62Smrg while(rightChain->getVertex(j+1)[1] == rightGridChain->get_v_value(rightGridChainStartIndex+1)) 531f220fa62Smrg j--; 532f220fa62Smrg 533f220fa62Smrg monoTriangulation2(rightChain->getVertex(j+1), 534f220fa62Smrg rightGridChain->get_vertex(rightGridChainStartIndex+1), 535f220fa62Smrg rightChain, 536f220fa62Smrg j+2, 537f220fa62Smrg endRightIndex, 538f220fa62Smrg 0, //a decrease chain 539f220fa62Smrg pStream); 540f220fa62Smrg 541f220fa62Smrg temp = j+1; 542f220fa62Smrg } 543f220fa62Smrg 544f220fa62Smrg stripOfFanRight(rightChain, temp, j+1, rightGridChain->getGrid(), 545f220fa62Smrg rightGridChain->getVlineIndex(rightGridChainStartIndex+1), 546f220fa62Smrg rightGridChain->getInnerIndex(rightGridChainStartIndex+1), 547f220fa62Smrg rightGridChain->getUlineIndex(rightGridChainStartIndex+1), 548f220fa62Smrg pStream, 549f220fa62Smrg 0 //the grid line is below the trim line 550f220fa62Smrg ); 551f220fa62Smrg 552f220fa62Smrg } 553f220fa62Smrg 554f220fa62Smrg 555f220fa62Smrg stripOfFanRight(rightChain, i-1, beginRightIndex, rightGridChain->getGrid(), 556f220fa62Smrg rightGridChain->getVlineIndex(rightGridChainStartIndex), 557f220fa62Smrg rightGridChain->getInnerIndex(rightGridChainStartIndex+1), 558f220fa62Smrg rightGridChain->getUlineIndex(rightGridChainStartIndex), 559f220fa62Smrg pStream, 560f220fa62Smrg 1 //the grid line is above the trm lines 561f220fa62Smrg ); 562f220fa62Smrg 563f220fa62Smrg //monotone triangulate the remaining rightchain together with the 564f220fa62Smrg //two vertices on the two grid v-lines 565f220fa62Smrg Real vert[2][2]; 566f220fa62Smrg vert[0][0] = vert[1][0] = rightGridChain->getInner_u_value(rightGridChainStartIndex+1); 567f220fa62Smrg vert[0][1] = rightGridChain->get_v_value(rightGridChainStartIndex); 568f220fa62Smrg vert[1][1] = rightGridChain->get_v_value(rightGridChainStartIndex+1); 569f220fa62Smrg 570f220fa62Smrg monoTriangulation2(&vert[0][0], 571f220fa62Smrg &vert[1][0], 572f220fa62Smrg rightChain, 573f220fa62Smrg i-1, 574f220fa62Smrg j+1, 575f220fa62Smrg 0, ///a decreae chain 576f220fa62Smrg pStream); 577f220fa62Smrg} 578f220fa62Smrg 579f220fa62Smrg#endif 580f220fa62Smrg 581f220fa62Smrgvoid stripOfFanRight(vertexArray* rightChain, 582f220fa62Smrg Int largeIndex, 583f220fa62Smrg Int smallIndex, 584f220fa62Smrg gridWrap* grid, 585f220fa62Smrg Int vlineIndex, 586f220fa62Smrg Int ulineSmallIndex, 587f220fa62Smrg Int ulineLargeIndex, 588f220fa62Smrg primStream* pStream, 589f220fa62Smrg Int gridLineUp /*1 if the grid line is above the trim lines*/ 590f220fa62Smrg ) 591f220fa62Smrg{ 592f220fa62Smrg assert(largeIndex >= smallIndex); 593f220fa62Smrg 594f220fa62Smrg Real grid_v_value; 595f220fa62Smrg grid_v_value = grid->get_v_value(vlineIndex); 596f220fa62Smrg 597f220fa62Smrg Real2* trimVerts=(Real2*) malloc(sizeof(Real2)* (largeIndex-smallIndex+1)); 598f220fa62Smrg assert(trimVerts); 599f220fa62Smrg 600f220fa62Smrg 601f220fa62Smrg Real2* gridVerts=(Real2*) malloc(sizeof(Real2)* (ulineLargeIndex-ulineSmallIndex+1)); 602f220fa62Smrg assert(gridVerts); 603f220fa62Smrg 604f220fa62Smrg Int k,i; 605f220fa62Smrg if(! gridLineUp) /*trim line is above grid line, so trim vertices are going right when index increases*/ 606f220fa62Smrg for(k=0, i=smallIndex; i<=largeIndex; i++, k++) 607f220fa62Smrg { 608f220fa62Smrg trimVerts[k][0] = rightChain->getVertex(i)[0]; 609f220fa62Smrg trimVerts[k][1] = rightChain->getVertex(i)[1]; 610f220fa62Smrg } 611f220fa62Smrg else 612f220fa62Smrg for(k=0, i=largeIndex; i>=smallIndex; i--, k++) 613f220fa62Smrg { 614f220fa62Smrg trimVerts[k][0] = rightChain->getVertex(i)[0]; 615f220fa62Smrg trimVerts[k][1] = rightChain->getVertex(i)[1]; 616f220fa62Smrg } 617f220fa62Smrg 618f220fa62Smrg for(k=0, i=ulineSmallIndex; i<= ulineLargeIndex; i++, k++) 619f220fa62Smrg { 620f220fa62Smrg gridVerts[k][0] = grid->get_u_value(i); 621f220fa62Smrg gridVerts[k][1] = grid_v_value; 622f220fa62Smrg } 623f220fa62Smrg 624f220fa62Smrg if(gridLineUp) 625f220fa62Smrg triangulateXYMono( 626f220fa62Smrg ulineLargeIndex-ulineSmallIndex+1, gridVerts, 627f220fa62Smrg largeIndex-smallIndex+1, trimVerts, 628f220fa62Smrg pStream); 629f220fa62Smrg else 630f220fa62Smrg triangulateXYMono(largeIndex-smallIndex+1, trimVerts, 631f220fa62Smrg ulineLargeIndex-ulineSmallIndex+1, gridVerts, 632f220fa62Smrg pStream); 633f220fa62Smrg free(trimVerts); 634f220fa62Smrg free(gridVerts); 635f220fa62Smrg} 636f220fa62Smrg 637f220fa62Smrg 638f220fa62Smrg 639f220fa62Smrg 640f220fa62Smrg 641f220fa62Smrg 642f220fa62Smrg 643f220fa62Smrg 644f220fa62Smrg 645