FreeWRL/FreeX3D  3.0.0
monoTriangulationBackend.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 "monoTriangulation.h"
39 #include "polyUtil.h"
40 #include "backend.h"
41 #include "arc.h"
42 
43 void reflexChain::outputFan(Real v[2], Backend* backend)
44 {
45  Int i;
46  /*
47  TrimVertex trimVert;
48  */
49  backend->bgntfan();
50 
51  /*
52  trimVert.param[0]=v[0];
53  trimVert.param[1]=v[1];
54  backend->tmeshvert(&trimVert);
55  */
56  backend->tmeshvert(v[0], v[1]);
57 
58  if(isIncreasing) {
59  for(i=0; i<index_queue; i++)
60  {
61  /*
62  trimVert.param[0]=queue[i][0];
63  trimVert.param[1]=queue[i][1];
64  backend->tmeshvert(&trimVert);
65  */
66  backend->tmeshvert(queue[i][0], queue[i][1]);
67  }
68  }
69  else {
70  for(i=index_queue-1; i>=0; i--)
71  {
72  /*
73  trimVert.param[0]=queue[i][0];
74  trimVert.param[1]=queue[i][1];
75  backend->tmeshvert(&trimVert);
76  */
77  backend->tmeshvert(queue[i][0], queue[i][1]);
78  }
79  }
80  backend->endtfan();
81 }
82 
83 void reflexChain::processNewVertex(Real v[2], Backend* backend)
84 {
85  Int i,j,k;
86  Int isReflex;
87  /*TrimVertex trimVert;*/
88  /*if there are at most one vertex in the queue, then simply insert
89  */
90  if(index_queue <=1){
91  insert(v);
92  return;
93  }
94 
95  /*there are at least two vertices in the queue*/
96  j=index_queue-1;
97 
98  for(i=j; i>=1; i--) {
99  if(isIncreasing) {
100  isReflex = (area(queue[i-1], queue[i], v) <= 0.0);
101  }
102  else /*decreasing*/{
103  isReflex = (area(v, queue[i], queue[i-1]) <= 0.0);
104  }
105  if(isReflex) {
106  break;
107  }
108  }
109 
110  /*
111  *if i<j then vertices: i+1--j are convex
112  * output triangle fan:
113  * v, and queue[i], i+1, ..., j
114  */
115  if(i<j)
116  {
117  backend->bgntfan();
118  /*
119  trimVert.param[0]=v[0];
120  trimVert.param[1]=v[1];
121  backend->tmeshvert(& trimVert);
122  */
123  backend->tmeshvert(v[0], v[1]);
124 
125  if(isIncreasing) {
126  for(k=i; k<=j; k++)
127  {
128  /*
129  trimVert.param[0]=queue[k][0];
130  trimVert.param[1]=queue[k][1];
131  backend->tmeshvert(& trimVert);
132  */
133  backend->tmeshvert(queue[k][0], queue[k][1]);
134  }
135  }
136  else {
137  for(k=j; k>=i; k--)
138  {
139  /*
140  trimVert.param[0]=queue[k][0];
141  trimVert.param[1]=queue[k][1];
142  backend->tmeshvert(& trimVert);
143  */
144  backend->tmeshvert(queue[k][0], queue[k][1]);
145  }
146  }
147 
148  backend->endtfan();
149  }
150 
151  /*delete vertices i+1--j from the queue*/
152  index_queue = i+1;
153  /*finally insert v at the end of the queue*/
154  insert(v);
155 
156 }
157 
158 
159 void monoTriangulationRec(Real* topVertex, Real* botVertex,
160  vertexArray* inc_chain, Int inc_current,
161  vertexArray* dec_chain, Int dec_current,
162  Backend* backend)
163 {
164  assert( inc_chain != NULL && dec_chain != NULL);
165  assert( ! (inc_current>=inc_chain->getNumElements() &&
166  dec_current>=dec_chain->getNumElements()));
167  Int inc_nVertices;
168  Int dec_nVertices;
169  Real** inc_array ;
170  Real** dec_array ;
171  Int i;
172  assert( ! ( (inc_chain==NULL) && (dec_chain==NULL)));
173 
174  if(inc_current>=inc_chain->getNumElements()) /*no more vertices on inc_chain*/
175  {
176 
177  dec_array = dec_chain->getArray();
178  dec_nVertices = dec_chain->getNumElements();
179  reflexChain rChain(20,0);
180  /*put the top vertex into the reflex chain*/
181  rChain.processNewVertex(topVertex, backend);
182  /*process all the vertices on the dec_chain*/
183  for(i=dec_current; i<dec_nVertices; i++){
184  rChain.processNewVertex(dec_array[i], backend);
185  }
186  /*process the bottom vertex*/
187  rChain.processNewVertex(botVertex, backend);
188 
189  }
190  else if(dec_current>= dec_chain->getNumElements()) /*no more vertices on dec_chain*/
191  {
192  inc_array = inc_chain->getArray();
193  inc_nVertices= inc_chain->getNumElements();
194  reflexChain rChain(20,1);
195  /*put the top vertex into the reflex chain*/
196  rChain.processNewVertex(topVertex, backend);
197  /*process all the vertices on the inc_chain*/
198  for(i=inc_current; i<inc_nVertices; i++){
199  rChain.processNewVertex(inc_array[i], backend);
200  }
201  /*process the bottom vertex*/
202  rChain.processNewVertex(botVertex, backend);
203  }
204  else /*neither chain is empty*/
205  {
206  inc_array = inc_chain -> getArray();
207  dec_array = dec_chain -> getArray();
208  inc_nVertices= inc_chain->getNumElements();
209  dec_nVertices= dec_chain->getNumElements();
210  /*if top of inc_chain is 'lower' than top of dec_chain, process all the
211  *vertices on the dec_chain which are higher than top of inc_chain
212  */
213  if(compV2InY(inc_array[inc_current], dec_array[dec_current]) <= 0)
214  {
215 
216  reflexChain rChain(20, 0);
217  rChain.processNewVertex(topVertex, backend);
218  for(i=dec_current; i<dec_nVertices; i++)
219  {
220  if(compV2InY(inc_array[inc_current], dec_array[i]) <= 0)
221  rChain.processNewVertex(dec_array[i], backend);
222  else
223  break;
224  }
225  rChain.outputFan(inc_array[inc_current], backend);
226  monoTriangulationRec(dec_array[i-1], botVertex,
227  inc_chain, inc_current,
228  dec_chain, i,
229  backend);
230  }
231  else /*compV2InY(inc_array[inc_current], dec_array[dec_current]) > 0*/
232  {
233 
234  reflexChain rChain(20, 1);
235  rChain.processNewVertex(topVertex, backend);
236  for(i=inc_current; i<inc_nVertices; i++)
237  {
238  if(compV2InY(inc_array[i], dec_array[dec_current]) >0)
239  rChain.processNewVertex(inc_array[i], backend);
240  else
241  break;
242  }
243  rChain.outputFan(dec_array[dec_current], backend);
244  monoTriangulationRec(inc_array[i-1], botVertex,
245  inc_chain, i,
246  dec_chain, dec_current,
247  backend);
248  }
249  }/*end case neither is empty*/
250 }
251 
252 
253 void monoTriangulationFunBackend(Arc_ptr loop, Int (*compFun)(Real*, Real*), Backend* backend)
254 {
255  Int i;
256  /*find the top vertex, bottom vertex, inccreasing chain, and decreasing chain,
257  *then call monoTriangulationRec
258  */
259  Arc_ptr tempV;
260  Arc_ptr topV;
261  Arc_ptr botV;
262  topV = botV = loop;
263  for(tempV = loop->next; tempV != loop; tempV = tempV->next)
264  {
265  if(compFun(topV->tail(), tempV->tail())<0) {
266  topV = tempV;
267  }
268  if(compFun(botV->tail(), tempV->tail())>0) {
269  botV = tempV;
270  }
271  }
272 
273  /*creat increase and decrease chains*/
274  vertexArray inc_chain(20); /*this is a dynamic array*/
275  for(i=1; i<=topV->pwlArc->npts-2; i++) { /*the first vertex is the top vertex which doesn't belong to inc_chain*/
276  inc_chain.appendVertex(topV->pwlArc->pts[i].param);
277  }
278  for(tempV = topV->next; tempV != botV; tempV = tempV->next)
279  {
280  for(i=0; i<=tempV->pwlArc->npts-2; i++){
281  inc_chain.appendVertex(tempV->pwlArc->pts[i].param);
282  }
283  }
284 
285  vertexArray dec_chain(20);
286  for(tempV = topV->prev; tempV != botV; tempV = tempV->prev)
287  {
288  for(i=tempV->pwlArc->npts-2; i>=0; i--){
289  dec_chain.appendVertex(tempV->pwlArc->pts[i].param);
290  }
291  }
292  for(i=botV->pwlArc->npts-2; i>=1; i--){
293  dec_chain.appendVertex(tempV->pwlArc->pts[i].param);
294  }
295 
296  monoTriangulationRecFunBackend(topV->tail(), botV->tail(), &inc_chain, 0, &dec_chain, 0, compFun, backend);
297 
298 }
299 
300 /*if compFun == compV2InY, top to bottom: V-monotone
301  *if compFun == compV2InX, right to left: U-monotone
302  */
303 void monoTriangulationRecFunBackend(Real* topVertex, Real* botVertex,
304  vertexArray* inc_chain, Int inc_current,
305  vertexArray* dec_chain, Int dec_current,
306  Int (*compFun)(Real*, Real*),
307  Backend* backend)
308 {
309  assert( inc_chain != NULL && dec_chain != NULL);
310  assert( ! (inc_current>=inc_chain->getNumElements() &&
311  dec_current>=dec_chain->getNumElements()));
312  Int inc_nVertices;
313  Int dec_nVertices;
314  Real** inc_array ;
315  Real** dec_array ;
316  Int i;
317  assert( ! ( (inc_chain==NULL) && (dec_chain==NULL)));
318 
319  if(inc_current>=inc_chain->getNumElements()) /*no more vertices on inc_chain*/
320  {
321 
322  dec_array = dec_chain->getArray();
323  dec_nVertices = dec_chain->getNumElements();
324  reflexChain rChain(20,0);
325  /*put the top vertex into the reflex chain*/
326  rChain.processNewVertex(topVertex, backend);
327  /*process all the vertices on the dec_chain*/
328  for(i=dec_current; i<dec_nVertices; i++){
329  rChain.processNewVertex(dec_array[i], backend);
330  }
331  /*process the bottom vertex*/
332  rChain.processNewVertex(botVertex, backend);
333 
334  }
335  else if(dec_current>= dec_chain->getNumElements()) /*no more vertices on dec_chain*/
336  {
337  inc_array = inc_chain->getArray();
338  inc_nVertices= inc_chain->getNumElements();
339  reflexChain rChain(20,1);
340  /*put the top vertex into the reflex chain*/
341  rChain.processNewVertex(topVertex, backend);
342  /*process all the vertices on the inc_chain*/
343  for(i=inc_current; i<inc_nVertices; i++){
344  rChain.processNewVertex(inc_array[i], backend);
345  }
346  /*process the bottom vertex*/
347  rChain.processNewVertex(botVertex, backend);
348  }
349  else /*neither chain is empty*/
350  {
351  inc_array = inc_chain -> getArray();
352  dec_array = dec_chain -> getArray();
353  inc_nVertices= inc_chain->getNumElements();
354  dec_nVertices= dec_chain->getNumElements();
355  /*if top of inc_chain is 'lower' than top of dec_chain, process all the
356  *vertices on the dec_chain which are higher than top of inc_chain
357  */
358  if(compFun(inc_array[inc_current], dec_array[dec_current]) <= 0)
359  {
360 
361  reflexChain rChain(20, 0);
362  rChain.processNewVertex(topVertex, backend);
363  for(i=dec_current; i<dec_nVertices; i++)
364  {
365  if(compFun(inc_array[inc_current], dec_array[i]) <= 0)
366  rChain.processNewVertex(dec_array[i], backend);
367  else
368  break;
369  }
370  rChain.outputFan(inc_array[inc_current], backend);
371  monoTriangulationRecFunBackend(dec_array[i-1], botVertex,
372  inc_chain, inc_current,
373  dec_chain, i,
374  compFun,
375  backend);
376  }
377  else /*compFun(inc_array[inc_current], dec_array[dec_current]) > 0*/
378  {
379 
380  reflexChain rChain(20, 1);
381  rChain.processNewVertex(topVertex, backend);
382  for(i=inc_current; i<inc_nVertices; i++)
383  {
384  if(compFun(inc_array[i], dec_array[dec_current]) >0)
385  rChain.processNewVertex(inc_array[i], backend);
386  else
387  break;
388  }
389  rChain.outputFan(dec_array[dec_current], backend);
390  monoTriangulationRecFunBackend(inc_array[i-1], botVertex,
391  inc_chain, i,
392  dec_chain, dec_current,
393  compFun,
394  backend);
395  }
396  }/*end case neither is empty*/
397 }