Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / glu / sgi / libnurbs / nurbtess / sampleMonoPoly.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 "gluos.h"
39 #include <stdlib.h>
40 #include <stdio.h>
41 #include <math.h>
42
43 #ifndef max
44 #define max(a,b) ((a>b)? a:b)
45 #endif
46 #ifndef min
47 #define min(a,b) ((a>b)? b:a)
48 #endif
49
50 #include <GL/gl.h>
51
52 #include "glimports.h"
53 #include "zlassert.h"
54 #include "sampleMonoPoly.h"
55 #include "sampleComp.h"
56 #include "polyDBG.h"
57 #include "partitionX.h"
58
59
60 #define ZERO 0.00001
61
62 //#define  MYDEBUG
63
64 //#define SHORTEN_GRID_LINE
65 //see work/newtess/internal/test/problems
66
67
68 /*split a polygon so that each vertex correcpond to one edge
69  *the head of the first edge of the returned plygon must be the head of the first
70  *edge of the origianl polygon. This is crucial for the code in sampleMonoPoly function
71  */
72  directedLine*  polygonConvert(directedLine* polygon)
73 {
74   int i;
75   directedLine* ret;
76   sampledLine* sline;
77   sline = new sampledLine(2);
78   sline->setPoint(0, polygon->getVertex(0));
79   sline->setPoint(1, polygon->getVertex(1));
80   ret=new directedLine(INCREASING, sline);
81   for(i=1; i<= polygon->get_npoints()-2; i++)
82     {
83       sline = new sampledLine(2);
84       sline->setPoint(0, polygon->getVertex(i));
85       sline->setPoint(1, polygon->getVertex(i+1));
86       ret->insert(new directedLine(INCREASING, sline));
87     }
88
89   for(directedLine *temp = polygon->getNext(); temp != polygon; temp = temp->getNext())
90     {
91       for(i=0; i<= temp->get_npoints()-2; i++)
92         {
93           sline = new sampledLine(2);
94           sline->setPoint(0, temp->getVertex(i));
95           sline->setPoint(1, temp->getVertex(i+1));
96           ret->insert(new directedLine(INCREASING, sline));
97         }
98     }
99   return ret;
100 }
101
102 void triangulateConvexPolyVertical(directedLine* topV, directedLine* botV, primStream *pStream)
103 {
104   Int i,j;
105   Int n_leftVerts;
106   Int n_rightVerts;
107   Real** leftVerts;
108   Real** rightVerts;
109   directedLine* tempV;
110   n_leftVerts = 0;
111   for(tempV = topV; tempV != botV; tempV = tempV->getNext())
112     {
113       n_leftVerts += tempV->get_npoints();
114     }
115   n_rightVerts=0;
116   for(tempV = botV; tempV != topV; tempV = tempV->getNext())
117     {
118       n_rightVerts += tempV->get_npoints();
119     }
120
121   Real2* temp_leftVerts = (Real2 *) malloc(sizeof(Real2) * n_leftVerts);
122   assert(temp_leftVerts);
123   Real2* temp_rightVerts = (Real2 *) malloc(sizeof(Real2) * n_rightVerts);
124   assert(temp_rightVerts);
125
126   leftVerts = (Real**) malloc(sizeof(Real2*) * n_leftVerts);
127   assert(leftVerts);
128   rightVerts = (Real**) malloc(sizeof(Real2*) * n_rightVerts);
129   assert(rightVerts);
130   for(i=0; i<n_leftVerts; i++)
131     leftVerts[i] = temp_leftVerts[i];
132   for(i=0; i<n_rightVerts; i++)
133     rightVerts[i] = temp_rightVerts[i];
134
135   i=0;
136   for(tempV = topV; tempV != botV; tempV = tempV->getNext())
137     {
138       for(j=1; j<tempV->get_npoints(); j++)
139         {
140           leftVerts[i][0] = tempV->getVertex(j)[0];
141           leftVerts[i][1] = tempV->getVertex(j)[1];
142           i++;
143         }
144     }
145   n_leftVerts = i;
146   i=0;
147   for(tempV = topV->getPrev(); tempV != botV->getPrev(); tempV = tempV->getPrev())
148     {
149       for(j=tempV->get_npoints()-1; j>=1; j--)
150         {
151           rightVerts[i][0] = tempV->getVertex(j)[0];
152           rightVerts[i][1] = tempV->getVertex(j)[1];
153           i++;
154         }
155     }
156   n_rightVerts = i;
157   triangulateXYMonoTB(n_leftVerts, leftVerts, n_rightVerts, rightVerts, pStream);
158   free(leftVerts);
159   free(rightVerts);
160   free(temp_leftVerts);
161   free(temp_rightVerts);
162 }  
163
164 void triangulateConvexPolyHoriz(directedLine* leftV, directedLine* rightV, primStream *pStream)
165 {
166   Int i,j;
167   Int n_lowerVerts;
168   Int n_upperVerts;
169   Real2 *lowerVerts;
170   Real2 *upperVerts;
171   directedLine* tempV;
172   n_lowerVerts=0;
173   for(tempV = leftV; tempV != rightV; tempV = tempV->getNext())
174     {
175       n_lowerVerts += tempV->get_npoints();
176     }
177   n_upperVerts=0;
178   for(tempV = rightV; tempV != leftV; tempV = tempV->getNext())
179     {
180       n_upperVerts += tempV->get_npoints();
181     }
182   lowerVerts = (Real2 *) malloc(sizeof(Real2) * n_lowerVerts);
183   assert(n_lowerVerts);
184   upperVerts = (Real2 *) malloc(sizeof(Real2) * n_upperVerts);
185   assert(n_upperVerts);
186   i=0;
187   for(tempV = leftV; tempV != rightV; tempV = tempV->getNext())
188     {
189       for(j=0; j<tempV->get_npoints(); j++)
190         {
191           lowerVerts[i][0] = tempV->getVertex(j)[0];
192           lowerVerts[i][1] = tempV->getVertex(j)[1];
193           i++;
194         }
195     }
196   i=0;
197   for(tempV = leftV->getPrev(); tempV != rightV->getPrev(); tempV = tempV->getPrev())
198     {
199       for(j=tempV->get_npoints()-1; j>=0; j--)
200         {
201           upperVerts[i][0] = tempV->getVertex(j)[0];
202           upperVerts[i][1] = tempV->getVertex(j)[1];
203           i++;
204         }
205     }
206   triangulateXYMono(n_upperVerts, upperVerts, n_lowerVerts, lowerVerts, pStream);
207   free(lowerVerts);
208   free(upperVerts);
209 }  
210 void triangulateConvexPoly(directedLine* polygon, Int ulinear, Int vlinear, primStream* pStream)
211 {
212   /*find left, right, top , bot
213     */
214   directedLine* tempV;
215   directedLine* topV;
216   directedLine* botV;
217   directedLine* leftV;
218   directedLine* rightV;
219   topV = botV = polygon;
220
221   for(tempV = polygon->getNext(); tempV != polygon; tempV = tempV->getNext())
222     {
223       if(compV2InY(topV->head(), tempV->head())<0) {
224
225         topV = tempV;
226       }
227       if(compV2InY(botV->head(), tempV->head())>0) {
228
229         botV = tempV;
230       }
231     }
232   //find leftV
233   for(tempV = topV; tempV != botV; tempV = tempV->getNext())
234     {
235       if(tempV->tail()[0] >= tempV->head()[0])
236         break;
237     }
238   leftV = tempV;
239   //find rightV
240   for(tempV = botV; tempV != topV; tempV = tempV->getNext())
241     {
242       if(tempV->tail()[0] <= tempV->head()[0])
243         break;
244     }
245   rightV = tempV;
246   if(vlinear)
247     {
248       triangulateConvexPolyHoriz( leftV, rightV, pStream);
249     }
250   else if(ulinear)
251     {
252       triangulateConvexPolyVertical(topV, botV, pStream);
253     }
254   else
255     {
256       if(DBG_is_U_direction(polygon))
257         {
258           triangulateConvexPolyHoriz( leftV, rightV, pStream);
259         }
260       else
261         triangulateConvexPolyVertical(topV, botV, pStream);
262     }
263 }             
264
265 /*for debug purpose*/
266 void drawCorners(
267                  Real* topV, Real* botV,                 
268                  vertexArray* leftChain,
269                  vertexArray* rightChain,
270                  gridBoundaryChain* leftGridChain,
271                  gridBoundaryChain* rightGridChain,
272                  Int gridIndex1,
273                  Int gridIndex2,
274                  Int leftCornerWhere,
275                  Int leftCornerIndex,
276                  Int rightCornerWhere,
277                  Int rightCornerIndex,
278                  Int bot_leftCornerWhere,
279                  Int bot_leftCornerIndex,
280                  Int bot_rightCornerWhere,
281                  Int bot_rightCornerIndex)
282 {
283   Real* leftCornerV;
284   Real* rightCornerV;
285   Real* bot_leftCornerV;
286   Real* bot_rightCornerV;
287
288   if(leftCornerWhere == 1)
289     leftCornerV = topV;
290   else if(leftCornerWhere == 0)
291     leftCornerV = leftChain->getVertex(leftCornerIndex);
292   else
293     leftCornerV = rightChain->getVertex(leftCornerIndex);
294
295   if(rightCornerWhere == 1)
296     rightCornerV = topV;
297   else if(rightCornerWhere == 0)
298     rightCornerV = leftChain->getVertex(rightCornerIndex);
299   else
300     rightCornerV = rightChain->getVertex(rightCornerIndex);
301
302   if(bot_leftCornerWhere == 1)
303     bot_leftCornerV = botV;
304   else if(bot_leftCornerWhere == 0)
305     bot_leftCornerV = leftChain->getVertex(bot_leftCornerIndex);
306   else
307     bot_leftCornerV = rightChain->getVertex(bot_leftCornerIndex);
308
309   if(bot_rightCornerWhere == 1)
310     bot_rightCornerV = botV;
311   else if(bot_rightCornerWhere == 0)
312     bot_rightCornerV = leftChain->getVertex(bot_rightCornerIndex);
313   else
314     bot_rightCornerV = rightChain->getVertex(bot_rightCornerIndex);
315
316   Real topGridV = leftGridChain->get_v_value(gridIndex1);
317   Real topGridU1 = leftGridChain->get_u_value(gridIndex1);
318   Real topGridU2 = rightGridChain->get_u_value(gridIndex1);
319   Real botGridV = leftGridChain->get_v_value(gridIndex2);
320   Real botGridU1 = leftGridChain->get_u_value(gridIndex2);
321   Real botGridU2 = rightGridChain->get_u_value(gridIndex2);
322   
323   glBegin(GL_LINE_STRIP);
324   glVertex2fv(leftCornerV);
325   glVertex2f(topGridU1, topGridV);
326   glEnd();
327
328   glBegin(GL_LINE_STRIP);
329   glVertex2fv(rightCornerV);
330   glVertex2f(topGridU2, topGridV);
331   glEnd();
332
333   glBegin(GL_LINE_STRIP);
334   glVertex2fv(bot_leftCornerV);
335   glVertex2f(botGridU1, botGridV);
336   glEnd();
337
338   glBegin(GL_LINE_STRIP);
339   glVertex2fv(bot_rightCornerV);
340   glVertex2f(botGridU2, botGridV);
341   glEnd();
342
343
344 }
345                  
346 void toVertexArrays(directedLine* topV, directedLine* botV, vertexArray& leftChain, vertexArray& rightChain)
347 {  
348   Int i;
349   directedLine* tempV;
350   for(i=1; i<=topV->get_npoints()-2; i++) { /*the first vertex is the top vertex which doesn't belong to inc_chain*/
351     leftChain.appendVertex(topV->getVertex(i));
352   }
353   for(tempV = topV->getNext(); tempV != botV; tempV = tempV->getNext())
354     {
355       for(i=0; i<=tempV->get_npoints()-2; i++){
356         leftChain.appendVertex(tempV->getVertex(i));
357       }
358     }  
359
360   for(tempV = topV->getPrev(); tempV != botV; tempV = tempV->getPrev())
361     {
362       for(i=tempV->get_npoints()-2; i>=0; i--){
363         rightChain.appendVertex(tempV->getVertex(i));
364       }
365     }
366   for(i=botV->get_npoints()-2; i>=1; i--){ 
367     rightChain.appendVertex(tempV->getVertex(i));
368   }
369 }
370
371
372 void findTopAndBot(directedLine* polygon, directedLine*& topV, directedLine*& botV)
373 {
374   assert(polygon);
375   directedLine* tempV;
376   topV = botV = polygon;
377    for(tempV = polygon->getNext(); tempV != polygon; tempV = tempV->getNext())
378     {
379       if(compV2InY(topV->head(), tempV->head())<0) {
380         topV = tempV;
381       }
382       if(compV2InY(botV->head(), tempV->head())>0) {
383         botV = tempV;
384       }
385     }
386 }
387    
388 void findGridChains(directedLine* topV, directedLine* botV, 
389                     gridWrap* grid,
390                     gridBoundaryChain*& leftGridChain,
391                     gridBoundaryChain*& rightGridChain)
392 {
393   /*find the first(top) and the last (bottom) grid line which intersect the
394    *this polygon
395    */
396   Int firstGridIndex; /*the index in the grid*/
397   Int lastGridIndex;
398
399   firstGridIndex = (Int) ((topV->head()[1] - grid->get_v_min()) / (grid->get_v_max() - grid->get_v_min()) * (grid->get_n_vlines()-1));
400
401   if(botV->head()[1] < grid->get_v_min())
402     lastGridIndex = 0;
403   else
404     lastGridIndex  = (Int) ((botV->head()[1] - grid->get_v_min()) / (grid->get_v_max() - grid->get_v_min()) * (grid->get_n_vlines()-1)) + 1;
405
406   /*find the interval inside  the polygon for each gridline*/
407   Int *leftGridIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1));
408   assert(leftGridIndices);
409   Int *rightGridIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1));
410   assert(rightGridIndices);
411   Int *leftGridInnerIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1));
412   assert(leftGridInnerIndices);
413   Int *rightGridInnerIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1));
414   assert(rightGridInnerIndices);
415
416   findLeftGridIndices(topV, firstGridIndex, lastGridIndex, grid,  leftGridIndices, leftGridInnerIndices);
417
418   findRightGridIndices(topV, firstGridIndex, lastGridIndex, grid,  rightGridIndices, rightGridInnerIndices);
419
420   leftGridChain =  new gridBoundaryChain(grid, firstGridIndex, firstGridIndex-lastGridIndex+1, leftGridIndices, leftGridInnerIndices);
421
422   rightGridChain = new gridBoundaryChain(grid, firstGridIndex, firstGridIndex-lastGridIndex+1, rightGridIndices, rightGridInnerIndices);
423
424   free(leftGridIndices);
425   free(rightGridIndices);
426   free(leftGridInnerIndices);
427   free(rightGridInnerIndices);
428 }
429
430 void findDownCorners(Real *botVertex, 
431                    vertexArray *leftChain, Int leftChainStartIndex, Int leftChainEndIndex,
432                    vertexArray *rightChain, Int rightChainStartIndex, Int rightChainEndIndex,
433                    Real v,
434                    Real uleft,
435                    Real uright,
436                    Int& ret_leftCornerWhere, /*0: left chain, 1: topvertex, 2: rightchain*/
437                    Int& ret_leftCornerIndex, /*useful when ret_leftCornerWhere == 0 or 2*/
438                    Int& ret_rightCornerWhere, /*0: left chain, 1: topvertex, 2: rightchain*/
439                    Int& ret_rightCornerIndex /*useful when ret_leftCornerWhere == 0 or 2*/
440                    )
441 {
442 #ifdef MYDEBUG
443 printf("*************enter find donw corner\n");
444 printf("finddownCorner: v=%f, uleft=%f, uright=%f\n", v, uleft, uright);
445 printf("(%i,%i,%i,%i)\n", leftChainStartIndex, leftChainEndIndex,rightChainStartIndex, rightChainEndIndex); 
446 printf("left chain is\n");
447 leftChain->print();
448 printf("right chain is\n");
449 rightChain->print();
450 #endif
451
452   assert(v > botVertex[1]);
453   Real leftGridPoint[2];
454   leftGridPoint[0] = uleft;
455   leftGridPoint[1] = v;
456   Real rightGridPoint[2];
457   rightGridPoint[0] = uright;
458   rightGridPoint[1] = v;
459
460   Int i;
461   Int index1, index2;
462
463   index1 = leftChain->findIndexBelowGen(v, leftChainStartIndex, leftChainEndIndex);
464   index2 = rightChain->findIndexBelowGen(v, rightChainStartIndex, rightChainEndIndex);
465
466   if(index2 <= rightChainEndIndex) //index2 was found above
467     index2 = rightChain->skipEqualityFromStart(v, index2, rightChainEndIndex);
468
469   if(index1>leftChainEndIndex && index2 > rightChainEndIndex) /*no point below v on left chain or right chain*/
470     {
471
472       /*the botVertex is the only vertex below v*/
473       ret_leftCornerWhere = 1;
474       ret_rightCornerWhere = 1;
475     }
476   else if(index1>leftChainEndIndex ) /*index2 <= rightChainEndIndex*/
477     {
478
479       ret_rightCornerWhere = 2; /*on right chain*/
480       ret_rightCornerIndex = index2;
481
482
483       Real tempMin = rightChain->getVertex(index2)[0];
484       Int tempI = index2;
485       for(i=index2+1; i<= rightChainEndIndex; i++)
486         if(rightChain->getVertex(i)[0] < tempMin)
487           {
488             tempI = i;
489             tempMin = rightChain->getVertex(i)[0];
490           }
491
492
493       //we consider whether we can use botVertex as left corner. First check 
494       //if (leftGirdPoint, botVertex) interesects right chian or not.
495      if(DBG_intersectChain(rightChain, rightChainStartIndex,rightChainEndIndex,
496                                     leftGridPoint, botVertex))
497        {
498          ret_leftCornerWhere = 2;//right
499          ret_leftCornerIndex = index2; //should use tempI???
500        }
501      else if(botVertex[0] < tempMin)
502        ret_leftCornerWhere = 1; //bot
503      else
504        {
505          ret_leftCornerWhere = 2; //right
506          ret_leftCornerIndex = tempI;
507        }
508     }
509   else if(index2> rightChainEndIndex) /*index1<=leftChainEndIndex*/
510     {
511       ret_leftCornerWhere = 0; /*left chain*/
512       ret_leftCornerIndex = index1;
513       
514       /*find the vertex on the left chain with the maximum u,
515        *either this vertex or the botvertex can be used as the right corner
516        */
517
518       Int tempI;
519       //skip those points which are equal to v. (avoid degeneratcy)
520       for(tempI = index1; tempI <= leftChainEndIndex; tempI++)
521         if(leftChain->getVertex(tempI)[1] < v) 
522           break;
523       if(tempI > leftChainEndIndex)
524         ret_rightCornerWhere = 1;
525       else
526         {
527           Real tempMax = leftChain->getVertex(tempI)[0];
528           for(i=tempI; i<= leftChainEndIndex; i++)
529             if(leftChain->getVertex(i)[0] > tempMax)
530               {
531                 tempI = i;
532                 tempMax = leftChain->getVertex(i)[0];
533               }
534
535
536
537           //we consider whether we can use botVertex as a corner. So first we check 
538           //whether (rightGridPoint, botVertex) interescts the left chain or not.
539           if(DBG_intersectChain(leftChain, leftChainStartIndex,leftChainEndIndex,
540                                     rightGridPoint, botVertex))
541             {
542               ret_rightCornerWhere = 0;
543               ret_rightCornerIndex = index1; //should use tempI???
544             }
545           else if(botVertex[0] > tempMax)
546             {
547                       
548               ret_rightCornerWhere = 1;
549             }
550           else
551             {
552               ret_rightCornerWhere = 0;
553               ret_rightCornerIndex = tempI;
554             }
555         }
556       
557     }
558   else /*index1<=leftChainEndIndex and index2 <=rightChainEndIndex*/
559     {
560       if(leftChain->getVertex(index1)[1] >= rightChain->getVertex(index2)[1]) /*left point above right point*/
561         {
562           ret_leftCornerWhere = 0; /*on left chain*/
563           ret_leftCornerIndex = index1;
564
565           Real tempMax;
566           Int tempI;
567
568           tempI = index1;
569           tempMax = leftChain->getVertex(index1)[0];
570
571           /*find the maximum u for all the points on the left above the right point index2*/
572           for(i=index1+1; i<= leftChainEndIndex; i++)
573             {
574               if(leftChain->getVertex(i)[1] < rightChain->getVertex(index2)[1])
575                 break;
576
577               if(leftChain->getVertex(i)[0]>tempMax)
578                 {
579                   tempI = i;
580                   tempMax = leftChain->getVertex(i)[0];
581                 }
582             }
583           //we consider if we can use rightChain(index2) as right corner
584           //we check if (rightChain(index2), rightGidPoint) intersecs left chain or not.
585           if(DBG_intersectChain(leftChain, leftChainStartIndex,leftChainEndIndex, rightGridPoint, rightChain->getVertex(index2)))
586             {
587               ret_rightCornerWhere = 0;
588               ret_rightCornerIndex = index1; //should use tempI???
589             }
590           else if(tempMax >= rightChain->getVertex(index2)[0] ||
591              tempMax >= uright
592              )
593             {
594
595               ret_rightCornerWhere = 0; /*on left Chain*/
596               ret_rightCornerIndex = tempI;
597             }
598           else
599             {
600               ret_rightCornerWhere = 2; /*on right chain*/
601               ret_rightCornerIndex = index2;
602             }
603         }
604       else /*left below right*/
605         {
606           ret_rightCornerWhere = 2; /*on the right*/
607           ret_rightCornerIndex = index2;
608           
609           Real tempMin;
610           Int tempI;
611           
612           tempI = index2;
613           tempMin = rightChain->getVertex(index2)[0];
614           
615           /*find the minimum u for all the points on the right above the left poitn index1*/
616           for(i=index2+1; i<= rightChainEndIndex; i++)
617             {
618               if( rightChain->getVertex(i)[1] < leftChain->getVertex(index1)[1])
619                 break;
620               if(rightChain->getVertex(i)[0] < tempMin)
621                 {
622                   tempI = i;
623                   tempMin = rightChain->getVertex(i)[0];
624                 }
625             }
626
627           //we consider if we can use leftchain(index1) as left corner. 
628           //we check if (leftChain(index1) intersects right chian or not
629           if(DBG_intersectChain(rightChain, rightChainStartIndex, rightChainEndIndex, leftGridPoint, leftChain->getVertex(index1)))
630             {
631               ret_leftCornerWhere = 2;
632               ret_leftCornerIndex = index2; //should use tempI???
633               }
634           else if(tempMin <= leftChain->getVertex(index1)[0] ||
635              tempMin <= uleft)                          
636             {
637               ret_leftCornerWhere = 2; /* on right chain*/
638               ret_leftCornerIndex = tempI;
639             }
640           else
641             {
642               ret_leftCornerWhere = 0; /*on left chain*/
643               ret_leftCornerIndex = index1;
644             }
645         }
646     }
647
648 }
649
650
651 void findUpCorners(Real *topVertex, 
652                    vertexArray *leftChain, Int leftChainStartIndex, Int leftChainEndIndex,
653                    vertexArray *rightChain, Int rightChainStartIndex, Int rightChainEndIndex,
654                    Real v,
655                    Real uleft,
656                    Real uright,
657                    Int& ret_leftCornerWhere, /*0: left chain, 1: topvertex, 2: rightchain*/
658                    Int& ret_leftCornerIndex, /*useful when ret_leftCornerWhere == 0 or 2*/
659                    Int& ret_rightCornerWhere, /*0: left chain, 1: topvertex, 2: rightchain*/
660                    Int& ret_rightCornerIndex /*useful when ret_leftCornerWhere == 0 or 2*/
661                    )
662 {
663 #ifdef MYDEBUG
664 printf("***********enter findUpCorners\n");
665 #endif
666
667   assert(v < topVertex[1]);
668   Real leftGridPoint[2];
669   leftGridPoint[0] = uleft;
670   leftGridPoint[1] = v;
671   Real rightGridPoint[2];
672   rightGridPoint[0] = uright;
673   rightGridPoint[1] = v;
674
675   Int i;
676   Int index1, index2;
677
678   index1 = leftChain->findIndexFirstAboveEqualGen(v, leftChainStartIndex, leftChainEndIndex);
679
680
681   index2 = rightChain->findIndexFirstAboveEqualGen(v, rightChainStartIndex, rightChainEndIndex);
682
683   if(index2>= leftChainStartIndex)  //index2 was found above  
684     index2 = rightChain->skipEqualityFromStart(v, index2, rightChainEndIndex);
685
686   if(index1<leftChainStartIndex && index2 <rightChainStartIndex) /*no point above v on left chain or right chain*/
687     {
688       /*the topVertex is the only vertex above v*/
689       ret_leftCornerWhere = 1;
690       ret_rightCornerWhere = 1;
691     }
692   else if(index1<leftChainStartIndex ) /*index2 >= rightChainStartIndex*/
693     {
694       ret_rightCornerWhere = 2; /*on right chain*/
695       ret_rightCornerIndex = index2;
696
697       //find the minimum u on right top, either that, or top, or right[index2] is the left corner
698       Real tempMin = rightChain->getVertex(index2)[0];
699       Int tempI = index2;
700       for(i=index2-1; i>=rightChainStartIndex; i--)
701         if(rightChain->getVertex(i)[0] < tempMin)
702           {
703             tempMin = rightChain->getVertex(i)[0];
704             tempI = i;
705           }
706       //chech whether (leftGridPoint, top) intersects rightchai,
707       //if yes, use right corner as left corner
708       //if not, use top or right[tempI] as left corner
709       if(DBG_intersectChain(rightChain, rightChainStartIndex, rightChainEndIndex,
710                         leftGridPoint, topVertex))
711         {
712           ret_leftCornerWhere = 2; //rightChain
713           ret_leftCornerIndex = index2; 
714         }
715       else if(topVertex[0] < tempMin)
716         ret_leftCornerWhere = 1; /*topvertex*/
717       else
718         {
719           ret_leftCornerWhere = 2; //right chain
720           ret_leftCornerIndex = tempI;
721         }
722               
723     }
724   else if(index2< rightChainStartIndex) /*index1>=leftChainStartIndex*/
725     {
726       ret_leftCornerWhere = 0; /*left chain*/
727       ret_leftCornerIndex = index1;
728        
729       //find the maximum u on the left top section. either that or topvertex, or left[index1]  is the right corner
730       Real tempMax = leftChain->getVertex(index1)[0];
731       Int tempI = index1;
732
733       for(i=index1-1; i>=leftChainStartIndex; i--){
734
735         if(leftChain->getVertex(i)[0] > tempMax)
736           {
737
738             tempMax = leftChain->getVertex(i)[0];
739             tempI = i;
740           }
741       }
742       //check whether (rightGridPoint, top) intersects leftChain or not
743       //if yes, we use leftCorner as the right corner
744       //if not, we use either top or left[tempI] as the right corner
745       if(DBG_intersectChain(leftChain, leftChainStartIndex,leftChainEndIndex,
746                             rightGridPoint, topVertex))
747          {
748            ret_rightCornerWhere = 0; //left chan
749            ret_rightCornerIndex = index1;
750          }
751       else if(topVertex[0] > tempMax)
752         ret_rightCornerWhere = 1;//topVertex
753       else
754         {
755           ret_rightCornerWhere = 0;//left chain
756           ret_rightCornerIndex = tempI;
757         }
758     }
759   else /*index1>=leftChainStartIndex and index2 >=rightChainStartIndex*/
760     {
761       if(leftChain->getVertex(index1)[1] <= rightChain->getVertex(index2)[1]) /*left point below right point*/
762         {
763           ret_leftCornerWhere = 0; /*on left chain*/
764           ret_leftCornerIndex = index1;
765
766           Real tempMax;
767           Int tempI;
768
769           tempI = index1;
770           tempMax = leftChain->getVertex(index1)[0];
771
772           /*find the maximum u for all the points on the left below the right point index2*/
773           for(i=index1-1; i>= leftChainStartIndex; i--)
774             {
775               if(leftChain->getVertex(i)[1] > rightChain->getVertex(index2)[1])
776                 break;
777
778               if(leftChain->getVertex(i)[0]>tempMax)
779                 {
780                   tempI = i;
781                   tempMax = leftChain->getVertex(i)[0];
782                 }
783             }
784           //chek whether (rightChain(index2), rightGridPoint) intersects leftchian or not
785           if(DBG_intersectChain(leftChain, leftChainStartIndex, leftChainEndIndex, rightGridPoint, rightChain->getVertex(index2)))
786              {
787                ret_rightCornerWhere = 0;
788                ret_rightCornerIndex = index1;
789              }
790           else if(tempMax >= rightChain->getVertex(index2)[0] ||
791              tempMax >= uright)
792             {
793               ret_rightCornerWhere = 0; /*on left Chain*/
794               ret_rightCornerIndex = tempI;
795             }
796           else
797             {
798               ret_rightCornerWhere = 2; /*on right chain*/
799               ret_rightCornerIndex = index2;
800             }
801         }
802       else /*left above right*/
803         {
804           ret_rightCornerWhere = 2; /*on the right*/
805           ret_rightCornerIndex = index2;
806           
807           Real tempMin;
808           Int tempI;
809           
810           tempI = index2;
811           tempMin = rightChain->getVertex(index2)[0];
812           
813           /*find the minimum u for all the points on the right below the left poitn index1*/
814           for(i=index2-1; i>= rightChainStartIndex; i--)
815             {
816               if( rightChain->getVertex(i)[1] > leftChain->getVertex(index1)[1])
817                 break;
818               if(rightChain->getVertex(i)[0] < tempMin)
819                 {
820                   tempI = i;
821                   tempMin = rightChain->getVertex(i)[0];
822                 }
823             }
824           //check whether (leftGRidPoint,left(index1)) interesect right chain 
825           if(DBG_intersectChain(rightChain, rightChainStartIndex, rightChainEndIndex,
826                                 leftGridPoint, leftChain->getVertex(index1)))
827             {
828               ret_leftCornerWhere = 2; //right
829               ret_leftCornerIndex = index2;
830             }
831           else if(tempMin <= leftChain->getVertex(index1)[0] ||
832              tempMin <= uleft)
833             {
834               ret_leftCornerWhere = 2; /* on right chain*/
835               ret_leftCornerIndex = tempI;
836             }
837           else
838             {
839               ret_leftCornerWhere = 0; /*on left chain*/
840               ret_leftCornerIndex = index1;
841             }
842         }
843     }
844 #ifdef MYDEBUG
845 printf("***********leave findUpCorners\n");
846 #endif
847 }
848
849 //return 1 if neck exists, 0 othewise
850 Int findNeckF(vertexArray *leftChain, Int botLeftIndex,
851               vertexArray *rightChain, Int botRightIndex,
852               gridBoundaryChain* leftGridChain,
853               gridBoundaryChain* rightGridChain,
854               Int gridStartIndex,
855               Int& neckLeft, 
856               Int& neckRight)
857 {
858 /*
859 printf("enter findNeckF, botleft, botright=%i,%i,gstartindex=%i\n",botLeftIndex,botRightIndex,gridStartIndex);
860 printf("leftChain is\n");
861 leftChain->print();
862 printf("rightChain is\n");
863 rightChain->print();
864 */
865
866   Int lowerGridIndex; //the grid below leftChain and rightChian vertices
867   Int i;
868   Int n_vlines = leftGridChain->get_nVlines();
869   Real v;
870   if(botLeftIndex >= leftChain->getNumElements() ||
871      botRightIndex >= rightChain->getNumElements())
872     return 0; //no neck exists
873      
874   v=min(leftChain->getVertex(botLeftIndex)[1], rightChain->getVertex(botRightIndex)[1]);  
875
876  
877
878
879   for(i=gridStartIndex; i<n_vlines; i++)
880     if(leftGridChain->get_v_value(i) <= v && 
881        leftGridChain->getUlineIndex(i)<= rightGridChain->getUlineIndex(i))
882       break;
883   
884   lowerGridIndex = i;
885
886   if(lowerGridIndex == n_vlines) //the two trm vertex are higher than all gridlines
887     return 0;
888   else 
889     {
890       Int botLeft2, botRight2;
891 /*
892 printf("leftGridChain->get_v_)value=%f\n",leftGridChain->get_v_value(lowerGridIndex), botLeftIndex); 
893 printf("leftChain->get_vertex(0)=(%f,%f)\n", leftChain->getVertex(0)[0],leftChain->getVertex(0)[1]);
894 printf("leftChain->get_vertex(1)=(%f,%f)\n", leftChain->getVertex(1)[0],leftChain->getVertex(1)[1]);
895 printf("leftChain->get_vertex(2)=(%f,%f)\n", leftChain->getVertex(2)[0],leftChain->getVertex(2)[1]);
896 */
897       botLeft2 = leftChain->findIndexFirstAboveEqualGen(leftGridChain->get_v_value(lowerGridIndex), botLeftIndex, leftChain->getNumElements()-1) -1 ;
898
899 /*
900 printf("botLeft2=%i\n", botLeft2);
901 printf("leftChain->getNumElements=%i\n", leftChain->getNumElements());
902 */
903
904       botRight2 = rightChain->findIndexFirstAboveEqualGen(leftGridChain->get_v_value(lowerGridIndex), botRightIndex, rightChain->getNumElements()-1) -1;
905       if(botRight2 < botRightIndex) botRight2=botRightIndex;
906
907       if(botLeft2 < botLeftIndex) botLeft2 = botLeftIndex;
908
909       assert(botLeft2 >= botLeftIndex);
910       assert(botRight2 >= botRightIndex);
911       //find nectLeft so that it is th erightmost vertex on letChain
912
913       Int tempI = botLeftIndex;
914       Real temp = leftChain->getVertex(tempI)[0];
915       for(i=botLeftIndex+1; i<= botLeft2; i++)
916         if(leftChain->getVertex(i)[0] > temp)
917           {
918             temp = leftChain->getVertex(i)[0];
919             tempI = i;
920           }
921       neckLeft = tempI;
922
923       tempI = botRightIndex;
924       temp = rightChain->getVertex(tempI)[0];
925       for(i=botRightIndex+1; i<= botRight2; i++)
926         if(rightChain->getVertex(i)[0] < temp)
927           {
928             temp = rightChain->getVertex(i)[0];
929             tempI = i;
930           }
931       neckRight = tempI;
932       return 1;
933     }
934 }
935                                                         
936   
937                   
938 /*find i>=botLeftIndex,j>=botRightIndex so that
939  *(leftChain[i], rightChain[j]) is a neck.
940  */
941 void findNeck(vertexArray *leftChain, Int botLeftIndex, 
942               vertexArray *rightChain, Int botRightIndex, 
943               Int& leftLastIndex, /*left point of the neck*/
944               Int& rightLastIndex /*right point of the neck*/
945               )
946 {
947   assert(botLeftIndex < leftChain->getNumElements() &&
948      botRightIndex < rightChain->getNumElements());
949      
950   /*now the neck exists for sure*/
951
952   if(leftChain->getVertex(botLeftIndex)[1] <= rightChain->getVertex(botRightIndex)[1]) //left below right
953     {
954
955       leftLastIndex = botLeftIndex;
956       
957       /*find i so that rightChain[i][1] >= leftchainbotverte[1], and i+1<
958        */
959       rightLastIndex=rightChain->findIndexAboveGen(leftChain->getVertex(botLeftIndex)[1], botRightIndex+1, rightChain->getNumElements()-1);    
960     }
961   else  //left above right
962     {
963
964       rightLastIndex = botRightIndex;
965      
966       leftLastIndex = leftChain->findIndexAboveGen(rightChain->getVertex(botRightIndex)[1], 
967                                                   botLeftIndex+1,
968                                                   leftChain->getNumElements()-1);
969     }
970 }
971       
972       
973
974 void findLeftGridIndices(directedLine* topEdge, Int firstGridIndex, Int lastGridIndex, gridWrap* grid,  Int* ret_indices, Int* ret_innerIndices)
975 {
976
977   Int i,k,isHoriz = 0;
978   Int n_ulines = grid->get_n_ulines();
979   Real uMin = grid->get_u_min();
980   Real uMax = grid->get_u_max();
981   /*
982   Real vMin = grid->get_v_min();
983   Real vMax = grid->get_v_max();
984   */
985   Real slop = 0.0, uinterc;
986
987 #ifdef SHORTEN_GRID_LINE
988   //uintercBuf stores all the interction u value for each grid line
989   //notice that lastGridIndex<= firstGridIndex
990   Real *uintercBuf = (Real *) malloc (sizeof(Real) * (firstGridIndex-lastGridIndex+1));
991   assert(uintercBuf);
992 #endif
993
994   /*initialization to make vtail bigger than grid->...*/
995   directedLine* dLine = topEdge;
996   Real vtail = grid->get_v_value(firstGridIndex) + 1.0; 
997   Real tempMaxU = grid->get_u_min();
998
999
1000   /*for each grid line*/
1001   for(k=0, i=firstGridIndex; i>=lastGridIndex; i--, k++)
1002     {
1003
1004       Real grid_v_value = grid->get_v_value(i);
1005
1006       /*check whether this grid line is below the current trim edge.*/
1007       if(vtail > grid_v_value)
1008         {
1009           /*since the grid line is below the trim edge, we 
1010            *find the trim edge which will contain the trim line
1011            */
1012           while( (vtail=dLine->tail()[1]) > grid_v_value){
1013
1014             tempMaxU = max(tempMaxU, dLine->tail()[0]);
1015             dLine = dLine -> getNext();
1016           }
1017
1018           if( fabs(dLine->head()[1] - vtail) < ZERO)
1019             isHoriz = 1;
1020           else
1021             {
1022               isHoriz = 0;
1023               slop = (dLine->head()[0] - dLine->tail()[0]) / (dLine->head()[1]-vtail);
1024             }
1025         }
1026
1027       if(isHoriz)
1028         {
1029           uinterc = max(dLine->head()[0], dLine->tail()[0]);
1030         }
1031       else
1032         {
1033           uinterc = slop * (grid_v_value - vtail) + dLine->tail()[0];
1034         }
1035       
1036       tempMaxU = max(tempMaxU, uinterc);
1037
1038       if(uinterc < uMin && uinterc >= uMin - ZERO)
1039         uinterc = uMin;
1040       if(uinterc > uMax && uinterc <= uMax + ZERO)
1041         uinterc = uMax;
1042
1043 #ifdef SHORTEN_GRID_LINE
1044       uintercBuf[k] = uinterc;
1045 #endif
1046
1047       assert(uinterc >= uMin && uinterc <= uMax);
1048        if(uinterc == uMax)
1049          ret_indices[k] = n_ulines-1;
1050        else
1051          ret_indices[k] = (Int)(((uinterc-uMin)/(uMax - uMin)) * (n_ulines-1)) + 1;
1052       if(ret_indices[k] >= n_ulines)
1053         ret_indices[k] = n_ulines-1;
1054
1055
1056       ret_innerIndices[k] = (Int)(((tempMaxU-uMin)/(uMax - uMin)) * (n_ulines-1)) + 1;
1057
1058       /*reinitialize tempMaxU for next grdiLine*/
1059       tempMaxU = uinterc;
1060     }
1061 #ifdef SHORTEN_GRID_LINE
1062   //for each grid line, compare the left grid point with the 
1063   //intersection point. If the two points are too close, then
1064   //we should move the grid point one grid to the right
1065   //and accordingly we should update the inner index.
1066   for(k=0, i=firstGridIndex; i>=lastGridIndex; i--, k++)
1067     {
1068       //check gridLine i
1069       //check ret_indices[k]
1070       Real a = grid->get_u_value(ret_indices[k]-1);
1071       Real b = grid->get_u_value(ret_indices[k]);
1072       assert(uintercBuf[k] >= a && uintercBuf < b);
1073       if( (b-uintercBuf[k]) <= 0.2 * (b-a)) //interc is very close to b
1074         {
1075           ret_indices[k]++;
1076         }
1077
1078       //check ret_innerIndices[k]
1079       if(k>0)
1080         {
1081           if(ret_innerIndices[k] < ret_indices[k-1])
1082             ret_innerIndices[k] = ret_indices[k-1];
1083           if(ret_innerIndices[k] < ret_indices[k])
1084             ret_innerIndices[k] = ret_indices[k];
1085         }
1086     }
1087   //clean up
1088   free(uintercBuf);
1089 #endif
1090 }
1091
1092 void findRightGridIndices(directedLine* topEdge, Int firstGridIndex, Int lastGridIndex, gridWrap* grid,  Int* ret_indices, Int* ret_innerIndices)
1093 {
1094
1095   Int i,k;
1096   Int n_ulines = grid->get_n_ulines();
1097   Real uMin = grid->get_u_min();
1098   Real uMax = grid->get_u_max();
1099   /*
1100   Real vMin = grid->get_v_min();
1101   Real vMax = grid->get_v_max();
1102   */
1103   Real slop = 0.0, uinterc;
1104
1105 #ifdef SHORTEN_GRID_LINE
1106   //uintercBuf stores all the interction u value for each grid line
1107   //notice that firstGridIndex >= lastGridIndex
1108   Real *uintercBuf = (Real *) malloc (sizeof(Real) * (firstGridIndex-lastGridIndex+1));
1109   assert(uintercBuf);
1110 #endif
1111
1112   /*initialization to make vhead bigger than grid->v_value...*/
1113   directedLine* dLine = topEdge->getPrev();
1114   Real vhead = dLine->tail()[1];
1115   Real tempMinU = grid->get_u_max();
1116
1117   /*for each grid line*/
1118   for(k=0, i=firstGridIndex; i>=lastGridIndex; i--, k++)
1119     {
1120
1121       Real grid_v_value = grid->get_v_value(i);
1122
1123
1124       /*check whether this grid line is below the current trim edge.*/
1125       if(vhead >= grid_v_value)
1126         {
1127           /*since the grid line is below the tail of the trim edge, we 
1128            *find the trim edge which will contain the trim line
1129            */
1130           while( (vhead=dLine->head()[1]) > grid_v_value){
1131             tempMinU = min(tempMinU, dLine->head()[0]);
1132             dLine = dLine -> getPrev();
1133           }
1134
1135           /*skip the equality in the case of degenerat case: horizontal */
1136           while(dLine->head()[1] == grid_v_value)
1137             dLine = dLine->getPrev();
1138             
1139           assert( dLine->tail()[1] != dLine->head()[1]);
1140           slop = (dLine->tail()[0] - dLine->head()[0]) / (dLine->tail()[1]-dLine->head()[1]);
1141           /*
1142            if(dLine->tail()[1] == vhead)
1143              isHoriz = 1;
1144              else
1145             {
1146               isHoriz = 0;
1147               slop = (dLine->tail()[0] - dLine->head()[0]) / (dLine->tail()[1]-vhead);
1148             }
1149             */
1150         }
1151         uinterc = slop * (grid_v_value - dLine->head()[1]) + dLine->head()[0];
1152
1153       //in case unterc is outside of the grid due to floating point
1154       if(uinterc < uMin)
1155         uinterc = uMin;
1156       else if(uinterc > uMax)
1157         uinterc = uMax;
1158
1159 #ifdef SHORTEN_GRID_LINE
1160       uintercBuf[k] = uinterc;
1161 #endif      
1162
1163       tempMinU = min(tempMinU, uinterc);
1164
1165       assert(uinterc >= uMin && uinterc <= uMax);      
1166
1167       if(uinterc == uMin)
1168         ret_indices[k] = 0;
1169       else
1170         ret_indices[k] = (int)ceil((((uinterc-uMin)/(uMax - uMin)) * (n_ulines-1))) -1;
1171 /*
1172 if(ret_indices[k] >= grid->get_n_ulines())
1173   {
1174   printf("ERROR3\n");
1175   exit(0);
1176 }
1177 if(ret_indices[k] < 0)    
1178   {
1179   printf("ERROR4\n");
1180   exit(0);
1181 }
1182 */
1183       ret_innerIndices[k] = (int)ceil ((((tempMinU-uMin)/(uMax - uMin)) * (n_ulines-1))) -1;
1184
1185       tempMinU = uinterc;
1186     }
1187 #ifdef SHORTEN_GRID_LINE
1188   //for each grid line, compare the left grid point with the 
1189   //intersection point. If the two points are too close, then
1190   //we should move the grid point one grid to the right
1191   //and accordingly we should update the inner index.
1192   for(k=0, i=firstGridIndex; i>=lastGridIndex; i--, k++)
1193     {
1194       //check gridLine i
1195       //check ret_indices[k]
1196       Real a = grid->get_u_value(ret_indices[k]);
1197       Real b = grid->get_u_value(ret_indices[k]+1);
1198       assert(uintercBuf[k] > a && uintercBuf <= b);
1199       if( (uintercBuf[k]-a) <= 0.2 * (b-a)) //interc is very close to a
1200         {
1201           ret_indices[k]--;
1202         }
1203
1204       //check ret_innerIndices[k]
1205       if(k>0)
1206         {
1207           if(ret_innerIndices[k] > ret_indices[k-1])
1208             ret_innerIndices[k] = ret_indices[k-1];
1209           if(ret_innerIndices[k] > ret_indices[k])
1210             ret_innerIndices[k] = ret_indices[k];
1211         }
1212     }
1213   //clean up
1214   free(uintercBuf);
1215 #endif
1216 }
1217
1218
1219 void sampleMonoPoly(directedLine* polygon, gridWrap* grid, Int ulinear, Int vlinear, primStream* pStream, rectBlockArray* rbArray)
1220 {
1221 /*
1222 {
1223 grid->print();
1224 polygon->writeAllPolygons("zloutputFile");
1225 exit(0);
1226 }
1227 */
1228
1229 if(grid->get_n_ulines() == 2 ||
1230    grid->get_n_vlines() == 2)
1231
1232   if(ulinear && grid->get_n_ulines() == 2)
1233     {
1234       monoTriangulationFun(polygon, compV2InY, pStream);   
1235       return;
1236     }
1237   else if(DBG_isConvex(polygon) && polygon->numEdges() >=4)
1238      {
1239        triangulateConvexPoly(polygon, ulinear, vlinear, pStream);
1240        return;
1241      }
1242   else if(vlinear || DBG_is_U_direction(polygon))
1243     {
1244       Int n_cusps;//num interior cusps
1245       Int n_edges = polygon->numEdges();
1246       directedLine** cusps = (directedLine**) malloc(sizeof(directedLine*) * n_edges);
1247       assert(cusps);
1248       findInteriorCuspsX(polygon, n_cusps, cusps);
1249
1250       if(n_cusps == 0) //u_monotone
1251         {
1252
1253           monoTriangulationFun(polygon, compV2InX, pStream);
1254
1255           free(cusps);
1256           return;          
1257         }
1258       else if(n_cusps == 1) //one interior cusp
1259         {
1260
1261           directedLine* new_polygon = polygonConvert(cusps[0]);
1262
1263           directedLine* other = findDiagonal_singleCuspX( new_polygon);
1264
1265
1266
1267           //<other> should NOT be null unless there are self-intersecting
1268           //trim curves. In that case, we don't want to core dump, instead,
1269           //we triangulate anyway, and print out error message.
1270           if(other == NULL)
1271             {
1272               monoTriangulationFun(polygon, compV2InX, pStream);
1273               free(cusps);
1274               return;
1275             }
1276
1277           directedLine* ret_p1;
1278           directedLine* ret_p2;
1279
1280           new_polygon->connectDiagonal_2slines(new_polygon, other, 
1281                                            &ret_p1,
1282                                            &ret_p2,
1283                                            new_polygon);
1284
1285           monoTriangulationFun(ret_p1, compV2InX, pStream);
1286           monoTriangulationFun(ret_p2, compV2InX, pStream);
1287
1288           ret_p1->deleteSinglePolygonWithSline();             
1289           ret_p2->deleteSinglePolygonWithSline();         
1290
1291           free(cusps);
1292           return;
1293          }
1294      free(cusps);
1295      }
1296 }
1297
1298   /*find the top and bottom of the polygon. It is supposed to be
1299    *a V-monotone polygon
1300    */
1301
1302   directedLine* tempV;
1303   directedLine* topV;
1304   directedLine* botV;
1305   topV = botV = polygon;
1306
1307   for(tempV = polygon->getNext(); tempV != polygon; tempV = tempV->getNext())
1308     {
1309       if(compV2InY(topV->head(), tempV->head())<0) {
1310
1311         topV = tempV;
1312       }
1313       if(compV2InY(botV->head(), tempV->head())>0) {
1314
1315         botV = tempV;
1316       }
1317     }
1318   
1319   /*find the first(top) and the last (bottom) grid line which intersect the
1320    *this polygon
1321    */
1322   Int firstGridIndex; /*the index in the grid*/
1323   Int lastGridIndex;
1324   firstGridIndex = (Int) ((topV->head()[1] - grid->get_v_min()) / (grid->get_v_max() - grid->get_v_min()) * (grid->get_n_vlines()-1));
1325   lastGridIndex  = (Int) ((botV->head()[1] - grid->get_v_min()) / (grid->get_v_max() - grid->get_v_min()) * (grid->get_n_vlines()-1)) + 1;
1326
1327
1328   /*find the interval inside  the polygon for each gridline*/
1329   Int *leftGridIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1));
1330   assert(leftGridIndices);
1331   Int *rightGridIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1));
1332   assert(rightGridIndices);
1333   Int *leftGridInnerIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1));
1334   assert(leftGridInnerIndices);
1335   Int *rightGridInnerIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1));
1336   assert(rightGridInnerIndices);
1337
1338   findLeftGridIndices(topV, firstGridIndex, lastGridIndex, grid,  leftGridIndices, leftGridInnerIndices);
1339
1340   findRightGridIndices(topV, firstGridIndex, lastGridIndex, grid,  rightGridIndices, rightGridInnerIndices);
1341
1342   gridBoundaryChain leftGridChain(grid, firstGridIndex, firstGridIndex-lastGridIndex+1, leftGridIndices, leftGridInnerIndices);
1343
1344   gridBoundaryChain rightGridChain(grid, firstGridIndex, firstGridIndex-lastGridIndex+1, rightGridIndices, rightGridInnerIndices);
1345
1346
1347
1348 //  leftGridChain.draw();
1349 //  leftGridChain.drawInner();
1350 //  rightGridChain.draw();
1351 //  rightGridChain.drawInner();
1352   /*(1) determine the grid boundaries (left and right).
1353    *(2) process polygon  into two monotone chaines: use vertexArray
1354    *(3) call sampleMonoPolyRec
1355    */
1356
1357   /*copy the two chains into vertexArray datastructure*/
1358   Int i;
1359   vertexArray leftChain(20); /*this is a dynamic array*/
1360   for(i=1; i<=topV->get_npoints()-2; i++) { /*the first vertex is the top vertex which doesn't belong to inc_chain*/
1361     leftChain.appendVertex(topV->getVertex(i));
1362   }
1363   for(tempV = topV->getNext(); tempV != botV; tempV = tempV->getNext())
1364     {
1365       for(i=0; i<=tempV->get_npoints()-2; i++){
1366         leftChain.appendVertex(tempV->getVertex(i));
1367       }
1368     }
1369   
1370   vertexArray rightChain(20);
1371   for(tempV = topV->getPrev(); tempV != botV; tempV = tempV->getPrev())
1372     {
1373       for(i=tempV->get_npoints()-2; i>=0; i--){
1374         rightChain.appendVertex(tempV->getVertex(i));
1375       }
1376     }
1377   for(i=botV->get_npoints()-2; i>=1; i--){ 
1378     rightChain.appendVertex(tempV->getVertex(i));
1379   }
1380
1381   sampleMonoPolyRec(topV->head(),
1382                     botV->head(),
1383                     &leftChain,
1384                     0,
1385                     &rightChain,
1386                     0,
1387                     &leftGridChain,
1388                     &rightGridChain,
1389                     0,
1390                     pStream,
1391                     rbArray);
1392
1393
1394   /*cleanup space*/
1395   free(leftGridIndices);
1396   free(rightGridIndices);
1397   free(leftGridInnerIndices);
1398   free(rightGridInnerIndices);
1399 }
1400
1401 void sampleMonoPolyRec(
1402                        Real* topVertex,
1403                        Real* botVertex,
1404                        vertexArray* leftChain, 
1405                        Int leftStartIndex,
1406                        vertexArray* rightChain,
1407                        Int rightStartIndex,
1408                        gridBoundaryChain* leftGridChain, 
1409                        gridBoundaryChain* rightGridChain, 
1410                        Int gridStartIndex,
1411                        primStream* pStream,
1412                        rectBlockArray* rbArray)
1413 {
1414
1415   /*find the first connected component, and the four corners.
1416    */
1417   Int index1, index2; /*the first and last grid line of the first connected component*/
1418
1419   if(topVertex[1] <= botVertex[1])
1420     return;
1421     
1422   /*find i so that the grid line is below the top vertex*/
1423   Int i=gridStartIndex;
1424   while (i < leftGridChain->get_nVlines())
1425     {
1426       if(leftGridChain->get_v_value(i) < topVertex[1])
1427         break;
1428       i++;
1429     }
1430
1431   /*find the first connected component starting with i*/
1432   /*find index1 so that left_uline_index <= right_uline_index, that is, this
1433    *grid line contains at least one inner grid point
1434    */
1435   index1=i;
1436   int num_skipped_grid_lines=0;
1437   while(index1 < leftGridChain->get_nVlines())
1438     {
1439       if(leftGridChain->getUlineIndex(index1) <= rightGridChain->getUlineIndex(index1))
1440         break;
1441       num_skipped_grid_lines++;
1442       index1++;
1443     }
1444
1445
1446
1447   if(index1 >= leftGridChain->get_nVlines()) /*no grid line exists which has inner point*/
1448     {
1449       /*stop recursion, ...*/
1450       /*monotone triangulate it...*/
1451 //      printf("no grid line exists\n");      
1452 /*
1453       monoTriangulationRecOpt(topVertex, botVertex, leftChain, leftStartIndex,
1454                            rightChain, rightStartIndex, pStream);
1455 */
1456
1457 if(num_skipped_grid_lines <2)
1458   {
1459     monoTriangulationRecGenOpt(topVertex, botVertex, leftChain, leftStartIndex,
1460                                leftChain->getNumElements()-1,
1461                                rightChain, rightStartIndex, 
1462                                rightChain->getNumElements()-1,
1463                                pStream);
1464   }
1465 else
1466   {
1467     //the optimum way to triangulate is top-down since this polygon
1468     //is narrow-long.
1469     monoTriangulationRec(topVertex, botVertex, leftChain, leftStartIndex,
1470                          rightChain, rightStartIndex, pStream);
1471   }
1472
1473 /*
1474       monoTriangulationRec(topVertex, botVertex, leftChain, leftStartIndex,
1475                            rightChain, rightStartIndex, pStream);
1476 */
1477
1478 /*      monoTriangulationRecGenTBOpt(topVertex, botVertex, 
1479                                    leftChain, leftStartIndex, leftChain->getNumElements()-1,
1480                                    rightChain, rightStartIndex, rightChain->getNumElements()-1, 
1481                                    pStream);*/
1482       
1483
1484
1485     }
1486   else
1487     {
1488
1489       /*find index2 so that left_inner_index <= right_inner_index holds until index2*/
1490       index2=index1+1;
1491       if(index2 < leftGridChain->get_nVlines())
1492         while(leftGridChain->getInnerIndex(index2) <= rightGridChain->getInnerIndex(index2))
1493           {
1494             index2++;
1495             if(index2 >= leftGridChain->get_nVlines())
1496               break;
1497           }
1498       
1499       index2--;
1500       
1501
1502       
1503       /*the neck*/
1504       Int neckLeftIndex;
1505       Int neckRightIndex;
1506
1507       /*the four corners*/
1508       Int up_leftCornerWhere;
1509       Int up_leftCornerIndex;
1510       Int up_rightCornerWhere;
1511       Int up_rightCornerIndex;
1512       Int down_leftCornerWhere;
1513       Int down_leftCornerIndex;
1514       Int down_rightCornerWhere;
1515       Int down_rightCornerIndex;
1516
1517       Real* tempBotVertex; /*the bottom vertex for this component*/
1518       Real* nextTopVertex=NULL; /*for the recursion*/
1519       Int nextLeftStartIndex=0;
1520       Int nextRightStartIndex=0;
1521
1522       /*find the points below the grid line index2 on both chains*/
1523       Int botLeftIndex = leftChain->findIndexStrictBelowGen(
1524                                                       leftGridChain->get_v_value(index2),
1525                                                       leftStartIndex,
1526                                                       leftChain->getNumElements()-1);
1527       Int botRightIndex = rightChain->findIndexStrictBelowGen(
1528                                                         rightGridChain->get_v_value(index2),
1529                                                         rightStartIndex,
1530                                                         rightChain->getNumElements()-1);
1531       /*if either botLeftIndex>= numelements,
1532        *        or botRightIndex >= numelemnet,
1533        *then there is no neck exists. the bottom vertex is botVertex, 
1534        */
1535       if(! findNeckF(leftChain, botLeftIndex, rightChain, botRightIndex,
1536                    leftGridChain, rightGridChain, index2, neckLeftIndex, neckRightIndex))
1537          /*
1538       if(botLeftIndex == leftChain->getNumElements() ||
1539          botRightIndex == rightChain->getNumElements())
1540          */
1541         {
1542 #ifdef MYDEBUG
1543           printf("neck NOT exists, botRightIndex=%i\n", botRightIndex);
1544 #endif
1545
1546           tempBotVertex =  botVertex;
1547           nextTopVertex = botVertex;
1548           botLeftIndex = leftChain->getNumElements()-1;
1549           botRightIndex = rightChain->getNumElements()-1;
1550         }
1551       else /*neck exists*/
1552         {
1553 #ifdef MYDEBUG
1554           printf("neck exists\n");
1555 #endif
1556
1557           /*
1558           findNeck(leftChain, botLeftIndex,
1559                    rightChain, botRightIndex,
1560                    neckLeftIndex,
1561                    neckRightIndex);
1562                    */
1563 #ifdef MYDEBUG
1564 printf("neck is found, neckLeftIndex=%i, neckRightIndex=%i\n", neckLeftIndex, neckRightIndex);
1565 glBegin(GL_LINES);
1566 glVertex2fv(leftChain->getVertex(neckLeftIndex));
1567 glVertex2fv(rightChain->getVertex(neckRightIndex));
1568 glEnd();
1569 #endif
1570
1571           if(leftChain->getVertex(neckLeftIndex)[1] <= rightChain->getVertex(neckRightIndex)[1])
1572             {
1573               tempBotVertex = leftChain->getVertex(neckLeftIndex);
1574               botLeftIndex = neckLeftIndex-1;
1575               botRightIndex = neckRightIndex;
1576               nextTopVertex = rightChain->getVertex(neckRightIndex);
1577               nextLeftStartIndex = neckLeftIndex;
1578               nextRightStartIndex = neckRightIndex+1;
1579             }
1580           else
1581             {
1582               tempBotVertex = rightChain->getVertex(neckRightIndex);
1583               botLeftIndex = neckLeftIndex;
1584               botRightIndex = neckRightIndex-1;           
1585               nextTopVertex = leftChain->getVertex(neckLeftIndex);
1586               nextLeftStartIndex = neckLeftIndex+1;
1587               nextRightStartIndex = neckRightIndex;
1588             }
1589         }
1590
1591       findUpCorners(topVertex,
1592                     leftChain,
1593                     leftStartIndex, botLeftIndex,
1594                     rightChain,
1595                     rightStartIndex, botRightIndex,
1596                     leftGridChain->get_v_value(index1),
1597                     leftGridChain->get_u_value(index1),
1598                     rightGridChain->get_u_value(index1),
1599                     up_leftCornerWhere,
1600                     up_leftCornerIndex,
1601                     up_rightCornerWhere,
1602                     up_rightCornerIndex);
1603
1604       findDownCorners(tempBotVertex,
1605                       leftChain,
1606                       leftStartIndex, botLeftIndex,
1607                       rightChain,
1608                       rightStartIndex, botRightIndex,
1609                       leftGridChain->get_v_value(index2),
1610                       leftGridChain->get_u_value(index2),
1611                       rightGridChain->get_u_value(index2),
1612                       down_leftCornerWhere,
1613                       down_leftCornerIndex,
1614                       down_rightCornerWhere,
1615                       down_rightCornerIndex);         
1616 #ifdef MYDEBUG
1617       printf("find corners done, down_leftwhere=%i, down_righwhere=%i,\n",down_leftCornerWhere, down_rightCornerWhere );
1618       printf("find corners done, up_leftwhere=%i, up_righwhere=%i,\n",up_leftCornerWhere, up_rightCornerWhere );
1619       printf("find corners done, up_leftindex=%i, up_righindex=%i,\n",up_leftCornerIndex, up_rightCornerIndex );
1620       printf("find corners done, down_leftindex=%i, down_righindex=%i,\n",down_leftCornerIndex, down_rightCornerIndex );
1621 #endif
1622
1623 /*
1624       drawCorners(topVertex,
1625                   tempBotVertex,
1626                   leftChain,
1627                   rightChain,
1628                   leftGridChain,
1629                   rightGridChain,
1630                   index1,
1631                   index2,
1632                   up_leftCornerWhere,
1633                   up_leftCornerIndex,
1634                   up_rightCornerWhere,
1635                   up_rightCornerIndex,
1636                   down_leftCornerWhere,
1637                   down_leftCornerIndex,
1638                   down_rightCornerWhere,
1639                   down_rightCornerIndex);
1640 */
1641
1642
1643       sampleConnectedComp(topVertex, tempBotVertex,
1644                           leftChain, 
1645                           leftStartIndex, botLeftIndex,
1646                           rightChain,
1647                           rightStartIndex, botRightIndex,
1648                           leftGridChain,
1649                           rightGridChain,
1650                           index1, index2,
1651                           up_leftCornerWhere,
1652                           up_leftCornerIndex,
1653                           up_rightCornerWhere,
1654                           up_rightCornerIndex,
1655                           down_leftCornerWhere,
1656                           down_leftCornerIndex,
1657                           down_rightCornerWhere,
1658                           down_rightCornerIndex,
1659                           pStream,
1660                           rbArray
1661                           );
1662
1663       /*recursion*/
1664
1665       sampleMonoPolyRec(
1666                         nextTopVertex,
1667                         botVertex,
1668                         leftChain, 
1669                         nextLeftStartIndex,
1670                         rightChain,
1671                         nextRightStartIndex,
1672                         leftGridChain, 
1673                         rightGridChain, 
1674                         index2+1,
1675                         pStream, rbArray);
1676                         
1677
1678     }
1679
1680 }
1681
1682 void sampleLeftStrip(vertexArray* leftChain,
1683                      Int topLeftIndex,
1684                      Int botLeftIndex,
1685                      gridBoundaryChain* leftGridChain,
1686                      Int leftGridChainStartIndex,
1687                      Int leftGridChainEndIndex,
1688                      primStream* pStream
1689                      )
1690 {
1691   assert(leftChain->getVertex(topLeftIndex)[1] > leftGridChain->get_v_value(leftGridChainStartIndex));
1692   assert(leftChain->getVertex(topLeftIndex+1)[1] <= leftGridChain->get_v_value(leftGridChainStartIndex));
1693   assert(leftChain->getVertex(botLeftIndex)[1] <= leftGridChain->get_v_value(leftGridChainEndIndex));
1694   assert(leftChain->getVertex(botLeftIndex-1)[1] > leftGridChain->get_v_value(leftGridChainEndIndex));
1695
1696   /*
1697    *(1)find the last grid line which doesn'; pass below
1698    * this first edge, sample this region: one trim edge and 
1699    * possily multiple grid lines.
1700    */
1701   Real *upperVert, *lowerVert; /*the end points of the first trim edge*/
1702   upperVert = leftChain->getVertex(topLeftIndex);
1703   lowerVert = leftChain->getVertex(topLeftIndex+1);
1704   
1705   Int index = leftGridChainStartIndex;
1706   while(leftGridChain->get_v_value(index) >= lowerVert[1]){
1707     index++;
1708     if(index > leftGridChainEndIndex) 
1709       break;
1710   }
1711   index--;
1712   
1713   sampleLeftSingleTrimEdgeRegion(upperVert, lowerVert,
1714                                  leftGridChain,
1715                                  leftGridChainStartIndex,
1716                                  index,
1717                                  pStream);
1718   sampleLeftStripRec(leftChain, topLeftIndex+1, botLeftIndex,
1719                      leftGridChain, index, leftGridChainEndIndex,
1720                      pStream);
1721
1722 }
1723
1724 void sampleLeftStripRec(vertexArray* leftChain,
1725                      Int topLeftIndex,
1726                      Int botLeftIndex,
1727                      gridBoundaryChain* leftGridChain,
1728                      Int leftGridChainStartIndex,
1729                      Int leftGridChainEndIndex,
1730                         primStream* pStream
1731                      )
1732 {
1733   /*now top left trim vertex is below the top grid line.
1734    */
1735   /*stop condition: if topLeftIndex >= botLeftIndex, then stop.
1736    */
1737   if(topLeftIndex >= botLeftIndex) 
1738     return;
1739
1740   /*find the last trim vertex which is above the second top grid line:
1741    * index1.
1742    *and sampleLeftOneGridStep(leftchain, topLeftIndex, index1, leftGridChain,
1743    * leftGridChainStartIndex).
1744    * index1 could be equal to topLeftIndex.
1745    */
1746   Real secondGridChainV = leftGridChain->get_v_value(leftGridChainStartIndex+1);
1747   assert(leftGridChainStartIndex < leftGridChainEndIndex);
1748   Int index1 = topLeftIndex;
1749   while(leftChain->getVertex(index1)[1] > secondGridChainV)
1750     index1++;
1751   index1--;
1752   
1753   sampleLeftOneGridStep(leftChain, topLeftIndex, index1, leftGridChain, leftGridChainStartIndex, pStream);
1754
1755
1756   /* 
1757    * Let the next trim vertex be nextTrimVertIndex (which should be  
1758    *  below the second grid line).
1759    * Find the last grid line index2 which is above nextTrimVert.
1760    * sampleLeftSingleTrimEdgeRegion(uppervert[2], lowervert[2], 
1761    *                      leftGridChain, leftGridChainStartIndex+1, index2).
1762    */
1763   Real *uppervert, *lowervert;
1764   uppervert = leftChain->getVertex(index1);
1765   lowervert = leftChain->getVertex(index1+1);
1766   Int index2 = leftGridChainStartIndex+1;
1767
1768   while(leftGridChain->get_v_value(index2) >= lowervert[1])
1769     {
1770       index2++;
1771       if(index2 > leftGridChainEndIndex)
1772         break;
1773     }
1774   index2--;
1775   sampleLeftSingleTrimEdgeRegion(uppervert, lowervert, leftGridChain, leftGridChainStartIndex+1, index2,  pStream);
1776
1777    /* sampleLeftStripRec(leftChain, 
1778                         nextTrimVertIndex,
1779                         botLeftIndex,
1780                         leftGridChain,
1781                         index2,
1782                         leftGridChainEndIndex
1783                         )
1784    *
1785    */
1786   sampleLeftStripRec(leftChain, index1+1, botLeftIndex, leftGridChain, index2, leftGridChainEndIndex, pStream);
1787   
1788 }
1789
1790
1791 /***************begin RecF***********************/
1792 /* the gridlines from leftGridChainStartIndex to 
1793  * leftGridChainEndIndex are assumed to form a
1794  * connected component.
1795  * the trim vertex of topLeftIndex is assumed to
1796  * be below the first gridline, and the tim vertex
1797  * of botLeftIndex is assumed to be above the last
1798  * grid line.
1799  * If botLeftIndex < topLeftIndex, then no connected componeent exists, and this funcion returns without
1800  * outputing any triangles.
1801  * Otherwise botLeftIndex >= topLeftIndex, there is at least one triangle to output.
1802  */
1803 void sampleLeftStripRecF(vertexArray* leftChain,
1804                      Int topLeftIndex,
1805                      Int botLeftIndex,
1806                      gridBoundaryChain* leftGridChain,
1807                      Int leftGridChainStartIndex,
1808                      Int leftGridChainEndIndex,
1809                         primStream* pStream
1810                      )
1811 {
1812   /*now top left trim vertex is below the top grid line.
1813    */
1814   /*stop condition: if topLeftIndex > botLeftIndex, then stop.
1815    */
1816   if(topLeftIndex > botLeftIndex) 
1817     return;
1818
1819   /*if there is only one grid Line, return.*/
1820
1821   if(leftGridChainStartIndex>=leftGridChainEndIndex)
1822     return;
1823
1824
1825   assert(leftChain->getVertex(topLeftIndex)[1] <= leftGridChain->get_v_value(leftGridChainStartIndex) &&
1826          leftChain->getVertex(botLeftIndex)[1] >= leftGridChain->get_v_value(leftGridChainEndIndex));
1827
1828   /*firs find the first trim vertex which is below or equal to the second top grid line:
1829    * index1.
1830    */
1831   Real secondGridChainV = leftGridChain->get_v_value(leftGridChainStartIndex+1);
1832
1833
1834   Int index1 = topLeftIndex;
1835
1836   while(leftChain->getVertex(index1)[1] > secondGridChainV){
1837     index1++;
1838     if(index1>botLeftIndex)
1839       break;
1840   }
1841
1842   /*now leftChain->getVertex(index-1)[1] > secondGridChainV and
1843    *    leftChain->getVertex(index)[1] <= secondGridChainV
1844    *If equality holds, then we should include the vertex index1, otherwise we include only index1-1, to
1845    *perform sampleOneGridStep.
1846    */
1847   if(index1>botLeftIndex) 
1848     index1--;
1849   else if(leftChain->getVertex(index1)[1] < secondGridChainV)
1850     index1--;
1851
1852   /*now we have leftChain->getVertex(index1)[1] >= secondGridChainV, and 
1853    *  leftChain->getVertex(index1+1)[1] <= secondGridChainV
1854    */
1855
1856
1857   sampleLeftOneGridStep(leftChain, topLeftIndex, index1, leftGridChain, leftGridChainStartIndex, pStream);
1858
1859
1860   /*if leftChain->getVertex(index1)[1] == secondGridChainV, then we can recursively do the rest.
1861    */
1862   if(leftChain->getVertex(index1)[1] == secondGridChainV)
1863     {
1864
1865       sampleLeftStripRecF(leftChain, index1, botLeftIndex,leftGridChain, leftGridChainStartIndex+1, leftGridChainEndIndex, pStream);
1866     }
1867   else if(index1 < botLeftIndex)
1868     {
1869
1870       /* Otherwise, we have leftChain->getVertex(index1)[1] > secondGridChainV,
1871        * let the next trim vertex be nextTrimVertIndex (which should be  strictly
1872        *  below the second grid line).
1873        * Find the last grid line index2 which is above nextTrimVert.
1874        * sampleLeftSingleTrimEdgeRegion(uppervert[2], lowervert[2], 
1875        *                      leftGridChain, leftGridChainStartIndex+1, index2).
1876        */
1877       Real *uppervert, *lowervert;
1878       uppervert = leftChain->getVertex(index1);
1879       lowervert = leftChain->getVertex(index1+1); //okay since index1<botLeftIndex
1880       Int index2 = leftGridChainStartIndex+1;
1881
1882       
1883       while(leftGridChain->get_v_value(index2) >= lowervert[1])
1884         {
1885           index2++;
1886           if(index2 > leftGridChainEndIndex)
1887             break;
1888         }
1889       index2--;
1890
1891       
1892       sampleLeftSingleTrimEdgeRegion(uppervert, lowervert, leftGridChain, leftGridChainStartIndex+1, index2,  pStream);
1893       
1894       /*recursion*/
1895
1896       sampleLeftStripRecF(leftChain, index1+1, botLeftIndex, leftGridChain, index2, leftGridChainEndIndex, pStream);
1897     }
1898   
1899 }
1900
1901 /***************End RecF***********************/
1902
1903 /*sample the left area in between one trim edge and multiple grid lines.
1904  * all the grid lines should be in between the two end poins of the
1905  *trim edge.
1906  */
1907 void sampleLeftSingleTrimEdgeRegion(Real upperVert[2], Real lowerVert[2],
1908                                     gridBoundaryChain* gridChain,
1909                                     Int beginIndex,
1910                                     Int endIndex,
1911                                     primStream* pStream)
1912 {
1913   Int i,j,k;
1914
1915   vertexArray vArray(endIndex-beginIndex+1);  
1916   vArray.appendVertex(gridChain->get_vertex(beginIndex));
1917
1918   for(k=1, i=beginIndex+1; i<=endIndex; i++, k++)
1919     {
1920       vArray.appendVertex(gridChain->get_vertex(i));
1921
1922       /*output the fan of the grid points of the (i)th and (i-1)th grid line.
1923        */
1924       if(gridChain->getUlineIndex(i) < gridChain->getUlineIndex(i-1))
1925         {
1926           pStream->begin();       
1927           pStream->insert(gridChain->get_vertex(i-1));
1928           for(j=gridChain->getUlineIndex(i); j<= gridChain->getUlineIndex(i-1); j++)
1929             pStream->insert(gridChain->getGrid()->get_u_value(j), gridChain->get_v_value(i));
1930           pStream->end(PRIMITIVE_STREAM_FAN);
1931         }
1932       else if(gridChain->getUlineIndex(i) > gridChain->getUlineIndex(i-1))
1933         {
1934           pStream->begin();
1935           pStream->insert(gridChain->get_vertex(i));
1936           for(j=gridChain->getUlineIndex(i); j>= gridChain->getUlineIndex(i-1); j--)
1937             pStream->insert(gridChain->getGrid()->get_u_value(j), gridChain->get_v_value(i-1));
1938           pStream->end(PRIMITIVE_STREAM_FAN);
1939         }
1940       /*otherwisem, the two are equal, so there is no fan to outout*/     
1941     }
1942   
1943   monoTriangulation2(upperVert, lowerVert, &vArray, 0, endIndex-beginIndex, 
1944                      0, /*decreasing chain*/
1945                      pStream);
1946 }
1947   
1948 /*return i, such that from begin to i-1 the chain is strictly u-monotone. 
1949  */                              
1950 Int findIncreaseChainFromBegin(vertexArray* chain, Int begin ,Int end)
1951 {
1952   Int i=begin;
1953   Real prevU = chain->getVertex(i)[0];
1954   Real thisU;
1955   for(i=begin+1; i<=end; i++){
1956     thisU = chain->getVertex(i)[0];
1957
1958     if(prevU < thisU){
1959       prevU = thisU;
1960     }
1961     else
1962       break;
1963   }
1964   return i;
1965 }
1966   
1967 /*check whether there is a vertex whose v value is strictly 
1968  *inbetween vup vbelow
1969  *if no middle exists return -1, else return the idnex.
1970  */
1971 Int checkMiddle(vertexArray* chain, Int begin, Int end, 
1972                 Real vup, Real vbelow)
1973 {
1974   Int i;
1975   for(i=begin; i<=end; i++)
1976     {
1977       if(chain->getVertex(i)[1] < vup && chain->getVertex(i)[1]>vbelow)
1978         return i;
1979     }
1980   return -1;
1981 }
1982   
1983 /*the degenerat case of sampleLeftOneGridStep*/
1984 void sampleLeftOneGridStepNoMiddle(vertexArray* leftChain,
1985                                    Int beginLeftIndex,
1986                                    Int endLeftIndex,
1987                                    gridBoundaryChain* leftGridChain,
1988                                    Int leftGridChainStartIndex,
1989                                    primStream* pStream)
1990 {
1991   /*since there is no middle, there is at most one point which is on the 
1992    *second grid line, there could be multiple points on the first (top)
1993    *grid line.
1994    */
1995
1996   leftGridChain->leftEndFan(leftGridChainStartIndex+1, pStream);
1997
1998   monoTriangulation2(leftGridChain->get_vertex(leftGridChainStartIndex),
1999                      leftGridChain->get_vertex(leftGridChainStartIndex+1),
2000                      leftChain,
2001                      beginLeftIndex,
2002                      endLeftIndex,
2003                      1, //is increase chain.
2004                      pStream);
2005 }
2006
2007
2008
2009 /*sampling the left area in between two grid lines.
2010  */
2011 void sampleLeftOneGridStep(vertexArray* leftChain,
2012                   Int beginLeftIndex,
2013                   Int endLeftIndex,
2014                   gridBoundaryChain* leftGridChain,
2015                   Int leftGridChainStartIndex,
2016                   primStream* pStream
2017                   )
2018 {
2019   if(checkMiddle(leftChain, beginLeftIndex, endLeftIndex, 
2020                  leftGridChain->get_v_value(leftGridChainStartIndex),
2021                  leftGridChain->get_v_value(leftGridChainStartIndex+1))<0)
2022     
2023     {
2024       
2025       sampleLeftOneGridStepNoMiddle(leftChain, beginLeftIndex, endLeftIndex, leftGridChain, leftGridChainStartIndex, pStream);
2026       return;
2027     }
2028   
2029   //copy into a polygon
2030   {
2031     directedLine* poly = NULL;
2032     sampledLine* sline;
2033     directedLine* dline;
2034     gridWrap* grid = leftGridChain->getGrid();
2035     Real vert1[2];
2036     Real vert2[2];
2037     Int i;
2038     
2039     Int innerInd = leftGridChain->getInnerIndex(leftGridChainStartIndex+1);
2040     Int upperInd = leftGridChain->getUlineIndex(leftGridChainStartIndex);
2041     Int lowerInd = leftGridChain->getUlineIndex(leftGridChainStartIndex+1);
2042     Real upperV = leftGridChain->get_v_value(leftGridChainStartIndex);
2043     Real lowerV = leftGridChain->get_v_value(leftGridChainStartIndex+1);
2044
2045     //the upper gridline
2046     vert1[1] = vert2[1] = upperV;
2047     for(i=innerInd;     i>upperInd;     i--)
2048       {
2049         vert1[0]=grid->get_u_value(i);
2050         vert2[0]=grid->get_u_value(i-1);
2051         sline = new sampledLine(vert1, vert2);
2052         dline = new directedLine(INCREASING, sline);
2053         if(poly == NULL)
2054           poly = dline;
2055         else
2056           poly->insert(dline);
2057       }
2058
2059     //the edge connecting upper grid with left chain
2060     vert1[0] = grid->get_u_value(upperInd);
2061     vert1[1] = upperV;
2062     sline = new sampledLine(vert1, leftChain->getVertex(beginLeftIndex));
2063     dline = new directedLine(INCREASING, sline);
2064     if(poly == NULL)
2065       poly = dline;
2066     else
2067       poly->insert(dline);    
2068  
2069     //the left chain
2070     for(i=beginLeftIndex; i<endLeftIndex; i++)
2071       {
2072         sline = new sampledLine(leftChain->getVertex(i), leftChain->getVertex(i+1));
2073         dline = new directedLine(INCREASING, sline);
2074         poly->insert(dline);
2075       }
2076
2077     //the edge connecting left chain with lower gridline
2078     vert2[0] = grid->get_u_value(lowerInd);
2079     vert2[1] = lowerV;
2080     sline = new sampledLine(leftChain->getVertex(endLeftIndex), vert2);
2081     dline = new directedLine(INCREASING, sline);
2082     poly->insert(dline);
2083
2084     //the lower grid line
2085     vert1[1] = vert2[1] = lowerV;
2086     for(i=lowerInd; i<innerInd; i++)
2087       {
2088         vert1[0] = grid->get_u_value(i);
2089         vert2[0] = grid->get_u_value(i+1);
2090         sline = new sampledLine(vert1, vert2);
2091         dline = new directedLine(INCREASING, sline);
2092         poly->insert(dline);       
2093       }
2094
2095     //the vertical grid line segement
2096     vert1[0]=vert2[0] = grid->get_u_value(innerInd);
2097     vert2[1]=upperV;
2098     vert1[1]=lowerV;
2099     sline=new sampledLine(vert1, vert2);
2100     dline=new directedLine(INCREASING, sline);
2101     poly->insert(dline);
2102     monoTriangulationOpt(poly, pStream);
2103     //cleanup
2104     poly->deleteSinglePolygonWithSline();
2105     return;
2106   }
2107  
2108
2109
2110  
2111
2112   Int i;
2113   if(1/*leftGridChain->getUlineIndex(leftGridChainStartIndex) >= 
2114      leftGridChain->getUlineIndex(leftGridChainStartIndex+1)*/
2115      ) /*the second grid line is beyond the first one to the left*/
2116     {
2117       /*find the maximal U-monotone chain 
2118        * of endLeftIndex, endLeftIndex-1, ..., 
2119        */
2120       i=endLeftIndex;
2121       Real prevU = leftChain->getVertex(i)[0];
2122       for(i=endLeftIndex-1; i>=beginLeftIndex; i--){
2123         Real thisU = leftChain->getVertex(i)[0];
2124         if( prevU < thisU){
2125           prevU = thisU;
2126         }
2127         else 
2128           break;
2129       }
2130       /*from endLeftIndex to i+1 is strictly U- monotone */
2131       /*if i+1==endLeftIndex and the vertex and leftchain is on the second gridline, then
2132        *we should use 2 vertices on the leftchain. If we only use one (endLeftIndex), then we
2133        *we would output degenerate triangles
2134        */
2135       if(i+1 == endLeftIndex && leftChain->getVertex(endLeftIndex)[1] == leftGridChain->get_v_value(1+leftGridChainStartIndex))
2136         i--;
2137
2138       Int j = beginLeftIndex/*endLeftIndex*/+1;
2139
2140
2141       if(leftGridChain->getInnerIndex(leftGridChainStartIndex+1) > leftGridChain->getUlineIndex(leftGridChainStartIndex))
2142         {
2143           j = findIncreaseChainFromBegin(leftChain, beginLeftIndex, i+1/*endLeftIndex*/);
2144
2145           Int temp = beginLeftIndex;
2146           /*now from begin to j-1 is strictly u-monotone*/
2147           /*if j-1 is on the first grid line, then we want to skip to the vertex which is strictly
2148            *below the grid line. This vertexmust exist since there is a 'corner turn' inbetween the two grid lines
2149            */
2150           if(j-1 == beginLeftIndex)
2151             {
2152               while(leftChain->getVertex(j-1)[1] == leftGridChain->get_v_value(leftGridChainStartIndex))
2153                 j++;            
2154
2155               Real vert[2];
2156               vert[0] = leftGridChain->get_u_value(leftGridChainStartIndex);
2157               vert[1] = leftGridChain->get_v_value(leftGridChainStartIndex);
2158
2159               monoTriangulation2(
2160                                  vert/*leftChain->getVertex(beginLeftIndex)*/,
2161                                  leftChain->getVertex(j-1),
2162                                  leftChain,
2163                                  beginLeftIndex,
2164                                  j-2,
2165                                  1,
2166                                  pStream //increase chain
2167                                  );
2168                                  
2169               temp = j-1;
2170             }
2171                                  
2172           stripOfFanLeft(leftChain, j-1, temp/*beginLeftIndex*/, leftGridChain->getGrid(),
2173                          leftGridChain->getVlineIndex(leftGridChainStartIndex),
2174                          leftGridChain->getUlineIndex(leftGridChainStartIndex),
2175                          leftGridChain->getInnerIndex(leftGridChainStartIndex+1),
2176                          pStream,
2177                          1 /*the grid line is above the trim line*/
2178                          );
2179         }
2180       
2181       stripOfFanLeft(leftChain, endLeftIndex, i+1, leftGridChain->getGrid(), 
2182                      leftGridChain->getVlineIndex(leftGridChainStartIndex+1),
2183                      leftGridChain->getUlineIndex(leftGridChainStartIndex+1),
2184                      leftGridChain->getInnerIndex(leftGridChainStartIndex+1),
2185                      pStream,
2186                      0 /*the grid line is below the trim lines*/
2187                      );
2188       
2189       /*monotone triangulate the remaining left chain togther with the
2190        *two vertices on the two grid v-lines.
2191        */
2192       Real vert[2][2];
2193       vert[0][0]=vert[1][0] = leftGridChain->getInner_u_value(leftGridChainStartIndex+1);
2194       vert[0][1] = leftGridChain->get_v_value(leftGridChainStartIndex);      
2195       vert[1][1] = leftGridChain->get_v_value(leftGridChainStartIndex+1);
2196
2197 //      vertexArray right(vert, 2);
2198
2199       monoTriangulation2(
2200                          &vert[0][0], /*top vertex */
2201                          &vert[1][0], /*bottom vertex*/
2202                          leftChain, 
2203                          /*beginLeftIndex*/j-1,
2204                          i+1,
2205                          1, /*an increasing chain*/
2206                          pStream);
2207     }
2208   else /*the second one is shorter than the first one to the left*/
2209     {
2210       /*find the maximal U-monotone chain of beginLeftIndex, beginLeftIndex+1,...,
2211        */
2212       i=beginLeftIndex;
2213       Real prevU = leftChain->getVertex(i)[0];
2214       for(i=beginLeftIndex+1; i<=endLeftIndex; i++){
2215         Real thisU = leftChain->getVertex(i)[0];
2216
2217         if(prevU < thisU){
2218           prevU = thisU;
2219         }
2220         else
2221           break;
2222       }
2223       /*from beginLeftIndex to i-1 is strictly U-monotone*/
2224
2225
2226       stripOfFanLeft(leftChain, i-1, beginLeftIndex, leftGridChain->getGrid(),
2227                          leftGridChain->getVlineIndex(leftGridChainStartIndex),
2228                          leftGridChain->getUlineIndex(leftGridChainStartIndex),
2229                          leftGridChain->getUlineIndex(leftGridChainStartIndex+1),
2230                          pStream,
2231                          1 /*the grid line is above the trim lines*/
2232                          );
2233       /*monotone triangulate the remaining left chain together with the 
2234        *two vertices on the two grid v-lines.
2235        */
2236       Real vert[2][2];
2237       vert[0][0]=vert[1][0] = leftGridChain->get_u_value(leftGridChainStartIndex+1);
2238       vert[0][1] = leftGridChain->get_v_value(leftGridChainStartIndex);      
2239       vert[1][1] = leftGridChain->get_v_value(leftGridChainStartIndex+1);
2240
2241       vertexArray right(vert, 2);
2242
2243       monoTriangulation2(
2244                          &vert[0][0], //top vertex 
2245                          &vert[1][0], //bottom vertex
2246                          leftChain, 
2247                          i-1,
2248                          endLeftIndex,
2249                          1, /*an increase chain*/
2250                          pStream);
2251
2252     }
2253 }
2254   
2255 /*n_upper>=1
2256  *n_lower>=1
2257  */
2258 void triangulateXYMono(Int n_upper, Real upperVerts[][2],
2259                        Int n_lower, Real lowerVerts[][2],
2260                        primStream* pStream)
2261 {
2262   Int i,j,k,l;
2263   Real* leftMostV;
2264
2265   assert(n_upper>=1 && n_lower>=1);
2266   if(upperVerts[0][0] <= lowerVerts[0][0])
2267     {
2268       i=1;
2269       j=0;
2270       leftMostV = upperVerts[0];
2271     }
2272   else
2273     {
2274       i=0;
2275       j=1;
2276       leftMostV = lowerVerts[0];
2277     }
2278   
2279   while(1)
2280     {
2281       if(i >= n_upper) /*case1: no more in upper*/
2282         {
2283
2284           if(j<n_lower-1) /*at least two vertices in lower*/
2285             {
2286               pStream->begin();
2287               pStream->insert(leftMostV);
2288               while(j<n_lower){
2289                 pStream->insert(lowerVerts[j]);
2290                 j++;
2291               }
2292               pStream->end(PRIMITIVE_STREAM_FAN);
2293             }
2294
2295           break;        
2296         }
2297       else if(j>= n_lower) /*case2: no more in lower*/
2298         {
2299
2300           if(i<n_upper-1) /*at least two vertices in upper*/
2301             {
2302               pStream->begin();
2303               pStream->insert(leftMostV);
2304
2305               for(k=n_upper-1; k>=i; k--)
2306                 pStream->insert(upperVerts[k]);
2307
2308               pStream->end(PRIMITIVE_STREAM_FAN);
2309             }
2310
2311           break;
2312         }
2313       else /* case3: neither is empty, plus the leftMostV, there is at least one triangle to output*/
2314         {
2315
2316           if(upperVerts[i][0] <= lowerVerts[j][0])
2317             {
2318               pStream->begin();
2319               pStream->insert(lowerVerts[j]); /*the origin of this fan*/
2320
2321               /*find the last k>=i such that 
2322                *upperverts[k][0] <= lowerverts[j][0]
2323                */
2324               k=i;
2325               while(k<n_upper)
2326                 {
2327                   if(upperVerts[k][0] > lowerVerts[j][0])
2328                     break;
2329                   k++;
2330                 }
2331               k--;
2332               for(l=k; l>=i; l--)/*the reverse is for two-face lighting*/
2333                 {
2334                   pStream->insert(upperVerts[l]);
2335                 }
2336               pStream->insert(leftMostV);
2337
2338               pStream->end(PRIMITIVE_STREAM_FAN);
2339               //update i for next loop
2340               i = k+1;
2341               leftMostV = upperVerts[k];
2342
2343             }
2344           else /*upperVerts[i][0] > lowerVerts[j][0]*/
2345             {
2346               pStream->begin();
2347               pStream->insert(upperVerts[i]);/*the origion of this fan*/
2348               pStream->insert(leftMostV);
2349               /*find the last k>=j such that
2350                *lowerverts[k][0] < upperverts[i][0]*/
2351               k=j;
2352               while(k< n_lower)
2353                 {
2354                   if(lowerVerts[k][0] >= upperVerts[i][0])
2355                     break;
2356                   pStream->insert(lowerVerts[k]);
2357                   k++;
2358                 }
2359               pStream->end(PRIMITIVE_STREAM_FAN);
2360               j=k;
2361               leftMostV = lowerVerts[j-1];
2362             }     
2363         }
2364     }
2365 }
2366                        
2367
2368 void stripOfFanLeft(vertexArray* leftChain, 
2369                     Int largeIndex,
2370                     Int smallIndex,
2371                     gridWrap* grid,
2372                     Int vlineIndex,
2373                     Int ulineSmallIndex,
2374                     Int ulineLargeIndex,
2375                     primStream* pStream,
2376                     Int gridLineUp /*1 if the grid line is above the trim lines*/
2377                      )
2378 {
2379   assert(largeIndex >= smallIndex);
2380
2381   Real grid_v_value;
2382   grid_v_value = grid->get_v_value(vlineIndex);
2383
2384   Real2* trimVerts=(Real2*) malloc(sizeof(Real2)* (largeIndex-smallIndex+1));
2385   assert(trimVerts);
2386
2387
2388   Real2* gridVerts=(Real2*) malloc(sizeof(Real2)* (ulineLargeIndex-ulineSmallIndex+1));
2389   assert(gridVerts);
2390
2391   Int k,i;
2392   if(gridLineUp) /*trim line is below grid line, so trim vertices are going right when index increases*/
2393     for(k=0, i=smallIndex; i<=largeIndex; i++, k++)
2394       {
2395       trimVerts[k][0] = leftChain->getVertex(i)[0];
2396       trimVerts[k][1] = leftChain->getVertex(i)[1];
2397     }
2398   else
2399     for(k=0, i=largeIndex; i>=smallIndex; i--, k++)
2400       {
2401         trimVerts[k][0] = leftChain->getVertex(i)[0];
2402         trimVerts[k][1] = leftChain->getVertex(i)[1];
2403       }
2404
2405   for(k=0, i=ulineSmallIndex; i<= ulineLargeIndex; i++, k++)
2406     {
2407       gridVerts[k][0] = grid->get_u_value(i);
2408       gridVerts[k][1] = grid_v_value;
2409     }
2410
2411   if(gridLineUp)
2412     triangulateXYMono(
2413                       ulineLargeIndex-ulineSmallIndex+1, gridVerts,
2414                       largeIndex-smallIndex+1, trimVerts,
2415                       pStream);
2416   else
2417     triangulateXYMono(largeIndex-smallIndex+1, trimVerts,
2418                       ulineLargeIndex-ulineSmallIndex+1, gridVerts,
2419                       pStream);
2420   free(trimVerts);
2421   free(gridVerts);
2422 }
2423
2424   
2425
2426
2427