[WIN32SS/USER32]
[reactos.git] / dll / opengl / glu32 / src / libnurbs / internals / 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 }