Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / glu / sgi / 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 }