Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > DoxygensampleCompTop.cc
Go to the documentation of this file.
00001 /* 00002 ** License Applicability. Except to the extent portions of this file are 00003 ** made subject to an alternative license as permitted in the SGI Free 00004 ** Software License B, Version 1.1 (the "License"), the contents of this 00005 ** file are subject only to the provisions of the License. You may not use 00006 ** this file except in compliance with the License. You may obtain a copy 00007 ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 00008 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: 00009 ** 00010 ** http://oss.sgi.com/projects/FreeB 00011 ** 00012 ** Note that, as provided in the License, the Software is distributed on an 00013 ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS 00014 ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND 00015 ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A 00016 ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. 00017 ** 00018 ** Original Code. The Original Code is: OpenGL Sample Implementation, 00019 ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, 00020 ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. 00021 ** Copyright in any portions created by third parties is as indicated 00022 ** elsewhere herein. All Rights Reserved. 00023 ** 00024 ** Additional Notice Provisions: The application programming interfaces 00025 ** established by SGI in conjunction with the Original Code are The 00026 ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released 00027 ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version 00028 ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X 00029 ** Window System(R) (Version 1.3), released October 19, 1998. This software 00030 ** was created using the OpenGL(R) version 1.2.1 Sample Implementation 00031 ** published by SGI, but has not been independently verified as being 00032 ** compliant with the OpenGL(R) version 1.2.1 Specification. 00033 ** 00034 ** $Date: 2006-03-12 00:07:02 +0000 (Sun, 12 Mar 2006) $ $Revision: 1.1 $ 00035 */ 00036 /* 00037 ** $Header: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/glu32/libnurbs/nurbtess/sampleCompTop.cc,v 1.1 2004/02/02 16:39:14 navaraf Exp $ 00038 */ 00039 00040 #include <stdlib.h> 00041 #include <stdio.h> 00042 #include <math.h> 00043 #include "zlassert.h" 00044 #include "sampleCompTop.h" 00045 #include "sampleCompRight.h" 00046 00047 #define max(a,b) ((a>b)? a:b) 00048 00049 //return : index_small, and index_large, 00050 //from [small, large] is strictly U-monotne, 00051 //from [large+1, end] is <u 00052 //and vertex[large][0] is >= u 00053 //if eveybody is <u, the large = start-1. 00054 //otherwise both large and small are meaningful and we have start<=small<=large<=end 00055 void findTopLeftSegment(vertexArray* leftChain, 00056 Int leftStart, 00057 Int leftEnd, 00058 Real u, 00059 Int& ret_index_small, 00060 Int& ret_index_large 00061 ) 00062 { 00063 Int i; 00064 assert(leftStart <= leftEnd); 00065 for(i=leftEnd; i>= leftStart; i--) 00066 { 00067 if(leftChain->getVertex(i)[0] >= u) 00068 break; 00069 } 00070 ret_index_large = i; 00071 if(ret_index_large >= leftStart) 00072 { 00073 for(i=ret_index_large; i>leftStart; i--) 00074 { 00075 if(leftChain->getVertex(i-1)[0] <= leftChain->getVertex(i)[0]) 00076 break; 00077 } 00078 ret_index_small = i; 00079 } 00080 } 00081 00082 void findTopRightSegment(vertexArray* rightChain, 00083 Int rightStart, 00084 Int rightEnd, 00085 Real u, 00086 Int& ret_index_small, 00087 Int& ret_index_large) 00088 { 00089 Int i; 00090 assert(rightStart<=rightEnd); 00091 for(i=rightEnd; i>=rightStart; i--) 00092 { 00093 if(rightChain->getVertex(i)[0] <= u) 00094 break; 00095 } 00096 ret_index_large = i; 00097 if(ret_index_large >= rightStart) 00098 { 00099 for(i=ret_index_large; i>rightStart;i--) 00100 { 00101 if(rightChain->getVertex(i-1)[0] >= rightChain->getVertex(i)[0]) 00102 break; 00103 } 00104 ret_index_small = i; 00105 } 00106 } 00107 00108 00109 void sampleTopRightWithGridLinePost(Real* topVertex, 00110 vertexArray* rightChain, 00111 Int rightStart, 00112 Int segIndexSmall, 00113 Int segIndexLarge, 00114 Int rightEnd, 00115 gridWrap* grid, 00116 Int gridV, 00117 Int leftU, 00118 Int rightU, 00119 primStream* pStream) 00120 { 00121 //the possible section which is to the right of rightU 00122 if(segIndexLarge < rightEnd) 00123 { 00124 Real *tempTop; 00125 if(segIndexLarge >= rightStart) 00126 tempTop = rightChain->getVertex(segIndexLarge); 00127 else 00128 tempTop = topVertex; 00129 Real tempBot[2]; 00130 tempBot[0] = grid->get_u_value(rightU); 00131 tempBot[1] = grid->get_v_value(gridV); 00132 monoTriangulationRecGenOpt(tempTop, tempBot, 00133 NULL, 1,0, 00134 rightChain, segIndexLarge+1, rightEnd, 00135 pStream); 00136 /* 00137 monoTriangulation2(tempTop, tempBot, 00138 rightChain, 00139 segIndexLarge+1, 00140 rightEnd, 00141 0, //a decrease chian 00142 pStream); 00143 */ 00144 00145 } 00146 00147 //the possible section which is strictly Umonotone 00148 if(segIndexLarge >= rightStart) 00149 { 00150 stripOfFanRight(rightChain, segIndexLarge, segIndexSmall, grid, gridV, leftU, rightU, pStream, 0); 00151 Real tempBot[2]; 00152 tempBot[0] = grid->get_u_value(leftU); 00153 tempBot[1] = grid->get_v_value(gridV); 00154 monoTriangulation2(topVertex, tempBot, rightChain, rightStart, segIndexSmall, 0, pStream); 00155 } 00156 else //the topVertex forms a fan with the grid points 00157 grid->outputFanWithPoint(gridV, leftU, rightU, topVertex, pStream); 00158 } 00159 00160 void sampleTopRightWithGridLine(Real* topVertex, 00161 vertexArray* rightChain, 00162 Int rightStart, 00163 Int rightEnd, 00164 gridWrap* grid, 00165 Int gridV, 00166 Int leftU, 00167 Int rightU, 00168 primStream* pStream 00169 ) 00170 { 00171 //if right chian is empty, then there is only one topVertex with one grid line 00172 if(rightEnd < rightStart){ 00173 grid->outputFanWithPoint(gridV, leftU, rightU, topVertex, pStream); 00174 return; 00175 } 00176 00177 Int segIndexSmall, segIndexLarge; 00178 findTopRightSegment(rightChain, 00179 rightStart, 00180 rightEnd, 00181 grid->get_u_value(rightU), 00182 segIndexSmall, 00183 segIndexLarge 00184 ); 00185 sampleTopRightWithGridLinePost(topVertex, rightChain, 00186 rightStart, 00187 segIndexSmall, 00188 segIndexLarge, 00189 rightEnd, 00190 grid, 00191 gridV, 00192 leftU, 00193 rightU, 00194 pStream); 00195 } 00196 00197 00198 void sampleTopLeftWithGridLinePost(Real* topVertex, 00199 vertexArray* leftChain, 00200 Int leftStart, 00201 Int segIndexSmall, 00202 Int segIndexLarge, 00203 Int leftEnd, 00204 gridWrap* grid, 00205 Int gridV, 00206 Int leftU, 00207 Int rightU, 00208 primStream* pStream) 00209 { 00210 //the possible section which is to the left of leftU 00211 00212 if(segIndexLarge < leftEnd) 00213 { 00214 Real *tempTop; 00215 if(segIndexLarge >= leftStart) 00216 tempTop = leftChain->getVertex(segIndexLarge); 00217 else 00218 tempTop = topVertex; 00219 Real tempBot[2]; 00220 tempBot[0] = grid->get_u_value(leftU); 00221 tempBot[1] = grid->get_v_value(gridV); 00222 00223 monoTriangulation2(tempTop, tempBot, 00224 leftChain, 00225 segIndexLarge+1, 00226 leftEnd, 00227 1, //a increase chian 00228 pStream); 00229 } 00230 00231 //the possible section which is strictly Umonotone 00232 if(segIndexLarge >= leftStart) 00233 { 00234 //if there are grid points which are to the right of topV, 00235 //then we should use topVertex to form a fan with these points to 00236 //optimize the triangualtion 00237 int do_optimize=1; 00238 if(topVertex[0] >= grid->get_u_value(rightU)) 00239 do_optimize = 0; 00240 else 00241 { 00242 //we also have to make sure that topVertex are the right most vertex 00243 //on the chain. 00244 int i; 00245 for(i=leftStart; i<=segIndexSmall; i++) 00246 if(leftChain->getVertex(i)[0] >= topVertex[0]) 00247 { 00248 do_optimize = 0; 00249 break; 00250 } 00251 } 00252 00253 if(do_optimize) 00254 { 00255 //find midU so that grid->get_u_value(midU) >= topVertex[0] 00256 //and grid->get_u_value(midU-1) < topVertex[0] 00257 int midU=rightU; 00258 while(grid->get_u_value(midU) >= topVertex[0]) 00259 { 00260 midU--; 00261 if(midU < leftU) 00262 break; 00263 } 00264 midU++; 00265 00266 grid->outputFanWithPoint(gridV, midU, rightU, topVertex, pStream); 00267 stripOfFanLeft(leftChain, segIndexLarge, segIndexSmall, grid, gridV, leftU, midU, pStream, 0); 00268 Real tempBot[2]; 00269 tempBot[0] = grid->get_u_value(midU); 00270 tempBot[1] = grid->get_v_value(gridV); 00271 monoTriangulation2(topVertex, tempBot, leftChain, leftStart, segIndexSmall, 1, pStream); 00272 } 00273 else //not optimize 00274 { 00275 00276 stripOfFanLeft(leftChain, segIndexLarge, segIndexSmall, grid, gridV, leftU, rightU, pStream, 0); 00277 Real tempBot[2]; 00278 tempBot[0] = grid->get_u_value(rightU); 00279 tempBot[1] = grid->get_v_value(gridV); 00280 monoTriangulation2(topVertex, tempBot, leftChain, leftStart, segIndexSmall, 1, pStream); 00281 } 00282 } 00283 else //the topVertex forms a fan with the grid points 00284 grid->outputFanWithPoint(gridV, leftU, rightU, topVertex, pStream); 00285 } 00286 00287 00288 void sampleTopLeftWithGridLine(Real* topVertex, 00289 vertexArray* leftChain, 00290 Int leftStart, 00291 Int leftEnd, 00292 gridWrap* grid, 00293 Int gridV, 00294 Int leftU, 00295 Int rightU, 00296 primStream* pStream 00297 ) 00298 { 00299 Int segIndexSmall, segIndexLarge; 00300 //if left chain is empty, then there is only one top vertex with one grid 00301 // line 00302 if(leftEnd < leftStart) { 00303 grid->outputFanWithPoint(gridV, leftU, rightU, topVertex, pStream); 00304 return; 00305 } 00306 findTopLeftSegment(leftChain, 00307 leftStart, 00308 leftEnd, 00309 grid->get_u_value(leftU), 00310 segIndexSmall, 00311 segIndexLarge 00312 ); 00313 sampleTopLeftWithGridLinePost(topVertex, 00314 leftChain, 00315 leftStart, 00316 segIndexSmall, 00317 segIndexLarge, 00318 leftEnd, 00319 grid, 00320 gridV, 00321 leftU, 00322 rightU, 00323 pStream); 00324 } 00325 00326 00327 //return 1 if saprator exits, 0 otherwise 00328 Int findTopSeparator(vertexArray* leftChain, 00329 Int leftStartIndex, 00330 Int leftEndIndex, 00331 vertexArray* rightChain, 00332 Int rightStartIndex, 00333 Int rightEndIndex, 00334 Int& ret_sep_left, 00335 Int& ret_sep_right) 00336 { 00337 00338 Int oldLeftI, oldRightI, newLeftI, newRightI; 00339 Int i,j,k; 00340 Real leftMax /*= leftChain->getVertex(leftEndIndex)[0]*/; 00341 Real rightMin /*= rightChain->getVertex(rightEndIndex)[0]*/; 00342 if(leftChain->getVertex(leftEndIndex)[1] > rightChain->getVertex(rightEndIndex)[1]) //left higher 00343 { 00344 oldLeftI = leftEndIndex+1; 00345 oldRightI = rightEndIndex; 00346 leftMax = leftChain->getVertex(leftEndIndex)[0] - Real(1.0); //initilza to left of leftU 00347 rightMin = rightChain->getVertex(rightEndIndex)[0]; 00348 } 00349 else 00350 { 00351 oldLeftI = leftEndIndex; 00352 oldRightI = rightEndIndex+1; 00353 leftMax = leftChain->getVertex(leftEndIndex)[0]; 00354 rightMin = rightChain->getVertex(rightEndIndex)[0] + Real(1.0); 00355 } 00356 00357 //i: the current working leftChain index, 00358 //j: the current working rightChain index, 00359 //if left(i) is higher than right(j), then the two chains beloew right(j) are separated. 00360 //else the two chains below left(i) are separeated. 00361 i=leftEndIndex; 00362 j=rightEndIndex; 00363 while(1) 00364 { 00365 newLeftI = oldLeftI; 00366 newRightI = oldRightI; 00367 00368 if(i<leftStartIndex) //left chain is done, go through remining right chain. 00369 { 00370 for(k=j-1; k>= rightStartIndex; k--) 00371 { 00372 if(rightChain->getVertex(k)[0] > leftMax) //no conflict 00373 { 00374 //update oldRightI if necessary 00375 if(rightChain->getVertex(k)[0] < rightMin) 00376 { 00377 rightMin = rightChain->getVertex(k)[0]; 00378 oldRightI = k; 00379 } 00380 } 00381 else //there is a conflict 00382 break; //the for-loop. below right(k-1) is seperated: oldLeftI, oldRightI. 00383 } 00384 break; //the while loop 00385 } 00386 else if(j<rightStartIndex) //rightChain is done 00387 { 00388 for(k=i-1; k>= leftStartIndex; k--) 00389 { 00390 if(leftChain->getVertex(k)[0] < rightMin) //no conflict 00391 { 00392 //update oldLeftI if necessary 00393 if(leftChain->getVertex(k)[0] > leftMax) 00394 { 00395 leftMax = leftChain->getVertex(k)[0]; 00396 oldLeftI = k; 00397 } 00398 } 00399 else //there is a conflict 00400 break; //the for loop 00401 } 00402 break; //the while loop 00403 } 00404 else if(leftChain->getVertex(i)[1] > rightChain->getVertex(j)[1]) //left hgiher 00405 { 00406 if(leftChain->getVertex(i)[0] > leftMax) //update leftMax and newLeftI. 00407 { 00408 leftMax = leftChain->getVertex(i)[0]; 00409 newLeftI = i; 00410 } 00411 for(k=j-1; k>= rightStartIndex; k--) //update rightMin and newRightI. 00412 { 00413 if(rightChain->getVertex(k)[1] > leftChain->getVertex(i)[1]) 00414 break; 00415 if(rightChain->getVertex(k)[0] < rightMin) 00416 { 00417 rightMin = rightChain->getVertex(k)[0]; 00418 newRightI = k; 00419 } 00420 } 00421 j = k; //next working j, since j will be higher than i in next loop 00422 if(leftMax >= rightMin) //there is a conflict 00423 break; 00424 else //still no conflict 00425 { 00426 oldLeftI = newLeftI; 00427 oldRightI = newRightI; 00428 } 00429 } 00430 else //right higher 00431 { 00432 if(rightChain->getVertex(j)[0] < rightMin) 00433 { 00434 rightMin = rightChain->getVertex(j)[0]; 00435 newRightI = j; 00436 } 00437 for(k=i-1; k>= leftStartIndex; k--) 00438 { 00439 if(leftChain->getVertex(k)[1] > rightChain->getVertex(j)[1]) 00440 break; 00441 if(leftChain->getVertex(k)[0] > leftMax) 00442 { 00443 leftMax = leftChain->getVertex(k)[0]; 00444 newLeftI = k; 00445 } 00446 } 00447 i = k; //next working i, since i will be higher than j next loop 00448 00449 if(leftMax >= rightMin) //there is a conflict 00450 break; 00451 else //still no conflict 00452 { 00453 oldLeftI = newLeftI; 00454 oldRightI = newRightI; 00455 } 00456 } 00457 }//end of while loop 00458 //now oldLeftI and oldRightI are the desired separeator index, notice that there are not necessarily valid 00459 if(oldLeftI > leftEndIndex || oldRightI > rightEndIndex) 00460 return 0; 00461 else 00462 { 00463 ret_sep_left = oldLeftI; 00464 ret_sep_right = oldRightI; 00465 return 1; 00466 } 00467 } 00468 00469 00470 void sampleCompTop(Real* topVertex, 00471 vertexArray* leftChain, 00472 Int leftStartIndex, 00473 vertexArray* rightChain, 00474 Int rightStartIndex, 00475 gridBoundaryChain* leftGridChain, 00476 gridBoundaryChain* rightGridChain, 00477 Int gridIndex1, 00478 Int up_leftCornerWhere, 00479 Int up_leftCornerIndex, 00480 Int up_rightCornerWhere, 00481 Int up_rightCornerIndex, 00482 primStream* pStream) 00483 { 00484 if(up_leftCornerWhere == 1 && up_rightCornerWhere == 1) //the top is topVertex with possible grid points 00485 { 00486 leftGridChain->getGrid()->outputFanWithPoint(leftGridChain->getVlineIndex(gridIndex1), 00487 leftGridChain->getUlineIndex(gridIndex1), 00488 rightGridChain->getUlineIndex(gridIndex1), 00489 topVertex, 00490 pStream); 00491 return; 00492 } 00493 00494 else if(up_leftCornerWhere != 0) 00495 { 00496 Real* tempTop; 00497 Int tempRightStart; 00498 if(up_leftCornerWhere == 1){ 00499 tempRightStart = rightStartIndex; 00500 tempTop = topVertex; 00501 } 00502 else 00503 { 00504 tempRightStart = up_leftCornerIndex+1; 00505 tempTop = rightChain->getVertex(up_leftCornerIndex); 00506 } 00507 sampleTopRightWithGridLine(tempTop, rightChain, tempRightStart, up_rightCornerIndex, 00508 rightGridChain->getGrid(), 00509 leftGridChain->getVlineIndex(gridIndex1), 00510 leftGridChain->getUlineIndex(gridIndex1), 00511 rightGridChain->getUlineIndex(gridIndex1), 00512 pStream); 00513 } 00514 else if(up_rightCornerWhere != 2) 00515 { 00516 Real* tempTop; 00517 Int tempLeftStart; 00518 if(up_rightCornerWhere == 1) 00519 { 00520 tempLeftStart = leftStartIndex; 00521 tempTop = topVertex; 00522 } 00523 else //0 00524 { 00525 tempLeftStart = up_rightCornerIndex+1; 00526 tempTop = leftChain->getVertex(up_rightCornerIndex); 00527 } 00528 /* 00529 sampleTopLeftWithGridLine(tempTop, leftChain, tempLeftStart, up_leftCornerIndex, 00530 leftGridChain->getGrid(), 00531 leftGridChain->getVlineIndex(gridIndex1), 00532 leftGridChain->getUlineIndex(gridIndex1), 00533 rightGridChain->getUlineIndex(gridIndex1), 00534 pStream); 00535 */ 00536 sampleCompTopSimple(topVertex, 00537 leftChain, 00538 leftStartIndex, 00539 rightChain, 00540 rightStartIndex, 00541 leftGridChain, 00542 rightGridChain, 00543 gridIndex1, 00544 up_leftCornerWhere, 00545 up_leftCornerIndex, 00546 up_rightCornerWhere, 00547 up_rightCornerIndex, 00548 pStream); 00549 } 00550 else //up_leftCornerWhere == 0, up_rightCornerWhere == 2. 00551 { 00552 sampleCompTopSimple(topVertex, 00553 leftChain, 00554 leftStartIndex, 00555 rightChain, 00556 rightStartIndex, 00557 leftGridChain, 00558 rightGridChain, 00559 gridIndex1, 00560 up_leftCornerWhere, 00561 up_leftCornerIndex, 00562 up_rightCornerWhere, 00563 up_rightCornerIndex, 00564 pStream); 00565 return; 00566 #ifdef NOT_REACHABLE //code is not reachable, for test purpose only 00567 //the following code is trying to do some optimization, but not quite working, also see sampleCompBot.C: 00568 Int sep_left, sep_right; 00569 if(findTopSeparator(leftChain, 00570 leftStartIndex, 00571 up_leftCornerIndex, 00572 rightChain, 00573 rightStartIndex, 00574 up_rightCornerIndex, 00575 sep_left, 00576 sep_right) 00577 ) //separator exists 00578 { 00579 00580 if( leftChain->getVertex(sep_left)[0] >= leftGridChain->get_u_value(gridIndex1) && 00581 rightChain->getVertex(sep_right)[0] <= rightGridChain->get_u_value(gridIndex1)) 00582 { 00583 Int gridSep; 00584 Int segLeftSmall, segLeftLarge, segRightSmall, segRightLarge; 00585 Int valid=1; //whether the gridStep is valid or not. 00586 findTopLeftSegment(leftChain, 00587 sep_left, 00588 up_leftCornerIndex, 00589 leftGridChain->get_u_value(gridIndex1), 00590 segLeftSmall, 00591 segLeftLarge); 00592 findTopRightSegment(rightChain, 00593 sep_right, 00594 up_rightCornerIndex, 00595 rightGridChain->get_u_value(gridIndex1), 00596 segRightSmall, 00597 segRightLarge); 00598 if(leftChain->getVertex(segLeftSmall)[1] >= rightChain->getVertex(segRightSmall)[1]) 00599 { 00600 gridSep = rightGridChain->getUlineIndex(gridIndex1); 00601 while(leftGridChain->getGrid()->get_u_value(gridSep) > leftChain->getVertex(segLeftSmall)[0]) 00602 gridSep--; 00603 if(segLeftSmall<segLeftLarge) 00604 if(leftGridChain->getGrid()->get_u_value(gridSep) < leftChain->getVertex(segLeftSmall+1)[0]) 00605 { 00606 valid = 0; 00607 } 00608 } 00609 else 00610 { 00611 gridSep = leftGridChain->getUlineIndex(gridIndex1); 00612 while(leftGridChain->getGrid()->get_u_value(gridSep) < rightChain->getVertex(segRightSmall)[0]) 00613 gridSep++; 00614 if(segRightSmall<segRightLarge) 00615 if(leftGridChain->getGrid()->get_u_value(gridSep) > rightChain->getVertex(segRightSmall+1)[0]) 00616 { 00617 valid = 0; 00618 } 00619 } 00620 00621 if(! valid) 00622 { 00623 sampleCompTopSimple(topVertex, 00624 leftChain, 00625 leftStartIndex, 00626 rightChain, 00627 rightStartIndex, 00628 leftGridChain, 00629 rightGridChain, 00630 gridIndex1, 00631 up_leftCornerWhere, 00632 up_leftCornerIndex, 00633 up_rightCornerWhere, 00634 up_rightCornerIndex, 00635 pStream); 00636 } 00637 else 00638 { 00639 sampleTopLeftWithGridLinePost(leftChain->getVertex(segLeftSmall), 00640 leftChain, 00641 segLeftSmall+1, 00642 segLeftSmall+1, 00643 segLeftLarge, 00644 up_leftCornerIndex, 00645 leftGridChain->getGrid(), 00646 leftGridChain->getVlineIndex(gridIndex1), 00647 leftGridChain->getUlineIndex(gridIndex1), 00648 gridSep, 00649 pStream); 00650 sampleTopRightWithGridLinePost(rightChain->getVertex(segRightSmall), 00651 rightChain, 00652 segRightSmall+1, 00653 segRightSmall+1, 00654 segRightLarge, 00655 up_rightCornerIndex, 00656 leftGridChain->getGrid(), 00657 leftGridChain->getVlineIndex(gridIndex1), 00658 gridSep, 00659 rightGridChain->getUlineIndex(gridIndex1), 00660 pStream); 00661 Real tempBot[2]; 00662 tempBot[0] = leftGridChain->getGrid()->get_u_value(gridSep); 00663 tempBot[1] = leftGridChain->get_v_value(gridIndex1); 00664 monoTriangulationRecGen(topVertex, tempBot, 00665 leftChain, leftStartIndex, segLeftSmall, 00666 rightChain, rightStartIndex, segRightSmall, 00667 pStream); 00668 } 00669 }//end if both sides have vetices inside the gridboundary points 00670 else if(leftChain->getVertex(sep_left)[0] >= leftGridChain->get_u_value(gridIndex1)) //left is in, right is nout 00671 { 00672 00673 Int segLeftSmall, segLeftLarge; 00674 findTopLeftSegment(leftChain, 00675 sep_left, 00676 up_leftCornerIndex, 00677 leftGridChain->get_u_value(gridIndex1), 00678 segLeftSmall, 00679 segLeftLarge); 00680 assert(segLeftLarge >= sep_left); 00681 monoTriangulation2(leftChain->getVertex(segLeftLarge), 00682 leftGridChain->get_vertex(gridIndex1), 00683 leftChain, 00684 segLeftLarge+1, 00685 up_leftCornerIndex, 00686 1, //a increase chain, 00687 pStream); 00688 00689 stripOfFanLeft(leftChain, segLeftLarge, segLeftSmall, 00690 leftGridChain->getGrid(), 00691 leftGridChain->getVlineIndex(gridIndex1), 00692 leftGridChain->getUlineIndex(gridIndex1), 00693 rightGridChain->getUlineIndex(gridIndex1), 00694 pStream, 0); 00695 00696 00697 monoTriangulationRecGen(topVertex, rightGridChain->get_vertex(gridIndex1), 00698 leftChain, leftStartIndex, segLeftSmall, 00699 rightChain, rightStartIndex, up_rightCornerIndex, 00700 pStream); 00701 }//end left in right out 00702 else if(rightChain->getVertex(sep_right)[0] <= rightGridChain->get_u_value(gridIndex1)) 00703 { 00704 Int segRightSmall, segRightLarge; 00705 findTopRightSegment(rightChain, 00706 sep_right, 00707 up_rightCornerIndex, 00708 rightGridChain->get_u_value(gridIndex1), 00709 segRightSmall, 00710 segRightLarge); 00711 assert(segRightLarge>=sep_right); 00712 monoTriangulation2(rightChain->getVertex(segRightLarge), 00713 rightGridChain->get_vertex(gridIndex1), 00714 rightChain, 00715 segRightLarge+1, 00716 up_rightCornerIndex, 00717 0, //a decrease chain 00718 pStream); 00719 stripOfFanRight(rightChain, segRightLarge, segRightSmall, 00720 rightGridChain->getGrid(), 00721 rightGridChain->getVlineIndex(gridIndex1), 00722 leftGridChain->getUlineIndex(gridIndex1), 00723 rightGridChain->getUlineIndex(gridIndex1), 00724 pStream, 0); 00725 00726 00727 monoTriangulationRecGen(topVertex, leftGridChain->get_vertex(gridIndex1), 00728 leftChain, leftStartIndex, up_leftCornerIndex, 00729 rightChain, rightStartIndex,segRightSmall, 00730 pStream); 00731 00732 }//end left out rigth in 00733 else //left out , right out 00734 { 00735 00736 sampleCompTopSimple(topVertex, 00737 leftChain, 00738 leftStartIndex, 00739 rightChain, 00740 rightStartIndex, 00741 leftGridChain, 00742 rightGridChain, 00743 gridIndex1, 00744 up_leftCornerWhere, 00745 up_leftCornerIndex, 00746 up_rightCornerWhere, 00747 up_rightCornerIndex, 00748 pStream); 00749 }//end leftout, right out 00750 }//end if separator exixts. 00751 else //no separator 00752 { 00753 00754 sampleCompTopSimple(topVertex, 00755 leftChain, 00756 leftStartIndex, 00757 rightChain, 00758 rightStartIndex, 00759 leftGridChain, 00760 rightGridChain, 00761 gridIndex1, 00762 up_leftCornerWhere, 00763 up_leftCornerIndex, 00764 up_rightCornerWhere, 00765 up_rightCornerIndex, 00766 pStream); 00767 } 00768 #endif 00769 }//end if 0,2 00770 }//end if the function 00771 00772 00773 static void sampleCompTopSimpleOpt(gridWrap* grid, 00774 Int gridV, 00775 Real* topVertex, Real* botVertex, 00776 vertexArray* inc_chain, Int inc_current, Int inc_end, 00777 vertexArray* dec_chain, Int dec_current, Int dec_end, 00778 primStream* pStream) 00779 { 00780 if(gridV <= 0 || dec_end<dec_current || inc_end <inc_current) 00781 { 00782 monoTriangulationRecGenOpt(topVertex, botVertex, 00783 inc_chain, inc_current, inc_end, 00784 dec_chain, dec_current, dec_end, 00785 pStream); 00786 return; 00787 } 00788 if(grid->get_v_value(gridV+1) >= topVertex[1]) 00789 { 00790 monoTriangulationRecGenOpt(topVertex, botVertex, 00791 inc_chain, inc_current, inc_end, 00792 dec_chain, dec_current, dec_end, 00793 pStream); 00794 return; 00795 } 00796 Int i,j,k; 00797 Real currentV = grid->get_v_value(gridV+1); 00798 if(inc_chain->getVertex(inc_end)[1] <= currentV && 00799 dec_chain->getVertex(dec_end)[1] < currentV) 00800 { 00801 //find i bottom up so that inc_chain[i]<= curentV and inc_chain[i-1] > currentV, 00802 //find j botom up so that dec_chain[j] < currentV and dec_chain[j-1] >= currentV 00803 for(i=inc_end; i >= inc_current; i--) 00804 { 00805 if(inc_chain->getVertex(i)[1] > currentV) 00806 break; 00807 } 00808 i++; 00809 for(j=dec_end; j >= dec_current; j--) 00810 { 00811 if(dec_chain->getVertex(j)[1] >= currentV) 00812 break; 00813 } 00814 j++; 00815 if(inc_chain->getVertex(i)[1] <= dec_chain->getVertex(j)[1]) 00816 { 00817 //find the k so that dec_chain[k][1] < inc_chain[i][1] 00818 for(k=j; k<=dec_end; k++) 00819 { 00820 if(dec_chain->getVertex(k)[1] < inc_chain->getVertex(i)[1]) 00821 break; 00822 } 00823 //we know that dec_chain[j][1] >= inc_chian[i][1] 00824 //we know that dec_chain[k-1][1]>=inc_chain[i][1] 00825 //we know that dec_chian[k][1] < inc_chain[i][1] 00826 //find l in [j, k-1] so that dec_chain[l][0] 0 is closest to 00827 // inc_chain[i] 00828 int l; 00829 Real tempI = Real(j); 00830 Real tempMin = (Real)fabs(inc_chain->getVertex(i)[0] - dec_chain->getVertex(j)[0]); 00831 for(l=j+1; l<= k-1; l++) 00832 { 00833 if(fabs(inc_chain->getVertex(i)[0] - dec_chain->getVertex(l)[0]) 00834 <= tempMin) 00835 { 00836 tempMin = (Real)fabs(inc_chain->getVertex(i)[0] - dec_chain->getVertex(l)[0]); 00837 tempI = (Real)l; 00838 } 00839 } 00840 //inc_chain[i] and dec_chain[tempI] are connected. 00841 monoTriangulationRecGenOpt(dec_chain->getVertex((int)tempI), 00842 botVertex, 00843 inc_chain, i, inc_end, 00844 dec_chain, (int)(tempI+1), dec_end, 00845 pStream); 00846 //recursively do the rest 00847 sampleCompTopSimpleOpt(grid, 00848 gridV+1, 00849 topVertex, inc_chain->getVertex(i), 00850 inc_chain, inc_current, i-1, 00851 dec_chain, dec_current, (int)tempI, 00852 pStream); 00853 } 00854 else 00855 { 00856 //find the k so that inc_chain[k][1] <= dec_chain[j][1] 00857 for(k=i; k<=inc_end; k++) 00858 { 00859 if(inc_chain->getVertex(k)[1] <= dec_chain->getVertex(j)[1]) 00860 break; 00861 } 00862 //we know that inc_chain[i] > dec_chain[j] 00863 //we know that inc_chain[k-1][1] > dec_chain[j][1] 00864 //we know that inc_chain[k][1] <= dec_chain[j][1] 00865 //so we find l between [i,k-1] so that 00866 //inc_chain[l][0] is the closet to dec_chain[j][0] 00867 int tempI = i; 00868 int l; 00869 Real tempMin = (Real)fabs(inc_chain->getVertex(i)[0] - dec_chain->getVertex(j)[0]); 00870 for(l=i+1; l<=k-1; l++) 00871 { 00872 if(fabs(inc_chain->getVertex(l)[0] - dec_chain->getVertex(j)[0]) <= tempMin) 00873 { 00874 tempMin = (Real)fabs(inc_chain->getVertex(l)[0] - dec_chain->getVertex(j)[0]); 00875 tempI = l; 00876 } 00877 } 00878 00879 //inc_chain[tempI] and dec_chain[j] are connected 00880 00881 monoTriangulationRecGenOpt(inc_chain->getVertex(tempI), 00882 botVertex, 00883 inc_chain, tempI+1, inc_end, 00884 dec_chain, j, dec_end, 00885 pStream); 00886 00887 //recurvesily do the rest 00888 sampleCompTopSimpleOpt(grid, gridV+1, 00889 topVertex, dec_chain->getVertex(j), 00890 inc_chain, inc_current, tempI, 00891 dec_chain, dec_current, j-1, 00892 pStream); 00893 } 00894 } 00895 else //go to the next higher gridV 00896 { 00897 sampleCompTopSimpleOpt(grid, 00898 gridV+1, 00899 topVertex, botVertex, 00900 inc_chain, inc_current, inc_end, 00901 dec_chain, dec_current, dec_end, 00902 pStream); 00903 } 00904 } 00905 00906 void sampleCompTopSimple(Real* topVertex, 00907 vertexArray* leftChain, 00908 Int leftStartIndex, 00909 vertexArray* rightChain, 00910 Int rightStartIndex, 00911 gridBoundaryChain* leftGridChain, 00912 gridBoundaryChain* rightGridChain, 00913 Int gridIndex1, 00914 Int up_leftCornerWhere, 00915 Int up_leftCornerIndex, 00916 Int up_rightCornerWhere, 00917 Int up_rightCornerIndex, 00918 primStream* pStream) 00919 { 00920 //the plan is to use monotriangulation algortihm. 00921 Int i,k; 00922 Real* ActualTop; 00923 Real* ActualBot; 00924 Int ActualLeftStart, ActualLeftEnd; 00925 Int ActualRightStart, ActualRightEnd; 00926 00927 //creat an array to store the points on the grid line 00928 gridWrap* grid = leftGridChain->getGrid(); 00929 Int gridV = leftGridChain->getVlineIndex(gridIndex1); 00930 Int gridLeftU = leftGridChain->getUlineIndex(gridIndex1); 00931 Int gridRightU = rightGridChain->getUlineIndex(gridIndex1); 00932 00933 Real2* gridPoints = (Real2*) malloc(sizeof(Real2) * (gridRightU - gridLeftU +1)); 00934 assert(gridPoints); 00935 00936 for(k=0, i=gridRightU; i>= gridLeftU; i--, k++) 00937 { 00938 gridPoints[k][0] = grid->get_u_value(i); 00939 gridPoints[k][1] = grid->get_v_value(gridV); 00940 } 00941 00942 if(up_leftCornerWhere != 2) 00943 ActualRightStart = rightStartIndex; 00944 else 00945 ActualRightStart = up_leftCornerIndex+1; //up_leftCornerIndex will be the ActualTop 00946 00947 if(up_rightCornerWhere != 2) //right corner is not on right chain 00948 ActualRightEnd = rightStartIndex-1; //meaning that there is no actual rigth section 00949 else 00950 ActualRightEnd = up_rightCornerIndex; 00951 00952 vertexArray ActualRightChain(max(0, ActualRightEnd-ActualRightStart+1) + gridRightU-gridLeftU+1); 00953 00954 for(i=ActualRightStart; i<= ActualRightEnd; i++) 00955 ActualRightChain.appendVertex(rightChain->getVertex(i)); 00956 for(i=0; i<gridRightU-gridLeftU+1; i++) 00957 ActualRightChain.appendVertex(gridPoints[i]); 00958 00959 //determine ActualLeftEnd 00960 if(up_leftCornerWhere != 0) 00961 ActualLeftEnd = leftStartIndex-1; 00962 else 00963 ActualLeftEnd = up_leftCornerIndex; 00964 00965 if(up_rightCornerWhere != 0) 00966 ActualLeftStart = leftStartIndex; 00967 else 00968 ActualLeftStart = up_rightCornerIndex+1; //up_rightCornerIndex will be the actual top 00969 00970 if(up_leftCornerWhere == 0) 00971 { 00972 if(up_rightCornerWhere == 0) 00973 ActualTop = leftChain->getVertex(up_rightCornerIndex); 00974 else 00975 ActualTop = topVertex; 00976 } 00977 else if(up_leftCornerWhere == 1) 00978 ActualTop = topVertex; 00979 else //up_leftCornerWhere == 2 00980 ActualTop = rightChain->getVertex(up_leftCornerIndex); 00981 00982 ActualBot = gridPoints[gridRightU - gridLeftU]; 00983 00984 00985 00986 00987 if(leftChain->getVertex(ActualLeftEnd)[1] == ActualBot[1]) 00988 { 00989 /* 00990 monoTriangulationRecGenOpt(ActualTop, leftChain->getVertex(ActualLeftEnd), 00991 leftChain, 00992 ActualLeftStart, ActualLeftEnd-1, 00993 &ActualRightChain, 00994 0, 00995 ActualRightChain.getNumElements()-1, 00996 pStream); 00997 */ 00998 00999 sampleCompTopSimpleOpt(grid, gridV, 01000 ActualTop, leftChain->getVertex(ActualLeftEnd), 01001 leftChain, 01002 ActualLeftStart, ActualLeftEnd-1, 01003 &ActualRightChain, 01004 0, 01005 ActualRightChain.getNumElements()-1, 01006 pStream); 01007 01008 } 01009 else 01010 { 01011 /* 01012 monoTriangulationRecGenOpt(ActualTop, ActualBot, leftChain, 01013 ActualLeftStart, ActualLeftEnd, 01014 &ActualRightChain, 01015 0, ActualRightChain.getNumElements()-2, //the last is the bot. 01016 pStream); 01017 */ 01018 01019 sampleCompTopSimpleOpt(grid, gridV, 01020 ActualTop, ActualBot, leftChain, 01021 ActualLeftStart, ActualLeftEnd, 01022 &ActualRightChain, 01023 0, ActualRightChain.getNumElements()-2, //the last is the bot. 01024 pStream); 01025 01026 01027 } 01028 01029 free(gridPoints); 01030 01031 } 01032 Generated on Wed May 23 2012 04:21:41 for ReactOS by
1.7.6.1
|