source: trunk/src/opengl/glu/nurbs/interface/insurfeval.cpp

Last change on this file was 3079, checked in by jeroen, 26 years ago

* empty log message *

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