Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / glu / sgi / libnurbs / nurbtess / sampleCompBot.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 "zlassert.h"
41 #include "sampleCompBot.h"
42 #include "sampleCompRight.h"
43
44 #define max(a,b) ((a>b)? a:b)
45
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, 
53                         Int leftEnd,
54                         Int leftCorner,
55                         Real u,
56                         Int& ret_index_mono,
57                         Int& ret_index_pass)
58 {
59   Int i;
60
61   assert(leftCorner <= leftEnd);
62   for(i=leftCorner; i<= leftEnd; i++)
63     if(leftChain->getVertex(i)[0] >= u)
64       break;
65   ret_index_pass = i;
66   if(ret_index_pass <= leftEnd)
67     {
68       for(i=ret_index_pass; i< leftEnd; i++)
69         {
70           if(leftChain->getVertex(i+1)[0] <= leftChain->getVertex(i)[0])
71             break;
72         }
73       ret_index_mono = i;
74     }
75
76 }
77
78 void findBotRightSegment(vertexArray* rightChain, 
79                          Int rightEnd,
80                          Int rightCorner,
81                          Real u,
82                          Int& ret_index_mono,
83                          Int& ret_index_pass)
84 {
85   Int i;
86   assert(rightCorner <= rightEnd);
87   for(i=rightCorner; i<= rightEnd; i++)
88     if(rightChain->getVertex(i)[0] <= u)
89       break;
90
91
92
93   ret_index_pass = i;
94
95   if(ret_index_pass <= rightEnd)
96     {
97       for(i=ret_index_pass; i< rightEnd; i++)
98         {
99           if(rightChain->getVertex(i+1)[0] >= rightChain->getVertex(i)[0])
100             break;
101         }
102       ret_index_mono = i;
103     }
104 }
105
106
107 void sampleBotRightWithGridLinePost(Real* botVertex,
108                                     vertexArray* rightChain,
109                                     Int rightEnd,
110                                     Int segIndexMono,
111                                     Int segIndexPass,
112                                     Int rightCorner,
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(segIndexPass > rightCorner) //from corner to pass-1 is > u.
121     {
122       Real *tempBot;
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.
126         tempBot = botVertex; 
127       Real tempTop[2];
128       tempTop[0] = grid->get_u_value(rightU);
129       tempTop[1] = grid->get_v_value(gridV);
130       
131       monoTriangulation2(tempTop, tempBot,
132                          rightChain,
133                          rightCorner,
134                          segIndexPass-1,
135                          0, // a decrease chain
136                          pStream);
137     }
138
139   //the possible section which is strictly Umonotone
140   if(segIndexPass <= rightEnd) //segIndex pass and mono exist
141     {
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
145       int do_optimize = 1;
146       if(botVertex[0] <= grid->get_u_value(leftU))
147         do_optimize = 0;
148       else
149         {
150           //we also have to make sure that botVertex is the left most vertex on the chain
151           int i;
152           for(i=segIndexMono; i<=rightEnd; i++)
153             if(rightChain->getVertex(i)[0] <= botVertex[0])
154               {
155                 do_optimize = 0;
156                 break;
157               }
158         }
159
160       if(do_optimize)
161         {
162           //find midU so that grid->get_u_value(midU) <= botVertex[0]
163           //and               grid->get_u_value(midU) >  botVertex[0]
164           int midU = leftU;
165           while(grid->get_u_value(midU) <= botVertex[0])
166             {
167               midU++;
168               if(midU > rightU)
169                 break;
170             }
171           midU--;
172
173           grid->outputFanWithPoint(gridV, leftU, midU, botVertex, pStream);
174           stripOfFanRight(rightChain, segIndexMono, segIndexPass, grid, gridV, midU, rightU, pStream, 1);         
175           Real tempTop[2];
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);
179         }
180       else //not optimize
181         {
182           stripOfFanRight(rightChain, segIndexMono, segIndexPass, grid, gridV, leftU, rightU, pStream, 1);
183           Real tempTop[2];
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);
187         }
188     }
189   else //the botVertex forms a fan witht eh grid points
190     grid->outputFanWithPoint(gridV, leftU, rightU, botVertex, pStream);
191 }
192       
193 void sampleBotRightWithGridLine(Real* botVertex, 
194                                 vertexArray* rightChain,
195                                 Int rightEnd,
196                                 Int rightCorner,
197                                 gridWrap* grid,
198                                 Int gridV,
199                                 Int leftU,
200                                 Int rightU,
201                                 primStream* pStream)
202 {
203   //if right chaain is empty, then there is only one bot vertex with
204   //one grid line
205   if(rightEnd<rightCorner){
206     grid->outputFanWithPoint(gridV, leftU, rightU, botVertex, pStream);
207     return;
208   }
209
210   Int segIndexMono = 0, segIndexPass;
211   findBotRightSegment(rightChain,
212                       rightEnd,
213                       rightCorner,
214                       grid->get_u_value(rightU),
215                       segIndexMono,
216                       segIndexPass);
217
218   sampleBotRightWithGridLinePost(botVertex, 
219                                  rightChain,
220                                  rightEnd,
221                                  segIndexMono,
222                                  segIndexPass,
223                                  rightCorner,
224                                  grid,
225                                  gridV,
226                                  leftU,
227                                  rightU,
228                                  pStream);
229 }
230   
231  
232 void sampleBotLeftWithGridLinePost(Real* botVertex,
233                                    vertexArray* leftChain,
234                                    Int leftEnd,
235                                    Int segIndexMono,
236                                    Int segIndexPass,
237                                    Int leftCorner,
238                                    gridWrap* grid,
239                                    Int gridV,
240                                    Int leftU, 
241                                    Int rightU,
242                                    primStream* pStream)
243 {
244
245   //the possible section which is to the left of leftU
246   if(segIndexPass > leftCorner) //at least leftCorner is to the left of leftU
247     {
248       Real *tempBot; 
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
252         tempBot = botVertex;
253       Real tempTop[2];
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,
258                          pStream);
259     }
260   //the possible section which is strictly Umonotone
261   if(segIndexPass <= leftEnd) //segIndexpass and mono exist
262     {
263       stripOfFanLeft(leftChain, segIndexMono, segIndexPass, grid, gridV, leftU, rightU, pStream, 1);
264       Real tempTop[2];
265       tempTop[0] = grid->get_u_value(rightU);
266       tempTop[1] = grid->get_v_value(gridV);
267
268       monoTriangulation2(tempTop, botVertex, leftChain, segIndexMono, leftEnd, 
269                          1,  //increase chain
270                          pStream);
271     }
272   else //the botVertex forms a fan with the grid points
273     {
274       grid->outputFanWithPoint(gridV, leftU, rightU, botVertex, pStream);
275     }
276
277 }
278
279 void sampleBotLeftWithGridLine(Real* botVertex,
280                                vertexArray* leftChain,
281                                Int leftEnd,
282                                Int leftCorner,
283                                gridWrap* grid,
284                                Int gridV,
285                                Int leftU,
286                                Int rightU,
287                                primStream* pStream)
288 {
289
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);
293     return;
294   }
295
296   Int segIndexPass, segIndexMono = 0;
297   findBotLeftSegment(leftChain, leftEnd, leftCorner, grid->get_u_value(leftU), segIndexMono, segIndexPass);
298
299   sampleBotLeftWithGridLinePost(botVertex,
300                             leftChain,
301                             leftEnd,
302                             segIndexMono,
303                             segIndexPass,
304                             leftCorner,
305                             grid,
306                             gridV,
307                             leftU, rightU, pStream);
308 }
309
310 //return 1 if separator exists, 0 otherwise
311 Int findBotSeparator(vertexArray* leftChain,
312                      Int leftEnd,
313                      Int leftCorner,
314                      vertexArray* rightChain,
315                      Int rightEnd,
316                      Int rightCorner,
317                      Int& ret_sep_left,
318                      Int& ret_sep_right)
319 {
320   Int oldLeftI, oldRightI, newLeftI, newRightI;
321   Int i,j,k;
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
325     {
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]; 
330     }
331   else //rightlower
332     {
333       oldLeftI = leftCorner;
334       oldRightI = rightCorner-1;
335       leftMax = leftChain->getVertex(leftCorner)[0];
336       rightMin = rightChain->getVertex(rightCorner)[0] + Real(1.0);
337     }
338
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.
343   i = leftCorner;
344   j = rightCorner;
345   while(1)
346     {
347       newLeftI = oldLeftI;
348       newRightI = oldRightI;
349       if(i> leftEnd) //left chain is doen , go through remaining right chain
350         {
351           for(k=j+1; k<= rightEnd; k++)
352             {
353               if(rightChain->getVertex(k)[0] > leftMax) //no conflict
354                 {
355                   //update oldRightI if necessary
356                   if(rightChain->getVertex(k)[0] < rightMin)
357                     {
358                       rightMin = rightChain->getVertex(k)[0];
359                       oldRightI = k;
360                     }
361                 }
362               else //there is a conflict
363                 break; //the for-loop, above right(k+1) is separated: oldLeftI, oldRightI
364             }
365           break; //the while loop
366         }
367       else if(j > rightEnd) //right Chain is doen
368         {
369           for(k=i+1; k<= leftEnd; k++)
370             {
371               if(leftChain->getVertex(k)[0] < rightMin) //no conflict
372                 {
373                   //update oldLeftI if necessary
374                   if(leftChain->getVertex(k)[0] > leftMax)
375                     {
376                       leftMax =  leftChain->getVertex(k)[0];
377                       oldLeftI = k;
378                     }
379                 }
380               else //there is a conflict
381                 break; //the for-loop, above left(k+1) is separated: oldLeftI, oldRightI
382             }
383           break; //the while loop
384         }
385       else if(leftChain->getVertex(i)[1] < rightChain->getVertex(j)[1]) //left lower
386         {
387
388           if(leftChain->getVertex(i)[0] > leftMax) //update leftMax amd newLeftI
389             {
390               leftMax = leftChain->getVertex(i)[0];
391               newLeftI = i;
392             }
393           for(k=j+1; k<= rightEnd; k++) //update rightMin and newRightI;
394             {
395               if(rightChain->getVertex(k)[1] < leftChain->getVertex(i)[1]) //right gets lower
396                 break;
397               if(rightChain->getVertex(k)[0] < rightMin)
398                 {
399                   rightMin = rightChain->getVertex(k)[0];
400                   newRightI = k;
401                 }
402             }
403           j = k; //next working j, since j will he lower than i in next loop
404           if(leftMax >= rightMin) //there is a conflict
405             break;
406           else //still no conflict
407             {
408               oldLeftI = newLeftI;
409               oldRightI = newRightI;
410
411             }
412         }
413       else //right lower
414         {
415           if(rightChain->getVertex(j)[0] < rightMin)
416             {
417               rightMin = rightChain->getVertex(j)[0];
418               newRightI = j;
419             }
420           for(k=i+1; k<= leftEnd; k++)
421             {
422               if(leftChain->getVertex(k)[1] < rightChain->getVertex(j)[1])
423                 break;
424               if(leftChain->getVertex(k)[0] > leftMax)
425                 {
426                   leftMax = leftChain->getVertex(k)[0];
427                   newLeftI = k;
428                 }
429             }
430           i=k; //nexct working i, since i will be lower than j next loop
431           if(leftMax >= rightMin) //there is conflict
432             break;
433           else //still no conflict
434             {
435               oldLeftI = newLeftI;
436               oldRightI = newRightI;
437             }
438         }
439     }//end of while loop
440   //now oldLeftI and oldRight I are the desired separator index notice that they are not 
441   //necessarily valid 
442   if(oldLeftI < leftCorner || oldRightI < rightCorner)
443     return 0; //no separator
444   else
445     {
446       ret_sep_left = oldLeftI;
447       ret_sep_right = oldRightI;
448       return 1;
449     }
450 }
451
452 void sampleCompBot(Real* botVertex,
453                    vertexArray* leftChain,
454                    Int leftEnd,
455                    vertexArray* rightChain,
456                    Int rightEnd,
457                    gridBoundaryChain* leftGridChain,
458                    gridBoundaryChain* rightGridChain,
459                    Int gridIndex,
460                    Int down_leftCornerWhere,
461                    Int down_leftCornerIndex,
462                    Int down_rightCornerWhere,
463                    Int down_rightCornerIndex,
464                    primStream* pStream)
465 {
466
467   if(down_leftCornerWhere == 1 && down_rightCornerWhere == 1) //the bot is botVertex with possible grid points
468     {
469
470       leftGridChain->getGrid()->outputFanWithPoint(leftGridChain->getVlineIndex(gridIndex),
471                                                    leftGridChain->getUlineIndex(gridIndex),
472                                                   rightGridChain->getUlineIndex(gridIndex),
473                                                    botVertex,
474                                                    pStream);
475       return;
476     }
477   else if(down_leftCornerWhere != 0)
478     {
479
480       Real* tempBot;
481       Int tempRightEnd;
482       if(down_leftCornerWhere == 1){
483         tempRightEnd = rightEnd;
484         tempBot = botVertex;
485       }
486       else
487         {
488           tempRightEnd = down_leftCornerIndex-1;
489           tempBot = rightChain->getVertex(down_leftCornerIndex);
490         }
491
492       sampleBotRightWithGridLine(tempBot,
493                                  rightChain, 
494                                  tempRightEnd,
495                                  down_rightCornerIndex,
496                                  rightGridChain->getGrid(),
497                                  leftGridChain->getVlineIndex(gridIndex),
498                                  leftGridChain->getUlineIndex(gridIndex),
499                                  rightGridChain->getUlineIndex(gridIndex),
500                                  pStream);
501     }
502   else if(down_rightCornerWhere != 2)
503     {
504
505       Real* tempBot;
506       Int tempLeftEnd;
507       if(down_rightCornerWhere == 1){
508         tempLeftEnd = leftEnd;
509         tempBot = botVertex;
510       }
511       else //right corner is on left chain
512         {
513           tempLeftEnd = down_rightCornerIndex-1;
514           tempBot = leftChain->getVertex(down_rightCornerIndex);          
515         }
516
517
518       sampleBotLeftWithGridLine(tempBot, leftChain, tempLeftEnd, down_leftCornerIndex, 
519                                 leftGridChain->getGrid(),
520                                 leftGridChain->getVlineIndex(gridIndex),
521                                 leftGridChain->getUlineIndex(gridIndex),
522                                 rightGridChain->getUlineIndex(gridIndex),
523                                 pStream);
524
525     }
526   else //down_leftCornereWhere == 0, down_rightCornerwhere == 2
527     {
528       sampleCompBotSimple(botVertex, 
529                           leftChain,
530                           leftEnd,
531                           rightChain,
532                           rightEnd,
533                           leftGridChain,
534                           rightGridChain,
535                           gridIndex,
536                           down_leftCornerWhere,
537                           down_leftCornerIndex,
538                           down_rightCornerWhere,
539                           down_rightCornerIndex,
540                           pStream);
541       
542       return;
543
544 #ifdef NOT_REACHABLE
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,
549                           sep_left, sep_right)
550          )//separator exiosts
551         {
552
553           if(leftChain->getVertex(sep_left)[0] >= leftGridChain->get_u_value(gridIndex) &&
554              rightChain->getVertex(sep_right)[0] <= rightGridChain->get_u_value(gridIndex))
555             {
556               Int gridSep;
557               Int segLeftMono, segLeftPass, segRightMono, segRightPass;
558               findBotLeftSegment(leftChain,
559                                  sep_left,
560                                  down_leftCornerIndex,
561                                  leftGridChain->get_u_value(gridIndex),
562                                  segLeftMono,
563                                  segLeftPass);
564               findBotRightSegment(rightChain,
565                                   sep_right,
566                                   down_rightCornerIndex,
567                                   rightGridChain->get_u_value(gridIndex),
568                                   segRightMono,
569                                   segRightPass);
570               if(leftChain->getVertex(segLeftMono)[1] <= rightChain->getVertex(segRightMono)[1])
571                 {
572                   gridSep = rightGridChain->getUlineIndex(gridIndex);
573                   while(leftGridChain->getGrid()->get_u_value(gridSep) > leftChain->getVertex(segLeftMono)[0])
574                     gridSep--;
575                 }
576               else 
577                 {
578                   gridSep = leftGridChain->getUlineIndex(gridIndex);
579                   while(leftGridChain->getGrid()->get_u_value(gridSep) < rightChain->getVertex(segRightMono)[0])
580                     gridSep++;
581                 }
582
583               sampleBotLeftWithGridLinePost(leftChain->getVertex(segLeftMono),
584                                             leftChain,
585                                             segLeftMono-1,
586                                             segLeftMono-1,
587                                             segLeftPass,
588                                             down_leftCornerIndex,
589                                             leftGridChain->getGrid(),
590                                             leftGridChain->getVlineIndex(gridIndex),
591                                             leftGridChain->getUlineIndex(gridIndex),
592                                             gridSep,
593                                             pStream);
594               sampleBotRightWithGridLinePost(rightChain->getVertex(segRightMono),
595                                              rightChain,
596                                              segRightMono-1,
597                                              segRightMono-1,
598                                              segRightPass,
599                                              down_rightCornerIndex,
600                                              rightGridChain->getGrid(),
601                                              rightGridChain->getVlineIndex(gridIndex),
602                                              gridSep,
603                                              rightGridChain->getUlineIndex(gridIndex),
604                                              pStream);
605               Real tempTop[2];
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,
611                                       pStream);
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
614             
615             {
616               Int segLeftMono, segLeftPass;
617               findBotLeftSegment(leftChain,
618                                  sep_left,
619                                  down_leftCornerIndex,
620                                  leftGridChain->get_u_value(gridIndex),
621                                  segLeftMono,
622                                  segLeftPass);                           
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),
626                                  leftChain,
627                                  down_leftCornerIndex,
628                                  segLeftPass-1,
629                                  1, //a increase chain
630                                  pStream);
631               stripOfFanLeft(leftChain, segLeftMono, segLeftPass, 
632                              leftGridChain->getGrid(),
633                              leftGridChain->getVlineIndex(gridIndex),
634                              leftGridChain->getUlineIndex(gridIndex),
635                              rightGridChain->getUlineIndex(gridIndex),
636                              pStream,1 );
637 /*
638               sampleBotLeftWithGridLinePost(leftChain->getVertex(segLeftMono),
639                                             leftChain,
640                                             segLeftMono-1,
641                                             segLeftMono-1,
642                                             segLeftPass,
643                                             down_leftCornerIndex,
644                                             leftGridChain->getGrid(),
645                                             leftGridChain->getVlineIndex(gridIndex),
646                                             leftGridChain->getUlineIndex(gridIndex),
647                                             rightGridChain->getUlineIndex(gridIndex),
648                                             pStream);                                       
649 */
650               
651               monoTriangulationRecGen(rightGridChain->get_vertex(gridIndex),
652                                       botVertex,
653                                       leftChain, segLeftMono, leftEnd,
654                                       rightChain, down_rightCornerIndex, rightEnd,
655                                       pStream);
656             }//end left in right out
657           else if(rightChain->getVertex(sep_right)[0] <= rightGridChain->get_u_value(gridIndex))//left out right in
658             {         
659               Int segRightMono, segRightPass;
660               findBotRightSegment(rightChain, sep_right, down_rightCornerIndex,
661                                   rightGridChain->get_u_value(gridIndex),
662                                   segRightMono,
663                                   segRightPass);
664
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),
668                                  rightChain,
669                                  down_rightCornerIndex,
670                                  segRightPass-1,
671                                  0, // a decrease chain
672                                  pStream);
673
674               stripOfFanRight(rightChain, segRightMono, segRightPass, 
675                               rightGridChain->getGrid(),
676                               rightGridChain->getVlineIndex(gridIndex),
677                               leftGridChain->getUlineIndex(gridIndex),
678                               rightGridChain->getUlineIndex(gridIndex),     
679                               pStream, 1);
680
681
682               monoTriangulationRecGen(leftGridChain->get_vertex(gridIndex),
683                                       botVertex,
684                                       leftChain, down_leftCornerIndex, leftEnd,
685                                       rightChain, segRightMono, rightEnd,
686                                       pStream);         
687
688             }//end left out right in
689           else //left out, right out
690             {
691               sampleCompBotSimple(botVertex, 
692                                  leftChain,
693                                  leftEnd,
694                                  rightChain,
695                                  rightEnd,
696                                  leftGridChain,
697                                  rightGridChain,
698                                  gridIndex,
699                                  down_leftCornerWhere,
700                                  down_leftCornerIndex,
701                                  down_rightCornerWhere,
702                                  down_rightCornerIndex,
703                                  pStream);
704             
705             }//end leftout right out
706         }//end if separator exists
707       else //no separator
708         {
709
710           sampleCompBotSimple(botVertex, 
711                              leftChain,
712                              leftEnd,
713                              rightChain,
714                              rightEnd,
715                              leftGridChain,
716                              rightGridChain,
717                              gridIndex,
718                              down_leftCornerWhere,
719                              down_leftCornerIndex,
720                              down_rightCornerWhere,
721                              down_rightCornerIndex,
722                              pStream);
723         }
724 #endif
725     }//end id 0 2
726 }//end if the functin
727
728                                  
729 void sampleCompBotSimple(Real* botVertex,
730                    vertexArray* leftChain,
731                    Int leftEnd,
732                    vertexArray* rightChain,
733                    Int rightEnd,
734                    gridBoundaryChain* leftGridChain,
735                    gridBoundaryChain* rightGridChain,
736                    Int gridIndex,
737                    Int down_leftCornerWhere,
738                    Int down_leftCornerIndex,
739                    Int down_rightCornerWhere,
740                    Int down_rightCornerIndex,
741                    primStream* pStream)  
742 {
743   //the plan is to use monotriangulation algorithm.
744   Int i,k;
745   Real* ActualTop;
746   Real* ActualBot;
747   Int ActualLeftStart, ActualLeftEnd;
748   Int ActualRightStart, ActualRightEnd;
749   
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));
756   assert(gridPoints);
757
758   for(k=0, i=gridRightU; i>= gridLeftU; i--, k++)
759     {
760       gridPoints[k][0] = grid->get_u_value(i);
761       gridPoints[k][1] = grid->get_v_value(gridV);
762     }
763
764   if(down_rightCornerWhere != 0) //rightCorner is not on lef
765     ActualLeftEnd = leftEnd;
766   else
767     ActualLeftEnd = down_rightCornerIndex-1; //down_rightCornerIndex will be th actualBot
768   
769   if(down_leftCornerWhere != 0) //left corner is not on let chian
770     ActualLeftStart = leftEnd+1; //meaning that there is no actual left section
771   else
772     ActualLeftStart = down_leftCornerIndex;
773   
774   vertexArray ActualLeftChain(max(0, ActualLeftEnd - ActualLeftStart +1) + gridRightU - gridLeftU +1);
775   
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));
780   
781   //determine ActualRightStart
782   if(down_rightCornerWhere != 2) //right is not on right
783     ActualRightStart = rightEnd +1; //meaning no section on right
784   else
785     ActualRightStart = down_rightCornerIndex;
786   
787   //determine actualrightEnd
788   if(down_leftCornerWhere != 2) //left is not on right
789     {
790
791       ActualRightEnd = rightEnd;
792     }
793   else //left corner is on right 
794     {
795       ActualRightEnd = down_leftCornerIndex-1; //down_leftCornerIndex will be the bot
796
797     }
798
799   //actual bot
800   if(down_rightCornerWhere == 2) 
801     {
802       if(down_leftCornerWhere == 2)
803         ActualBot = rightChain->getVertex(down_leftCornerIndex);
804       else
805         ActualBot = botVertex;
806     }
807   else if(down_rightCornerWhere == 1) //right corner bot
808     ActualBot = botVertex;
809   else //down_rightCornerWhere == 0
810     ActualBot = leftChain->getVertex(down_rightCornerIndex);
811   
812   ActualTop = gridPoints[0];
813 /*
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);
819 */
820   if(rightChain->getVertex(ActualRightStart)[1] == ActualTop[1])
821     monoTriangulationRecGenOpt(rightChain->getVertex(ActualRightStart),
822                             ActualBot,
823                             &ActualLeftChain,
824                             0, 
825                             ActualLeftChain.getNumElements()-1,
826                             rightChain,
827                             ActualRightStart+1,
828                             ActualRightEnd,
829                             pStream);
830   else
831     monoTriangulationRecGenOpt(ActualTop, ActualBot, 
832                           &ActualLeftChain,
833                           1, //the first one is the top vertex
834                           ActualLeftChain.getNumElements()-1,
835                           rightChain,
836                           ActualRightStart,
837                           ActualRightEnd,
838                           pStream);
839   free(gridPoints);
840 }
841   
842   
843                                  
844