reshuffling of dlls
[reactos.git] / reactos / dll / glu32 / libnurbs / interface / insurfeval.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 ** $Date$ $Revision: 1.1 $
35 */
36 /*
37 ** $Header: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/glu32/libnurbs/interface/insurfeval.cc,v 1.1 2004/02/02 16:39:08 navaraf Exp $
38 */
39
40 #include "gluos.h"
41 #include <stdlib.h>
42 #include <stdio.h>
43 #include <GL/gl.h>
44 #include <math.h>
45 #include <assert.h>
46
47 #include "glsurfeval.h"
48
49 //extern int surfcount;
50
51 //#define CRACK_TEST
52
53 #define AVOID_ZERO_NORMAL
54
55 #ifdef AVOID_ZERO_NORMAL
56 #define myabs(x) ((x>0)? x: (-x))
57 #define MYZERO 0.000001
58 #define MYDELTA 0.001
59 #endif
60
61 //#define USE_LOD
62 #ifdef USE_LOD
63 //#define LOD_EVAL_COORD(u,v) inDoEvalCoord2EM(u,v)
64 #define LOD_EVAL_COORD(u,v) glEvalCoord2f(u,v)
65
66 static void LOD_interpolate(REAL A[2], REAL B[2], REAL C[2], int j, int k, int pow2_level,
67 REAL& u, REAL& v)
68 {
69 REAL a,a1,b,b1;
70
71 a = ((REAL) j) / ((REAL) pow2_level);
72 a1 = 1-a;
73
74 if(j != 0)
75 {
76 b = ((REAL) k) / ((REAL)j);
77 b1 = 1-b;
78 }
79 REAL x,y,z;
80 x = a1;
81 if(j==0)
82 {
83 y=0; z=0;
84 }
85 else{
86 y = b1*a;
87 z = b *a;
88 }
89
90 u = x*A[0] + y*B[0] + z*C[0];
91 v = x*A[1] + y*B[1] + z*C[1];
92 }
93
94 void OpenGLSurfaceEvaluator::LOD_triangle(REAL A[2], REAL B[2], REAL C[2],
95 int level)
96 {
97 int k,j;
98 int pow2_level;
99 /*compute 2^level*/
100 pow2_level = 1;
101
102 for(j=0; j<level; j++)
103 pow2_level *= 2;
104 for(j=0; j<=pow2_level-1; j++)
105 {
106 REAL u,v;
107
108 /* beginCallBack(GL_TRIANGLE_STRIP);*/
109 glBegin(GL_TRIANGLE_STRIP);
110 LOD_interpolate(A,B,C, j+1, j+1, pow2_level, u,v);
111 #ifdef USE_LOD
112 LOD_EVAL_COORD(u,v);
113 // glEvalCoord2f(u,v);
114 #else
115 inDoEvalCoord2EM(u,v);
116 #endif
117
118 for(k=0; k<=j; k++)
119 {
120 LOD_interpolate(A,B,C,j,j-k,pow2_level, u,v);
121 #ifdef USE_LOD
122 LOD_EVAL_COORD(u,v);
123 // glEvalCoord2f(u,v);
124 #else
125 inDoEvalCoord2EM(u,v);
126 #endif
127
128 LOD_interpolate(A,B,C,j+1,j-k,pow2_level, u,v);
129
130 #ifdef USE_LOD
131 LOD_EVAL_COORD(u,v);
132 // glEvalCoord2f(u,v);
133 #else
134 inDoEvalCoord2EM(u,v);
135 #endif
136 }
137 // endCallBack();
138 glEnd();
139 }
140 }
141
142 void OpenGLSurfaceEvaluator::LOD_eval(int num_vert, REAL* verts, int type,
143 int level
144 )
145 {
146 int i,k;
147 switch(type){
148 case GL_TRIANGLE_STRIP:
149 case GL_QUAD_STRIP:
150 for(i=2, k=4; i<=num_vert-2; i+=2, k+=4)
151 {
152 LOD_triangle(verts+k-4, verts+k-2, verts+k,
153 level
154 );
155 LOD_triangle(verts+k-2, verts+k+2, verts+k,
156 level
157 );
158 }
159 if(num_vert % 2 ==1)
160 {
161 LOD_triangle(verts+2*(num_vert-3), verts+2*(num_vert-2), verts+2*(num_vert-1),
162 level
163 );
164 }
165 break;
166 case GL_TRIANGLE_FAN:
167 for(i=1, k=2; i<=num_vert-2; i++, k+=2)
168 {
169 LOD_triangle(verts,verts+k, verts+k+2,
170 level
171 );
172 }
173 break;
174
175 default:
176 fprintf(stderr, "typy not supported in LOD_\n");
177 }
178 }
179
180
181 #endif //USE_LOD
182
183 //#define GENERIC_TEST
184 #ifdef GENERIC_TEST
185 extern float xmin, xmax, ymin, ymax, zmin, zmax; /*bounding box*/
186 extern int temp_signal;
187
188 static void gTessVertexSphere(float u, float v, float temp_normal[3], float temp_vertex[3])
189 {
190 float r=2.0;
191 float Ox = 0.5*(xmin+xmax);
192 float Oy = 0.5*(ymin+ymax);
193 float Oz = 0.5*(zmin+zmax);
194 float nx = cos(v) * sin(u);
195 float ny = sin(v) * sin(u);
196 float nz = cos(u);
197 float x= Ox+r * nx;
198 float y= Oy+r * ny;
199 float z= Oz+r * nz;
200
201 temp_normal[0] = nx;
202 temp_normal[1] = ny;
203 temp_normal[2] = nz;
204 temp_vertex[0] = x;
205 temp_vertex[1] = y;
206 temp_vertex[2] = z;
207
208 // glNormal3f(nx,ny,nz);
209 // glVertex3f(x,y,z);
210 }
211
212 static void gTessVertexCyl(float u, float v, float temp_normal[3], float temp_vertex[3])
213 {
214 float r=2.0;
215 float Ox = 0.5*(xmin+xmax);
216 float Oy = 0.5*(ymin+ymax);
217 float Oz = 0.5*(zmin+zmax);
218 float nx = cos(v);
219 float ny = sin(v);
220 float nz = 0;
221 float x= Ox+r * nx;
222 float y= Oy+r * ny;
223 float z= Oz - 2*u;
224
225 temp_normal[0] = nx;
226 temp_normal[1] = ny;
227 temp_normal[2] = nz;
228 temp_vertex[0] = x;
229 temp_vertex[1] = y;
230 temp_vertex[2] = z;
231
232 /*
233 glNormal3f(nx,ny,nz);
234 glVertex3f(x,y,z);
235 */
236 }
237
238 #endif //GENERIC_TEST
239
240 void OpenGLSurfaceEvaluator::inBPMListEval(bezierPatchMesh* list)
241 {
242 bezierPatchMesh* temp;
243 for(temp = list; temp != NULL; temp = temp->next)
244 {
245 inBPMEval(temp);
246 }
247 }
248
249 void OpenGLSurfaceEvaluator::inBPMEval(bezierPatchMesh* bpm)
250 {
251 int i,j,k,l;
252 float u,v;
253
254 int ustride = bpm->bpatch->dimension * bpm->bpatch->vorder;
255 int vstride = bpm->bpatch->dimension;
256 inMap2f(
257 (bpm->bpatch->dimension == 3)? GL_MAP2_VERTEX_3 : GL_MAP2_VERTEX_4,
258 bpm->bpatch->umin,
259 bpm->bpatch->umax,
260 ustride,
261 bpm->bpatch->uorder,
262 bpm->bpatch->vmin,
263 bpm->bpatch->vmax,
264 vstride,
265 bpm->bpatch->vorder,
266 bpm->bpatch->ctlpoints);
267
268 bpm->vertex_array = (float*) malloc(sizeof(float)* (bpm->index_UVarray/2) * 3+1); /*in case the origional dimenion is 4, then we need 4 space to pass to evaluator.*/
269 assert(bpm->vertex_array);
270 bpm->normal_array = (float*) malloc(sizeof(float)* (bpm->index_UVarray/2) * 3);
271 assert(bpm->normal_array);
272 #ifdef CRACK_TEST
273 if( global_ev_u1 ==2 && global_ev_u2 == 3
274 && global_ev_v1 ==2 && global_ev_v2 == 3)
275 {
276 REAL vertex[4];
277 REAL normal[4];
278 #ifdef DEBUG
279 printf("***number 1\n");
280 #endif
281
282 beginCallBack(GL_QUAD_STRIP, NULL);
283 inEvalCoord2f(3.0, 3.0);
284 inEvalCoord2f(2.0, 3.0);
285 inEvalCoord2f(3.0, 2.7);
286 inEvalCoord2f(2.0, 2.7);
287 inEvalCoord2f(3.0, 2.0);
288 inEvalCoord2f(2.0, 2.0);
289 endCallBack(NULL);
290
291
292 beginCallBack(GL_TRIANGLE_STRIP, NULL);
293 inEvalCoord2f(2.0, 3.0);
294 inEvalCoord2f(2.0, 2.0);
295 inEvalCoord2f(2.0, 2.7);
296 endCallBack(NULL);
297
298 }
299
300 /*
301 if( global_ev_u1 ==2 && global_ev_u2 == 3
302 && global_ev_v1 ==1 && global_ev_v2 == 2)
303 {
304 #ifdef DEBUG
305 printf("***number 2\n");
306 #endif
307 beginCallBack(GL_QUAD_STRIP);
308 inEvalCoord2f(2.0, 2.0);
309 inEvalCoord2f(2.0, 1.0);
310 inEvalCoord2f(3.0, 2.0);
311 inEvalCoord2f(3.0, 1.0);
312 endCallBack();
313 }
314 */
315 if( global_ev_u1 ==1 && global_ev_u2 == 2
316 && global_ev_v1 ==2 && global_ev_v2 == 3)
317 {
318 #ifdef DEBUG
319 printf("***number 3\n");
320 #endif
321 beginCallBack(GL_QUAD_STRIP, NULL);
322 inEvalCoord2f(2.0, 3.0);
323 inEvalCoord2f(1.0, 3.0);
324 inEvalCoord2f(2.0, 2.3);
325 inEvalCoord2f(1.0, 2.3);
326 inEvalCoord2f(2.0, 2.0);
327 inEvalCoord2f(1.0, 2.0);
328 endCallBack(NULL);
329
330 beginCallBack(GL_TRIANGLE_STRIP, NULL);
331 inEvalCoord2f(2.0, 2.3);
332 inEvalCoord2f(2.0, 2.0);
333 inEvalCoord2f(2.0, 3.0);
334 endCallBack(NULL);
335
336 }
337 return;
338 #endif
339
340 k=0;
341 l=0;
342
343 for(i=0; i<bpm->index_length_array; i++)
344 {
345 beginCallBack(bpm->type_array[i], userData);
346 for(j=0; j<bpm->length_array[i]; j++)
347 {
348 u = bpm->UVarray[k];
349 v = bpm->UVarray[k+1];
350 inDoEvalCoord2NOGE(u,v,
351 bpm->vertex_array+l,
352 bpm->normal_array+l);
353
354 normalCallBack(bpm->normal_array+l, userData);
355 vertexCallBack(bpm->vertex_array+l, userData);
356
357 k += 2;
358 l += 3;
359 }
360 endCallBack(userData);
361 }
362 }
363
364 void OpenGLSurfaceEvaluator::inEvalPoint2(int i, int j)
365 {
366 REAL du, dv;
367 REAL point[4];
368 REAL normal[3];
369 REAL u,v;
370 du = (global_grid_u1 - global_grid_u0) / (REAL)global_grid_nu;
371 dv = (global_grid_v1 - global_grid_v0) / (REAL)global_grid_nv;
372 u = (i==global_grid_nu)? global_grid_u1:(global_grid_u0 + i*du);
373 v = (j == global_grid_nv)? global_grid_v1: (global_grid_v0 +j*dv);
374 inDoEvalCoord2(u,v,point,normal);
375 }
376
377 void OpenGLSurfaceEvaluator::inEvalCoord2f(REAL u, REAL v)
378 {
379
380 REAL point[4];
381 REAL normal[3];
382 inDoEvalCoord2(u,v,point, normal);
383 }
384
385
386
387 /*define a grid. store the values into the global variabls:
388 * global_grid_*
389 *These values will be used later by evaluating functions
390 */
391 void OpenGLSurfaceEvaluator::inMapGrid2f(int nu, REAL u0, REAL u1,
392 int nv, REAL v0, REAL v1)
393 {
394 global_grid_u0 = u0;
395 global_grid_u1 = u1;
396 global_grid_nu = nu;
397 global_grid_v0 = v0;
398 global_grid_v1 = v1;
399 global_grid_nv = nv;
400 }
401
402 void OpenGLSurfaceEvaluator::inEvalMesh2(int lowU, int lowV, int highU, int highV)
403 {
404 REAL du, dv;
405 int i,j;
406 REAL point[4];
407 REAL normal[3];
408 if(global_grid_nu == 0 || global_grid_nv == 0)
409 return; /*no points need to be output*/
410 du = (global_grid_u1 - global_grid_u0) / (REAL)global_grid_nu;
411 dv = (global_grid_v1 - global_grid_v0) / (REAL)global_grid_nv;
412
413 if(global_grid_nu >= global_grid_nv){
414 for(i=lowU; i<highU; i++){
415 REAL u1 = (i==global_grid_nu)? global_grid_u1:(global_grid_u0 + i*du);
416 REAL u2 = ((i+1) == global_grid_nu)? global_grid_u1: (global_grid_u0+(i+1)*du);
417
418 bgnqstrip();
419 for(j=highV; j>=lowV; j--){
420 REAL v1 = (j == global_grid_nv)? global_grid_v1: (global_grid_v0 +j*dv);
421
422 inDoEvalCoord2(u1, v1, point, normal);
423 inDoEvalCoord2(u2, v1, point, normal);
424 }
425 endqstrip();
426 }
427 }
428
429 else{
430 for(i=lowV; i<highV; i++){
431 REAL v1 = (i==global_grid_nv)? global_grid_v1:(global_grid_v0 + i*dv);
432 REAL v2 = ((i+1) == global_grid_nv)? global_grid_v1: (global_grid_v0+(i+1)*dv);
433
434 bgnqstrip();
435 for(j=highU; j>=lowU; j--){
436 REAL u1 = (j == global_grid_nu)? global_grid_u1: (global_grid_u0 +j*du);
437 inDoEvalCoord2(u1, v2, point, normal);
438 inDoEvalCoord2(u1, v1, point, normal);
439 }
440 endqstrip();
441 }
442 }
443
444 }
445
446 void OpenGLSurfaceEvaluator::inMap2f(int k,
447 REAL ulower,
448 REAL uupper,
449 int ustride,
450 int uorder,
451 REAL vlower,
452 REAL vupper,
453 int vstride,
454 int vorder,
455 REAL *ctlPoints)
456 {
457 int i,j,x;
458 REAL *data = global_ev_ctlPoints;
459
460
461
462 if(k == GL_MAP2_VERTEX_3) k=3;
463 else if (k==GL_MAP2_VERTEX_4) k =4;
464 else {
465 printf("error in inMap2f, maptype=%i is wrong, k,map is not updated\n", k);
466 return;
467 }
468
469 global_ev_k = k;
470 global_ev_u1 = ulower;
471 global_ev_u2 = uupper;
472 global_ev_ustride = ustride;
473 global_ev_uorder = uorder;
474 global_ev_v1 = vlower;
475 global_ev_v2 = vupper;
476 global_ev_vstride = vstride;
477 global_ev_vorder = vorder;
478
479 /*copy the contrl points from ctlPoints to global_ev_ctlPoints*/
480 for (i=0; i<uorder; i++) {
481 for (j=0; j<vorder; j++) {
482 for (x=0; x<k; x++) {
483 data[x] = ctlPoints[x];
484 }
485 ctlPoints += vstride;
486 data += k;
487 }
488 ctlPoints += ustride - vstride * vorder;
489 }
490
491 }
492
493
494 /*
495 *given a point p with homegeneous coordiante (x,y,z,w),
496 *let pu(x,y,z,w) be its partial derivative vector with
497 *respect to u
498 *and pv(x,y,z,w) be its partial derivative vector with repect to v.
499 *This function returns the partial derivative vectors of the
500 *inhomegensous coordinates, i.e.,
501 * (x/w, y/w, z/w) with respect to u and v.
502 */
503 void OpenGLSurfaceEvaluator::inComputeFirstPartials(REAL *p, REAL *pu, REAL *pv)
504 {
505 pu[0] = pu[0]*p[3] - pu[3]*p[0];
506 pu[1] = pu[1]*p[3] - pu[3]*p[1];
507 pu[2] = pu[2]*p[3] - pu[3]*p[2];
508
509 pv[0] = pv[0]*p[3] - pv[3]*p[0];
510 pv[1] = pv[1]*p[3] - pv[3]*p[1];
511 pv[2] = pv[2]*p[3] - pv[3]*p[2];
512 }
513
514 /*compute the cross product of pu and pv and normalize.
515 *the normal is returned in retNormal
516 * pu: dimension 3
517 * pv: dimension 3
518 * n: return normal, of dimension 3
519 */
520 void OpenGLSurfaceEvaluator::inComputeNormal2(REAL *pu, REAL *pv, REAL *n)
521 {
522 REAL mag;
523
524 n[0] = pu[1]*pv[2] - pu[2]*pv[1];
525 n[1] = pu[2]*pv[0] - pu[0]*pv[2];
526 n[2] = pu[0]*pv[1] - pu[1]*pv[0];
527
528 mag = sqrt(n[0]*n[0] + n[1]*n[1] + n[2]*n[2]);
529
530 if (mag > 0.0) {
531 n[0] /= mag;
532 n[1] /= mag;
533 n[2] /= mag;
534 }
535 }
536
537
538
539 /*Compute point and normal
540 *see the head of inDoDomain2WithDerivs
541 *for the meaning of the arguments
542 */
543 void OpenGLSurfaceEvaluator::inDoEvalCoord2(REAL u, REAL v,
544 REAL *retPoint, REAL *retNormal)
545 {
546
547 REAL du[4];
548 REAL dv[4];
549
550
551 assert(global_ev_k>=3 && global_ev_k <= 4);
552 /*compute homegeneous point and partial derivatives*/
553 inDoDomain2WithDerivs(global_ev_k, u, v, global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, retPoint, du, dv);
554
555 #ifdef AVOID_ZERO_NORMAL
556
557 if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO)
558 {
559
560 REAL tempdu[4];
561 REAL tempdata[4];
562 REAL u1 = global_ev_u1;
563 REAL u2 = global_ev_u2;
564 if(u-MYDELTA*(u2-u1) < u1)
565 u = u+ MYDELTA*(u2-u1);
566 else
567 u = u-MYDELTA*(u2-u1);
568 inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, tempdu, dv);
569 }
570 if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO)
571 {
572 REAL tempdv[4];
573 REAL tempdata[4];
574 REAL v1 = global_ev_v1;
575 REAL v2 = global_ev_v2;
576 if(v-MYDELTA*(v2-v1) < v1)
577 v = v+ MYDELTA*(v2-v1);
578 else
579 v = v-MYDELTA*(v2-v1);
580 inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, du, tempdv);
581 }
582 #endif
583
584
585 /*compute normal*/
586 switch(global_ev_k){
587 case 3:
588 inComputeNormal2(du, dv, retNormal);
589
590 break;
591 case 4:
592 inComputeFirstPartials(retPoint, du, dv);
593 inComputeNormal2(du, dv, retNormal);
594 /*transform the homegeneous coordinate of retPoint into inhomogenous one*/
595 retPoint[0] /= retPoint[3];
596 retPoint[1] /= retPoint[3];
597 retPoint[2] /= retPoint[3];
598 break;
599 }
600 /*output this vertex*/
601 /* inMeshStreamInsert(global_ms, retPoint, retNormal);*/
602
603
604
605 glNormal3fv(retNormal);
606 glVertex3fv(retPoint);
607
608
609
610
611 #ifdef DEBUG
612 printf("vertex(%f,%f,%f)\n", retPoint[0],retPoint[1],retPoint[2]);
613 #endif
614
615
616
617 }
618
619 /*Compute point and normal
620 *see the head of inDoDomain2WithDerivs
621 *for the meaning of the arguments
622 */
623 void OpenGLSurfaceEvaluator::inDoEvalCoord2NOGE_BU(REAL u, REAL v,
624 REAL *retPoint, REAL *retNormal)
625 {
626
627 REAL du[4];
628 REAL dv[4];
629
630
631 assert(global_ev_k>=3 && global_ev_k <= 4);
632 /*compute homegeneous point and partial derivatives*/
633 // inPreEvaluateBU(global_ev_k, global_ev_uorder, global_ev_vorder, (u-global_ev_u1)/(global_ev_u2-global_ev_u1), global_ev_ctlPoints);
634 inDoDomain2WithDerivsBU(global_ev_k, u, v, global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, retPoint, du, dv);
635
636
637 #ifdef AVOID_ZERO_NORMAL
638
639 if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO)
640 {
641
642 REAL tempdu[4];
643 REAL tempdata[4];
644 REAL u1 = global_ev_u1;
645 REAL u2 = global_ev_u2;
646 if(u-MYDELTA*(u2-u1) < u1)
647 u = u+ MYDELTA*(u2-u1);
648 else
649 u = u-MYDELTA*(u2-u1);
650 inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, tempdu, dv);
651 }
652 if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO)
653 {
654 REAL tempdv[4];
655 REAL tempdata[4];
656 REAL v1 = global_ev_v1;
657 REAL v2 = global_ev_v2;
658 if(v-MYDELTA*(v2-v1) < v1)
659 v = v+ MYDELTA*(v2-v1);
660 else
661 v = v-MYDELTA*(v2-v1);
662 inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, du, tempdv);
663 }
664 #endif
665
666 /*compute normal*/
667 switch(global_ev_k){
668 case 3:
669 inComputeNormal2(du, dv, retNormal);
670 break;
671 case 4:
672 inComputeFirstPartials(retPoint, du, dv);
673 inComputeNormal2(du, dv, retNormal);
674 /*transform the homegeneous coordinate of retPoint into inhomogenous one*/
675 retPoint[0] /= retPoint[3];
676 retPoint[1] /= retPoint[3];
677 retPoint[2] /= retPoint[3];
678 break;
679 }
680 }
681
682 /*Compute point and normal
683 *see the head of inDoDomain2WithDerivs
684 *for the meaning of the arguments
685 */
686 void OpenGLSurfaceEvaluator::inDoEvalCoord2NOGE_BV(REAL u, REAL v,
687 REAL *retPoint, REAL *retNormal)
688 {
689
690 REAL du[4];
691 REAL dv[4];
692
693
694 assert(global_ev_k>=3 && global_ev_k <= 4);
695 /*compute homegeneous point and partial derivatives*/
696 // inPreEvaluateBV(global_ev_k, global_ev_uorder, global_ev_vorder, (v-global_ev_v1)/(global_ev_v2-global_ev_v1), global_ev_ctlPoints);
697
698 inDoDomain2WithDerivsBV(global_ev_k, u, v, global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, retPoint, du, dv);
699
700
701 #ifdef AVOID_ZERO_NORMAL
702
703 if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO)
704 {
705
706 REAL tempdu[4];
707 REAL tempdata[4];
708 REAL u1 = global_ev_u1;
709 REAL u2 = global_ev_u2;
710 if(u-MYDELTA*(u2-u1) < u1)
711 u = u+ MYDELTA*(u2-u1);
712 else
713 u = u-MYDELTA*(u2-u1);
714 inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, tempdu, dv);
715 }
716 if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO)
717 {
718 REAL tempdv[4];
719 REAL tempdata[4];
720 REAL v1 = global_ev_v1;
721 REAL v2 = global_ev_v2;
722 if(v-MYDELTA*(v2-v1) < v1)
723 v = v+ MYDELTA*(v2-v1);
724 else
725 v = v-MYDELTA*(v2-v1);
726 inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, du, tempdv);
727 }
728 #endif
729
730 /*compute normal*/
731 switch(global_ev_k){
732 case 3:
733 inComputeNormal2(du, dv, retNormal);
734 break;
735 case 4:
736 inComputeFirstPartials(retPoint, du, dv);
737 inComputeNormal2(du, dv, retNormal);
738 /*transform the homegeneous coordinate of retPoint into inhomogenous one*/
739 retPoint[0] /= retPoint[3];
740 retPoint[1] /= retPoint[3];
741 retPoint[2] /= retPoint[3];
742 break;
743 }
744 }
745
746
747 /*Compute point and normal
748 *see the head of inDoDomain2WithDerivs
749 *for the meaning of the arguments
750 */
751 void OpenGLSurfaceEvaluator::inDoEvalCoord2NOGE(REAL u, REAL v,
752 REAL *retPoint, REAL *retNormal)
753 {
754
755 REAL du[4];
756 REAL dv[4];
757
758
759 assert(global_ev_k>=3 && global_ev_k <= 4);
760 /*compute homegeneous point and partial derivatives*/
761 inDoDomain2WithDerivs(global_ev_k, u, v, global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, retPoint, du, dv);
762
763
764 #ifdef AVOID_ZERO_NORMAL
765
766 if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO)
767 {
768
769 REAL tempdu[4];
770 REAL tempdata[4];
771 REAL u1 = global_ev_u1;
772 REAL u2 = global_ev_u2;
773 if(u-MYDELTA*(u2-u1) < u1)
774 u = u+ MYDELTA*(u2-u1);
775 else
776 u = u-MYDELTA*(u2-u1);
777 inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, tempdu, dv);
778 }
779 if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO)
780 {
781 REAL tempdv[4];
782 REAL tempdata[4];
783 REAL v1 = global_ev_v1;
784 REAL v2 = global_ev_v2;
785 if(v-MYDELTA*(v2-v1) < v1)
786 v = v+ MYDELTA*(v2-v1);
787 else
788 v = v-MYDELTA*(v2-v1);
789 inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, du, tempdv);
790 }
791 #endif
792
793 /*compute normal*/
794 switch(global_ev_k){
795 case 3:
796 inComputeNormal2(du, dv, retNormal);
797 break;
798 case 4:
799 inComputeFirstPartials(retPoint, du, dv);
800 inComputeNormal2(du, dv, retNormal);
801 /*transform the homegeneous coordinate of retPoint into inhomogenous one*/
802 retPoint[0] /= retPoint[3];
803 retPoint[1] /= retPoint[3];
804 retPoint[2] /= retPoint[3];
805 break;
806 }
807 // glNormal3fv(retNormal);
808 // glVertex3fv(retPoint);
809 }
810
811 void OpenGLSurfaceEvaluator::inPreEvaluateBV(int k, int uorder, int vorder, REAL vprime, REAL *baseData)
812 {
813 int j,row,col;
814 REAL p, pdv;
815 REAL *data;
816
817 if(global_vprime != vprime || global_vorder != vorder) {
818 inPreEvaluateWithDeriv(vorder, vprime, global_vcoeff, global_vcoeffDeriv);
819 global_vprime = vprime;
820 global_vorder = vorder;
821 }
822
823 for(j=0; j<k; j++){
824 data = baseData+j;
825 for(row=0; row<uorder; row++){
826 p = global_vcoeff[0] * (*data);
827 pdv = global_vcoeffDeriv[0] * (*data);
828 data += k;
829 for(col = 1; col < vorder; col++){
830 p += global_vcoeff[col] * (*data);
831 pdv += global_vcoeffDeriv[col] * (*data);
832 data += k;
833 }
834 global_BV[row][j] = p;
835 global_PBV[row][j] = pdv;
836 }
837 }
838 }
839
840 void OpenGLSurfaceEvaluator::inPreEvaluateBU(int k, int uorder, int vorder, REAL uprime, REAL *baseData)
841 {
842 int j,row,col;
843 REAL p, pdu;
844 REAL *data;
845
846 if(global_uprime != uprime || global_uorder != uorder) {
847 inPreEvaluateWithDeriv(uorder, uprime, global_ucoeff, global_ucoeffDeriv);
848 global_uprime = uprime;
849 global_uorder = uorder;
850 }
851
852 for(j=0; j<k; j++){
853 data = baseData+j;
854 for(col=0; col<vorder; col++){
855 data = baseData+j + k*col;
856 p = global_ucoeff[0] * (*data);
857 pdu = global_ucoeffDeriv[0] * (*data);
858 data += k*uorder;
859 for(row = 1; row < uorder; row++){
860 p += global_ucoeff[row] * (*data);
861 pdu += global_ucoeffDeriv[row] * (*data);
862 data += k * uorder;
863 }
864 global_BU[col][j] = p;
865 global_PBU[col][j] = pdu;
866 }
867 }
868 }
869
870 void OpenGLSurfaceEvaluator::inDoDomain2WithDerivsBU(int k, REAL u, REAL v,
871 REAL u1, REAL u2, int uorder,
872 REAL v1, REAL v2, int vorder,
873 REAL *baseData,
874 REAL *retPoint, REAL* retdu, REAL *retdv)
875 {
876 int j, col;
877
878 REAL vprime;
879
880
881 if((u2 == u1) || (v2 == v1))
882 return;
883
884 vprime = (v - v1) / (v2 - v1);
885
886
887 if(global_vprime != vprime || global_vorder != vorder) {
888 inPreEvaluateWithDeriv(vorder, vprime, global_vcoeff, global_vcoeffDeriv);
889 global_vprime = vprime;
890 global_vorder = vorder;
891 }
892
893
894 for(j=0; j<k; j++)
895 {
896 retPoint[j] = retdu[j] = retdv[j] = 0.0;
897 for (col = 0; col < vorder; col++) {
898 retPoint[j] += global_BU[col][j] * global_vcoeff[col];
899 retdu[j] += global_PBU[col][j] * global_vcoeff[col];
900 retdv[j] += global_BU[col][j] * global_vcoeffDeriv[col];
901 }
902 }
903 }
904
905 void OpenGLSurfaceEvaluator::inDoDomain2WithDerivsBV(int k, REAL u, REAL v,
906 REAL u1, REAL u2, int uorder,
907 REAL v1, REAL v2, int vorder,
908 REAL *baseData,
909 REAL *retPoint, REAL* retdu, REAL *retdv)
910 {
911 int j, row;
912 REAL uprime;
913
914
915 if((u2 == u1) || (v2 == v1))
916 return;
917 uprime = (u - u1) / (u2 - u1);
918
919
920 if(global_uprime != uprime || global_uorder != uorder) {
921 inPreEvaluateWithDeriv(uorder, uprime, global_ucoeff, global_ucoeffDeriv);
922 global_uprime = uprime;
923 global_uorder = uorder;
924 }
925
926
927 for(j=0; j<k; j++)
928 {
929 retPoint[j] = retdu[j] = retdv[j] = 0.0;
930 for (row = 0; row < uorder; row++) {
931 retPoint[j] += global_BV[row][j] * global_ucoeff[row];
932 retdu[j] += global_BV[row][j] * global_ucoeffDeriv[row];
933 retdv[j] += global_PBV[row][j] * global_ucoeff[row];
934 }
935 }
936 }
937
938
939 /*
940 *given a Bezier surface, and parameter (u,v), compute the point in the object space,
941 *and the normal
942 *k: the dimension of the object space: usually 2,3,or 4.
943 *u,v: the paramter pair.
944 *u1,u2,uorder: the Bezier polynomial of u coord is defined on [u1,u2] with order uorder.
945 *v1,v2,vorder: the Bezier polynomial of v coord is defined on [v1,v2] with order vorder.
946 *baseData: contrl points. arranged as: (u,v,k).
947 *retPoint: the computed point (one point) with dimension k.
948 *retdu: the computed partial derivative with respect to u.
949 *retdv: the computed partial derivative with respect to v.
950 */
951 void OpenGLSurfaceEvaluator::inDoDomain2WithDerivs(int k, REAL u, REAL v,
952 REAL u1, REAL u2, int uorder,
953 REAL v1, REAL v2, int vorder,
954 REAL *baseData,
955 REAL *retPoint, REAL *retdu, REAL *retdv)
956 {
957 int j, row, col;
958 REAL uprime;
959 REAL vprime;
960 REAL p;
961 REAL pdv;
962 REAL *data;
963
964 if((u2 == u1) || (v2 == v1))
965 return;
966 uprime = (u - u1) / (u2 - u1);
967 vprime = (v - v1) / (v2 - v1);
968
969 /* Compute coefficients for values and derivs */
970
971 /* Use already cached values if possible */
972 if(global_uprime != uprime || global_uorder != uorder) {
973 inPreEvaluateWithDeriv(uorder, uprime, global_ucoeff, global_ucoeffDeriv);
974 global_uorder = uorder;
975 global_uprime = uprime;
976 }
977 if (global_vprime != vprime ||
978 global_vorder != vorder) {
979 inPreEvaluateWithDeriv(vorder, vprime, global_vcoeff, global_vcoeffDeriv);
980 global_vorder = vorder;
981 global_vprime = vprime;
982 }
983
984 for (j = 0; j < k; j++) {
985 data=baseData+j;
986 retPoint[j] = retdu[j] = retdv[j] = 0.0;
987 for (row = 0; row < uorder; row++) {
988 /*
989 ** Minor optimization.
990 ** The col == 0 part of the loop is extracted so we don't
991 ** have to initialize p and pdv to 0.
992 */
993 p = global_vcoeff[0] * (*data);
994 pdv = global_vcoeffDeriv[0] * (*data);
995 data += k;
996 for (col = 1; col < vorder; col++) {
997 /* Incrementally build up p, pdv value */
998 p += global_vcoeff[col] * (*data);
999 pdv += global_vcoeffDeriv[col] * (*data);
1000 data += k;
1001 }
1002 /* Use p, pdv value to incrementally add up r, du, dv */
1003 retPoint[j] += global_ucoeff[row] * p;
1004 retdu[j] += global_ucoeffDeriv[row] * p;
1005 retdv[j] += global_ucoeff[row] * pdv;
1006 }
1007 }
1008 }
1009
1010
1011 /*
1012 *compute the Bezier polynomials C[n,j](v) for all j at v with
1013 *return values stored in coeff[], where
1014 * C[n,j](v) = (n,j) * v^j * (1-v)^(n-j),
1015 * j=0,1,2,...,n.
1016 *order : n+1
1017 *vprime: v
1018 *coeff : coeff[j]=C[n,j](v), this array store the returned values.
1019 *The algorithm is a recursive scheme:
1020 * C[0,0]=1;
1021 * C[n,j](v) = (1-v)*C[n-1,j](v) + v*C[n-1,j-1](v), n>=1
1022 *This code is copied from opengl/soft/so_eval.c:PreEvaluate
1023 */
1024 void OpenGLSurfaceEvaluator::inPreEvaluate(int order, REAL vprime, REAL *coeff)
1025 {
1026 int i, j;
1027 REAL oldval, temp;
1028 REAL oneMinusvprime;
1029
1030 /*
1031 * Minor optimization
1032 * Compute orders 1 and 2 outright, and set coeff[0], coeff[1] to
1033 * their i==1 loop values to avoid the initialization and the i==1 loop.
1034 */
1035 if (order == 1) {
1036 coeff[0] = 1.0;
1037 return;
1038 }
1039
1040 oneMinusvprime = 1-vprime;
1041 coeff[0] = oneMinusvprime;
1042 coeff[1] = vprime;
1043 if (order == 2) return;
1044
1045 for (i = 2; i < order; i++) {
1046 oldval = coeff[0] * vprime;
1047 coeff[0] = oneMinusvprime * coeff[0];
1048 for (j = 1; j < i; j++) {
1049 temp = oldval;
1050 oldval = coeff[j] * vprime;
1051 coeff[j] = temp + oneMinusvprime * coeff[j];
1052 }
1053 coeff[j] = oldval;
1054 }
1055 }
1056
1057 /*
1058 *compute the Bezier polynomials C[n,j](v) and derivatives for all j at v with
1059 *return values stored in coeff[] and coeffDeriv[].
1060 *see the head of function inPreEvaluate for the definition of C[n,j](v)
1061 *and how to compute the values.
1062 *The algorithm to compute the derivative is:
1063 * dC[0,0](v) = 0.
1064 * dC[n,j](v) = n*(dC[n-1,j-1](v) - dC[n-1,j](v)).
1065 *
1066 *This code is copied from opengl/soft/so_eval.c:PreEvaluateWidthDeriv
1067 */
1068 void OpenGLSurfaceEvaluator::inPreEvaluateWithDeriv(int order, REAL vprime,
1069 REAL *coeff, REAL *coeffDeriv)
1070 {
1071 int i, j;
1072 REAL oldval, temp;
1073 REAL oneMinusvprime;
1074
1075 oneMinusvprime = 1-vprime;
1076 /*
1077 * Minor optimization
1078 * Compute orders 1 and 2 outright, and set coeff[0], coeff[1] to
1079 * their i==1 loop values to avoid the initialization and the i==1 loop.
1080 */
1081 if (order == 1) {
1082 coeff[0] = 1.0;
1083 coeffDeriv[0] = 0.0;
1084 return;
1085 } else if (order == 2) {
1086 coeffDeriv[0] = -1.0;
1087 coeffDeriv[1] = 1.0;
1088 coeff[0] = oneMinusvprime;
1089 coeff[1] = vprime;
1090 return;
1091 }
1092 coeff[0] = oneMinusvprime;
1093 coeff[1] = vprime;
1094 for (i = 2; i < order - 1; i++) {
1095 oldval = coeff[0] * vprime;
1096 coeff[0] = oneMinusvprime * coeff[0];
1097 for (j = 1; j < i; j++) {
1098 temp = oldval;
1099 oldval = coeff[j] * vprime;
1100 coeff[j] = temp + oneMinusvprime * coeff[j];
1101 }
1102 coeff[j] = oldval;
1103 }
1104 coeffDeriv[0] = -coeff[0];
1105 /*
1106 ** Minor optimization:
1107 ** Would make this a "for (j=1; j<order-1; j++)" loop, but it is always
1108 ** executed at least once, so this is more efficient.
1109 */
1110 j=1;
1111 do {
1112 coeffDeriv[j] = coeff[j-1] - coeff[j];
1113 j++;
1114 } while (j < order - 1);
1115 coeffDeriv[j] = coeff[j-1];
1116
1117 oldval = coeff[0] * vprime;
1118 coeff[0] = oneMinusvprime * coeff[0];
1119 for (j = 1; j < i; j++) {
1120 temp = oldval;
1121 oldval = coeff[j] * vprime;
1122 coeff[j] = temp + oneMinusvprime * coeff[j];
1123 }
1124 coeff[j] = oldval;
1125 }
1126
1127 void OpenGLSurfaceEvaluator::inEvalULine(int n_points, REAL v, REAL* u_vals,
1128 int stride, REAL ret_points[][3], REAL ret_normals[][3])
1129 {
1130 int i,k;
1131 REAL temp[4];
1132 inPreEvaluateBV_intfac(v);
1133
1134 for(i=0,k=0; i<n_points; i++, k += stride)
1135 {
1136 inDoEvalCoord2NOGE_BV(u_vals[k],v,temp, ret_normals[i]);
1137
1138 ret_points[i][0] = temp[0];
1139 ret_points[i][1] = temp[1];
1140 ret_points[i][2] = temp[2];
1141
1142 }
1143
1144 }
1145
1146 void OpenGLSurfaceEvaluator::inEvalVLine(int n_points, REAL u, REAL* v_vals,
1147 int stride, REAL ret_points[][3], REAL ret_normals[][3])
1148 {
1149 int i,k;
1150 REAL temp[4];
1151 inPreEvaluateBU_intfac(u);
1152 for(i=0,k=0; i<n_points; i++, k += stride)
1153 {
1154 inDoEvalCoord2NOGE_BU(u, v_vals[k], temp, ret_normals[i]);
1155 ret_points[i][0] = temp[0];
1156 ret_points[i][1] = temp[1];
1157 ret_points[i][2] = temp[2];
1158 }
1159 }
1160
1161
1162 /*triangulate a strip bounded by two lines which are parallel to U-axis
1163 *upperVerts: the verteces on the upper line
1164 *lowerVertx: the verteces on the lower line
1165 *n_upper >=1
1166 *n_lower >=1
1167 */
1168 void OpenGLSurfaceEvaluator::inEvalUStrip(int n_upper, REAL v_upper, REAL* upper_val, int n_lower, REAL v_lower, REAL* lower_val)
1169 {
1170 int i,j,k,l;
1171 REAL leftMostV[2];
1172 typedef REAL REAL3[3];
1173
1174 REAL3* upperXYZ = (REAL3*) malloc(sizeof(REAL3)*n_upper);
1175 assert(upperXYZ);
1176 REAL3* upperNormal = (REAL3*) malloc(sizeof(REAL3) * n_upper);
1177 assert(upperNormal);
1178 REAL3* lowerXYZ = (REAL3*) malloc(sizeof(REAL3)*n_lower);
1179 assert(lowerXYZ);
1180 REAL3* lowerNormal = (REAL3*) malloc(sizeof(REAL3) * n_lower);
1181 assert(lowerNormal);
1182
1183 inEvalULine(n_upper, v_upper, upper_val, 1, upperXYZ, upperNormal);
1184 inEvalULine(n_lower, v_lower, lower_val, 1, lowerXYZ, lowerNormal);
1185
1186
1187
1188 REAL* leftMostXYZ;
1189 REAL* leftMostNormal;
1190
1191 /*
1192 *the algorithm works by scanning from left to right.
1193 *leftMostV: the left most of the remaining verteces (on both upper and lower).
1194 * it could an element of upperVerts or lowerVerts.
1195 *i: upperVerts[i] is the first vertex to the right of leftMostV on upper line *j: lowerVerts[j] is the first vertex to the right of leftMostV on lower line */
1196
1197 /*initialize i,j,and leftMostV
1198 */
1199 if(upper_val[0] <= lower_val[0])
1200 {
1201 i=1;
1202 j=0;
1203
1204 leftMostV[0] = upper_val[0];
1205 leftMostV[1] = v_upper;
1206 leftMostXYZ = upperXYZ[0];
1207 leftMostNormal = upperNormal[0];
1208 }
1209 else
1210 {
1211 i=0;
1212 j=1;
1213
1214 leftMostV[0] = lower_val[0];
1215 leftMostV[1] = v_lower;
1216
1217 leftMostXYZ = lowerXYZ[0];
1218 leftMostNormal = lowerNormal[0];
1219 }
1220
1221 /*the main loop.
1222 *the invariance is that:
1223 *at the beginning of each loop, the meaning of i,j,and leftMostV are
1224 *maintained
1225 */
1226 while(1)
1227 {
1228 if(i >= n_upper) /*case1: no more in upper*/
1229 {
1230 if(j<n_lower-1) /*at least two vertices in lower*/
1231 {
1232 bgntfan();
1233 glNormal3fv(leftMostNormal);
1234 glVertex3fv(leftMostXYZ);
1235
1236 while(j<n_lower){
1237 glNormal3fv(lowerNormal[j]);
1238 glVertex3fv(lowerXYZ[j]);
1239 j++;
1240
1241 }
1242 endtfan();
1243 }
1244 break; /*exit the main loop*/
1245 }
1246 else if(j>= n_lower) /*case2: no more in lower*/
1247 {
1248 if(i<n_upper-1) /*at least two vertices in upper*/
1249 {
1250 bgntfan();
1251 glNormal3fv(leftMostNormal);
1252 glVertex3fv(leftMostXYZ);
1253
1254 for(k=n_upper-1; k>=i; k--) /*reverse order for two-side lighting*/
1255 {
1256 glNormal3fv(upperNormal[k]);
1257 glVertex3fv(upperXYZ[k]);
1258 }
1259
1260 endtfan();
1261 }
1262 break; /*exit the main loop*/
1263 }
1264 else /* case3: neither is empty, plus the leftMostV, there is at least one triangle to output*/
1265 {
1266 if(upper_val[i] <= lower_val[j])
1267 {
1268 bgntfan();
1269
1270 glNormal3fv(lowerNormal[j]);
1271 glVertex3fv(lowerXYZ[j]);
1272
1273 /*find the last k>=i such that
1274 *upperverts[k][0] <= lowerverts[j][0]
1275 */
1276 k=i;
1277
1278 while(k<n_upper)
1279 {
1280 if(upper_val[k] > lower_val[j])
1281 break;
1282 k++;
1283
1284 }
1285 k--;
1286
1287
1288 for(l=k; l>=i; l--)/*the reverse is for two-side lighting*/
1289 {
1290 glNormal3fv(upperNormal[l]);
1291 glVertex3fv(upperXYZ[l]);
1292
1293 }
1294 glNormal3fv(leftMostNormal);
1295 glVertex3fv(leftMostXYZ);
1296
1297 endtfan();
1298
1299 /*update i and leftMostV for next loop
1300 */
1301 i = k+1;
1302
1303 leftMostV[0] = upper_val[k];
1304 leftMostV[1] = v_upper;
1305 leftMostNormal = upperNormal[k];
1306 leftMostXYZ = upperXYZ[k];
1307 }
1308 else /*upperVerts[i][0] > lowerVerts[j][0]*/
1309 {
1310 bgntfan();
1311 glNormal3fv(upperNormal[i]);
1312 glVertex3fv(upperXYZ[i]);
1313
1314 glNormal3fv(leftMostNormal);
1315 glVertex3fv(leftMostXYZ);
1316
1317
1318 /*find the last k>=j such that
1319 *lowerverts[k][0] < upperverts[i][0]
1320 */
1321 k=j;
1322 while(k< n_lower)
1323 {
1324 if(lower_val[k] >= upper_val[i])
1325 break;
1326 glNormal3fv(lowerNormal[k]);
1327 glVertex3fv(lowerXYZ[k]);
1328
1329 k++;
1330 }
1331 endtfan();
1332
1333 /*update j and leftMostV for next loop
1334 */
1335 j=k;
1336 leftMostV[0] = lower_val[j-1];
1337 leftMostV[1] = v_lower;
1338
1339 leftMostNormal = lowerNormal[j-1];
1340 leftMostXYZ = lowerXYZ[j-1];
1341 }
1342 }
1343 }
1344 //clean up
1345 free(upperXYZ);
1346 free(lowerXYZ);
1347 free(upperNormal);
1348 free(lowerNormal);
1349 }
1350
1351 /*triangulate a strip bounded by two lines which are parallel to V-axis
1352 *leftVerts: the verteces on the left line
1353 *rightVertx: the verteces on the right line
1354 *n_left >=1
1355 *n_right >=1
1356 */
1357 void OpenGLSurfaceEvaluator::inEvalVStrip(int n_left, REAL u_left, REAL* left_val, int n_right, REAL u_right, REAL* right_val)
1358 {
1359 int i,j,k,l;
1360 REAL botMostV[2];
1361 typedef REAL REAL3[3];
1362
1363 REAL3* leftXYZ = (REAL3*) malloc(sizeof(REAL3)*n_left);
1364 assert(leftXYZ);
1365 REAL3* leftNormal = (REAL3*) malloc(sizeof(REAL3) * n_left);
1366 assert(leftNormal);
1367 REAL3* rightXYZ = (REAL3*) malloc(sizeof(REAL3)*n_right);
1368 assert(rightXYZ);
1369 REAL3* rightNormal = (REAL3*) malloc(sizeof(REAL3) * n_right);
1370 assert(rightNormal);
1371
1372 inEvalVLine(n_left, u_left, left_val, 1, leftXYZ, leftNormal);
1373 inEvalVLine(n_right, u_right, right_val, 1, rightXYZ, rightNormal);
1374
1375
1376
1377 REAL* botMostXYZ;
1378 REAL* botMostNormal;
1379
1380 /*
1381 *the algorithm works by scanning from bot to top.
1382 *botMostV: the bot most of the remaining verteces (on both left and right).
1383 * it could an element of leftVerts or rightVerts.
1384 *i: leftVerts[i] is the first vertex to the top of botMostV on left line
1385 *j: rightVerts[j] is the first vertex to the top of botMostV on rightline */
1386
1387 /*initialize i,j,and botMostV
1388 */
1389 if(left_val[0] <= right_val[0])
1390 {
1391 i=1;
1392 j=0;
1393
1394 botMostV[0] = u_left;
1395 botMostV[1] = left_val[0];
1396 botMostXYZ = leftXYZ[0];
1397 botMostNormal = leftNormal[0];
1398 }
1399 else
1400 {
1401 i=0;
1402 j=1;
1403
1404 botMostV[0] = u_right;
1405 botMostV[1] = right_val[0];
1406
1407 botMostXYZ = rightXYZ[0];
1408 botMostNormal = rightNormal[0];
1409 }
1410
1411 /*the main loop.
1412 *the invariance is that:
1413 *at the beginning of each loop, the meaning of i,j,and botMostV are
1414 *maintained
1415 */
1416 while(1)
1417 {
1418 if(i >= n_left) /*case1: no more in left*/
1419 {
1420 if(j<n_right-1) /*at least two vertices in right*/
1421 {
1422 bgntfan();
1423 glNormal3fv(botMostNormal);
1424 glVertex3fv(botMostXYZ);
1425
1426 while(j<n_right){
1427 glNormal3fv(rightNormal[j]);
1428 glVertex3fv(rightXYZ[j]);
1429 j++;
1430
1431 }
1432 endtfan();
1433 }
1434 break; /*exit the main loop*/
1435 }
1436 else if(j>= n_right) /*case2: no more in right*/
1437 {
1438 if(i<n_left-1) /*at least two vertices in left*/
1439 {
1440 bgntfan();
1441 glNormal3fv(botMostNormal);
1442 glVertex3fv(botMostXYZ);
1443
1444 for(k=n_left-1; k>=i; k--) /*reverse order for two-side lighting*/
1445 {
1446 glNormal3fv(leftNormal[k]);
1447 glVertex3fv(leftXYZ[k]);
1448 }
1449
1450 endtfan();
1451 }
1452 break; /*exit the main loop*/
1453 }
1454 else /* case3: neither is empty, plus the botMostV, there is at least one triangle to output*/
1455 {
1456 if(left_val[i] <= right_val[j])
1457 {
1458 bgntfan();
1459
1460 glNormal3fv(rightNormal[j]);
1461 glVertex3fv(rightXYZ[j]);
1462
1463 /*find the last k>=i such that
1464 *leftverts[k][0] <= rightverts[j][0]
1465 */
1466 k=i;
1467
1468 while(k<n_left)
1469 {
1470 if(left_val[k] > right_val[j])
1471 break;
1472 k++;
1473
1474 }
1475 k--;
1476
1477
1478 for(l=k; l>=i; l--)/*the reverse is for two-side lighting*/
1479 {
1480 glNormal3fv(leftNormal[l]);
1481 glVertex3fv(leftXYZ[l]);
1482
1483 }
1484 glNormal3fv(botMostNormal);
1485 glVertex3fv(botMostXYZ);
1486
1487 endtfan();
1488
1489 /*update i and botMostV for next loop
1490 */
1491 i = k+1;
1492
1493 botMostV[0] = u_left;
1494 botMostV[1] = left_val[k];
1495 botMostNormal = leftNormal[k];
1496 botMostXYZ = leftXYZ[k];
1497 }
1498 else /*left_val[i] > right_val[j])*/
1499 {
1500 bgntfan();
1501 glNormal3fv(leftNormal[i]);
1502 glVertex3fv(leftXYZ[i]);
1503
1504 glNormal3fv(botMostNormal);
1505 glVertex3fv(botMostXYZ);
1506
1507
1508 /*find the last k>=j such that
1509 *rightverts[k][0] < leftverts[i][0]
1510 */
1511 k=j;
1512 while(k< n_right)
1513 {
1514 if(right_val[k] >= left_val[i])
1515 break;
1516 glNormal3fv(rightNormal[k]);
1517 glVertex3fv(rightXYZ[k]);
1518
1519 k++;
1520 }
1521 endtfan();
1522
1523 /*update j and botMostV for next loop
1524 */
1525 j=k;
1526 botMostV[0] = u_right;
1527 botMostV[1] = right_val[j-1];
1528
1529 botMostNormal = rightNormal[j-1];
1530 botMostXYZ = rightXYZ[j-1];
1531 }
1532 }
1533 }
1534 //clean up
1535 free(leftXYZ);
1536 free(leftXYZ);
1537 free(rightNormal);
1538 free(rightNormal);
1539 }
1540
1541 /*-----------------------begin evalMachine-------------------*/
1542 void OpenGLSurfaceEvaluator::inMap2fEM(int which, int k,
1543 REAL ulower,
1544 REAL uupper,
1545 int ustride,
1546 int uorder,
1547 REAL vlower,
1548 REAL vupper,
1549 int vstride,
1550 int vorder,
1551 REAL *ctlPoints)
1552 {
1553 int i,j,x;
1554 surfEvalMachine *temp_em;
1555 switch(which){
1556 case 0: //vertex
1557 vertex_flag = 1;
1558 temp_em = &em_vertex;
1559 break;
1560 case 1: //normal
1561 normal_flag = 1;
1562 temp_em = &em_normal;
1563 break;
1564 case 2: //color
1565 color_flag = 1;
1566 temp_em = &em_color;
1567 break;
1568 default:
1569 texcoord_flag = 1;
1570 temp_em = &em_texcoord;
1571 break;
1572 }
1573
1574 REAL *data = temp_em->ctlPoints;
1575
1576 temp_em->uprime = -1;//initilized
1577 temp_em->vprime = -1;
1578
1579 temp_em->k = k;
1580 temp_em->u1 = ulower;
1581 temp_em->u2 = uupper;
1582 temp_em->ustride = ustride;
1583 temp_em->uorder = uorder;
1584 temp_em->v1 = vlower;
1585 temp_em->v2 = vupper;
1586 temp_em->vstride = vstride;
1587 temp_em->vorder = vorder;
1588
1589 /*copy the contrl points from ctlPoints to global_ev_ctlPoints*/
1590 for (i=0; i<uorder; i++) {
1591 for (j=0; j<vorder; j++) {
1592 for (x=0; x<k; x++) {
1593 data[x] = ctlPoints[x];
1594 }
1595 ctlPoints += vstride;
1596 data += k;
1597 }
1598 ctlPoints += ustride - vstride * vorder;
1599 }
1600 }
1601
1602 void OpenGLSurfaceEvaluator::inDoDomain2WithDerivsEM(surfEvalMachine *em, REAL u, REAL v,
1603 REAL *retPoint, REAL *retdu, REAL *retdv)
1604 {
1605 int j, row, col;
1606 REAL the_uprime;
1607 REAL the_vprime;
1608 REAL p;
1609 REAL pdv;
1610 REAL *data;
1611
1612 if((em->u2 == em->u1) || (em->v2 == em->v1))
1613 return;
1614 the_uprime = (u - em->u1) / (em->u2 - em->u1);
1615 the_vprime = (v - em->v1) / (em->v2 - em->v1);
1616
1617 /* Compute coefficients for values and derivs */
1618
1619 /* Use already cached values if possible */
1620 if(em->uprime != the_uprime) {
1621 inPreEvaluateWithDeriv(em->uorder, the_uprime, em->ucoeff, em->ucoeffDeriv);
1622 em->uprime = the_uprime;
1623 }
1624 if (em->vprime != the_vprime) {
1625 inPreEvaluateWithDeriv(em->vorder, the_vprime, em->vcoeff, em->vcoeffDeriv);
1626 em->vprime = the_vprime;
1627 }
1628
1629 for (j = 0; j < em->k; j++) {
1630 data=em->ctlPoints+j;
1631 retPoint[j] = retdu[j] = retdv[j] = 0.0;
1632 for (row = 0; row < em->uorder; row++) {
1633 /*
1634 ** Minor optimization.
1635 ** The col == 0 part of the loop is extracted so we don't
1636 ** have to initialize p and pdv to 0.
1637 */
1638 p = em->vcoeff[0] * (*data);
1639 pdv = em->vcoeffDeriv[0] * (*data);
1640 data += em->k;
1641 for (col = 1; col < em->vorder; col++) {
1642 /* Incrementally build up p, pdv value */
1643 p += em->vcoeff[col] * (*data);
1644 pdv += em->vcoeffDeriv[col] * (*data);
1645 data += em->k;
1646 }
1647 /* Use p, pdv value to incrementally add up r, du, dv */
1648 retPoint[j] += em->ucoeff[row] * p;
1649 retdu[j] += em->ucoeffDeriv[row] * p;
1650 retdv[j] += em->ucoeff[row] * pdv;
1651 }
1652 }
1653 }
1654
1655 void OpenGLSurfaceEvaluator::inDoDomain2EM(surfEvalMachine *em, REAL u, REAL v,
1656 REAL *retPoint)
1657 {
1658 int j, row, col;
1659 REAL the_uprime;
1660 REAL the_vprime;
1661 REAL p;
1662 REAL *data;
1663
1664 if((em->u2 == em->u1) || (em->v2 == em->v1))
1665 return;
1666 the_uprime = (u - em->u1) / (em->u2 - em->u1);
1667 the_vprime = (v - em->v1) / (em->v2 - em->v1);
1668
1669 /* Compute coefficients for values and derivs */
1670
1671 /* Use already cached values if possible */
1672 if(em->uprime != the_uprime) {
1673 inPreEvaluate(em->uorder, the_uprime, em->ucoeff);
1674 em->uprime = the_uprime;
1675 }
1676 if (em->vprime != the_vprime) {
1677 inPreEvaluate(em->vorder, the_vprime, em->vcoeff);
1678 em->vprime = the_vprime;
1679 }
1680
1681 for (j = 0; j < em->k; j++) {
1682 data=em->ctlPoints+j;
1683 retPoint[j] = 0.0;
1684 for (row = 0; row < em->uorder; row++) {
1685 /*
1686 ** Minor optimization.
1687 ** The col == 0 part of the loop is extracted so we don't
1688 ** have to initialize p and pdv to 0.
1689 */
1690 p = em->vcoeff[0] * (*data);
1691 data += em->k;
1692 for (col = 1; col < em->vorder; col++) {
1693 /* Incrementally build up p, pdv value */
1694 p += em->vcoeff[col] * (*data);
1695 data += em->k;
1696 }
1697 /* Use p, pdv value to incrementally add up r, du, dv */
1698 retPoint[j] += em->ucoeff[row] * p;
1699 }
1700 }
1701 }
1702
1703
1704 void OpenGLSurfaceEvaluator::inDoEvalCoord2EM(REAL u, REAL v)
1705 {
1706 REAL temp_vertex[5];
1707 REAL temp_normal[3];
1708 REAL temp_color[4];
1709 REAL temp_texcoord[4];
1710
1711 if(texcoord_flag)
1712 {
1713 inDoDomain2EM(&em_texcoord, u,v, temp_texcoord);
1714 texcoordCallBack(temp_texcoord, userData);
1715 }
1716 if(color_flag)
1717 {
1718 inDoDomain2EM(&em_color, u,v, temp_color);
1719 colorCallBack(temp_color, userData);
1720 }
1721
1722 if(normal_flag) //there is a normla map
1723 {
1724 inDoDomain2EM(&em_normal, u,v, temp_normal);
1725 normalCallBack(temp_normal, userData);
1726
1727 if(vertex_flag)
1728 {
1729 inDoDomain2EM(&em_vertex, u,v,temp_vertex);
1730 if(em_vertex.k == 4)
1731 {
1732 temp_vertex[0] /= temp_vertex[3];
1733 temp_vertex[1] /= temp_vertex[3];
1734 temp_vertex[2] /= temp_vertex[3];
1735 }
1736 temp_vertex[3]=u;
1737 temp_vertex[4]=v;
1738 vertexCallBack(temp_vertex, userData);
1739 }
1740 }
1741 else if(auto_normal_flag) //no normal map but there is a normal callbackfunctin
1742 {
1743 REAL du[4];
1744 REAL dv[4];
1745
1746 /*compute homegeneous point and partial derivatives*/
1747 inDoDomain2WithDerivsEM(&em_vertex, u,v,temp_vertex,du,dv);
1748
1749 if(em_vertex.k ==4)
1750 inComputeFirstPartials(temp_vertex, du, dv);
1751
1752 #ifdef AVOID_ZERO_NORMAL
1753 if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO)
1754 {
1755
1756 REAL tempdu[4];
1757 REAL tempdata[4];
1758 REAL u1 = em_vertex.u1;
1759 REAL u2 = em_vertex.u2;
1760 if(u-MYDELTA*(u2-u1) < u1)
1761 u = u+ MYDELTA*(u2-u1);
1762 else
1763 u = u-MYDELTA*(u2-u1);
1764 inDoDomain2WithDerivsEM(&em_vertex,u,v, tempdata, tempdu, dv);
1765
1766 if(em_vertex.k ==4)
1767 inComputeFirstPartials(temp_vertex, du, dv);
1768 }
1769 else if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO)
1770 {
1771 REAL tempdv[4];
1772 REAL tempdata[4];
1773 REAL v1 = em_vertex.v1;
1774 REAL v2 = em_vertex.v2;
1775 if(v-MYDELTA*(v2-v1) < v1)
1776 v = v+ MYDELTA*(v2-v1);
1777 else
1778 v = v-MYDELTA*(v2-v1);
1779 inDoDomain2WithDerivsEM(&em_vertex,u,v, tempdata, du, tempdv);
1780
1781 if(em_vertex.k ==4)
1782 inComputeFirstPartials(temp_vertex, du, dv);
1783 }
1784 #endif
1785
1786 /*compute normal*/
1787 switch(em_vertex.k){
1788 case 3:
1789
1790 inComputeNormal2(du, dv, temp_normal);
1791 break;
1792 case 4:
1793
1794 // inComputeFirstPartials(temp_vertex, du, dv);
1795 inComputeNormal2(du, dv, temp_normal);
1796
1797 /*transform the homegeneous coordinate of retPoint into inhomogenous one*/
1798 temp_vertex[0] /= temp_vertex[3];
1799 temp_vertex[1] /= temp_vertex[3];
1800 temp_vertex[2] /= temp_vertex[3];
1801 break;
1802 }
1803 normalCallBack(temp_normal, userData);
1804 temp_vertex[3] = u;
1805 temp_vertex[4] = v;
1806 vertexCallBack(temp_vertex, userData);
1807
1808 }/*end if auto_normal*/
1809 else //no normal map, and no normal callback function
1810 {
1811 if(vertex_flag)
1812 {
1813 inDoDomain2EM(&em_vertex, u,v,temp_vertex);
1814 if(em_vertex.k == 4)
1815 {
1816 temp_vertex[0] /= temp_vertex[3];
1817 temp_vertex[1] /= temp_vertex[3];
1818 temp_vertex[2] /= temp_vertex[3];
1819 }
1820 temp_vertex[3] = u;
1821 temp_vertex[4] = v;
1822 vertexCallBack(temp_vertex, userData);
1823 }
1824 }
1825 }
1826
1827
1828 void OpenGLSurfaceEvaluator::inBPMEvalEM(bezierPatchMesh* bpm)
1829 {
1830 int i,j,k;
1831 float u,v;
1832
1833 int ustride;
1834 int vstride;
1835
1836 #ifdef USE_LOD
1837 if(bpm->bpatch != NULL)
1838 {
1839 bezierPatch* p=bpm->bpatch;
1840 ustride = p->dimension * p->vorder;
1841 vstride = p->dimension;
1842
1843 glMap2f( (p->dimension == 3)? GL_MAP2_VERTEX_3 : GL_MAP2_VERTEX_4,
1844 p->umin,
1845 p->umax,
1846 ustride,
1847 p->uorder,
1848 p->vmin,
1849 p->vmax,
1850 vstride,
1851 p->vorder,
1852 p->ctlpoints);
1853
1854
1855 /*
1856 inMap2fEM(0, p->dimension,
1857 p->umin,
1858 p->umax,
1859 ustride,
1860 p->uorder,
1861 p->vmin,
1862 p->vmax,
1863 vstride,
1864 p->vorder,
1865 p->ctlpoints);
1866 */
1867 }
1868 #else
1869
1870 if(bpm->bpatch != NULL){
1871 bezierPatch* p = bpm->bpatch;
1872 ustride = p->dimension * p->vorder;
1873 vstride = p->dimension;
1874 inMap2fEM(0, p->dimension,
1875 p->umin,
1876 p->umax,
1877 ustride,
1878 p->uorder,
1879 p->vmin,
1880 p->vmax,
1881 vstride,
1882 p->vorder,
1883 p->ctlpoints);
1884 }
1885 if(bpm->bpatch_normal != NULL){
1886 bezierPatch* p = bpm->bpatch_normal;
1887 ustride = p->dimension * p->vorder;
1888 vstride = p->dimension;
1889 inMap2fEM(1, p->dimension,
1890 p->umin,
1891 p->umax,
1892 ustride,
1893 p->uorder,
1894 p->vmin,
1895 p->vmax,
1896 vstride,
1897 p->vorder,
1898 p->ctlpoints);
1899 }
1900 if(bpm->bpatch_color != NULL){
1901 bezierPatch* p = bpm->bpatch_color;
1902 ustride = p->dimension * p->vorder;
1903 vstride = p->dimension;
1904 inMap2fEM(2, p->dimension,
1905 p->umin,
1906 p->umax,
1907 ustride,
1908 p->uorder,
1909 p->vmin,
1910 p->vmax,
1911 vstride,
1912 p->vorder,
1913 p->ctlpoints);
1914 }
1915 if(bpm->bpatch_texcoord != NULL){
1916 bezierPatch* p = bpm->bpatch_texcoord;
1917 ustride = p->dimension * p->vorder;
1918 vstride = p->dimension;
1919 inMap2fEM(3, p->dimension,
1920 p->umin,
1921 p->umax,
1922 ustride,
1923 p->uorder,
1924 p->vmin,
1925 p->vmax,
1926 vstride,
1927 p->vorder,
1928 p->ctlpoints);
1929 }
1930 #endif
1931
1932
1933 k=0;
1934 for(i=0; i<bpm->index_length_array; i++)
1935 {
1936 #ifdef USE_LOD
1937 if(bpm->type_array[i] == GL_POLYGON) //a mesh
1938 {
1939 GLfloat *temp = bpm->UVarray+k;
1940 GLfloat u0 = temp[0];
1941 GLfloat v0 = temp[1];
1942 GLfloat u1 = temp[2];
1943 GLfloat v1 = temp[3];
1944 GLint nu = (GLint) ( temp[4]);
1945 GLint nv = (GLint) ( temp[5]);
1946 GLint umin = (GLint) ( temp[6]);
1947 GLint vmin = (GLint) ( temp[7]);
1948 GLint umax = (GLint) ( temp[8]);
1949 GLint vmax = (GLint) ( temp[9]);
1950
1951 glMapGrid2f(LOD_eval_level*nu, u0, u1, LOD_eval_level*nv, v0, v1);
1952 glEvalMesh2(GL_FILL, LOD_eval_level*umin, LOD_eval_level*umax, LOD_eval_level*vmin, LOD_eval_level*vmax);
1953 }
1954 else
1955 {
1956 LOD_eval(bpm->length_array[i], bpm->UVarray+k, bpm->type_array[i],
1957 0
1958 );
1959 }
1960 k+= 2*bpm->length_array[i];
1961
1962 #else //undef USE_LOD
1963
1964 #ifdef CRACK_TEST
1965 if( bpm->bpatch->umin == 2 && bpm->bpatch->umax == 3
1966 && bpm->bpatch->vmin ==2 && bpm->bpatch->vmax == 3)
1967 {
1968 REAL vertex[4];
1969 REAL normal[4];
1970 #ifdef DEBUG
1971 printf("***number ****1\n");
1972 #endif
1973
1974 beginCallBack(GL_QUAD_STRIP, NULL);
1975 inDoEvalCoord2EM(3.0, 3.0);
1976 inDoEvalCoord2EM(2.0, 3.0);
1977 inDoEvalCoord2EM(3.0, 2.7);
1978 inDoEvalCoord2EM(2.0, 2.7);
1979 inDoEvalCoord2EM(3.0, 2.0);
1980 inDoEvalCoord2EM(2.0, 2.0);
1981 endCallBack(NULL);
1982
1983 beginCallBack(GL_TRIANGLE_STRIP, NULL);
1984 inDoEvalCoord2EM(2.0, 3.0);
1985 inDoEvalCoord2EM(2.0, 2.0);
1986 inDoEvalCoord2EM(2.0, 2.7);
1987 endCallBack(NULL);
1988
1989 }
1990 if( bpm->bpatch->umin == 1 && bpm->bpatch->umax == 2
1991 && bpm->bpatch->vmin ==2 && bpm->bpatch->vmax == 3)
1992 {
1993 #ifdef DEBUG
1994 printf("***number 3\n");
1995 #endif
1996 beginCallBack(GL_QUAD_STRIP, NULL);
1997 inDoEvalCoord2EM(2.0, 3.0);
1998 inDoEvalCoord2EM(1.0, 3.0);
1999 inDoEvalCoord2EM(2.0, 2.3);
2000 inDoEvalCoord2EM(1.0, 2.3);
2001 inDoEvalCoord2EM(2.0, 2.0);
2002 inDoEvalCoord2EM(1.0, 2.0);
2003 endCallBack(NULL);
2004
2005 beginCallBack(GL_TRIANGLE_STRIP, NULL);
2006 inDoEvalCoord2EM(2.0, 2.3);
2007 inDoEvalCoord2EM(2.0, 2.0);
2008 inDoEvalCoord2EM(2.0, 3.0);
2009 endCallBack(NULL);
2010
2011 }
2012 return;
2013 #endif //CRACK_TEST
2014
2015 beginCallBack(bpm->type_array[i], userData);
2016
2017 for(j=0; j<bpm->length_array[i]; j++)
2018 {
2019 u = bpm->UVarray[k];
2020 v = bpm->UVarray[k+1];
2021 #ifdef USE_LOD
2022 LOD_EVAL_COORD(u,v);
2023 // glEvalCoord2f(u,v);
2024 #else
2025
2026 #ifdef GENERIC_TEST
2027 float temp_normal[3];
2028 float temp_vertex[3];
2029 if(temp_signal == 0)
2030 {
2031 gTessVertexSphere(u,v, temp_normal, temp_vertex);
2032 //printf("normal=(%f,%f,%f)\n", temp_normal[0], temp_normal[1], temp_normal[2])//printf("veretx=(%f,%f,%f)\n", temp_vertex[0], temp_vertex[1], temp_vertex[2]);
2033 normalCallBack(temp_normal, userData);
2034 vertexCallBack(temp_vertex, userData);
2035 }
2036 else if(temp_signal == 1)
2037 {
2038 gTessVertexCyl(u,v, temp_normal, temp_vertex);
2039 //printf("normal=(%f,%f,%f)\n", temp_normal[0], temp_normal[1], temp_normal[2])//printf("veretx=(%f,%f,%f)\n", temp_vertex[0], temp_vertex[1], temp_vertex[2]);
2040 normalCallBack(temp_normal, userData);
2041 vertexCallBack(temp_vertex, userData);
2042 }
2043 else
2044 #endif //GENERIC_TEST
2045
2046 inDoEvalCoord2EM(u,v);
2047
2048 #endif //USE_LOD
2049
2050 k += 2;
2051 }
2052 endCallBack(userData);
2053
2054 #endif //USE_LOD
2055 }
2056 }
2057
2058 void OpenGLSurfaceEvaluator::inBPMListEvalEM(bezierPatchMesh* list)
2059 {
2060 bezierPatchMesh* temp;
2061 for(temp = list; temp != NULL; temp = temp->next)
2062 {
2063 inBPMEvalEM(temp);
2064 }
2065 }
2066