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