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