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 "gluos.h"
41 #include "glimports.h"
42 #include "zlassert.h"
43 #include "sampleCompRight.h"
44 
45 #define max(a,b) ((a>b)? a:b)
46 #define min(a,b) ((a>b)? b:a)
47 
48 
49 
50 #ifdef NOT_TAKEOUT
51 
52 /*notice that we need leftChain because the
53  *corners could be on the leftChain.
54  */
sampleCompRight(Real * topVertex,Real * botVertex,vertexArray * leftChain,Int leftStartIndex,Int leftEndIndex,vertexArray * rightChain,Int rightStartIndex,Int rightEndIndex,gridBoundaryChain * rightGridChain,Int gridIndex1,Int gridIndex2,Int up_rightCornerWhere,Int up_rightCornerIndex,Int down_rightCornerWhere,Int down_rightCornerIndex,primStream * pStream)55 void sampleCompRight(Real* topVertex, Real* botVertex,
56 		    vertexArray* leftChain,
57 		    Int leftStartIndex, Int leftEndIndex,
58 		    vertexArray* rightChain,
59 		    Int rightStartIndex, Int rightEndIndex,
60 		    gridBoundaryChain* rightGridChain,
61 		    Int gridIndex1, Int gridIndex2,
62 		    Int up_rightCornerWhere,
63 		    Int up_rightCornerIndex,
64 		    Int down_rightCornerWhere,
65 		    Int down_rightCornerIndex,
66 		    primStream* pStream)
67 {
68   /*find out whether there is a trim vertex  which is
69    *inbetween the top and bot grid lines or not.
70    */
71   Int midIndex1;
72   Int midIndex2;
73   Int gridMidIndex1 = 0, gridMidIndex2 = 0;
74   //midIndex1: array[i] <= v, array[i+1] > v
75   //midIndex2: array[i] >= v,  array[i+1] < v
76   midIndex1 = rightChain->findIndexBelowGen(rightGridChain->get_v_value(gridIndex1),
77 					    rightStartIndex,
78 					    rightEndIndex);
79   midIndex2 = -1; //initilization
80   if(midIndex1 <= rightEndIndex && gridIndex1 < gridIndex2)
81     if(rightChain->getVertex(midIndex1)[1] >= rightGridChain->get_v_value(gridIndex2))
82       {
83 	//midIndex2 must exist:
84 	midIndex2 = rightChain->findIndexAboveGen(rightGridChain->get_v_value(gridIndex2),
85 						  midIndex1, //midIndex1<=midIndex2
86 						  rightEndIndex);
87 	//find gridMidIndex1 so that either it=gridIndex1 when the gridline is
88 	// at the same height as trim vertex midIndex1, or it is the last one
89 	//which is strictly above midIndex1.
90 	{
91 	  Real temp = rightChain->getVertex(midIndex1)[1];
92 	  if(rightGridChain->get_v_value(gridIndex1) == temp)
93 	    gridMidIndex1 = gridIndex1;
94 	  else
95 	    {
96 	    gridMidIndex1 = gridIndex1;
97 	    while(rightGridChain->get_v_value(gridMidIndex1) > temp)
98 	      gridMidIndex1++;
99 	    gridMidIndex1--;
100 	    }
101 	}//end of find gridMindIndex1
102 	//find gridMidIndex2 so that it is the (first one below or equal
103 	//midIndex) last one above or equal midIndex2
104 	{
105 	  Real temp = rightChain->getVertex(midIndex2)[1];
106 	  for(gridMidIndex2 = gridMidIndex1+1; gridMidIndex2 <= gridIndex2; gridMidIndex2++)
107 	    if(rightGridChain->get_v_value(gridMidIndex2) <= temp)
108 	      break;
109 
110 	  assert(gridMidIndex2 <= gridIndex2);
111 	}//end of find gridMidIndex2
112       }
113 
114 
115 
116   //to interprete the corner information
117   Real* cornerTop;
118   Real* cornerBot;
119   Int cornerRightStart;
120   Int cornerRightEnd;
121   Int cornerLeftUpEnd;
122   Int cornerLeftDownStart;
123   if(up_rightCornerWhere == 2) //right corner is on right chain
124     {
125       cornerTop = rightChain->getVertex(up_rightCornerIndex);
126       cornerRightStart = up_rightCornerIndex+1;
127       cornerLeftUpEnd = -1; //no left
128     }
129   else if(up_rightCornerWhere == 1) //right corner is on top
130     {
131       cornerTop = topVertex;
132       cornerRightStart = rightStartIndex;
133       cornerLeftUpEnd = -1; //no left
134     }
135   else //right corner is on left chain
136     {
137       cornerTop = topVertex;
138       cornerRightStart = rightStartIndex;
139       cornerLeftUpEnd = up_rightCornerIndex;
140     }
141 
142   if(down_rightCornerWhere == 2) //right corner is on right chan
143     {
144       cornerBot = rightChain->getVertex(down_rightCornerIndex);
145       cornerRightEnd = down_rightCornerIndex-1;
146       cornerLeftDownStart = leftEndIndex+1; //no left
147     }
148   else if (down_rightCornerWhere == 1) //right corner is at bot
149     {
150       cornerBot = botVertex;
151       cornerRightEnd = rightEndIndex;
152       cornerLeftDownStart = leftEndIndex+1; //no left
153     }
154   else //right corner is on the left chain
155     {
156       cornerBot = botVertex;
157       cornerRightEnd = rightEndIndex;
158       cornerLeftDownStart = down_rightCornerIndex;
159     }
160 
161   //sample
162   if(midIndex2 >= 0) //there is a trm point between grid lines
163     {
164 
165       sampleRightSingleTrimEdgeRegionGen(cornerTop, rightChain->getVertex(midIndex1),
166 					 rightChain,
167 					 cornerRightStart,
168 					 midIndex1-1,
169 					 rightGridChain,
170 					 gridIndex1,
171 					 gridMidIndex1,
172 					 leftChain,
173 					 leftStartIndex,
174 					 cornerLeftUpEnd,
175 					 0, //no left down section,
176 					 -1,
177 					 pStream);
178 
179       sampleRightSingleTrimEdgeRegionGen(rightChain->getVertex(midIndex2),
180 					 cornerBot,
181 					 rightChain,
182 					 midIndex2+1,
183 					 cornerRightEnd,
184 					 rightGridChain,
185 					 gridMidIndex2,
186 					 gridIndex2,
187 					 leftChain,
188 					 0, //no left up section
189 					 -1,
190 					 cornerLeftDownStart,
191 					 leftEndIndex,
192 					 pStream);
193 
194       sampleRightStripRecF(rightChain,
195 			   midIndex1,
196 			   midIndex2,
197 			   rightGridChain,
198 			   gridMidIndex1,
199 			   gridMidIndex2,
200 			   pStream);
201 
202     }
203   else
204     {
205       sampleRightSingleTrimEdgeRegionGen(cornerTop, cornerBot,
206 					 rightChain,
207 					 cornerRightStart,
208 					 cornerRightEnd,
209 					 rightGridChain,
210 					 gridIndex1,
211 					 gridIndex2,
212 					 leftChain,
213 					 leftStartIndex,
214 					 cornerLeftUpEnd,
215 					 cornerLeftDownStart,
216 					 leftEndIndex,
217 					 pStream);
218     }
219 }
220 
sampleRightSingleTrimEdgeRegionGen(Real topVertex[2],Real botVertex[2],vertexArray * rightChain,Int rightStart,Int rightEnd,gridBoundaryChain * gridChain,Int gridBeginIndex,Int gridEndIndex,vertexArray * leftChain,Int leftUpBegin,Int leftUpEnd,Int leftDownBegin,Int leftDownEnd,primStream * pStream)221 void sampleRightSingleTrimEdgeRegionGen(Real topVertex[2], Real botVertex[2],
222 					 vertexArray* rightChain,
223 					 Int rightStart,
224 					 Int rightEnd,
225 					 gridBoundaryChain* gridChain,
226 					 Int gridBeginIndex,
227 					 Int gridEndIndex,
228 					 vertexArray* leftChain,
229 					 Int leftUpBegin,
230 					 Int leftUpEnd,
231 					 Int leftDownBegin,
232 					 Int leftDownEnd,
233 					 primStream* pStream)
234 {
235   Int i,k;
236    /*creat an array to store all the up and down secments of the left chain,
237    *and the right end grid points
238    *
239    *although vertex array is a dynamic array, but to gain efficiency,
240    *it is better to initiliza the exact array size
241    */
242   vertexArray vArray(gridEndIndex-gridBeginIndex+1 +
243 		     max(0,leftUpEnd - leftUpBegin+1)+
244 		     max(0,leftDownEnd - leftDownBegin+1));
245   //append the vertices on the up section of the left chain
246   for(i=leftUpBegin; i<= leftUpEnd; i++)
247     vArray.appendVertex(leftChain->getVertex(i));
248 
249   //append the vertices of the right extremal grid points,
250   //and at the same time, perform triangulation for the stair cases
251   vArray.appendVertex(gridChain->get_vertex(gridBeginIndex));
252 
253   for(k=1, i=gridBeginIndex+1; i<= gridEndIndex; i++, k++)
254     {
255       vArray.appendVertex(gridChain->get_vertex(i));
256 
257       //output the fan of the grid points of the (i)th and (i-1)th grid line.
258       gridChain->rightEndFan(i, pStream);
259     }
260 
261   //append all the vertices on the down section of the left chain
262   for(i=leftDownBegin; i<= leftDownEnd; i++)
263     vArray.appendVertex(leftChain->getVertex(i));
264   monoTriangulationRecGen(topVertex, botVertex,
265 			  &vArray, 0, vArray.getNumElements()-1,
266 			  rightChain, rightStart, rightEnd,
267 			  pStream);
268 }
269 
sampleRightSingleTrimEdgeRegion(Real upperVert[2],Real lowerVert[2],gridBoundaryChain * gridChain,Int beginIndex,Int endIndex,primStream * pStream)270 void sampleRightSingleTrimEdgeRegion(Real upperVert[2], Real lowerVert[2],
271 				     gridBoundaryChain* gridChain,
272 				     Int beginIndex,
273 				     Int endIndex,
274 				     primStream* pStream)
275 {
276   Int i,k;
277   vertexArray vArray(endIndex-beginIndex+1);
278   vArray.appendVertex(gridChain->get_vertex(beginIndex));
279   for(k=1, i=beginIndex+1; i<= endIndex; i++, k++)
280     {
281       vArray.appendVertex(gridChain->get_vertex(i));
282       //output the fan of the grid points of the (i)_th and i-1th gridLine
283       gridChain->rightEndFan(i, pStream);
284     }
285   monoTriangulation2(upperVert, lowerVert, &vArray, 0, endIndex-beginIndex,
286 		     1, //increase chain (to the left)
287 		     pStream);
288 }
289 
290 
291 /*the gridlines from rightGridChainStartIndex to
292  *rightGridChainEndIndex are assumed to form a
293  *connected componenet
294  *the trm vertex of topRightIndex is assumed to be below
295  *or equal the first gridLine, and the trm vertex of
296  *botRightIndex is assumed to be above or equal the last gridline
297  **there could be multipe trm vertices equal to the last gridline, but
298  **only one could be equal to top gridline. shape: ____| (recall that
299  **for left chain recF, we allow shape: |----
300  *if botRightIndex<topRightIndex, then no connected componenet exists, and
301  *no triangles are generated.
302  *Othewise, botRightIndex>= topRightIndex, there is at least one triangles to
303  *output
304  */
sampleRightStripRecF(vertexArray * rightChain,Int topRightIndex,Int botRightIndex,gridBoundaryChain * rightGridChain,Int rightGridChainStartIndex,Int rightGridChainEndIndex,primStream * pStream)305 void sampleRightStripRecF(vertexArray* rightChain,
306 		     Int topRightIndex,
307 		     Int botRightIndex,
308 		     gridBoundaryChain* rightGridChain,
309 		     Int rightGridChainStartIndex,
310 		     Int rightGridChainEndIndex,
311 		     primStream* pStream
312 		     )
313 {
314 
315   //sstop conditionL: if topRightIndex > botRightIndex, then stop
316   if(topRightIndex > botRightIndex)
317     return;
318 
319   //if there is only one grid line, return
320   if(rightGridChainStartIndex >= rightGridChainEndIndex)
321     return;
322 
323 
324   assert(rightChain->getVertex(topRightIndex)[1] <= rightGridChain->get_v_value(rightGridChainStartIndex) &&
325 	 rightChain->getVertex(botRightIndex)[1] >= rightGridChain->get_v_value(rightGridChainEndIndex));
326 
327   //firstfind the first trim vertex which is strictly below the second top
328   //grid line: index1.
329   Real secondGridChainV = rightGridChain->get_v_value(rightGridChainStartIndex+1);
330   Int index1 = topRightIndex;
331   while(rightChain->getVertex(index1)[1] >= secondGridChainV){
332     index1++;
333     if(index1 >  botRightIndex)
334       break;
335   }
336   //now rightChain->getVertex(index1-1)[1] >= secondGridChainV and
337   //rightChain->getVertex(index1)[1] < secondGridChainV and
338   //we should include index1-1 to perform a gridStep
339     index1--;
340 
341   //now we have rightChain->getVertex(index1)[1] >= secondGridChainV, and
342   //rightChain->getVertex(index1+1)[1] < secondGridChainV
343   sampleRightOneGridStep(rightChain, topRightIndex, index1, rightGridChain, rightGridChainStartIndex, pStream);
344 
345   //if rightChain->getVertex(index1)[1] ==secondGridChainV then we can
346   //recurvesively to the rest
347   if(rightChain->getVertex(index1)[1] == secondGridChainV)
348     {
349 
350 
351       sampleRightStripRecF(rightChain, index1, botRightIndex, rightGridChain, rightGridChainStartIndex+1, rightGridChainEndIndex, pStream);
352     }
353   else if(index1 < botRightIndex)
354     {
355       //otherwise, we have rightChain->getVertex(index1)[1] > secondV
356       //let the next trim vertex be nextTrimVertex, (which should be strictly
357       //below the second grid line). Find the last grid line index2 which is STRICTLY ABOVE
358       //nextTrimVertex.
359       //sample one trm edge region.
360       Real *uppervert, *lowervert;
361       uppervert = rightChain->getVertex(index1);
362       lowervert = rightChain->getVertex(index1+1); //okay since index1<botRightindex
363       Int index2 = rightGridChainStartIndex+1;
364       while(rightGridChain->get_v_value(index2) > lowervert[1])
365 	{
366 	  index2++;
367 	  if(index2 > rightGridChainEndIndex)
368 	    break;
369 	}
370       index2--;
371 
372       sampleRightSingleTrimEdgeRegion(uppervert, lowervert, rightGridChain, rightGridChainStartIndex+1, index2, pStream);
373 
374       //recursion
375       sampleRightStripRecF(rightChain, index1+1, botRightIndex, rightGridChain, index2, rightGridChainEndIndex, pStream);
376     }
377 }
378 
379 //the degenerate case of sampleRightOneGridStep
sampleRightOneGridStepNoMiddle(vertexArray * rightChain,Int beginRightIndex,Int endRightIndex,gridBoundaryChain * rightGridChain,Int rightGridChainStartIndex,primStream * pStream)380 void sampleRightOneGridStepNoMiddle(vertexArray* rightChain,
381 				    Int beginRightIndex,
382 				    Int endRightIndex,
383 				    gridBoundaryChain* rightGridChain,
384 				    Int rightGridChainStartIndex,
385 				    primStream* pStream)
386 {
387   /*since there is no middle, there is at most one point which is on the
388    *second grid line, there could be multiple points on the first (top)
389    *grid line.
390    */
391   rightGridChain->rightEndFan(rightGridChainStartIndex+1, pStream);
392   monoTriangulation2(rightGridChain->get_vertex(rightGridChainStartIndex),
393 		     rightGridChain->get_vertex(rightGridChainStartIndex+1),
394 		     rightChain,
395 		     beginRightIndex,
396 		     endRightIndex,
397 		     0, //decrease chain
398 		     pStream);
399 }
400 
401 //sampling the right area in between two grid lines
402 //shape: _________|
sampleRightOneGridStep(vertexArray * rightChain,Int beginRightIndex,Int endRightIndex,gridBoundaryChain * rightGridChain,Int rightGridChainStartIndex,primStream * pStream)403 void sampleRightOneGridStep(vertexArray* rightChain,
404 			    Int beginRightIndex,
405 			    Int endRightIndex,
406 			    gridBoundaryChain* rightGridChain,
407 			    Int rightGridChainStartIndex,
408 			    primStream* pStream)
409 {
410   if(checkMiddle(rightChain, beginRightIndex, endRightIndex,
411 		 rightGridChain->get_v_value(rightGridChainStartIndex),
412 		 rightGridChain->get_v_value(rightGridChainStartIndex+1))<0)
413     {
414       sampleRightOneGridStepNoMiddle(rightChain, beginRightIndex, endRightIndex, rightGridChain, rightGridChainStartIndex, pStream);
415       return;
416     }
417 
418   //copy into a polygn
419   {
420     directedLine* poly = NULL;
421     sampledLine* sline;
422     directedLine* dline;
423     gridWrap* grid = rightGridChain->getGrid();
424     float vert1[2];
425     float vert2[2];
426     Int i;
427 
428     Int innerInd = rightGridChain->getInnerIndex(rightGridChainStartIndex+1);
429     Int upperInd = rightGridChain->getUlineIndex(rightGridChainStartIndex);
430     Int lowerInd = rightGridChain->getUlineIndex(rightGridChainStartIndex+1);
431     Real upperV = rightGridChain->get_v_value(rightGridChainStartIndex);
432     Real lowerV = rightGridChain->get_v_value(rightGridChainStartIndex+1);
433 
434     //the upper gridline
435     vert1[1]=vert2[1]=upperV;
436     for(i=upperInd;
437 	i>innerInd;
438 	i--)
439       {
440 	vert1[0]=grid->get_u_value(i);
441 	vert2[0]=grid->get_u_value(i-1);
442 	sline = new sampledLine(vert1, vert2);
443 	dline = new directedLine(INCREASING, sline);
444 	if(poly == NULL)
445 	  poly = dline;
446 	else
447 	  poly->insert(dline);
448       }
449 
450     //the vertical grid line segment
451     vert1[0]=vert2[0] = grid->get_u_value(innerInd);
452     vert1[1]=upperV;
453     vert2[1]=lowerV;
454     sline=new sampledLine(vert1, vert2);
455     dline=new directedLine(INCREASING, sline);
456     if(poly == NULL)
457       poly = dline;
458     else
459       poly->insert(dline);
460 
461     //the lower grid line
462     vert1[1]=vert2[1]=lowerV;
463     for(i=innerInd; i<lowerInd; i++)
464       {
465 	vert1[0] = grid->get_u_value(i);
466 	vert2[0] = grid->get_u_value(i+1);
467 	sline = new sampledLine(vert1, vert2);
468 	dline = new directedLine(INCREASING, sline);
469 	poly->insert(dline);
470       }
471 
472     //the edge connecting lower grid to right chain
473     vert1[0]=grid->get_u_value(lowerInd);
474     sline = new sampledLine(vert1, rightChain->getVertex(endRightIndex));
475     dline = new directedLine(INCREASING, sline);
476     poly->insert(dline);
477 
478 
479     //the right Chain
480     for(i=endRightIndex; i>beginRightIndex; i--)
481       {
482 	sline = new sampledLine(rightChain->getVertex(i), rightChain->getVertex(i-1));
483 	dline = new directedLine(INCREASING, sline);
484 	poly->insert(dline);
485       }
486 
487     //the edge connecting right chain with upper grid
488     vert2[1]=upperV;
489     vert2[0]=grid->get_u_value(upperInd);
490     sline = new sampledLine(rightChain->getVertex(beginRightIndex), vert2);
491     dline = new directedLine(INCREASING, sline);
492     poly->insert(dline);
493     monoTriangulationOpt(poly, pStream);
494     //clean up
495     poly->deleteSinglePolygonWithSline();
496 
497     return;
498   }
499 
500   //this following code cannot be reached, but leave it for debuggig purpose.
501   Int i;
502   //find the maximal U-monotone chain of beginRightIndex, beginRightIndex+1,...
503   i=beginRightIndex;
504   Real prevU = rightChain->getVertex(i)[0];
505   for(i=beginRightIndex+1; i<= endRightIndex; i++){
506     Real thisU = rightChain->getVertex(i)[0];
507     if(thisU < prevU)
508       prevU = thisU;
509     else
510       break;
511   }
512   //from beginRightIndex to i-1 is strictly U-monotne
513   //if(i-1==beginRightIndex and the vertex of rightchain is on the first
514   //gridline, then we should use 2 vertices  on the right chain. Of we only
515   //use one (begin), we would output degenrate triangles.
516   if(i-1 == beginRightIndex && rightChain->getVertex(beginRightIndex)[1] == rightGridChain->get_v_value(rightGridChainStartIndex))
517     i++;
518 
519   Int j = endRightIndex -1;
520   if(rightGridChain->getInnerIndex(rightGridChainStartIndex+1) < rightGridChain->getUlineIndex(rightGridChainStartIndex+1))
521     {
522       j = rightChain->findDecreaseChainFromEnd(i-1/*beginRightIndex*/, endRightIndex);
523       Int temp = endRightIndex;
524       //now from j+1 to end is strictly U-monotone.
525       //if j+1 is on the last grid line, then we wat to skip to the vertex
526       //whcih is strictly above the second grid line. This vertex must exist
527       //since there is a middle vertex
528       if(j+1 == endRightIndex)
529 	{
530 	  while(rightChain->getVertex(j+1)[1] == rightGridChain->get_v_value(rightGridChainStartIndex+1))
531 	    j--;
532 
533 	  monoTriangulation2(rightChain->getVertex(j+1),
534 			     rightGridChain->get_vertex(rightGridChainStartIndex+1),
535 			     rightChain,
536 			     j+2,
537 			     endRightIndex,
538 			     0, //a decrease chain
539 			     pStream);
540 
541 	  temp = j+1;
542 	}
543 
544       stripOfFanRight(rightChain, temp, j+1, rightGridChain->getGrid(),
545 		      rightGridChain->getVlineIndex(rightGridChainStartIndex+1),
546 		      rightGridChain->getInnerIndex(rightGridChainStartIndex+1),
547 		      rightGridChain->getUlineIndex(rightGridChainStartIndex+1),
548 		      pStream,
549 		      0 //the grid line is below the trim line
550 		      );
551 
552     }
553 
554 
555   stripOfFanRight(rightChain, i-1, beginRightIndex, rightGridChain->getGrid(),
556 		  rightGridChain->getVlineIndex(rightGridChainStartIndex),
557 		  rightGridChain->getInnerIndex(rightGridChainStartIndex+1),
558 		  rightGridChain->getUlineIndex(rightGridChainStartIndex),
559 		  pStream,
560 		  1 //the grid line is above the trm lines
561 		  );
562 
563   //monotone triangulate the remaining rightchain together with the
564   //two vertices on the two grid v-lines
565   Real vert[2][2];
566   vert[0][0] = vert[1][0] = rightGridChain->getInner_u_value(rightGridChainStartIndex+1);
567   vert[0][1] = rightGridChain->get_v_value(rightGridChainStartIndex);
568   vert[1][1] = rightGridChain->get_v_value(rightGridChainStartIndex+1);
569 
570   monoTriangulation2(&vert[0][0],
571 		     &vert[1][0],
572 		     rightChain,
573 		     i-1,
574 		     j+1,
575 		     0, ///a decreae chain
576 		     pStream);
577 }
578 
579 #endif
580 
stripOfFanRight(vertexArray * rightChain,Int largeIndex,Int smallIndex,gridWrap * grid,Int vlineIndex,Int ulineSmallIndex,Int ulineLargeIndex,primStream * pStream,Int gridLineUp)581 void stripOfFanRight(vertexArray* rightChain,
582 		    Int largeIndex,
583 		    Int smallIndex,
584 		    gridWrap* grid,
585 		    Int vlineIndex,
586 		    Int ulineSmallIndex,
587 		    Int ulineLargeIndex,
588 		    primStream* pStream,
589 		    Int gridLineUp /*1 if the grid line is above the trim lines*/
590 		     )
591 {
592   assert(largeIndex >= smallIndex);
593 
594   Real grid_v_value;
595   grid_v_value = grid->get_v_value(vlineIndex);
596 
597   Real2* trimVerts=(Real2*) malloc(sizeof(Real2)* (largeIndex-smallIndex+1));
598   assert(trimVerts);
599 
600 
601   Real2* gridVerts=(Real2*) malloc(sizeof(Real2)* (ulineLargeIndex-ulineSmallIndex+1));
602   assert(gridVerts);
603 
604   Int k,i;
605   if(! gridLineUp) /*trim line is above grid line, so trim vertices are going right when index increases*/
606     for(k=0, i=smallIndex; i<=largeIndex; i++, k++)
607       {
608       trimVerts[k][0] = rightChain->getVertex(i)[0];
609       trimVerts[k][1] = rightChain->getVertex(i)[1];
610     }
611   else
612     for(k=0, i=largeIndex; i>=smallIndex; i--, k++)
613       {
614 	trimVerts[k][0] = rightChain->getVertex(i)[0];
615 	trimVerts[k][1] = rightChain->getVertex(i)[1];
616       }
617 
618   for(k=0, i=ulineSmallIndex; i<= ulineLargeIndex; i++, k++)
619     {
620       gridVerts[k][0] = grid->get_u_value(i);
621       gridVerts[k][1] = grid_v_value;
622     }
623 
624   if(gridLineUp)
625     triangulateXYMono(
626 		      ulineLargeIndex-ulineSmallIndex+1, gridVerts,
627 		      largeIndex-smallIndex+1, trimVerts,
628 		      pStream);
629   else
630     triangulateXYMono(largeIndex-smallIndex+1, trimVerts,
631 		      ulineLargeIndex-ulineSmallIndex+1, gridVerts,
632 		      pStream);
633   free(trimVerts);
634   free(gridVerts);
635 }
636 
637 
638 
639 
640 
641 
642 
643 
644 
645