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