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 "glimports.h"
41#include "sampleComp.h"
42#include "sampleCompTop.h"
43#include "sampleCompBot.h"
44#include "sampleCompRight.h"
45
46
47
48#define max(a,b) ((a>b)? a:b)
49#define min(a,b) ((a>b)? b:a)
50
51void sampleConnectedComp(Real* topVertex, Real* botVertex,
52		    vertexArray* leftChain,
53		    Int leftStartIndex, Int leftEndIndex,
54		    vertexArray* rightChain,
55		    Int rightStartIndex, Int rightEndIndex,
56		    gridBoundaryChain* leftGridChain,
57		    gridBoundaryChain* rightGridChain,
58		    Int gridIndex1, Int gridIndex2,
59		    Int up_leftCornerWhere,
60		    Int up_leftCornerIndex,
61		    Int up_rightCornerWhere,
62		    Int up_rightCornerIndex,
63		    Int down_leftCornerWhere,
64		    Int down_leftCornerIndex,
65		    Int down_rightCornerWhere,
66		    Int down_rightCornerIndex,
67		    primStream* pStream,
68		    rectBlockArray* rbArray
69		    )
70{
71
72 sampleCompLeft(topVertex, botVertex,
73		leftChain,
74		leftStartIndex,	leftEndIndex,
75		rightChain,
76		rightStartIndex, rightEndIndex,
77		leftGridChain,
78		gridIndex1,
79		gridIndex2,
80		up_leftCornerWhere,
81		up_leftCornerIndex,
82		down_leftCornerWhere,
83		down_leftCornerIndex,
84		pStream);
85
86
87 sampleCompRight(topVertex, botVertex,
88		 leftChain,
89		 leftStartIndex, leftEndIndex,
90		 rightChain,
91		 rightStartIndex,
92		 rightEndIndex,
93		 rightGridChain,
94		 gridIndex1, gridIndex2,
95		 up_rightCornerWhere,
96		 up_rightCornerIndex,
97		 down_rightCornerWhere,
98		 down_rightCornerIndex,
99		 pStream);
100
101
102 sampleCompTop(topVertex,
103		     leftChain,
104		     leftStartIndex,
105		     rightChain,
106		     rightStartIndex,
107		     leftGridChain,
108		     rightGridChain,
109		     gridIndex1,
110		     up_leftCornerWhere,
111		     up_leftCornerIndex,
112		     up_rightCornerWhere,
113		     up_rightCornerIndex,
114		     pStream);
115
116 sampleCompBot(botVertex,
117		     leftChain,
118		     leftEndIndex,
119		     rightChain,
120		     rightEndIndex,
121		     leftGridChain,
122		     rightGridChain,
123		     gridIndex2,
124		     down_leftCornerWhere,
125		     down_leftCornerIndex,
126		     down_rightCornerWhere,
127		     down_rightCornerIndex,
128		     pStream);
129
130
131 //the center
132
133 rbArray->insert(new rectBlock(leftGridChain, rightGridChain, gridIndex1, gridIndex2));
134
135
136}
137
138/*notice that we need rightChain because the
139 *corners could be on the rightChain.
140 *here comp means component.
141 */
142void sampleCompLeft(Real* topVertex, Real* botVertex,
143		    vertexArray* leftChain,
144		    Int leftStartIndex, Int leftEndIndex,
145		    vertexArray* rightChain,
146		    Int rightStartIndex, Int rightEndIndex,
147		    gridBoundaryChain* leftGridChain,
148		    Int gridIndex1, Int gridIndex2,
149		    Int up_leftCornerWhere,
150		    Int up_leftCornerIndex,
151		    Int down_leftCornerWhere,
152		    Int down_leftCornerIndex,
153		    primStream* pStream)
154{
155  /*find out whether there is a trim vertex which is
156   *inbetween the top and bot grid lines or not.
157   */
158  Int midIndex1;
159  Int midIndex2;
160  Int gridMidIndex1 = 0, gridMidIndex2 = 0;
161  //midIndex1: array[i] <= v, array[i-1] > v
162  //midIndex2: array[i] >= v, array[i+1] < v
163  // v(gridMidIndex1) >= v(midindex1) > v(gridMidIndex1+1)
164  // v(gridMidIndex2-1) >= v(midIndex2) > v(gridMidIndex2) ??
165  midIndex1 = leftChain->findIndexBelowGen(
166					   leftGridChain->get_v_value(gridIndex1),
167					   leftStartIndex,
168					   leftEndIndex);
169
170  midIndex2 = -1; /*initilization*/
171  if(midIndex1<= leftEndIndex && gridIndex1<gridIndex2)
172    if(leftChain->getVertex(midIndex1)[1] >= leftGridChain->get_v_value(gridIndex2))
173      {
174	midIndex2 = leftChain->findIndexAboveGen(
175						 leftGridChain->get_v_value(gridIndex2),
176						 midIndex1, //midIndex1 <= midIndex2.
177						 leftEndIndex);
178	gridMidIndex1  = leftGridChain->lookfor(leftChain->getVertex(midIndex1)[1],
179						gridIndex1, gridIndex2);
180	gridMidIndex2 = 1+leftGridChain->lookfor(leftChain->getVertex(midIndex2)[1],
181					       gridMidIndex1, gridIndex2);
182      }
183
184
185  /*to interprete the corner information*/
186  Real* cornerTop;
187  Real* cornerBot;
188  Int cornerLeftStart;
189  Int cornerLeftEnd;
190  Int cornerRightUpEnd;
191  Int cornerRightDownStart;
192  if(up_leftCornerWhere == 0) /*left corner is on left chain*/
193    {
194      cornerTop = leftChain->getVertex(up_leftCornerIndex);
195      cornerLeftStart = up_leftCornerIndex+1;
196      cornerRightUpEnd = -1; /*no right*/
197    }
198  else if(up_leftCornerWhere == 1) /*left corner is on top*/
199    {
200      cornerTop = topVertex;
201      cornerLeftStart = leftStartIndex;
202      cornerRightUpEnd = -1; /*no right*/
203    }
204  else /*left corner is on right chain*/
205    {
206      cornerTop = topVertex;
207      cornerLeftStart = leftStartIndex;
208      cornerRightUpEnd = up_leftCornerIndex;
209    }
210
211  if(down_leftCornerWhere == 0) /*left corner is on left chain*/
212    {
213      cornerBot = leftChain->getVertex(down_leftCornerIndex);
214      cornerLeftEnd = down_leftCornerIndex-1;
215      cornerRightDownStart = rightEndIndex+1; /*no right*/
216    }
217  else if(down_leftCornerWhere == 1) /*left corner is on bot*/
218    {
219      cornerBot = botVertex;
220      cornerLeftEnd = leftEndIndex;
221      cornerRightDownStart = rightEndIndex+1; /*no right*/
222    }
223  else /*left corner is on the right chian*/
224    {
225      cornerBot = botVertex;
226      cornerLeftEnd = leftEndIndex;
227      cornerRightDownStart = down_leftCornerIndex;
228    }
229
230
231
232
233  /*sample*/
234  if(midIndex2 >= 0) /*there is a trim point inbewteen grid lines*/
235    {
236
237      sampleLeftSingleTrimEdgeRegionGen(cornerTop, leftChain->getVertex(midIndex1),
238					leftChain,
239					cornerLeftStart,
240					midIndex1-1,
241					leftGridChain,
242					gridIndex1,
243					gridMidIndex1,
244					rightChain,
245					rightStartIndex,
246					cornerRightUpEnd,
247					0, //no right down section
248					-1,
249					pStream);
250
251      sampleLeftSingleTrimEdgeRegionGen(leftChain->getVertex(midIndex2),
252					cornerBot,
253					leftChain,
254					midIndex2+1,
255					cornerLeftEnd,
256					leftGridChain,
257					gridMidIndex2,
258					gridIndex2,
259					rightChain,
260					0, //no right up section
261					-1,
262					cornerRightDownStart,
263					rightEndIndex,
264					pStream);
265
266
267      sampleLeftStripRecF(leftChain,
268			  midIndex1,
269			  midIndex2,
270			  leftGridChain,
271			  gridMidIndex1,
272			  gridMidIndex2,
273			  pStream);
274    }
275  else
276    {
277      sampleLeftSingleTrimEdgeRegionGen(cornerTop, cornerBot,
278					leftChain,
279					cornerLeftStart,
280					cornerLeftEnd,
281					leftGridChain,
282					gridIndex1,
283					gridIndex2,
284					rightChain,
285					rightStartIndex,
286					cornerRightUpEnd,
287					cornerRightDownStart,
288					rightEndIndex,
289					pStream);
290    }
291}
292
293void sampleLeftSingleTrimEdgeRegionGen(Real topVert[2], Real botVert[2],
294				       vertexArray* leftChain,
295				       Int leftStart,
296				       Int leftEnd,
297				       gridBoundaryChain* gridChain,
298				       Int gridBeginIndex,
299				       Int gridEndIndex,
300				       vertexArray* rightChain,
301				       Int rightUpBegin,
302				       Int rightUpEnd,
303				       Int rightDownBegin,
304				       Int rightDownEnd,
305				       primStream* pStream)
306{
307  Int i,j,k;
308
309  /*creat an array to store all the up and down secments of the right chain,
310   *and the left end grid points
311   *
312   *although vertex array is a dynamic array, but to gain efficiency,
313   *it is better to initiliza the exact array size
314   */
315  vertexArray vArray(gridEndIndex-gridBeginIndex+1 +
316		     max(0,rightUpEnd - rightUpBegin+1)+
317		     max(0,rightDownEnd - rightDownBegin+1));
318
319  /*append the vertices on the up section of thr right chain*/
320  for(i=rightUpBegin; i<= rightUpEnd; i++)
321    vArray.appendVertex(rightChain->getVertex(i));
322
323  /*append the vertices of the left extremal grid points,
324   *and at the same time, perform triangulation for the stair cases
325   */
326  vArray.appendVertex(gridChain->get_vertex(gridBeginIndex));
327
328  for(k=1, i=gridBeginIndex+1; i<=gridEndIndex; i++, k++)
329    {
330      vArray.appendVertex(gridChain->get_vertex(i));
331
332      /*output the fan of the grid points of the (i)th and (i-1)th grid line.
333       */
334      if(gridChain->getUlineIndex(i) < gridChain->getUlineIndex(i-1))
335	{
336	  pStream->begin();
337	  pStream->insert(gridChain->get_vertex(i-1));
338	  for(j=gridChain->getUlineIndex(i); j<= gridChain->getUlineIndex(i-1); j++)
339	    pStream->insert(gridChain->getGrid()->get_u_value(j), gridChain->get_v_value(i));
340	  pStream->end(PRIMITIVE_STREAM_FAN);
341	}
342      else if(gridChain->getUlineIndex(i) > gridChain->getUlineIndex(i-1))
343	{
344	  pStream->begin();
345	  pStream->insert(gridChain->get_vertex(i));
346	  for(j=gridChain->getUlineIndex(i); j>= gridChain->getUlineIndex(i-1); j--)
347	    pStream->insert(gridChain->getGrid()->get_u_value(j), gridChain->get_v_value(i-1));
348	  pStream->end(PRIMITIVE_STREAM_FAN);
349	}
350      /*otherwisem, the two are equal, so there is no fan to outout*/
351    }
352
353  /*then append all the vertices on the down section of the right chain*/
354  for(i=rightDownBegin; i<= rightDownEnd; i++)
355    vArray.appendVertex(rightChain->getVertex(i));
356
357  monoTriangulationRecGen(topVert, botVert,
358			  leftChain, leftStart, leftEnd,
359			  &vArray, 0, vArray.getNumElements()-1,
360			  pStream);
361
362}
363
364
365
366
367
368
369
370
371
372