dri: Rework planar image interface
[mesa.git] / src / glu / sgi / libnurbs / nurbtess / sampleCompTop.cc
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 <math.h>
41 #include "zlassert.h"
42 #include "sampleCompTop.h"
43 #include "sampleCompRight.h"
44
45 #define max(a,b) ((a>b)? a:b)
46
47 //return : index_small, and index_large,
48 //from [small, large] is strictly U-monotne,
49 //from [large+1, end] is <u
50 //and vertex[large][0] is >= u
51 //if eveybody is <u, the large = start-1.
52 //otherwise both large and small are meaningful and we have start<=small<=large<=end
53 void findTopLeftSegment(vertexArray* leftChain,
54 Int leftStart,
55 Int leftEnd,
56 Real u,
57 Int& ret_index_small,
58 Int& ret_index_large
59 )
60 {
61 Int i;
62 assert(leftStart <= leftEnd);
63 for(i=leftEnd; i>= leftStart; i--)
64 {
65 if(leftChain->getVertex(i)[0] >= u)
66 break;
67 }
68 ret_index_large = i;
69 if(ret_index_large >= leftStart)
70 {
71 for(i=ret_index_large; i>leftStart; i--)
72 {
73 if(leftChain->getVertex(i-1)[0] <= leftChain->getVertex(i)[0])
74 break;
75 }
76 ret_index_small = i;
77 }
78 }
79
80 void findTopRightSegment(vertexArray* rightChain,
81 Int rightStart,
82 Int rightEnd,
83 Real u,
84 Int& ret_index_small,
85 Int& ret_index_large)
86 {
87 Int i;
88 assert(rightStart<=rightEnd);
89 for(i=rightEnd; i>=rightStart; i--)
90 {
91 if(rightChain->getVertex(i)[0] <= u)
92 break;
93 }
94 ret_index_large = i;
95 if(ret_index_large >= rightStart)
96 {
97 for(i=ret_index_large; i>rightStart;i--)
98 {
99 if(rightChain->getVertex(i-1)[0] >= rightChain->getVertex(i)[0])
100 break;
101 }
102 ret_index_small = i;
103 }
104 }
105
106
107 void sampleTopRightWithGridLinePost(Real* topVertex,
108 vertexArray* rightChain,
109 Int rightStart,
110 Int segIndexSmall,
111 Int segIndexLarge,
112 Int rightEnd,
113 gridWrap* grid,
114 Int gridV,
115 Int leftU,
116 Int rightU,
117 primStream* pStream)
118 {
119 //the possible section which is to the right of rightU
120 if(segIndexLarge < rightEnd)
121 {
122 Real *tempTop;
123 if(segIndexLarge >= rightStart)
124 tempTop = rightChain->getVertex(segIndexLarge);
125 else
126 tempTop = topVertex;
127 Real tempBot[2];
128 tempBot[0] = grid->get_u_value(rightU);
129 tempBot[1] = grid->get_v_value(gridV);
130 monoTriangulationRecGenOpt(tempTop, tempBot,
131 NULL, 1,0,
132 rightChain, segIndexLarge+1, rightEnd,
133 pStream);
134 /*
135 monoTriangulation2(tempTop, tempBot,
136 rightChain,
137 segIndexLarge+1,
138 rightEnd,
139 0, //a decrease chian
140 pStream);
141 */
142
143 }
144
145 //the possible section which is strictly Umonotone
146 if(segIndexLarge >= rightStart)
147 {
148 stripOfFanRight(rightChain, segIndexLarge, segIndexSmall, grid, gridV, leftU, rightU, pStream, 0);
149 Real tempBot[2];
150 tempBot[0] = grid->get_u_value(leftU);
151 tempBot[1] = grid->get_v_value(gridV);
152 monoTriangulation2(topVertex, tempBot, rightChain, rightStart, segIndexSmall, 0, pStream);
153 }
154 else //the topVertex forms a fan with the grid points
155 grid->outputFanWithPoint(gridV, leftU, rightU, topVertex, pStream);
156 }
157
158 void sampleTopRightWithGridLine(Real* topVertex,
159 vertexArray* rightChain,
160 Int rightStart,
161 Int rightEnd,
162 gridWrap* grid,
163 Int gridV,
164 Int leftU,
165 Int rightU,
166 primStream* pStream
167 )
168 {
169 //if right chian is empty, then there is only one topVertex with one grid line
170 if(rightEnd < rightStart){
171 grid->outputFanWithPoint(gridV, leftU, rightU, topVertex, pStream);
172 return;
173 }
174
175 Int segIndexSmall = 0, segIndexLarge;
176 findTopRightSegment(rightChain,
177 rightStart,
178 rightEnd,
179 grid->get_u_value(rightU),
180 segIndexSmall,
181 segIndexLarge
182 );
183 sampleTopRightWithGridLinePost(topVertex, rightChain,
184 rightStart,
185 segIndexSmall,
186 segIndexLarge,
187 rightEnd,
188 grid,
189 gridV,
190 leftU,
191 rightU,
192 pStream);
193 }
194
195
196 void sampleTopLeftWithGridLinePost(Real* topVertex,
197 vertexArray* leftChain,
198 Int leftStart,
199 Int segIndexSmall,
200 Int segIndexLarge,
201 Int leftEnd,
202 gridWrap* grid,
203 Int gridV,
204 Int leftU,
205 Int rightU,
206 primStream* pStream)
207 {
208 //the possible section which is to the left of leftU
209
210 if(segIndexLarge < leftEnd)
211 {
212 Real *tempTop;
213 if(segIndexLarge >= leftStart)
214 tempTop = leftChain->getVertex(segIndexLarge);
215 else
216 tempTop = topVertex;
217 Real tempBot[2];
218 tempBot[0] = grid->get_u_value(leftU);
219 tempBot[1] = grid->get_v_value(gridV);
220
221 monoTriangulation2(tempTop, tempBot,
222 leftChain,
223 segIndexLarge+1,
224 leftEnd,
225 1, //a increase chian
226 pStream);
227 }
228
229 //the possible section which is strictly Umonotone
230 if(segIndexLarge >= leftStart)
231 {
232 //if there are grid points which are to the right of topV,
233 //then we should use topVertex to form a fan with these points to
234 //optimize the triangualtion
235 int do_optimize=1;
236 if(topVertex[0] >= grid->get_u_value(rightU))
237 do_optimize = 0;
238 else
239 {
240 //we also have to make sure that topVertex are the right most vertex
241 //on the chain.
242 int i;
243 for(i=leftStart; i<=segIndexSmall; i++)
244 if(leftChain->getVertex(i)[0] >= topVertex[0])
245 {
246 do_optimize = 0;
247 break;
248 }
249 }
250
251 if(do_optimize)
252 {
253 //find midU so that grid->get_u_value(midU) >= topVertex[0]
254 //and grid->get_u_value(midU-1) < topVertex[0]
255 int midU=rightU;
256 while(grid->get_u_value(midU) >= topVertex[0])
257 {
258 midU--;
259 if(midU < leftU)
260 break;
261 }
262 midU++;
263
264 grid->outputFanWithPoint(gridV, midU, rightU, topVertex, pStream);
265 stripOfFanLeft(leftChain, segIndexLarge, segIndexSmall, grid, gridV, leftU, midU, pStream, 0);
266 Real tempBot[2];
267 tempBot[0] = grid->get_u_value(midU);
268 tempBot[1] = grid->get_v_value(gridV);
269 monoTriangulation2(topVertex, tempBot, leftChain, leftStart, segIndexSmall, 1, pStream);
270 }
271 else //not optimize
272 {
273
274 stripOfFanLeft(leftChain, segIndexLarge, segIndexSmall, grid, gridV, leftU, rightU, pStream, 0);
275 Real tempBot[2];
276 tempBot[0] = grid->get_u_value(rightU);
277 tempBot[1] = grid->get_v_value(gridV);
278 monoTriangulation2(topVertex, tempBot, leftChain, leftStart, segIndexSmall, 1, pStream);
279 }
280 }
281 else //the topVertex forms a fan with the grid points
282 grid->outputFanWithPoint(gridV, leftU, rightU, topVertex, pStream);
283 }
284
285
286 void sampleTopLeftWithGridLine(Real* topVertex,
287 vertexArray* leftChain,
288 Int leftStart,
289 Int leftEnd,
290 gridWrap* grid,
291 Int gridV,
292 Int leftU,
293 Int rightU,
294 primStream* pStream
295 )
296 {
297 Int segIndexSmall = 0, segIndexLarge;
298 //if left chain is empty, then there is only one top vertex with one grid
299 // line
300 if(leftEnd < leftStart) {
301 grid->outputFanWithPoint(gridV, leftU, rightU, topVertex, pStream);
302 return;
303 }
304 findTopLeftSegment(leftChain,
305 leftStart,
306 leftEnd,
307 grid->get_u_value(leftU),
308 segIndexSmall,
309 segIndexLarge
310 );
311 sampleTopLeftWithGridLinePost(topVertex,
312 leftChain,
313 leftStart,
314 segIndexSmall,
315 segIndexLarge,
316 leftEnd,
317 grid,
318 gridV,
319 leftU,
320 rightU,
321 pStream);
322 }
323
324
325 //return 1 if saprator exits, 0 otherwise
326 Int findTopSeparator(vertexArray* leftChain,
327 Int leftStartIndex,
328 Int leftEndIndex,
329 vertexArray* rightChain,
330 Int rightStartIndex,
331 Int rightEndIndex,
332 Int& ret_sep_left,
333 Int& ret_sep_right)
334 {
335
336 Int oldLeftI, oldRightI, newLeftI, newRightI;
337 Int i,j,k;
338 Real leftMax /*= leftChain->getVertex(leftEndIndex)[0]*/;
339 Real rightMin /*= rightChain->getVertex(rightEndIndex)[0]*/;
340 if(leftChain->getVertex(leftEndIndex)[1] > rightChain->getVertex(rightEndIndex)[1]) //left higher
341 {
342 oldLeftI = leftEndIndex+1;
343 oldRightI = rightEndIndex;
344 leftMax = leftChain->getVertex(leftEndIndex)[0] - Real(1.0); //initilza to left of leftU
345 rightMin = rightChain->getVertex(rightEndIndex)[0];
346 }
347 else
348 {
349 oldLeftI = leftEndIndex;
350 oldRightI = rightEndIndex+1;
351 leftMax = leftChain->getVertex(leftEndIndex)[0];
352 rightMin = rightChain->getVertex(rightEndIndex)[0] + Real(1.0);
353 }
354
355 //i: the current working leftChain index,
356 //j: the current working rightChain index,
357 //if left(i) is higher than right(j), then the two chains beloew right(j) are separated.
358 //else the two chains below left(i) are separeated.
359 i=leftEndIndex;
360 j=rightEndIndex;
361 while(1)
362 {
363 newLeftI = oldLeftI;
364 newRightI = oldRightI;
365
366 if(i<leftStartIndex) //left chain is done, go through remining right chain.
367 {
368 for(k=j-1; k>= rightStartIndex; k--)
369 {
370 if(rightChain->getVertex(k)[0] > leftMax) //no conflict
371 {
372 //update oldRightI if necessary
373 if(rightChain->getVertex(k)[0] < rightMin)
374 {
375 rightMin = rightChain->getVertex(k)[0];
376 oldRightI = k;
377 }
378 }
379 else //there is a conflict
380 break; //the for-loop. below right(k-1) is seperated: oldLeftI, oldRightI.
381 }
382 break; //the while loop
383 }
384 else if(j<rightStartIndex) //rightChain is done
385 {
386 for(k=i-1; k>= leftStartIndex; k--)
387 {
388 if(leftChain->getVertex(k)[0] < rightMin) //no conflict
389 {
390 //update oldLeftI if necessary
391 if(leftChain->getVertex(k)[0] > leftMax)
392 {
393 leftMax = leftChain->getVertex(k)[0];
394 oldLeftI = k;
395 }
396 }
397 else //there is a conflict
398 break; //the for loop
399 }
400 break; //the while loop
401 }
402 else if(leftChain->getVertex(i)[1] > rightChain->getVertex(j)[1]) //left hgiher
403 {
404 if(leftChain->getVertex(i)[0] > leftMax) //update leftMax and newLeftI.
405 {
406 leftMax = leftChain->getVertex(i)[0];
407 newLeftI = i;
408 }
409 for(k=j-1; k>= rightStartIndex; k--) //update rightMin and newRightI.
410 {
411 if(rightChain->getVertex(k)[1] > leftChain->getVertex(i)[1])
412 break;
413 if(rightChain->getVertex(k)[0] < rightMin)
414 {
415 rightMin = rightChain->getVertex(k)[0];
416 newRightI = k;
417 }
418 }
419 j = k; //next working j, since j will be higher than i in next loop
420 if(leftMax >= rightMin) //there is a conflict
421 break;
422 else //still no conflict
423 {
424 oldLeftI = newLeftI;
425 oldRightI = newRightI;
426 }
427 }
428 else //right higher
429 {
430 if(rightChain->getVertex(j)[0] < rightMin)
431 {
432 rightMin = rightChain->getVertex(j)[0];
433 newRightI = j;
434 }
435 for(k=i-1; k>= leftStartIndex; k--)
436 {
437 if(leftChain->getVertex(k)[1] > rightChain->getVertex(j)[1])
438 break;
439 if(leftChain->getVertex(k)[0] > leftMax)
440 {
441 leftMax = leftChain->getVertex(k)[0];
442 newLeftI = k;
443 }
444 }
445 i = k; //next working i, since i will be higher than j next loop
446
447 if(leftMax >= rightMin) //there is a conflict
448 break;
449 else //still no conflict
450 {
451 oldLeftI = newLeftI;
452 oldRightI = newRightI;
453 }
454 }
455 }//end of while loop
456 //now oldLeftI and oldRightI are the desired separeator index, notice that there are not necessarily valid
457 if(oldLeftI > leftEndIndex || oldRightI > rightEndIndex)
458 return 0;
459 else
460 {
461 ret_sep_left = oldLeftI;
462 ret_sep_right = oldRightI;
463 return 1;
464 }
465 }
466
467
468 void sampleCompTop(Real* topVertex,
469 vertexArray* leftChain,
470 Int leftStartIndex,
471 vertexArray* rightChain,
472 Int rightStartIndex,
473 gridBoundaryChain* leftGridChain,
474 gridBoundaryChain* rightGridChain,
475 Int gridIndex1,
476 Int up_leftCornerWhere,
477 Int up_leftCornerIndex,
478 Int up_rightCornerWhere,
479 Int up_rightCornerIndex,
480 primStream* pStream)
481 {
482 if(up_leftCornerWhere == 1 && up_rightCornerWhere == 1) //the top is topVertex with possible grid points
483 {
484 leftGridChain->getGrid()->outputFanWithPoint(leftGridChain->getVlineIndex(gridIndex1),
485 leftGridChain->getUlineIndex(gridIndex1),
486 rightGridChain->getUlineIndex(gridIndex1),
487 topVertex,
488 pStream);
489 return;
490 }
491
492 else if(up_leftCornerWhere != 0)
493 {
494 Real* tempTop;
495 Int tempRightStart;
496 if(up_leftCornerWhere == 1){
497 tempRightStart = rightStartIndex;
498 tempTop = topVertex;
499 }
500 else
501 {
502 tempRightStart = up_leftCornerIndex+1;
503 tempTop = rightChain->getVertex(up_leftCornerIndex);
504 }
505 sampleTopRightWithGridLine(tempTop, rightChain, tempRightStart, up_rightCornerIndex,
506 rightGridChain->getGrid(),
507 leftGridChain->getVlineIndex(gridIndex1),
508 leftGridChain->getUlineIndex(gridIndex1),
509 rightGridChain->getUlineIndex(gridIndex1),
510 pStream);
511 }
512 else if(up_rightCornerWhere != 2)
513 {
514 Real* tempTop;
515 Int tempLeftStart;
516 if(up_rightCornerWhere == 1)
517 {
518 tempLeftStart = leftStartIndex;
519 tempTop = topVertex;
520 }
521 else //0
522 {
523 tempLeftStart = up_rightCornerIndex+1;
524 tempTop = leftChain->getVertex(up_rightCornerIndex);
525 }
526 /*
527 sampleTopLeftWithGridLine(tempTop, leftChain, tempLeftStart, up_leftCornerIndex,
528 leftGridChain->getGrid(),
529 leftGridChain->getVlineIndex(gridIndex1),
530 leftGridChain->getUlineIndex(gridIndex1),
531 rightGridChain->getUlineIndex(gridIndex1),
532 pStream);
533 */
534 sampleCompTopSimple(topVertex,
535 leftChain,
536 leftStartIndex,
537 rightChain,
538 rightStartIndex,
539 leftGridChain,
540 rightGridChain,
541 gridIndex1,
542 up_leftCornerWhere,
543 up_leftCornerIndex,
544 up_rightCornerWhere,
545 up_rightCornerIndex,
546 pStream);
547 }
548 else //up_leftCornerWhere == 0, up_rightCornerWhere == 2.
549 {
550 sampleCompTopSimple(topVertex,
551 leftChain,
552 leftStartIndex,
553 rightChain,
554 rightStartIndex,
555 leftGridChain,
556 rightGridChain,
557 gridIndex1,
558 up_leftCornerWhere,
559 up_leftCornerIndex,
560 up_rightCornerWhere,
561 up_rightCornerIndex,
562 pStream);
563 return;
564 #ifdef NOT_REACHABLE //code is not reachable, for test purpose only
565 //the following code is trying to do some optimization, but not quite working, also see sampleCompBot.C:
566 Int sep_left, sep_right;
567 if(findTopSeparator(leftChain,
568 leftStartIndex,
569 up_leftCornerIndex,
570 rightChain,
571 rightStartIndex,
572 up_rightCornerIndex,
573 sep_left,
574 sep_right)
575 ) //separator exists
576 {
577
578 if( leftChain->getVertex(sep_left)[0] >= leftGridChain->get_u_value(gridIndex1) &&
579 rightChain->getVertex(sep_right)[0] <= rightGridChain->get_u_value(gridIndex1))
580 {
581 Int gridSep;
582 Int segLeftSmall, segLeftLarge, segRightSmall, segRightLarge;
583 Int valid=1; //whether the gridStep is valid or not.
584 findTopLeftSegment(leftChain,
585 sep_left,
586 up_leftCornerIndex,
587 leftGridChain->get_u_value(gridIndex1),
588 segLeftSmall,
589 segLeftLarge);
590 findTopRightSegment(rightChain,
591 sep_right,
592 up_rightCornerIndex,
593 rightGridChain->get_u_value(gridIndex1),
594 segRightSmall,
595 segRightLarge);
596 if(leftChain->getVertex(segLeftSmall)[1] >= rightChain->getVertex(segRightSmall)[1])
597 {
598 gridSep = rightGridChain->getUlineIndex(gridIndex1);
599 while(leftGridChain->getGrid()->get_u_value(gridSep) > leftChain->getVertex(segLeftSmall)[0])
600 gridSep--;
601 if(segLeftSmall<segLeftLarge)
602 if(leftGridChain->getGrid()->get_u_value(gridSep) < leftChain->getVertex(segLeftSmall+1)[0])
603 {
604 valid = 0;
605 }
606 }
607 else
608 {
609 gridSep = leftGridChain->getUlineIndex(gridIndex1);
610 while(leftGridChain->getGrid()->get_u_value(gridSep) < rightChain->getVertex(segRightSmall)[0])
611 gridSep++;
612 if(segRightSmall<segRightLarge)
613 if(leftGridChain->getGrid()->get_u_value(gridSep) > rightChain->getVertex(segRightSmall+1)[0])
614 {
615 valid = 0;
616 }
617 }
618
619 if(! valid)
620 {
621 sampleCompTopSimple(topVertex,
622 leftChain,
623 leftStartIndex,
624 rightChain,
625 rightStartIndex,
626 leftGridChain,
627 rightGridChain,
628 gridIndex1,
629 up_leftCornerWhere,
630 up_leftCornerIndex,
631 up_rightCornerWhere,
632 up_rightCornerIndex,
633 pStream);
634 }
635 else
636 {
637 sampleTopLeftWithGridLinePost(leftChain->getVertex(segLeftSmall),
638 leftChain,
639 segLeftSmall+1,
640 segLeftSmall+1,
641 segLeftLarge,
642 up_leftCornerIndex,
643 leftGridChain->getGrid(),
644 leftGridChain->getVlineIndex(gridIndex1),
645 leftGridChain->getUlineIndex(gridIndex1),
646 gridSep,
647 pStream);
648 sampleTopRightWithGridLinePost(rightChain->getVertex(segRightSmall),
649 rightChain,
650 segRightSmall+1,
651 segRightSmall+1,
652 segRightLarge,
653 up_rightCornerIndex,
654 leftGridChain->getGrid(),
655 leftGridChain->getVlineIndex(gridIndex1),
656 gridSep,
657 rightGridChain->getUlineIndex(gridIndex1),
658 pStream);
659 Real tempBot[2];
660 tempBot[0] = leftGridChain->getGrid()->get_u_value(gridSep);
661 tempBot[1] = leftGridChain->get_v_value(gridIndex1);
662 monoTriangulationRecGen(topVertex, tempBot,
663 leftChain, leftStartIndex, segLeftSmall,
664 rightChain, rightStartIndex, segRightSmall,
665 pStream);
666 }
667 }//end if both sides have vetices inside the gridboundary points
668 else if(leftChain->getVertex(sep_left)[0] >= leftGridChain->get_u_value(gridIndex1)) //left is in, right is nout
669 {
670
671 Int segLeftSmall, segLeftLarge;
672 findTopLeftSegment(leftChain,
673 sep_left,
674 up_leftCornerIndex,
675 leftGridChain->get_u_value(gridIndex1),
676 segLeftSmall,
677 segLeftLarge);
678 assert(segLeftLarge >= sep_left);
679 monoTriangulation2(leftChain->getVertex(segLeftLarge),
680 leftGridChain->get_vertex(gridIndex1),
681 leftChain,
682 segLeftLarge+1,
683 up_leftCornerIndex,
684 1, //a increase chain,
685 pStream);
686
687 stripOfFanLeft(leftChain, segLeftLarge, segLeftSmall,
688 leftGridChain->getGrid(),
689 leftGridChain->getVlineIndex(gridIndex1),
690 leftGridChain->getUlineIndex(gridIndex1),
691 rightGridChain->getUlineIndex(gridIndex1),
692 pStream, 0);
693
694
695 monoTriangulationRecGen(topVertex, rightGridChain->get_vertex(gridIndex1),
696 leftChain, leftStartIndex, segLeftSmall,
697 rightChain, rightStartIndex, up_rightCornerIndex,
698 pStream);
699 }//end left in right out
700 else if(rightChain->getVertex(sep_right)[0] <= rightGridChain->get_u_value(gridIndex1))
701 {
702 Int segRightSmall, segRightLarge;
703 findTopRightSegment(rightChain,
704 sep_right,
705 up_rightCornerIndex,
706 rightGridChain->get_u_value(gridIndex1),
707 segRightSmall,
708 segRightLarge);
709 assert(segRightLarge>=sep_right);
710 monoTriangulation2(rightChain->getVertex(segRightLarge),
711 rightGridChain->get_vertex(gridIndex1),
712 rightChain,
713 segRightLarge+1,
714 up_rightCornerIndex,
715 0, //a decrease chain
716 pStream);
717 stripOfFanRight(rightChain, segRightLarge, segRightSmall,
718 rightGridChain->getGrid(),
719 rightGridChain->getVlineIndex(gridIndex1),
720 leftGridChain->getUlineIndex(gridIndex1),
721 rightGridChain->getUlineIndex(gridIndex1),
722 pStream, 0);
723
724
725 monoTriangulationRecGen(topVertex, leftGridChain->get_vertex(gridIndex1),
726 leftChain, leftStartIndex, up_leftCornerIndex,
727 rightChain, rightStartIndex,segRightSmall,
728 pStream);
729
730 }//end left out rigth in
731 else //left out , right out
732 {
733
734 sampleCompTopSimple(topVertex,
735 leftChain,
736 leftStartIndex,
737 rightChain,
738 rightStartIndex,
739 leftGridChain,
740 rightGridChain,
741 gridIndex1,
742 up_leftCornerWhere,
743 up_leftCornerIndex,
744 up_rightCornerWhere,
745 up_rightCornerIndex,
746 pStream);
747 }//end leftout, right out
748 }//end if separator exixts.
749 else //no separator
750 {
751
752 sampleCompTopSimple(topVertex,
753 leftChain,
754 leftStartIndex,
755 rightChain,
756 rightStartIndex,
757 leftGridChain,
758 rightGridChain,
759 gridIndex1,
760 up_leftCornerWhere,
761 up_leftCornerIndex,
762 up_rightCornerWhere,
763 up_rightCornerIndex,
764 pStream);
765 }
766 #endif
767 }//end if 0,2
768 }//end if the function
769
770
771 static void sampleCompTopSimpleOpt(gridWrap* grid,
772 Int gridV,
773 Real* topVertex, Real* botVertex,
774 vertexArray* inc_chain, Int inc_current, Int inc_end,
775 vertexArray* dec_chain, Int dec_current, Int dec_end,
776 primStream* pStream)
777 {
778 if(gridV <= 0 || dec_end<dec_current || inc_end <inc_current)
779 {
780 monoTriangulationRecGenOpt(topVertex, botVertex,
781 inc_chain, inc_current, inc_end,
782 dec_chain, dec_current, dec_end,
783 pStream);
784 return;
785 }
786 if(grid->get_v_value(gridV+1) >= topVertex[1])
787 {
788 monoTriangulationRecGenOpt(topVertex, botVertex,
789 inc_chain, inc_current, inc_end,
790 dec_chain, dec_current, dec_end,
791 pStream);
792 return;
793 }
794 Int i,j,k;
795 Real currentV = grid->get_v_value(gridV+1);
796 if(inc_chain->getVertex(inc_end)[1] <= currentV &&
797 dec_chain->getVertex(dec_end)[1] < currentV)
798 {
799 //find i bottom up so that inc_chain[i]<= curentV and inc_chain[i-1] > currentV,
800 //find j botom up so that dec_chain[j] < currentV and dec_chain[j-1] >= currentV
801 for(i=inc_end; i >= inc_current; i--)
802 {
803 if(inc_chain->getVertex(i)[1] > currentV)
804 break;
805 }
806 i++;
807 for(j=dec_end; j >= dec_current; j--)
808 {
809 if(dec_chain->getVertex(j)[1] >= currentV)
810 break;
811 }
812 j++;
813 if(inc_chain->getVertex(i)[1] <= dec_chain->getVertex(j)[1])
814 {
815 //find the k so that dec_chain[k][1] < inc_chain[i][1]
816 for(k=j; k<=dec_end; k++)
817 {
818 if(dec_chain->getVertex(k)[1] < inc_chain->getVertex(i)[1])
819 break;
820 }
821 //we know that dec_chain[j][1] >= inc_chian[i][1]
822 //we know that dec_chain[k-1][1]>=inc_chain[i][1]
823 //we know that dec_chian[k][1] < inc_chain[i][1]
824 //find l in [j, k-1] so that dec_chain[l][0] 0 is closest to
825 // inc_chain[i]
826 int l;
827 Real tempI = Real(j);
828 Real tempMin = (Real)fabs(inc_chain->getVertex(i)[0] - dec_chain->getVertex(j)[0]);
829 for(l=j+1; l<= k-1; l++)
830 {
831 if(fabs(inc_chain->getVertex(i)[0] - dec_chain->getVertex(l)[0])
832 <= tempMin)
833 {
834 tempMin = (Real)fabs(inc_chain->getVertex(i)[0] - dec_chain->getVertex(l)[0]);
835 tempI = (Real)l;
836 }
837 }
838 //inc_chain[i] and dec_chain[tempI] are connected.
839 monoTriangulationRecGenOpt(dec_chain->getVertex((int)tempI),
840 botVertex,
841 inc_chain, i, inc_end,
842 dec_chain, (int)(tempI+1), dec_end,
843 pStream);
844 //recursively do the rest
845 sampleCompTopSimpleOpt(grid,
846 gridV+1,
847 topVertex, inc_chain->getVertex(i),
848 inc_chain, inc_current, i-1,
849 dec_chain, dec_current, (int)tempI,
850 pStream);
851 }
852 else
853 {
854 //find the k so that inc_chain[k][1] <= dec_chain[j][1]
855 for(k=i; k<=inc_end; k++)
856 {
857 if(inc_chain->getVertex(k)[1] <= dec_chain->getVertex(j)[1])
858 break;
859 }
860 //we know that inc_chain[i] > dec_chain[j]
861 //we know that inc_chain[k-1][1] > dec_chain[j][1]
862 //we know that inc_chain[k][1] <= dec_chain[j][1]
863 //so we find l between [i,k-1] so that
864 //inc_chain[l][0] is the closet to dec_chain[j][0]
865 int tempI = i;
866 int l;
867 Real tempMin = (Real)fabs(inc_chain->getVertex(i)[0] - dec_chain->getVertex(j)[0]);
868 for(l=i+1; l<=k-1; l++)
869 {
870 if(fabs(inc_chain->getVertex(l)[0] - dec_chain->getVertex(j)[0]) <= tempMin)
871 {
872 tempMin = (Real)fabs(inc_chain->getVertex(l)[0] - dec_chain->getVertex(j)[0]);
873 tempI = l;
874 }
875 }
876
877 //inc_chain[tempI] and dec_chain[j] are connected
878
879 monoTriangulationRecGenOpt(inc_chain->getVertex(tempI),
880 botVertex,
881 inc_chain, tempI+1, inc_end,
882 dec_chain, j, dec_end,
883 pStream);
884
885 //recurvesily do the rest
886 sampleCompTopSimpleOpt(grid, gridV+1,
887 topVertex, dec_chain->getVertex(j),
888 inc_chain, inc_current, tempI,
889 dec_chain, dec_current, j-1,
890 pStream);
891 }
892 }
893 else //go to the next higher gridV
894 {
895 sampleCompTopSimpleOpt(grid,
896 gridV+1,
897 topVertex, botVertex,
898 inc_chain, inc_current, inc_end,
899 dec_chain, dec_current, dec_end,
900 pStream);
901 }
902 }
903
904 void sampleCompTopSimple(Real* topVertex,
905 vertexArray* leftChain,
906 Int leftStartIndex,
907 vertexArray* rightChain,
908 Int rightStartIndex,
909 gridBoundaryChain* leftGridChain,
910 gridBoundaryChain* rightGridChain,
911 Int gridIndex1,
912 Int up_leftCornerWhere,
913 Int up_leftCornerIndex,
914 Int up_rightCornerWhere,
915 Int up_rightCornerIndex,
916 primStream* pStream)
917 {
918 //the plan is to use monotriangulation algortihm.
919 Int i,k;
920 Real* ActualTop;
921 Real* ActualBot;
922 Int ActualLeftStart, ActualLeftEnd;
923 Int ActualRightStart, ActualRightEnd;
924
925 //creat an array to store the points on the grid line
926 gridWrap* grid = leftGridChain->getGrid();
927 Int gridV = leftGridChain->getVlineIndex(gridIndex1);
928 Int gridLeftU = leftGridChain->getUlineIndex(gridIndex1);
929 Int gridRightU = rightGridChain->getUlineIndex(gridIndex1);
930
931 Real2* gridPoints = (Real2*) malloc(sizeof(Real2) * (gridRightU - gridLeftU +1));
932 assert(gridPoints);
933
934 for(k=0, i=gridRightU; i>= gridLeftU; i--, k++)
935 {
936 gridPoints[k][0] = grid->get_u_value(i);
937 gridPoints[k][1] = grid->get_v_value(gridV);
938 }
939
940 if(up_leftCornerWhere != 2)
941 ActualRightStart = rightStartIndex;
942 else
943 ActualRightStart = up_leftCornerIndex+1; //up_leftCornerIndex will be the ActualTop
944
945 if(up_rightCornerWhere != 2) //right corner is not on right chain
946 ActualRightEnd = rightStartIndex-1; //meaning that there is no actual rigth section
947 else
948 ActualRightEnd = up_rightCornerIndex;
949
950 vertexArray ActualRightChain(max(0, ActualRightEnd-ActualRightStart+1) + gridRightU-gridLeftU+1);
951
952 for(i=ActualRightStart; i<= ActualRightEnd; i++)
953 ActualRightChain.appendVertex(rightChain->getVertex(i));
954 for(i=0; i<gridRightU-gridLeftU+1; i++)
955 ActualRightChain.appendVertex(gridPoints[i]);
956
957 //determine ActualLeftEnd
958 if(up_leftCornerWhere != 0)
959 ActualLeftEnd = leftStartIndex-1;
960 else
961 ActualLeftEnd = up_leftCornerIndex;
962
963 if(up_rightCornerWhere != 0)
964 ActualLeftStart = leftStartIndex;
965 else
966 ActualLeftStart = up_rightCornerIndex+1; //up_rightCornerIndex will be the actual top
967
968 if(up_leftCornerWhere == 0)
969 {
970 if(up_rightCornerWhere == 0)
971 ActualTop = leftChain->getVertex(up_rightCornerIndex);
972 else
973 ActualTop = topVertex;
974 }
975 else if(up_leftCornerWhere == 1)
976 ActualTop = topVertex;
977 else //up_leftCornerWhere == 2
978 ActualTop = rightChain->getVertex(up_leftCornerIndex);
979
980 ActualBot = gridPoints[gridRightU - gridLeftU];
981
982
983
984
985 if(leftChain->getVertex(ActualLeftEnd)[1] == ActualBot[1])
986 {
987 /*
988 monoTriangulationRecGenOpt(ActualTop, leftChain->getVertex(ActualLeftEnd),
989 leftChain,
990 ActualLeftStart, ActualLeftEnd-1,
991 &ActualRightChain,
992 0,
993 ActualRightChain.getNumElements()-1,
994 pStream);
995 */
996
997 sampleCompTopSimpleOpt(grid, gridV,
998 ActualTop, leftChain->getVertex(ActualLeftEnd),
999 leftChain,
1000 ActualLeftStart, ActualLeftEnd-1,
1001 &ActualRightChain,
1002 0,
1003 ActualRightChain.getNumElements()-1,
1004 pStream);
1005
1006 }
1007 else
1008 {
1009 /*
1010 monoTriangulationRecGenOpt(ActualTop, ActualBot, leftChain,
1011 ActualLeftStart, ActualLeftEnd,
1012 &ActualRightChain,
1013 0, ActualRightChain.getNumElements()-2, //the last is the bot.
1014 pStream);
1015 */
1016
1017 sampleCompTopSimpleOpt(grid, gridV,
1018 ActualTop, ActualBot, leftChain,
1019 ActualLeftStart, ActualLeftEnd,
1020 &ActualRightChain,
1021 0, ActualRightChain.getNumElements()-2, //the last is the bot.
1022 pStream);
1023
1024
1025 }
1026
1027 free(gridPoints);
1028
1029 }
1030