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:
10
** http://oss.sgi.com/projects/FreeB
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.
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.
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.
41
#include "sampleCompBot.h"
42
#include "sampleCompRight.h"
44
#define max(a,b) ((a>b)? a:b)
46
//return: index_mono, index_pass
47
//from [pass, mono] is strictly U-monotone
48
//from [corner, pass] is <u
49
// vertex[pass][0] >= u
50
//if everybost is <u, then pass = end+1.
51
//otherwise both mono and pass are meanng full and we have corner<=pass<=mono<=end
52
void findBotLeftSegment(vertexArray* leftChain,
61
assert(leftCorner <= leftEnd);
62
for(i=leftCorner; i<= leftEnd; i++)
63
if(leftChain->getVertex(i)[0] >= u)
66
if(ret_index_pass <= leftEnd)
68
for(i=ret_index_pass; i< leftEnd; i++)
70
if(leftChain->getVertex(i+1)[0] <= leftChain->getVertex(i)[0])
78
void findBotRightSegment(vertexArray* rightChain,
86
assert(rightCorner <= rightEnd);
87
for(i=rightCorner; i<= rightEnd; i++)
88
if(rightChain->getVertex(i)[0] <= u)
95
if(ret_index_pass <= rightEnd)
97
for(i=ret_index_pass; i< rightEnd; i++)
99
if(rightChain->getVertex(i+1)[0] >= rightChain->getVertex(i)[0])
107
void sampleBotRightWithGridLinePost(Real* botVertex,
108
vertexArray* rightChain,
119
//the possible section which is to the right of rightU
120
if(segIndexPass > rightCorner) //from corner to pass-1 is > u.
123
if(segIndexPass <= rightEnd) //there is a point to the left of u
124
tempBot = rightChain->getVertex(segIndexPass);
125
else //nothing is to the left of u.
128
tempTop[0] = grid->get_u_value(rightU);
129
tempTop[1] = grid->get_v_value(gridV);
131
monoTriangulation2(tempTop, tempBot,
135
0, // a decrease chain
139
//the possible section which is strictly Umonotone
140
if(segIndexPass <= rightEnd) //segIndex pass and mono exist
142
//if there are grid points which are to the left of botVertex
143
//then we should use botVertex to form a fan with these points to
144
//optimize the triangulation
146
if(botVertex[0] <= grid->get_u_value(leftU))
150
//we also have to make sure that botVertex is the left most vertex on the chain
152
for(i=segIndexMono; i<=rightEnd; i++)
153
if(rightChain->getVertex(i)[0] <= botVertex[0])
162
//find midU so that grid->get_u_value(midU) <= botVertex[0]
163
//and grid->get_u_value(midU) > botVertex[0]
165
while(grid->get_u_value(midU) <= botVertex[0])
173
grid->outputFanWithPoint(gridV, leftU, midU, botVertex, pStream);
174
stripOfFanRight(rightChain, segIndexMono, segIndexPass, grid, gridV, midU, rightU, pStream, 1);
176
tempTop[0] = grid->get_u_value(midU);
177
tempTop[1] = grid->get_v_value(gridV);
178
monoTriangulation2(tempTop, botVertex, rightChain, segIndexMono, rightEnd, 0, pStream);
182
stripOfFanRight(rightChain, segIndexMono, segIndexPass, grid, gridV, leftU, rightU, pStream, 1);
184
tempTop[0] = grid->get_u_value(leftU);
185
tempTop[1] = grid->get_v_value(gridV);
186
monoTriangulation2(tempTop, botVertex, rightChain, segIndexMono, rightEnd, 0, pStream);
189
else //the botVertex forms a fan witht eh grid points
190
grid->outputFanWithPoint(gridV, leftU, rightU, botVertex, pStream);
193
void sampleBotRightWithGridLine(Real* botVertex,
194
vertexArray* rightChain,
203
//if right chaain is empty, then there is only one bot vertex with
205
if(rightEnd<rightCorner){
206
grid->outputFanWithPoint(gridV, leftU, rightU, botVertex, pStream);
210
Int segIndexMono, segIndexPass;
211
findBotRightSegment(rightChain,
214
grid->get_u_value(rightU),
218
sampleBotRightWithGridLinePost(botVertex,
232
void sampleBotLeftWithGridLinePost(Real* botVertex,
233
vertexArray* leftChain,
245
//the possible section which is to the left of leftU
246
if(segIndexPass > leftCorner) //at least leftCorner is to the left of leftU
249
if(segIndexPass <= leftEnd) //from corner to pass-1 is <u
250
tempBot = leftChain->getVertex(segIndexPass);
251
else //nothing is to the rigth of u
254
tempTop[0] = grid->get_u_value(leftU);
255
tempTop[1] = grid->get_v_value(gridV);
256
monoTriangulation2(tempTop, tempBot, leftChain, leftCorner, segIndexPass-1,
257
1, //a increase chain,
260
//the possible section which is strictly Umonotone
261
if(segIndexPass <= leftEnd) //segIndexpass and mono exist
263
stripOfFanLeft(leftChain, segIndexMono, segIndexPass, grid, gridV, leftU, rightU, pStream, 1);
265
tempTop[0] = grid->get_u_value(rightU);
266
tempTop[1] = grid->get_v_value(gridV);
268
monoTriangulation2(tempTop, botVertex, leftChain, segIndexMono, leftEnd,
272
else //the botVertex forms a fan with the grid points
274
grid->outputFanWithPoint(gridV, leftU, rightU, botVertex, pStream);
279
void sampleBotLeftWithGridLine(Real* botVertex,
280
vertexArray* leftChain,
290
//if leftChain is empty, then there is only one botVertex with one grid line
291
if(leftEnd< leftCorner){
292
grid->outputFanWithPoint(gridV, leftU, rightU, botVertex, pStream);
296
Int segIndexPass, segIndexMono;
297
findBotLeftSegment(leftChain, leftEnd, leftCorner, grid->get_u_value(leftU), segIndexMono, segIndexPass);
299
sampleBotLeftWithGridLinePost(botVertex,
307
leftU, rightU, pStream);
310
//return 1 if separator exists, 0 otherwise
311
Int findBotSeparator(vertexArray* leftChain,
314
vertexArray* rightChain,
320
Int oldLeftI, oldRightI, newLeftI, newRightI;
322
Real leftMax /*= leftChain->getVertex(leftCorner)[0]*/;
323
Real rightMin /*= rightChain->getVertex(rightCorner)[0]*/;
324
if(leftChain->getVertex(leftCorner)[1] < rightChain->getVertex(rightCorner)[1])//leftlower
326
oldLeftI = leftCorner-1;
327
oldRightI = rightCorner;
328
leftMax = leftChain->getVertex(leftCorner)[0] - Real(1.0) ; //initilize to be left of leftCorner
329
rightMin = rightChain->getVertex(rightCorner)[0];
333
oldLeftI = leftCorner;
334
oldRightI = rightCorner-1;
335
leftMax = leftChain->getVertex(leftCorner)[0];
336
rightMin = rightChain->getVertex(rightCorner)[0] + Real(1.0);
339
//i: the current working leftChain Index
340
//j: the curent working right chian index
341
//if(left(i) is lower than right(j), then the two chains above right(j) are separated.
342
//else the two chains below left(i) are separated.
348
newRightI = oldRightI;
349
if(i> leftEnd) //left chain is doen , go through remaining right chain
351
for(k=j+1; k<= rightEnd; k++)
353
if(rightChain->getVertex(k)[0] > leftMax) //no conflict
355
//update oldRightI if necessary
356
if(rightChain->getVertex(k)[0] < rightMin)
358
rightMin = rightChain->getVertex(k)[0];
362
else //there is a conflict
363
break; //the for-loop, above right(k+1) is separated: oldLeftI, oldRightI
365
break; //the while loop
367
else if(j > rightEnd) //right Chain is doen
369
for(k=i+1; k<= leftEnd; k++)
371
if(leftChain->getVertex(k)[0] < rightMin) //no conflict
373
//update oldLeftI if necessary
374
if(leftChain->getVertex(k)[0] > leftMax)
376
leftMax = leftChain->getVertex(k)[0];
380
else //there is a conflict
381
break; //the for-loop, above left(k+1) is separated: oldLeftI, oldRightI
383
break; //the while loop
385
else if(leftChain->getVertex(i)[1] < rightChain->getVertex(j)[1]) //left lower
388
if(leftChain->getVertex(i)[0] > leftMax) //update leftMax amd newLeftI
390
leftMax = leftChain->getVertex(i)[0];
393
for(k=j+1; k<= rightEnd; k++) //update rightMin and newRightI;
395
if(rightChain->getVertex(k)[1] < leftChain->getVertex(i)[1]) //right gets lower
397
if(rightChain->getVertex(k)[0] < rightMin)
399
rightMin = rightChain->getVertex(k)[0];
403
j = k; //next working j, since j will he lower than i in next loop
404
if(leftMax >= rightMin) //there is a conflict
406
else //still no conflict
409
oldRightI = newRightI;
415
if(rightChain->getVertex(j)[0] < rightMin)
417
rightMin = rightChain->getVertex(j)[0];
420
for(k=i+1; k<= leftEnd; k++)
422
if(leftChain->getVertex(k)[1] < rightChain->getVertex(j)[1])
424
if(leftChain->getVertex(k)[0] > leftMax)
426
leftMax = leftChain->getVertex(k)[0];
430
i=k; //nexct working i, since i will be lower than j next loop
431
if(leftMax >= rightMin) //there is conflict
433
else //still no conflict
436
oldRightI = newRightI;
440
//now oldLeftI and oldRight I are the desired separator index notice that they are not
442
if(oldLeftI < leftCorner || oldRightI < rightCorner)
443
return 0; //no separator
446
ret_sep_left = oldLeftI;
447
ret_sep_right = oldRightI;
452
void sampleCompBot(Real* botVertex,
453
vertexArray* leftChain,
455
vertexArray* rightChain,
457
gridBoundaryChain* leftGridChain,
458
gridBoundaryChain* rightGridChain,
460
Int down_leftCornerWhere,
461
Int down_leftCornerIndex,
462
Int down_rightCornerWhere,
463
Int down_rightCornerIndex,
467
if(down_leftCornerWhere == 1 && down_rightCornerWhere == 1) //the bot is botVertex with possible grid points
470
leftGridChain->getGrid()->outputFanWithPoint(leftGridChain->getVlineIndex(gridIndex),
471
leftGridChain->getUlineIndex(gridIndex),
472
rightGridChain->getUlineIndex(gridIndex),
477
else if(down_leftCornerWhere != 0)
482
if(down_leftCornerWhere == 1){
483
tempRightEnd = rightEnd;
488
tempRightEnd = down_leftCornerIndex-1;
489
tempBot = rightChain->getVertex(down_leftCornerIndex);
492
sampleBotRightWithGridLine(tempBot,
495
down_rightCornerIndex,
496
rightGridChain->getGrid(),
497
leftGridChain->getVlineIndex(gridIndex),
498
leftGridChain->getUlineIndex(gridIndex),
499
rightGridChain->getUlineIndex(gridIndex),
502
else if(down_rightCornerWhere != 2)
507
if(down_rightCornerWhere == 1){
508
tempLeftEnd = leftEnd;
511
else //right corner is on left chain
513
tempLeftEnd = down_rightCornerIndex-1;
514
tempBot = leftChain->getVertex(down_rightCornerIndex);
518
sampleBotLeftWithGridLine(tempBot, leftChain, tempLeftEnd, down_leftCornerIndex,
519
leftGridChain->getGrid(),
520
leftGridChain->getVlineIndex(gridIndex),
521
leftGridChain->getUlineIndex(gridIndex),
522
rightGridChain->getUlineIndex(gridIndex),
526
else //down_leftCornereWhere == 0, down_rightCornerwhere == 2
528
sampleCompBotSimple(botVertex,
536
down_leftCornerWhere,
537
down_leftCornerIndex,
538
down_rightCornerWhere,
539
down_rightCornerIndex,
545
//the following code is trying to do some optimization, but not quite working. so it is not reachable, but leave it here for reference
546
Int sep_left, sep_right;
547
if(findBotSeparator(leftChain, leftEnd, down_leftCornerIndex,
548
rightChain, rightEnd, down_rightCornerIndex,
553
if(leftChain->getVertex(sep_left)[0] >= leftGridChain->get_u_value(gridIndex) &&
554
rightChain->getVertex(sep_right)[0] <= rightGridChain->get_u_value(gridIndex))
557
Int segLeftMono, segLeftPass, segRightMono, segRightPass;
558
findBotLeftSegment(leftChain,
560
down_leftCornerIndex,
561
leftGridChain->get_u_value(gridIndex),
564
findBotRightSegment(rightChain,
566
down_rightCornerIndex,
567
rightGridChain->get_u_value(gridIndex),
570
if(leftChain->getVertex(segLeftMono)[1] <= rightChain->getVertex(segRightMono)[1])
572
gridSep = rightGridChain->getUlineIndex(gridIndex);
573
while(leftGridChain->getGrid()->get_u_value(gridSep) > leftChain->getVertex(segLeftMono)[0])
578
gridSep = leftGridChain->getUlineIndex(gridIndex);
579
while(leftGridChain->getGrid()->get_u_value(gridSep) < rightChain->getVertex(segRightMono)[0])
583
sampleBotLeftWithGridLinePost(leftChain->getVertex(segLeftMono),
588
down_leftCornerIndex,
589
leftGridChain->getGrid(),
590
leftGridChain->getVlineIndex(gridIndex),
591
leftGridChain->getUlineIndex(gridIndex),
594
sampleBotRightWithGridLinePost(rightChain->getVertex(segRightMono),
599
down_rightCornerIndex,
600
rightGridChain->getGrid(),
601
rightGridChain->getVlineIndex(gridIndex),
603
rightGridChain->getUlineIndex(gridIndex),
606
tempTop[0] = leftGridChain->getGrid()->get_u_value(gridSep);
607
tempTop[1] = leftGridChain->get_v_value(gridIndex);
608
monoTriangulationRecGen(tempTop, botVertex,
609
leftChain, segLeftMono, leftEnd,
610
rightChain, segRightMono, rightEnd,
612
}//end if both sides have vertices inside the gridboundary points
613
else if(leftChain->getVertex(sep_left)[0] >= leftGridChain->get_u_value(gridIndex)) //left n right out
616
Int segLeftMono, segLeftPass;
617
findBotLeftSegment(leftChain,
619
down_leftCornerIndex,
620
leftGridChain->get_u_value(gridIndex),
623
assert(segLeftPass <= sep_left); //make sure there is a point to the right of u.
624
monoTriangulation2(leftGridChain->get_vertex(gridIndex),
625
leftChain->getVertex(segLeftPass),
627
down_leftCornerIndex,
629
1, //a increase chain
631
stripOfFanLeft(leftChain, segLeftMono, segLeftPass,
632
leftGridChain->getGrid(),
633
leftGridChain->getVlineIndex(gridIndex),
634
leftGridChain->getUlineIndex(gridIndex),
635
rightGridChain->getUlineIndex(gridIndex),
638
sampleBotLeftWithGridLinePost(leftChain->getVertex(segLeftMono),
643
down_leftCornerIndex,
644
leftGridChain->getGrid(),
645
leftGridChain->getVlineIndex(gridIndex),
646
leftGridChain->getUlineIndex(gridIndex),
647
rightGridChain->getUlineIndex(gridIndex),
651
monoTriangulationRecGen(rightGridChain->get_vertex(gridIndex),
653
leftChain, segLeftMono, leftEnd,
654
rightChain, down_rightCornerIndex, rightEnd,
656
}//end left in right out
657
else if(rightChain->getVertex(sep_right)[0] <= rightGridChain->get_u_value(gridIndex))//left out right in
659
Int segRightMono, segRightPass;
660
findBotRightSegment(rightChain, sep_right, down_rightCornerIndex,
661
rightGridChain->get_u_value(gridIndex),
665
assert(segRightPass <= sep_right); //make sure there is a point to the left of u.
666
monoTriangulation2(rightGridChain->get_vertex(gridIndex),
667
rightChain->getVertex(segRightPass),
669
down_rightCornerIndex,
671
0, // a decrease chain
674
stripOfFanRight(rightChain, segRightMono, segRightPass,
675
rightGridChain->getGrid(),
676
rightGridChain->getVlineIndex(gridIndex),
677
leftGridChain->getUlineIndex(gridIndex),
678
rightGridChain->getUlineIndex(gridIndex),
682
monoTriangulationRecGen(leftGridChain->get_vertex(gridIndex),
684
leftChain, down_leftCornerIndex, leftEnd,
685
rightChain, segRightMono, rightEnd,
688
}//end left out right in
689
else //left out, right out
691
sampleCompBotSimple(botVertex,
699
down_leftCornerWhere,
700
down_leftCornerIndex,
701
down_rightCornerWhere,
702
down_rightCornerIndex,
705
}//end leftout right out
706
}//end if separator exists
710
sampleCompBotSimple(botVertex,
718
down_leftCornerWhere,
719
down_leftCornerIndex,
720
down_rightCornerWhere,
721
down_rightCornerIndex,
726
}//end if the functin
729
void sampleCompBotSimple(Real* botVertex,
730
vertexArray* leftChain,
732
vertexArray* rightChain,
734
gridBoundaryChain* leftGridChain,
735
gridBoundaryChain* rightGridChain,
737
Int down_leftCornerWhere,
738
Int down_leftCornerIndex,
739
Int down_rightCornerWhere,
740
Int down_rightCornerIndex,
743
//the plan is to use monotriangulation algorithm.
747
Int ActualLeftStart, ActualLeftEnd;
748
Int ActualRightStart, ActualRightEnd;
750
//creat an array to store the points on the grid line
751
gridWrap* grid = leftGridChain->getGrid();
752
Int gridV = leftGridChain->getVlineIndex(gridIndex);
753
Int gridLeftU = leftGridChain->getUlineIndex(gridIndex);
754
Int gridRightU = rightGridChain->getUlineIndex(gridIndex);
755
Real2* gridPoints = (Real2*) malloc(sizeof(Real2) * (gridRightU - gridLeftU +1));
758
for(k=0, i=gridRightU; i>= gridLeftU; i--, k++)
760
gridPoints[k][0] = grid->get_u_value(i);
761
gridPoints[k][1] = grid->get_v_value(gridV);
764
if(down_rightCornerWhere != 0) //rightCorner is not on lef
765
ActualLeftEnd = leftEnd;
767
ActualLeftEnd = down_rightCornerIndex-1; //down_rightCornerIndex will be th actualBot
769
if(down_leftCornerWhere != 0) //left corner is not on let chian
770
ActualLeftStart = leftEnd+1; //meaning that there is no actual left section
772
ActualLeftStart = down_leftCornerIndex;
774
vertexArray ActualLeftChain(max(0, ActualLeftEnd - ActualLeftStart +1) + gridRightU - gridLeftU +1);
776
for(i=0; i<gridRightU - gridLeftU +1 ; i++)
777
ActualLeftChain.appendVertex(gridPoints[i]);
778
for(i=ActualLeftStart; i<= ActualLeftEnd; i++)
779
ActualLeftChain.appendVertex(leftChain->getVertex(i));
781
//determine ActualRightStart
782
if(down_rightCornerWhere != 2) //right is not on right
783
ActualRightStart = rightEnd +1; //meaning no section on right
785
ActualRightStart = down_rightCornerIndex;
787
//determine actualrightEnd
788
if(down_leftCornerWhere != 2) //left is not on right
791
ActualRightEnd = rightEnd;
793
else //left corner is on right
795
ActualRightEnd = down_leftCornerIndex-1; //down_leftCornerIndex will be the bot
800
if(down_rightCornerWhere == 2)
802
if(down_leftCornerWhere == 2)
803
ActualBot = rightChain->getVertex(down_leftCornerIndex);
805
ActualBot = botVertex;
807
else if(down_rightCornerWhere == 1) //right corner bot
808
ActualBot = botVertex;
809
else //down_rightCornerWhere == 0
810
ActualBot = leftChain->getVertex(down_rightCornerIndex);
812
ActualTop = gridPoints[0];
814
printf("in bot simple, actual leftChain is \n");
815
ActualLeftChain.print();
816
printf("Actual Top = %f,%f\n", ActualTop[0],ActualTop[1]);
817
printf("Actual Bot = %f,%f\n", ActualBot[0],ActualBot[1]);
818
printf("Actual right start = %i, end=%i\n",ActualRightStart, ActualRightEnd);
820
if(rightChain->getVertex(ActualRightStart)[1] == ActualTop[1])
821
monoTriangulationRecGenOpt(rightChain->getVertex(ActualRightStart),
825
ActualLeftChain.getNumElements()-1,
831
monoTriangulationRecGenOpt(ActualTop, ActualBot,
833
1, //the first one is the top vertex
834
ActualLeftChain.getNumElements()-1,