Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / glu / sgi / libnurbs / nurbtess / gridWrap.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 "gluos.h"
39 #include <stdlib.h>
40 #include <stdio.h>
41 #include <GL/gl.h>
42 #include "zlassert.h"
43 #include "gridWrap.h"
44
45
46 /*******************grid structure****************************/
47 void gridWrap::print()
48 {
49   printf("n_ulines = %i\n", n_ulines);
50   printf("n_vlines = %i\n", n_vlines);
51   printf("u_min=%f, umax=%f, vmin=%f, vmax=%f\n", u_min, u_max, v_min, v_max);
52 }
53
54 gridWrap::gridWrap(Int nUlines, Real* uvals,
55                    Int nVlines, Real* vvals)
56 {
57   assert(nUlines>=2);
58   assert(nVlines>=2);
59
60   is_uniform = 0;
61   n_ulines = nUlines;
62   n_vlines = nVlines;
63   u_min = uvals[0];
64   u_max = uvals[nUlines-1];
65   v_min = vvals[0];
66   v_max = vvals[nVlines-1];
67   u_values = (Real*) malloc(sizeof(Real) * n_ulines);
68   assert(u_values);
69   v_values = (Real*) malloc(sizeof(Real) * n_vlines);
70   assert(v_values);  
71   
72   Int i;
73   for(i=0; i<n_ulines; i++)
74     u_values[i] = uvals[i];
75   for(i=0; i<n_vlines; i++)
76     v_values[i] = vvals[i];
77 }
78   
79 gridWrap::gridWrap(Int nUlines, Int nVlines,
80                    Real uMin, Real uMax,
81                    Real vMin, Real vMax
82                    )
83 {
84   is_uniform = 1;
85   n_ulines = nUlines;
86   n_vlines = nVlines;
87   u_min = uMin;
88   u_max = uMax;
89   v_min = vMin;
90   v_max = vMax;
91   u_values = (Real*) malloc(sizeof(Real) * n_ulines);
92   assert(u_values);
93   v_values = (Real*) malloc(sizeof(Real) * n_vlines);
94   assert(v_values);
95   
96   Int i;
97   assert(nUlines>=2);
98   assert(nVlines>=2);
99   Real du = (uMax-uMin)/(nUlines-1);
100   Real dv = (vMax-vMin)/(nVlines-1);
101
102   float tempu=uMin;
103   u_values[0] = tempu;
104   for(i=1; i<nUlines; i++)
105     {
106       tempu += du;
107       u_values[i] = tempu;
108     }
109   u_values[nUlines-1] = uMax;
110
111   float tempv=vMin;
112   v_values[0] = tempv;
113   for(i=1; i<nVlines; i++)
114     {
115       tempv += dv;
116       v_values[i] = tempv;
117     }
118   v_values[nVlines-1] = vMax;
119 }
120
121 gridWrap::~gridWrap()
122 {
123   free(u_values);
124   free(v_values);
125 }
126
127 void gridWrap::draw()
128 {
129   int i,j;
130   glBegin(GL_POINTS);
131   for(i=0; i<n_ulines; i++)
132     for(j=0; j<n_vlines; j++)
133       glVertex2f(get_u_value(i), get_v_value(j));
134   glEnd();
135 }
136
137 void gridWrap::outputFanWithPoint(Int v, Int uleft, Int uright, Real vert[2], primStream* pStream)
138 {
139   Int i;
140   if(uleft >= uright) 
141     return; //no triangles to output.
142     
143   pStream->begin();
144   pStream->insert(vert);
145
146   assert(vert[1] != v_values[v]); //don't output degenerate triangles
147
148   if(vert[1] > v_values[v]) //vertex is above this grid line: notice the orientation
149     {
150       for(i=uleft; i<=uright; i++)
151         pStream->insert(u_values[i], v_values[v]);
152     }
153   else //vertex is below the grid line
154     {
155       for(i=uright; i>= uleft; i--)
156         pStream->insert(u_values[i], v_values[v]);
157     }   
158   
159   pStream->end(PRIMITIVE_STREAM_FAN);
160 }
161
162
163
164 /*each chain stores a number of consecutive 
165  *V-lines within a grid. 
166  *There is one grid vertex on each V-line.
167  * The total number of V-lines is:
168  *   nVlines.
169  * with respect to the grid, the index of the first V-line is 
170  *   firstVlineIndex.
171  * So with respect to the grid, the index of the ith V-line is 
172  *   firstVlineIndex-i.
173  * the grid-index of the uline at the ith vline (recall that each vline has one grid point)
174  * is ulineIndices[i]. The u_value is cached in ulineValues[i], that is,
175  *   ulineValues[i] = grid->get_u_value(ulineIndices[i]) 
176  */
177 gridBoundaryChain::gridBoundaryChain(
178                                      gridWrap* gr, 
179                                      Int first_vline_index, 
180                                      Int n_vlines, 
181                                      Int* uline_indices,
182                                      Int* inner_indices
183                                      )
184 : grid(gr), firstVlineIndex(first_vline_index), nVlines(n_vlines)
185 {
186   ulineIndices = (Int*) malloc(sizeof(Int) * n_vlines);
187   assert(ulineIndices);
188
189   innerIndices = (Int*) malloc(sizeof(Int) * n_vlines);
190   assert(innerIndices);
191
192   vertices = (Real2*) malloc(sizeof(Real2) * n_vlines);
193   assert(vertices);
194   
195
196
197   Int i;
198   for(i=0; i<n_vlines; i++){
199     ulineIndices[i] = uline_indices[i];
200     innerIndices[i] = inner_indices[i];
201   }
202   
203   for(i=0; i<n_vlines; i++){
204     vertices[i][0] = gr->get_u_value(ulineIndices[i]);
205     vertices[i][1] = gr->get_v_value(first_vline_index-i);
206   }
207 }
208   
209 void gridBoundaryChain::draw()
210 {
211   Int i;
212   glBegin(GL_LINE_STRIP);
213   for(i=0; i<nVlines; i++)
214     {
215       glVertex2fv(vertices[i]);
216     }
217   glEnd();
218 }
219
220 void gridBoundaryChain::drawInner()
221 {
222   Int i;
223   for(i=1; i<nVlines; i++)
224     {
225       glBegin(GL_LINE_STRIP);
226       glVertex2f(grid->get_u_value(innerIndices[i]), get_v_value(i-1) );
227       glVertex2f(grid->get_u_value(innerIndices[i]), get_v_value(i) );
228       glEnd();
229     }
230 }
231   
232 Int gridBoundaryChain::lookfor(Real v, Int i1, Int i2)
233 {
234   Int mid;
235   while(i1 < i2-1)
236     {
237       mid = (i1+i2)/2;
238       if(v > vertices[mid][1])
239         {
240           i2 = mid;
241         }
242       else
243         i1 = mid;
244     }
245   return i1;
246 }
247
248 /*output the fan of the right end between grid line i-1 and grid line i*/
249 void gridBoundaryChain::rightEndFan(Int i, primStream* pStream)
250 {
251   Int j;
252   if(getUlineIndex(i) > getUlineIndex(i-1))
253     {
254       pStream->begin();
255       pStream->insert(get_vertex(i-1));
256       for(j=getUlineIndex(i-1); j<= getUlineIndex(i); j++)
257         pStream->insert(grid->get_u_value(j), get_v_value(i));
258       pStream->end(PRIMITIVE_STREAM_FAN);
259     }
260   else if(getUlineIndex(i) < getUlineIndex(i-1))
261     {
262       pStream->begin();
263       pStream->insert(get_vertex(i));
264       for(j=getUlineIndex(i-1); j>= getUlineIndex(i); j--)
265         pStream->insert(grid->get_u_value(j), get_v_value(i-1));
266       pStream->end(PRIMITIVE_STREAM_FAN);
267     }
268   //otherside, the two are equal, so there is no fan to output
269 }
270                       
271
272 /*output the fan of the left end between grid line i-1 and grid line i*/
273 void gridBoundaryChain::leftEndFan(Int i, primStream* pStream)
274 {
275   Int j;
276   if(getUlineIndex(i) < getUlineIndex(i-1))
277     {
278       pStream->begin();
279       pStream->insert(get_vertex(i-1));
280       for(j=getUlineIndex(i); j<= getUlineIndex(i-1); j++)
281         pStream->insert(grid->get_u_value(j), get_v_value(i));
282       pStream->end(PRIMITIVE_STREAM_FAN);
283     }
284   else if(getUlineIndex(i) > getUlineIndex(i-1))
285     {
286       pStream->begin();
287       pStream->insert(get_vertex(i));
288       for(j=getUlineIndex(i); j>= getUlineIndex(i-1); j--)
289         pStream->insert(grid->get_u_value(j), get_v_value(i-1));
290       pStream->end(PRIMITIVE_STREAM_FAN);
291     }
292   /*otherwisem, the two are equal, so there is no fan to outout*/         
293 }