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:
10 ** http://oss.sgi.com/projects/FreeB
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.
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.
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.
34 ** $Date$ $Revision: 1.1 $
37 ** $Header: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/glu32/libnurbs/internals/monoTriangulationBackend.cc,v 1.1 2004/02/02 16:39:12 navaraf Exp $
40 #include "monoTriangulation.h"
45 void reflexChain::outputFan(Real v
[2], Backend
* backend
)
50 backend
->tmeshvert(v
[0], v
[1]);
53 for(i
=0; i
<index_queue
; i
++)
56 trimVert.param[0]=queue[i][0];
57 trimVert.param[1]=queue[i][1];
58 backend->tmeshvert(&trimVert);
60 backend
->tmeshvert(queue
[i
][0], queue
[i
][1]);
64 for(i
=index_queue
-1; i
>=0; i
--)
67 trimVert.param[0]=queue[i][0];
68 trimVert.param[1]=queue[i][1];
69 backend->tmeshvert(&trimVert);
71 backend
->tmeshvert(queue
[i
][0], queue
[i
][1]);
77 void reflexChain::processNewVertex(Real v
[2], Backend
* backend
)
82 /*if there are at most one vertex in the queue, then simply insert
89 /*there are at least two vertices in the queue*/
94 isReflex
= (area(queue
[i
-1], queue
[i
], v
) <= 0.0);
97 isReflex
= (area(v
, queue
[i
], queue
[i
-1]) <= 0.0);
105 *if i<j then vertices: i+1--j are convex
106 * output triangle fan:
107 * v, and queue[i], i+1, ..., j
113 trimVert.param[0]=v[0];
114 trimVert.param[1]=v[1];
115 backend->tmeshvert(& trimVert);
117 backend
->tmeshvert(v
[0], v
[1]);
123 trimVert.param[0]=queue[k][0];
124 trimVert.param[1]=queue[k][1];
125 backend->tmeshvert(& trimVert);
127 backend
->tmeshvert(queue
[k
][0], queue
[k
][1]);
134 trimVert.param[0]=queue[k][0];
135 trimVert.param[1]=queue[k][1];
136 backend->tmeshvert(& trimVert);
138 backend
->tmeshvert(queue
[k
][0], queue
[k
][1]);
145 /*delete vertices i+1--j from the queue*/
147 /*finally insert v at the end of the queue*/
153 void monoTriangulationRec(Real
* topVertex
, Real
* botVertex
,
154 vertexArray
* inc_chain
, Int inc_current
,
155 vertexArray
* dec_chain
, Int dec_current
,
158 assert( inc_chain
!= NULL
&& dec_chain
!= NULL
);
159 assert( ! (inc_current
>=inc_chain
->getNumElements() &&
160 dec_current
>=dec_chain
->getNumElements()));
166 assert( ! ( (inc_chain
==NULL
) && (dec_chain
==NULL
)));
168 if(inc_current
>=inc_chain
->getNumElements()) /*no more vertices on inc_chain*/
171 dec_array
= dec_chain
->getArray();
172 dec_nVertices
= dec_chain
->getNumElements();
173 reflexChain
rChain(20,0);
174 /*put the top vertex into the reflex chain*/
175 rChain
.processNewVertex(topVertex
, backend
);
176 /*process all the vertices on the dec_chain*/
177 for(i
=dec_current
; i
<dec_nVertices
; i
++){
178 rChain
.processNewVertex(dec_array
[i
], backend
);
180 /*process the bottom vertex*/
181 rChain
.processNewVertex(botVertex
, backend
);
184 else if(dec_current
>= dec_chain
->getNumElements()) /*no more vertices on dec_chain*/
186 inc_array
= inc_chain
->getArray();
187 inc_nVertices
= inc_chain
->getNumElements();
188 reflexChain
rChain(20,1);
189 /*put the top vertex into the reflex chain*/
190 rChain
.processNewVertex(topVertex
, backend
);
191 /*process all the vertices on the inc_chain*/
192 for(i
=inc_current
; i
<inc_nVertices
; i
++){
193 rChain
.processNewVertex(inc_array
[i
], backend
);
195 /*process the bottom vertex*/
196 rChain
.processNewVertex(botVertex
, backend
);
198 else /*neither chain is empty*/
200 inc_array
= inc_chain
-> getArray();
201 dec_array
= dec_chain
-> getArray();
202 inc_nVertices
= inc_chain
->getNumElements();
203 dec_nVertices
= dec_chain
->getNumElements();
204 /*if top of inc_chain is 'lower' than top of dec_chain, process all the
205 *vertices on the dec_chain which are higher than top of inc_chain
207 if(compV2InY(inc_array
[inc_current
], dec_array
[dec_current
]) <= 0)
210 reflexChain
rChain(20, 0);
211 rChain
.processNewVertex(topVertex
, backend
);
212 for(i
=dec_current
; i
<dec_nVertices
; i
++)
214 if(compV2InY(inc_array
[inc_current
], dec_array
[i
]) <= 0)
215 rChain
.processNewVertex(dec_array
[i
], backend
);
219 rChain
.outputFan(inc_array
[inc_current
], backend
);
220 monoTriangulationRec(dec_array
[i
-1], botVertex
,
221 inc_chain
, inc_current
,
225 else /*compV2InY(inc_array[inc_current], dec_array[dec_current]) > 0*/
228 reflexChain
rChain(20, 1);
229 rChain
.processNewVertex(topVertex
, backend
);
230 for(i
=inc_current
; i
<inc_nVertices
; i
++)
232 if(compV2InY(inc_array
[i
], dec_array
[dec_current
]) >0)
233 rChain
.processNewVertex(inc_array
[i
], backend
);
237 rChain
.outputFan(dec_array
[dec_current
], backend
);
238 monoTriangulationRec(inc_array
[i
-1], botVertex
,
240 dec_chain
, dec_current
,
243 }/*end case neither is empty*/
247 void monoTriangulationFunBackend(Arc_ptr loop
, Int (*compFun
)(Real
*, Real
*), Backend
* backend
)
250 /*find the top vertex, bottom vertex, inccreasing chain, and decreasing chain,
251 *then call monoTriangulationRec
257 for(tempV
= loop
->next
; tempV
!= loop
; tempV
= tempV
->next
)
259 if(compFun(topV
->tail(), tempV
->tail())<0) {
262 if(compFun(botV
->tail(), tempV
->tail())>0) {
267 /*creat increase and decrease chains*/
268 vertexArray
inc_chain(20); /*this is a dynamic array*/
269 for(i
=1; i
<=topV
->pwlArc
->npts
-2; i
++) { /*the first vertex is the top vertex which doesn't belong to inc_chain*/
270 inc_chain
.appendVertex(topV
->pwlArc
->pts
[i
].param
);
272 for(tempV
= topV
->next
; tempV
!= botV
; tempV
= tempV
->next
)
274 for(i
=0; i
<=tempV
->pwlArc
->npts
-2; i
++){
275 inc_chain
.appendVertex(tempV
->pwlArc
->pts
[i
].param
);
279 vertexArray
dec_chain(20);
280 for(tempV
= topV
->prev
; tempV
!= botV
; tempV
= tempV
->prev
)
282 for(i
=tempV
->pwlArc
->npts
-2; i
>=0; i
--){
283 dec_chain
.appendVertex(tempV
->pwlArc
->pts
[i
].param
);
286 for(i
=botV
->pwlArc
->npts
-2; i
>=1; i
--){
287 dec_chain
.appendVertex(tempV
->pwlArc
->pts
[i
].param
);
290 monoTriangulationRecFunBackend(topV
->tail(), botV
->tail(), &inc_chain
, 0, &dec_chain
, 0, compFun
, backend
);
294 /*if compFun == compV2InY, top to bottom: V-monotone
295 *if compFun == compV2InX, right to left: U-monotone
297 void monoTriangulationRecFunBackend(Real
* topVertex
, Real
* botVertex
,
298 vertexArray
* inc_chain
, Int inc_current
,
299 vertexArray
* dec_chain
, Int dec_current
,
300 Int (*compFun
)(Real
*, Real
*),
303 assert( inc_chain
!= NULL
&& dec_chain
!= NULL
);
304 assert( ! (inc_current
>=inc_chain
->getNumElements() &&
305 dec_current
>=dec_chain
->getNumElements()));
311 assert( ! ( (inc_chain
==NULL
) && (dec_chain
==NULL
)));
313 if(inc_current
>=inc_chain
->getNumElements()) /*no more vertices on inc_chain*/
316 dec_array
= dec_chain
->getArray();
317 dec_nVertices
= dec_chain
->getNumElements();
318 reflexChain
rChain(20,0);
319 /*put the top vertex into the reflex chain*/
320 rChain
.processNewVertex(topVertex
, backend
);
321 /*process all the vertices on the dec_chain*/
322 for(i
=dec_current
; i
<dec_nVertices
; i
++){
323 rChain
.processNewVertex(dec_array
[i
], backend
);
325 /*process the bottom vertex*/
326 rChain
.processNewVertex(botVertex
, backend
);
329 else if(dec_current
>= dec_chain
->getNumElements()) /*no more vertices on dec_chain*/
331 inc_array
= inc_chain
->getArray();
332 inc_nVertices
= inc_chain
->getNumElements();
333 reflexChain
rChain(20,1);
334 /*put the top vertex into the reflex chain*/
335 rChain
.processNewVertex(topVertex
, backend
);
336 /*process all the vertices on the inc_chain*/
337 for(i
=inc_current
; i
<inc_nVertices
; i
++){
338 rChain
.processNewVertex(inc_array
[i
], backend
);
340 /*process the bottom vertex*/
341 rChain
.processNewVertex(botVertex
, backend
);
343 else /*neither chain is empty*/
345 inc_array
= inc_chain
-> getArray();
346 dec_array
= dec_chain
-> getArray();
347 inc_nVertices
= inc_chain
->getNumElements();
348 dec_nVertices
= dec_chain
->getNumElements();
349 /*if top of inc_chain is 'lower' than top of dec_chain, process all the
350 *vertices on the dec_chain which are higher than top of inc_chain
352 if(compFun(inc_array
[inc_current
], dec_array
[dec_current
]) <= 0)
355 reflexChain
rChain(20, 0);
356 rChain
.processNewVertex(topVertex
, backend
);
357 for(i
=dec_current
; i
<dec_nVertices
; i
++)
359 if(compFun(inc_array
[inc_current
], dec_array
[i
]) <= 0)
360 rChain
.processNewVertex(dec_array
[i
], backend
);
364 rChain
.outputFan(inc_array
[inc_current
], backend
);
365 monoTriangulationRecFunBackend(dec_array
[i
-1], botVertex
,
366 inc_chain
, inc_current
,
371 else /*compFun(inc_array[inc_current], dec_array[dec_current]) > 0*/
374 reflexChain
rChain(20, 1);
375 rChain
.processNewVertex(topVertex
, backend
);
376 for(i
=inc_current
; i
<inc_nVertices
; i
++)
378 if(compFun(inc_array
[i
], dec_array
[dec_current
]) >0)
379 rChain
.processNewVertex(inc_array
[i
], backend
);
383 rChain
.outputFan(dec_array
[dec_current
], backend
);
384 monoTriangulationRecFunBackend(inc_array
[i
-1], botVertex
,
386 dec_chain
, dec_current
,
390 }/*end case neither is empty*/