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 
845