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:
10
** http://oss.sgi.com/projects/FreeB
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.
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.
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.
34
** $Date: 2004/05/12 15:29:36 $ $Revision: 1.3 $
37
** $Header: /home/krh/git/sync/mesa-cvs-repo/Mesa/src/glu/sgi/libnurbs/interface/insurfeval.cc,v 1.3 2004/05/12 15:29:36 brianp Exp $
47
#include "glsurfeval.h"
49
//extern int surfcount;
53
#define AVOID_ZERO_NORMAL
55
#ifdef AVOID_ZERO_NORMAL
56
#define myabs(x) ((x>0)? x: (-x))
57
#define MYZERO 0.000001
63
//#define LOD_EVAL_COORD(u,v) inDoEvalCoord2EM(u,v)
64
#define LOD_EVAL_COORD(u,v) glEvalCoord2f(u,v)
66
static void LOD_interpolate(REAL A[2], REAL B[2], REAL C[2], int j, int k, int pow2_level,
71
a = ((REAL) j) / ((REAL) pow2_level);
76
b = ((REAL) k) / ((REAL)j);
90
u = x*A[0] + y*B[0] + z*C[0];
91
v = x*A[1] + y*B[1] + z*C[1];
94
void OpenGLSurfaceEvaluator::LOD_triangle(REAL A[2], REAL B[2], REAL C[2],
102
for(j=0; j<level; j++)
104
for(j=0; j<=pow2_level-1; j++)
108
/* beginCallBack(GL_TRIANGLE_STRIP);*/
109
glBegin(GL_TRIANGLE_STRIP);
110
LOD_interpolate(A,B,C, j+1, j+1, pow2_level, u,v);
113
// glEvalCoord2f(u,v);
115
inDoEvalCoord2EM(u,v);
120
LOD_interpolate(A,B,C,j,j-k,pow2_level, u,v);
123
// glEvalCoord2f(u,v);
125
inDoEvalCoord2EM(u,v);
128
LOD_interpolate(A,B,C,j+1,j-k,pow2_level, u,v);
132
// glEvalCoord2f(u,v);
134
inDoEvalCoord2EM(u,v);
142
void OpenGLSurfaceEvaluator::LOD_eval(int num_vert, REAL* verts, int type,
148
case GL_TRIANGLE_STRIP:
150
for(i=2, k=4; i<=num_vert-2; i+=2, k+=4)
152
LOD_triangle(verts+k-4, verts+k-2, verts+k,
155
LOD_triangle(verts+k-2, verts+k+2, verts+k,
161
LOD_triangle(verts+2*(num_vert-3), verts+2*(num_vert-2), verts+2*(num_vert-1),
166
case GL_TRIANGLE_FAN:
167
for(i=1, k=2; i<=num_vert-2; i++, k+=2)
169
LOD_triangle(verts,verts+k, verts+k+2,
176
fprintf(stderr, "typy not supported in LOD_\n");
183
//#define GENERIC_TEST
185
extern float xmin, xmax, ymin, ymax, zmin, zmax; /*bounding box*/
186
extern int temp_signal;
188
static void gTessVertexSphere(float u, float v, float temp_normal[3], float temp_vertex[3])
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);
208
// glNormal3f(nx,ny,nz);
209
// glVertex3f(x,y,z);
212
static void gTessVertexCyl(float u, float v, float temp_normal[3], float temp_vertex[3])
215
float Ox = 0.5*(xmin+xmax);
216
float Oy = 0.5*(ymin+ymax);
217
float Oz = 0.5*(zmin+zmax);
233
glNormal3f(nx,ny,nz);
238
#endif //GENERIC_TEST
240
void OpenGLSurfaceEvaluator::inBPMListEval(bezierPatchMesh* list)
242
bezierPatchMesh* temp;
243
for(temp = list; temp != NULL; temp = temp->next)
249
void OpenGLSurfaceEvaluator::inBPMEval(bezierPatchMesh* bpm)
254
int ustride = bpm->bpatch->dimension * bpm->bpatch->vorder;
255
int vstride = bpm->bpatch->dimension;
257
(bpm->bpatch->dimension == 3)? GL_MAP2_VERTEX_3 : GL_MAP2_VERTEX_4,
266
bpm->bpatch->ctlpoints);
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);
273
if( global_ev_u1 ==2 && global_ev_u2 == 3
274
&& global_ev_v1 ==2 && global_ev_v2 == 3)
279
printf("***number 1\n");
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);
292
beginCallBack(GL_TRIANGLE_STRIP, NULL);
293
inEvalCoord2f(2.0, 3.0);
294
inEvalCoord2f(2.0, 2.0);
295
inEvalCoord2f(2.0, 2.7);
301
if( global_ev_u1 ==2 && global_ev_u2 == 3
302
&& global_ev_v1 ==1 && global_ev_v2 == 2)
305
printf("***number 2\n");
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);
315
if( global_ev_u1 ==1 && global_ev_u2 == 2
316
&& global_ev_v1 ==2 && global_ev_v2 == 3)
319
printf("***number 3\n");
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);
330
beginCallBack(GL_TRIANGLE_STRIP, NULL);
331
inEvalCoord2f(2.0, 2.3);
332
inEvalCoord2f(2.0, 2.0);
333
inEvalCoord2f(2.0, 3.0);
343
for(i=0; i<bpm->index_length_array; i++)
345
beginCallBack(bpm->type_array[i], userData);
346
for(j=0; j<bpm->length_array[i]; j++)
349
v = bpm->UVarray[k+1];
350
inDoEvalCoord2NOGE(u,v,
352
bpm->normal_array+l);
354
normalCallBack(bpm->normal_array+l, userData);
355
vertexCallBack(bpm->vertex_array+l, userData);
360
endCallBack(userData);
364
void OpenGLSurfaceEvaluator::inEvalPoint2(int i, int j)
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);
377
void OpenGLSurfaceEvaluator::inEvalCoord2f(REAL u, REAL v)
382
inDoEvalCoord2(u,v,point, normal);
387
/*define a grid. store the values into the global variabls:
389
*These values will be used later by evaluating functions
391
void OpenGLSurfaceEvaluator::inMapGrid2f(int nu, REAL u0, REAL u1,
392
int nv, REAL v0, REAL v1)
402
void OpenGLSurfaceEvaluator::inEvalMesh2(int lowU, int lowV, int highU, int highV)
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;
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);
419
for(j=highV; j>=lowV; j--){
420
REAL v1 = (j == global_grid_nv)? global_grid_v1: (global_grid_v0 +j*dv);
422
inDoEvalCoord2(u1, v1, point, normal);
423
inDoEvalCoord2(u2, v1, point, normal);
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);
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);
446
void OpenGLSurfaceEvaluator::inMap2f(int k,
458
REAL *data = global_ev_ctlPoints;
462
if(k == GL_MAP2_VERTEX_3) k=3;
463
else if (k==GL_MAP2_VERTEX_4) k =4;
465
printf("error in inMap2f, maptype=%i is wrong, k,map is not updated\n", 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;
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];
485
ctlPoints += vstride;
488
ctlPoints += ustride - vstride * vorder;
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
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.
503
void OpenGLSurfaceEvaluator::inComputeFirstPartials(REAL *p, REAL *pu, REAL *pv)
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];
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];
514
/*compute the cross product of pu and pv and normalize.
515
*the normal is returned in retNormal
518
* n: return normal, of dimension 3
520
void OpenGLSurfaceEvaluator::inComputeNormal2(REAL *pu, REAL *pv, REAL *n)
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];
528
mag = sqrt(n[0]*n[0] + n[1]*n[1] + n[2]*n[2]);
539
/*Compute point and normal
540
*see the head of inDoDomain2WithDerivs
541
*for the meaning of the arguments
543
void OpenGLSurfaceEvaluator::inDoEvalCoord2(REAL u, REAL v,
544
REAL *retPoint, REAL *retNormal)
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);
555
#ifdef AVOID_ZERO_NORMAL
557
if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO)
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);
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);
570
if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO)
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);
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);
588
inComputeNormal2(du, dv, retNormal);
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];
600
/*output this vertex*/
601
/* inMeshStreamInsert(global_ms, retPoint, retNormal);*/
605
glNormal3fv(retNormal);
606
glVertex3fv(retPoint);
612
printf("vertex(%f,%f,%f)\n", retPoint[0],retPoint[1],retPoint[2]);
619
/*Compute point and normal
620
*see the head of inDoDomain2WithDerivs
621
*for the meaning of the arguments
623
void OpenGLSurfaceEvaluator::inDoEvalCoord2NOGE_BU(REAL u, REAL v,
624
REAL *retPoint, REAL *retNormal)
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);
637
#ifdef AVOID_ZERO_NORMAL
639
if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO)
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);
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);
652
if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO)
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);
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);
669
inComputeNormal2(du, dv, retNormal);
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];
682
/*Compute point and normal
683
*see the head of inDoDomain2WithDerivs
684
*for the meaning of the arguments
686
void OpenGLSurfaceEvaluator::inDoEvalCoord2NOGE_BV(REAL u, REAL v,
687
REAL *retPoint, REAL *retNormal)
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);
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);
701
#ifdef AVOID_ZERO_NORMAL
703
if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO)
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);
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);
716
if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO)
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);
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);
733
inComputeNormal2(du, dv, retNormal);
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];
747
/*Compute point and normal
748
*see the head of inDoDomain2WithDerivs
749
*for the meaning of the arguments
751
void OpenGLSurfaceEvaluator::inDoEvalCoord2NOGE(REAL u, REAL v,
752
REAL *retPoint, REAL *retNormal)
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);
764
#ifdef AVOID_ZERO_NORMAL
766
if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO)
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);
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);
779
if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO)
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);
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);
796
inComputeNormal2(du, dv, retNormal);
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];
807
// glNormal3fv(retNormal);
808
// glVertex3fv(retPoint);
811
void OpenGLSurfaceEvaluator::inPreEvaluateBV(int k, int uorder, int vorder, REAL vprime, REAL *baseData)
817
if(global_vprime != vprime || global_vorder != vorder) {
818
inPreEvaluateWithDeriv(vorder, vprime, global_vcoeff, global_vcoeffDeriv);
819
global_vprime = vprime;
820
global_vorder = vorder;
825
for(row=0; row<uorder; row++){
826
p = global_vcoeff[0] * (*data);
827
pdv = global_vcoeffDeriv[0] * (*data);
829
for(col = 1; col < vorder; col++){
830
p += global_vcoeff[col] * (*data);
831
pdv += global_vcoeffDeriv[col] * (*data);
834
global_BV[row][j] = p;
835
global_PBV[row][j] = pdv;
840
void OpenGLSurfaceEvaluator::inPreEvaluateBU(int k, int uorder, int vorder, REAL uprime, REAL *baseData)
846
if(global_uprime != uprime || global_uorder != uorder) {
847
inPreEvaluateWithDeriv(uorder, uprime, global_ucoeff, global_ucoeffDeriv);
848
global_uprime = uprime;
849
global_uorder = uorder;
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);
859
for(row = 1; row < uorder; row++){
860
p += global_ucoeff[row] * (*data);
861
pdu += global_ucoeffDeriv[row] * (*data);
864
global_BU[col][j] = p;
865
global_PBU[col][j] = pdu;
870
void OpenGLSurfaceEvaluator::inDoDomain2WithDerivsBU(int k, REAL u, REAL v,
871
REAL u1, REAL u2, int uorder,
872
REAL v1, REAL v2, int vorder,
874
REAL *retPoint, REAL* retdu, REAL *retdv)
881
if((u2 == u1) || (v2 == v1))
884
vprime = (v - v1) / (v2 - v1);
887
if(global_vprime != vprime || global_vorder != vorder) {
888
inPreEvaluateWithDeriv(vorder, vprime, global_vcoeff, global_vcoeffDeriv);
889
global_vprime = vprime;
890
global_vorder = vorder;
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];
905
void OpenGLSurfaceEvaluator::inDoDomain2WithDerivsBV(int k, REAL u, REAL v,
906
REAL u1, REAL u2, int uorder,
907
REAL v1, REAL v2, int vorder,
909
REAL *retPoint, REAL* retdu, REAL *retdv)
915
if((u2 == u1) || (v2 == v1))
917
uprime = (u - u1) / (u2 - u1);
920
if(global_uprime != uprime || global_uorder != uorder) {
921
inPreEvaluateWithDeriv(uorder, uprime, global_ucoeff, global_ucoeffDeriv);
922
global_uprime = uprime;
923
global_uorder = uorder;
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];
940
*given a Bezier surface, and parameter (u,v), compute the point in the object space,
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.
951
void OpenGLSurfaceEvaluator::inDoDomain2WithDerivs(int k, REAL u, REAL v,
952
REAL u1, REAL u2, int uorder,
953
REAL v1, REAL v2, int vorder,
955
REAL *retPoint, REAL *retdu, REAL *retdv)
964
if((u2 == u1) || (v2 == v1))
966
uprime = (u - u1) / (u2 - u1);
967
vprime = (v - v1) / (v2 - v1);
969
/* Compute coefficients for values and derivs */
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;
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;
984
for (j = 0; j < k; j++) {
986
retPoint[j] = retdu[j] = retdv[j] = 0.0;
987
for (row = 0; row < uorder; row++) {
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.
993
p = global_vcoeff[0] * (*data);
994
pdv = global_vcoeffDeriv[0] * (*data);
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);
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;
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),
1018
*coeff : coeff[j]=C[n,j](v), this array store the returned values.
1019
*The algorithm is a recursive scheme:
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
1024
void OpenGLSurfaceEvaluator::inPreEvaluate(int order, REAL vprime, REAL *coeff)
1028
REAL oneMinusvprime;
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.
1040
oneMinusvprime = 1-vprime;
1041
coeff[0] = oneMinusvprime;
1043
if (order == 2) return;
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++) {
1050
oldval = coeff[j] * vprime;
1051
coeff[j] = temp + oneMinusvprime * coeff[j];
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:
1064
* dC[n,j](v) = n*(dC[n-1,j-1](v) - dC[n-1,j](v)).
1066
*This code is copied from opengl/soft/so_eval.c:PreEvaluateWidthDeriv
1068
void OpenGLSurfaceEvaluator::inPreEvaluateWithDeriv(int order, REAL vprime,
1069
REAL *coeff, REAL *coeffDeriv)
1073
REAL oneMinusvprime;
1075
oneMinusvprime = 1-vprime;
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.
1083
coeffDeriv[0] = 0.0;
1085
} else if (order == 2) {
1086
coeffDeriv[0] = -1.0;
1087
coeffDeriv[1] = 1.0;
1088
coeff[0] = oneMinusvprime;
1092
coeff[0] = oneMinusvprime;
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++) {
1099
oldval = coeff[j] * vprime;
1100
coeff[j] = temp + oneMinusvprime * coeff[j];
1104
coeffDeriv[0] = -coeff[0];
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.
1112
coeffDeriv[j] = coeff[j-1] - coeff[j];
1114
} while (j < order - 1);
1115
coeffDeriv[j] = coeff[j-1];
1117
oldval = coeff[0] * vprime;
1118
coeff[0] = oneMinusvprime * coeff[0];
1119
for (j = 1; j < i; j++) {
1121
oldval = coeff[j] * vprime;
1122
coeff[j] = temp + oneMinusvprime * coeff[j];
1127
void OpenGLSurfaceEvaluator::inEvalULine(int n_points, REAL v, REAL* u_vals,
1128
int stride, REAL ret_points[][3], REAL ret_normals[][3])
1132
inPreEvaluateBV_intfac(v);
1134
for(i=0,k=0; i<n_points; i++, k += stride)
1136
inDoEvalCoord2NOGE_BV(u_vals[k],v,temp, ret_normals[i]);
1138
ret_points[i][0] = temp[0];
1139
ret_points[i][1] = temp[1];
1140
ret_points[i][2] = temp[2];
1146
void OpenGLSurfaceEvaluator::inEvalVLine(int n_points, REAL u, REAL* v_vals,
1147
int stride, REAL ret_points[][3], REAL ret_normals[][3])
1151
inPreEvaluateBU_intfac(u);
1152
for(i=0,k=0; i<n_points; i++, k += stride)
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];
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
1168
void OpenGLSurfaceEvaluator::inEvalUStrip(int n_upper, REAL v_upper, REAL* upper_val, int n_lower, REAL v_lower, REAL* lower_val)
1172
typedef REAL REAL3[3];
1174
REAL3* upperXYZ = (REAL3*) malloc(sizeof(REAL3)*n_upper);
1176
REAL3* upperNormal = (REAL3*) malloc(sizeof(REAL3) * n_upper);
1177
assert(upperNormal);
1178
REAL3* lowerXYZ = (REAL3*) malloc(sizeof(REAL3)*n_lower);
1180
REAL3* lowerNormal = (REAL3*) malloc(sizeof(REAL3) * n_lower);
1181
assert(lowerNormal);
1183
inEvalULine(n_upper, v_upper, upper_val, 1, upperXYZ, upperNormal);
1184
inEvalULine(n_lower, v_lower, lower_val, 1, lowerXYZ, lowerNormal);
1189
REAL* leftMostNormal;
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 */
1197
/*initialize i,j,and leftMostV
1199
if(upper_val[0] <= lower_val[0])
1204
leftMostV[0] = upper_val[0];
1205
leftMostV[1] = v_upper;
1206
leftMostXYZ = upperXYZ[0];
1207
leftMostNormal = upperNormal[0];
1214
leftMostV[0] = lower_val[0];
1215
leftMostV[1] = v_lower;
1217
leftMostXYZ = lowerXYZ[0];
1218
leftMostNormal = lowerNormal[0];
1222
*the invariance is that:
1223
*at the beginning of each loop, the meaning of i,j,and leftMostV are
1228
if(i >= n_upper) /*case1: no more in upper*/
1230
if(j<n_lower-1) /*at least two vertices in lower*/
1233
glNormal3fv(leftMostNormal);
1234
glVertex3fv(leftMostXYZ);
1237
glNormal3fv(lowerNormal[j]);
1238
glVertex3fv(lowerXYZ[j]);
1244
break; /*exit the main loop*/
1246
else if(j>= n_lower) /*case2: no more in lower*/
1248
if(i<n_upper-1) /*at least two vertices in upper*/
1251
glNormal3fv(leftMostNormal);
1252
glVertex3fv(leftMostXYZ);
1254
for(k=n_upper-1; k>=i; k--) /*reverse order for two-side lighting*/
1256
glNormal3fv(upperNormal[k]);
1257
glVertex3fv(upperXYZ[k]);
1262
break; /*exit the main loop*/
1264
else /* case3: neither is empty, plus the leftMostV, there is at least one triangle to output*/
1266
if(upper_val[i] <= lower_val[j])
1270
glNormal3fv(lowerNormal[j]);
1271
glVertex3fv(lowerXYZ[j]);
1273
/*find the last k>=i such that
1274
*upperverts[k][0] <= lowerverts[j][0]
1280
if(upper_val[k] > lower_val[j])
1288
for(l=k; l>=i; l--)/*the reverse is for two-side lighting*/
1290
glNormal3fv(upperNormal[l]);
1291
glVertex3fv(upperXYZ[l]);
1294
glNormal3fv(leftMostNormal);
1295
glVertex3fv(leftMostXYZ);
1299
/*update i and leftMostV for next loop
1303
leftMostV[0] = upper_val[k];
1304
leftMostV[1] = v_upper;
1305
leftMostNormal = upperNormal[k];
1306
leftMostXYZ = upperXYZ[k];
1308
else /*upperVerts[i][0] > lowerVerts[j][0]*/
1311
glNormal3fv(upperNormal[i]);
1312
glVertex3fv(upperXYZ[i]);
1314
glNormal3fv(leftMostNormal);
1315
glVertex3fv(leftMostXYZ);
1318
/*find the last k>=j such that
1319
*lowerverts[k][0] < upperverts[i][0]
1324
if(lower_val[k] >= upper_val[i])
1326
glNormal3fv(lowerNormal[k]);
1327
glVertex3fv(lowerXYZ[k]);
1333
/*update j and leftMostV for next loop
1336
leftMostV[0] = lower_val[j-1];
1337
leftMostV[1] = v_lower;
1339
leftMostNormal = lowerNormal[j-1];
1340
leftMostXYZ = lowerXYZ[j-1];
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
1357
void OpenGLSurfaceEvaluator::inEvalVStrip(int n_left, REAL u_left, REAL* left_val, int n_right, REAL u_right, REAL* right_val)
1361
typedef REAL REAL3[3];
1363
REAL3* leftXYZ = (REAL3*) malloc(sizeof(REAL3)*n_left);
1365
REAL3* leftNormal = (REAL3*) malloc(sizeof(REAL3) * n_left);
1367
REAL3* rightXYZ = (REAL3*) malloc(sizeof(REAL3)*n_right);
1369
REAL3* rightNormal = (REAL3*) malloc(sizeof(REAL3) * n_right);
1370
assert(rightNormal);
1372
inEvalVLine(n_left, u_left, left_val, 1, leftXYZ, leftNormal);
1373
inEvalVLine(n_right, u_right, right_val, 1, rightXYZ, rightNormal);
1378
REAL* botMostNormal;
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 */
1387
/*initialize i,j,and botMostV
1389
if(left_val[0] <= right_val[0])
1394
botMostV[0] = u_left;
1395
botMostV[1] = left_val[0];
1396
botMostXYZ = leftXYZ[0];
1397
botMostNormal = leftNormal[0];
1404
botMostV[0] = u_right;
1405
botMostV[1] = right_val[0];
1407
botMostXYZ = rightXYZ[0];
1408
botMostNormal = rightNormal[0];
1412
*the invariance is that:
1413
*at the beginning of each loop, the meaning of i,j,and botMostV are
1418
if(i >= n_left) /*case1: no more in left*/
1420
if(j<n_right-1) /*at least two vertices in right*/
1423
glNormal3fv(botMostNormal);
1424
glVertex3fv(botMostXYZ);
1427
glNormal3fv(rightNormal[j]);
1428
glVertex3fv(rightXYZ[j]);
1434
break; /*exit the main loop*/
1436
else if(j>= n_right) /*case2: no more in right*/
1438
if(i<n_left-1) /*at least two vertices in left*/
1441
glNormal3fv(botMostNormal);
1442
glVertex3fv(botMostXYZ);
1444
for(k=n_left-1; k>=i; k--) /*reverse order for two-side lighting*/
1446
glNormal3fv(leftNormal[k]);
1447
glVertex3fv(leftXYZ[k]);
1452
break; /*exit the main loop*/
1454
else /* case3: neither is empty, plus the botMostV, there is at least one triangle to output*/
1456
if(left_val[i] <= right_val[j])
1460
glNormal3fv(rightNormal[j]);
1461
glVertex3fv(rightXYZ[j]);
1463
/*find the last k>=i such that
1464
*leftverts[k][0] <= rightverts[j][0]
1470
if(left_val[k] > right_val[j])
1478
for(l=k; l>=i; l--)/*the reverse is for two-side lighting*/
1480
glNormal3fv(leftNormal[l]);
1481
glVertex3fv(leftXYZ[l]);
1484
glNormal3fv(botMostNormal);
1485
glVertex3fv(botMostXYZ);
1489
/*update i and botMostV for next loop
1493
botMostV[0] = u_left;
1494
botMostV[1] = left_val[k];
1495
botMostNormal = leftNormal[k];
1496
botMostXYZ = leftXYZ[k];
1498
else /*left_val[i] > right_val[j])*/
1501
glNormal3fv(leftNormal[i]);
1502
glVertex3fv(leftXYZ[i]);
1504
glNormal3fv(botMostNormal);
1505
glVertex3fv(botMostXYZ);
1508
/*find the last k>=j such that
1509
*rightverts[k][0] < leftverts[i][0]
1514
if(right_val[k] >= left_val[i])
1516
glNormal3fv(rightNormal[k]);
1517
glVertex3fv(rightXYZ[k]);
1523
/*update j and botMostV for next loop
1526
botMostV[0] = u_right;
1527
botMostV[1] = right_val[j-1];
1529
botMostNormal = rightNormal[j-1];
1530
botMostXYZ = rightXYZ[j-1];
1541
/*-----------------------begin evalMachine-------------------*/
1542
void OpenGLSurfaceEvaluator::inMap2fEM(int which, int k,
1554
surfEvalMachine *temp_em;
1558
temp_em = &em_vertex;
1562
temp_em = &em_normal;
1566
temp_em = &em_color;
1570
temp_em = &em_texcoord;
1574
REAL *data = temp_em->ctlPoints;
1576
temp_em->uprime = -1;//initilized
1577
temp_em->vprime = -1;
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;
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];
1595
ctlPoints += vstride;
1598
ctlPoints += ustride - vstride * vorder;
1602
void OpenGLSurfaceEvaluator::inDoDomain2WithDerivsEM(surfEvalMachine *em, REAL u, REAL v,
1603
REAL *retPoint, REAL *retdu, REAL *retdv)
1612
if((em->u2 == em->u1) || (em->v2 == em->v1))
1614
the_uprime = (u - em->u1) / (em->u2 - em->u1);
1615
the_vprime = (v - em->v1) / (em->v2 - em->v1);
1617
/* Compute coefficients for values and derivs */
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;
1624
if (em->vprime != the_vprime) {
1625
inPreEvaluateWithDeriv(em->vorder, the_vprime, em->vcoeff, em->vcoeffDeriv);
1626
em->vprime = the_vprime;
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++) {
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.
1638
p = em->vcoeff[0] * (*data);
1639
pdv = em->vcoeffDeriv[0] * (*data);
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);
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;
1655
void OpenGLSurfaceEvaluator::inDoDomain2EM(surfEvalMachine *em, REAL u, REAL v,
1664
if((em->u2 == em->u1) || (em->v2 == em->v1))
1666
the_uprime = (u - em->u1) / (em->u2 - em->u1);
1667
the_vprime = (v - em->v1) / (em->v2 - em->v1);
1669
/* Compute coefficients for values and derivs */
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;
1676
if (em->vprime != the_vprime) {
1677
inPreEvaluate(em->vorder, the_vprime, em->vcoeff);
1678
em->vprime = the_vprime;
1681
for (j = 0; j < em->k; j++) {
1682
data=em->ctlPoints+j;
1684
for (row = 0; row < em->uorder; row++) {
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.
1690
p = em->vcoeff[0] * (*data);
1692
for (col = 1; col < em->vorder; col++) {
1693
/* Incrementally build up p, pdv value */
1694
p += em->vcoeff[col] * (*data);
1697
/* Use p, pdv value to incrementally add up r, du, dv */
1698
retPoint[j] += em->ucoeff[row] * p;
1704
void OpenGLSurfaceEvaluator::inDoEvalCoord2EM(REAL u, REAL v)
1706
REAL temp_vertex[5];
1707
REAL temp_normal[3];
1709
REAL temp_texcoord[4];
1713
inDoDomain2EM(&em_texcoord, u,v, temp_texcoord);
1714
texcoordCallBack(temp_texcoord, userData);
1718
inDoDomain2EM(&em_color, u,v, temp_color);
1719
colorCallBack(temp_color, userData);
1722
if(normal_flag) //there is a normla map
1724
inDoDomain2EM(&em_normal, u,v, temp_normal);
1725
normalCallBack(temp_normal, userData);
1729
inDoDomain2EM(&em_vertex, u,v,temp_vertex);
1730
if(em_vertex.k == 4)
1732
temp_vertex[0] /= temp_vertex[3];
1733
temp_vertex[1] /= temp_vertex[3];
1734
temp_vertex[2] /= temp_vertex[3];
1738
vertexCallBack(temp_vertex, userData);
1741
else if(auto_normal_flag) //no normal map but there is a normal callbackfunctin
1746
/*compute homegeneous point and partial derivatives*/
1747
inDoDomain2WithDerivsEM(&em_vertex, u,v,temp_vertex,du,dv);
1750
inComputeFirstPartials(temp_vertex, du, dv);
1752
#ifdef AVOID_ZERO_NORMAL
1753
if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO)
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);
1763
u = u-MYDELTA*(u2-u1);
1764
inDoDomain2WithDerivsEM(&em_vertex,u,v, tempdata, tempdu, dv);
1767
inComputeFirstPartials(temp_vertex, du, dv);
1769
else if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO)
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);
1778
v = v-MYDELTA*(v2-v1);
1779
inDoDomain2WithDerivsEM(&em_vertex,u,v, tempdata, du, tempdv);
1782
inComputeFirstPartials(temp_vertex, du, dv);
1787
switch(em_vertex.k){
1790
inComputeNormal2(du, dv, temp_normal);
1794
// inComputeFirstPartials(temp_vertex, du, dv);
1795
inComputeNormal2(du, dv, temp_normal);
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];
1803
normalCallBack(temp_normal, userData);
1806
vertexCallBack(temp_vertex, userData);
1808
}/*end if auto_normal*/
1809
else //no normal map, and no normal callback function
1813
inDoDomain2EM(&em_vertex, u,v,temp_vertex);
1814
if(em_vertex.k == 4)
1816
temp_vertex[0] /= temp_vertex[3];
1817
temp_vertex[1] /= temp_vertex[3];
1818
temp_vertex[2] /= temp_vertex[3];
1822
vertexCallBack(temp_vertex, userData);
1828
void OpenGLSurfaceEvaluator::inBPMEvalEM(bezierPatchMesh* bpm)
1837
if(bpm->bpatch != NULL)
1839
bezierPatch* p=bpm->bpatch;
1840
ustride = p->dimension * p->vorder;
1841
vstride = p->dimension;
1843
glMap2f( (p->dimension == 3)? GL_MAP2_VERTEX_3 : GL_MAP2_VERTEX_4,
1856
inMap2fEM(0, p->dimension,
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,
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,
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,
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,
1934
for(i=0; i<bpm->index_length_array; i++)
1937
if(bpm->type_array[i] == GL_POLYGON) //a mesh
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]);
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);
1956
LOD_eval(bpm->length_array[i], bpm->UVarray+k, bpm->type_array[i],
1960
k+= 2*bpm->length_array[i];
1962
#else //undef USE_LOD
1965
if( bpm->bpatch->umin == 2 && bpm->bpatch->umax == 3
1966
&& bpm->bpatch->vmin ==2 && bpm->bpatch->vmax == 3)
1971
printf("***number ****1\n");
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);
1983
beginCallBack(GL_TRIANGLE_STRIP, NULL);
1984
inDoEvalCoord2EM(2.0, 3.0);
1985
inDoEvalCoord2EM(2.0, 2.0);
1986
inDoEvalCoord2EM(2.0, 2.7);
1990
if( bpm->bpatch->umin == 1 && bpm->bpatch->umax == 2
1991
&& bpm->bpatch->vmin ==2 && bpm->bpatch->vmax == 3)
1994
printf("***number 3\n");
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);
2005
beginCallBack(GL_TRIANGLE_STRIP, NULL);
2006
inDoEvalCoord2EM(2.0, 2.3);
2007
inDoEvalCoord2EM(2.0, 2.0);
2008
inDoEvalCoord2EM(2.0, 3.0);
2015
beginCallBack(bpm->type_array[i], userData);
2017
for(j=0; j<bpm->length_array[i]; j++)
2019
u = bpm->UVarray[k];
2020
v = bpm->UVarray[k+1];
2022
LOD_EVAL_COORD(u,v);
2023
// glEvalCoord2f(u,v);
2027
float temp_normal[3];
2028
float temp_vertex[3];
2029
if(temp_signal == 0)
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);
2036
else if(temp_signal == 1)
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);
2044
#endif //GENERIC_TEST
2046
inDoEvalCoord2EM(u,v);
2052
endCallBack(userData);
2058
void OpenGLSurfaceEvaluator::inBPMListEvalEM(bezierPatchMesh* list)
2060
bezierPatchMesh* temp;
2061
for(temp = list; temp != NULL; temp = temp->next)