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.
45 #include "glsurfeval.h"
47 //extern int surfcount;
51 #define AVOID_ZERO_NORMAL
53 #ifdef AVOID_ZERO_NORMAL
54 #define myabs(x) ((x>0)? x: (-x))
55 #define MYZERO 0.000001
61 //#define LOD_EVAL_COORD(u,v) inDoEvalCoord2EM(u,v)
62 #define LOD_EVAL_COORD(u,v) glEvalCoord2f(u,v)
64 static void LOD_interpolate(REAL A[2], REAL B[2], REAL C[2], int j, int k, int pow2_level,
69 a = ((REAL) j) / ((REAL) pow2_level);
74 b = ((REAL) k) / ((REAL)j);
88 u = x*A[0] + y*B[0] + z*C[0];
89 v = x*A[1] + y*B[1] + z*C[1];
92 void OpenGLSurfaceEvaluator::LOD_triangle(REAL A[2], REAL B[2], REAL C[2],
100 for(j=0; j<level; j++)
102 for(j=0; j<=pow2_level-1; j++)
106 /* beginCallBack(GL_TRIANGLE_STRIP);*/
107 glBegin(GL_TRIANGLE_STRIP);
108 LOD_interpolate(A,B,C, j+1, j+1, pow2_level, u,v);
111 // glEvalCoord2f(u,v);
113 inDoEvalCoord2EM(u,v);
118 LOD_interpolate(A,B,C,j,j-k,pow2_level, u,v);
121 // glEvalCoord2f(u,v);
123 inDoEvalCoord2EM(u,v);
126 LOD_interpolate(A,B,C,j+1,j-k,pow2_level, u,v);
130 // glEvalCoord2f(u,v);
132 inDoEvalCoord2EM(u,v);
140 void OpenGLSurfaceEvaluator::LOD_eval(int num_vert, REAL* verts, int type,
146 case GL_TRIANGLE_STRIP:
148 for(i=2, k=4; i<=num_vert-2; i+=2, k+=4)
150 LOD_triangle(verts+k-4, verts+k-2, verts+k,
153 LOD_triangle(verts+k-2, verts+k+2, verts+k,
159 LOD_triangle(verts+2*(num_vert-3), verts+2*(num_vert-2), verts+2*(num_vert-1),
164 case GL_TRIANGLE_FAN:
165 for(i=1, k=2; i<=num_vert-2; i++, k+=2)
167 LOD_triangle(verts,verts+k, verts+k+2,
174 fprintf(stderr, "typy not supported in LOD_\n");
181 //#define GENERIC_TEST
183 extern float xmin, xmax, ymin, ymax, zmin, zmax; /*bounding box*/
184 extern int temp_signal;
186 static void gTessVertexSphere(float u, float v, float temp_normal[3], float temp_vertex[3])
189 float Ox = 0.5*(xmin+xmax);
190 float Oy = 0.5*(ymin+ymax);
191 float Oz = 0.5*(zmin+zmax);
192 float nx = cos(v) * sin(u);
193 float ny = sin(v) * sin(u);
206 // glNormal3f(nx,ny,nz);
207 // glVertex3f(x,y,z);
210 static void gTessVertexCyl(float u, float v, float temp_normal[3], float temp_vertex[3])
213 float Ox = 0.5*(xmin+xmax);
214 float Oy = 0.5*(ymin+ymax);
215 float Oz = 0.5*(zmin+zmax);
231 glNormal3f(nx,ny,nz);
236 #endif //GENERIC_TEST
238 void OpenGLSurfaceEvaluator::inBPMListEval(bezierPatchMesh* list)
240 bezierPatchMesh* temp;
241 for(temp = list; temp != NULL; temp = temp->next)
247 void OpenGLSurfaceEvaluator::inBPMEval(bezierPatchMesh* bpm)
252 int ustride = bpm->bpatch->dimension * bpm->bpatch->vorder;
253 int vstride = bpm->bpatch->dimension;
255 (bpm->bpatch->dimension == 3)? GL_MAP2_VERTEX_3 : GL_MAP2_VERTEX_4,
264 bpm->bpatch->ctlpoints);
266 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.*/
267 assert(bpm->vertex_array);
268 bpm->normal_array = (float*) malloc(sizeof(float)* (bpm->index_UVarray/2) * 3);
269 assert(bpm->normal_array);
271 if( global_ev_u1 ==2 && global_ev_u2 == 3
272 && global_ev_v1 ==2 && global_ev_v2 == 3)
277 printf("***number 1\n");
280 beginCallBack(GL_QUAD_STRIP, NULL);
281 inEvalCoord2f(3.0, 3.0);
282 inEvalCoord2f(2.0, 3.0);
283 inEvalCoord2f(3.0, 2.7);
284 inEvalCoord2f(2.0, 2.7);
285 inEvalCoord2f(3.0, 2.0);
286 inEvalCoord2f(2.0, 2.0);
290 beginCallBack(GL_TRIANGLE_STRIP, NULL);
291 inEvalCoord2f(2.0, 3.0);
292 inEvalCoord2f(2.0, 2.0);
293 inEvalCoord2f(2.0, 2.7);
299 if( global_ev_u1 ==2 && global_ev_u2 == 3
300 && global_ev_v1 ==1 && global_ev_v2 == 2)
303 printf("***number 2\n");
305 beginCallBack(GL_QUAD_STRIP);
306 inEvalCoord2f(2.0, 2.0);
307 inEvalCoord2f(2.0, 1.0);
308 inEvalCoord2f(3.0, 2.0);
309 inEvalCoord2f(3.0, 1.0);
313 if( global_ev_u1 ==1 && global_ev_u2 == 2
314 && global_ev_v1 ==2 && global_ev_v2 == 3)
317 printf("***number 3\n");
319 beginCallBack(GL_QUAD_STRIP, NULL);
320 inEvalCoord2f(2.0, 3.0);
321 inEvalCoord2f(1.0, 3.0);
322 inEvalCoord2f(2.0, 2.3);
323 inEvalCoord2f(1.0, 2.3);
324 inEvalCoord2f(2.0, 2.0);
325 inEvalCoord2f(1.0, 2.0);
328 beginCallBack(GL_TRIANGLE_STRIP, NULL);
329 inEvalCoord2f(2.0, 2.3);
330 inEvalCoord2f(2.0, 2.0);
331 inEvalCoord2f(2.0, 3.0);
341 for(i=0; i<bpm->index_length_array; i++)
343 beginCallBack(bpm->type_array[i], userData);
344 for(j=0; j<bpm->length_array[i]; j++)
347 v = bpm->UVarray[k+1];
348 inDoEvalCoord2NOGE(u,v,
350 bpm->normal_array+l);
352 normalCallBack(bpm->normal_array+l, userData);
353 vertexCallBack(bpm->vertex_array+l, userData);
358 endCallBack(userData);
362 void OpenGLSurfaceEvaluator::inEvalPoint2(int i, int j)
368 du = (global_grid_u1 - global_grid_u0) / (REAL)global_grid_nu;
369 dv = (global_grid_v1 - global_grid_v0) / (REAL)global_grid_nv;
370 u = (i==global_grid_nu)? global_grid_u1:(global_grid_u0 + i*du);
371 v = (j == global_grid_nv)? global_grid_v1: (global_grid_v0 +j*dv);
372 inDoEvalCoord2(u,v,point,normal);
375 void OpenGLSurfaceEvaluator::inEvalCoord2f(REAL u, REAL v)
380 inDoEvalCoord2(u,v,point, normal);
385 /*define a grid. store the values into the global variabls:
387 *These values will be used later by evaluating functions
389 void OpenGLSurfaceEvaluator::inMapGrid2f(int nu, REAL u0, REAL u1,
390 int nv, REAL v0, REAL v1)
400 void OpenGLSurfaceEvaluator::inEvalMesh2(int lowU, int lowV, int highU, int highV)
406 if(global_grid_nu == 0 || global_grid_nv == 0)
407 return; /*no points need to be output*/
408 du = (global_grid_u1 - global_grid_u0) / (REAL)global_grid_nu;
409 dv = (global_grid_v1 - global_grid_v0) / (REAL)global_grid_nv;
411 if(global_grid_nu >= global_grid_nv){
412 for(i=lowU; i<highU; i++){
413 REAL u1 = (i==global_grid_nu)? global_grid_u1:(global_grid_u0 + i*du);
414 REAL u2 = ((i+1) == global_grid_nu)? global_grid_u1: (global_grid_u0+(i+1)*du);
417 for(j=highV; j>=lowV; j--){
418 REAL v1 = (j == global_grid_nv)? global_grid_v1: (global_grid_v0 +j*dv);
420 inDoEvalCoord2(u1, v1, point, normal);
421 inDoEvalCoord2(u2, v1, point, normal);
428 for(i=lowV; i<highV; i++){
429 REAL v1 = (i==global_grid_nv)? global_grid_v1:(global_grid_v0 + i*dv);
430 REAL v2 = ((i+1) == global_grid_nv)? global_grid_v1: (global_grid_v0+(i+1)*dv);
433 for(j=highU; j>=lowU; j--){
434 REAL u1 = (j == global_grid_nu)? global_grid_u1: (global_grid_u0 +j*du);
435 inDoEvalCoord2(u1, v2, point, normal);
436 inDoEvalCoord2(u1, v1, point, normal);
444 void OpenGLSurfaceEvaluator::inMap2f(int k,
456 REAL *data = global_ev_ctlPoints;
460 if(k == GL_MAP2_VERTEX_3) k=3;
461 else if (k==GL_MAP2_VERTEX_4) k =4;
463 printf("error in inMap2f, maptype=%i is wrong, k,map is not updated\n", k);
468 global_ev_u1 = ulower;
469 global_ev_u2 = uupper;
470 global_ev_ustride = ustride;
471 global_ev_uorder = uorder;
472 global_ev_v1 = vlower;
473 global_ev_v2 = vupper;
474 global_ev_vstride = vstride;
475 global_ev_vorder = vorder;
477 /*copy the contrl points from ctlPoints to global_ev_ctlPoints*/
478 for (i=0; i<uorder; i++) {
479 for (j=0; j<vorder; j++) {
480 for (x=0; x<k; x++) {
481 data[x] = ctlPoints[x];
483 ctlPoints += vstride;
486 ctlPoints += ustride - vstride * vorder;
493 *given a point p with homegeneous coordiante (x,y,z,w),
494 *let pu(x,y,z,w) be its partial derivative vector with
496 *and pv(x,y,z,w) be its partial derivative vector with repect to v.
497 *This function returns the partial derivative vectors of the
498 *inhomegensous coordinates, i.e.,
499 * (x/w, y/w, z/w) with respect to u and v.
501 void OpenGLSurfaceEvaluator::inComputeFirstPartials(REAL *p, REAL *pu, REAL *pv)
503 pu[0] = pu[0]*p[3] - pu[3]*p[0];
504 pu[1] = pu[1]*p[3] - pu[3]*p[1];
505 pu[2] = pu[2]*p[3] - pu[3]*p[2];
507 pv[0] = pv[0]*p[3] - pv[3]*p[0];
508 pv[1] = pv[1]*p[3] - pv[3]*p[1];
509 pv[2] = pv[2]*p[3] - pv[3]*p[2];
512 /*compute the cross product of pu and pv and normalize.
513 *the normal is returned in retNormal
516 * n: return normal, of dimension 3
518 void OpenGLSurfaceEvaluator::inComputeNormal2(REAL *pu, REAL *pv, REAL *n)
522 n[0] = pu[1]*pv[2] - pu[2]*pv[1];
523 n[1] = pu[2]*pv[0] - pu[0]*pv[2];
524 n[2] = pu[0]*pv[1] - pu[1]*pv[0];
526 mag = sqrt(n[0]*n[0] + n[1]*n[1] + n[2]*n[2]);
537 /*Compute point and normal
538 *see the head of inDoDomain2WithDerivs
539 *for the meaning of the arguments
541 void OpenGLSurfaceEvaluator::inDoEvalCoord2(REAL u, REAL v,
542 REAL *retPoint, REAL *retNormal)
549 assert(global_ev_k>=3 && global_ev_k <= 4);
550 /*compute homegeneous point and partial derivatives*/
551 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);
553 #ifdef AVOID_ZERO_NORMAL
555 if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO)
560 REAL u1 = global_ev_u1;
561 REAL u2 = global_ev_u2;
562 if(u-MYDELTA*(u2-u1) < u1)
563 u = u+ MYDELTA*(u2-u1);
565 u = u-MYDELTA*(u2-u1);
566 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);
568 if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO)
572 REAL v1 = global_ev_v1;
573 REAL v2 = global_ev_v2;
574 if(v-MYDELTA*(v2-v1) < v1)
575 v = v+ MYDELTA*(v2-v1);
577 v = v-MYDELTA*(v2-v1);
578 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);
586 inComputeNormal2(du, dv, retNormal);
590 inComputeFirstPartials(retPoint, du, dv);
591 inComputeNormal2(du, dv, retNormal);
592 /*transform the homegeneous coordinate of retPoint into inhomogenous one*/
593 retPoint[0] /= retPoint[3];
594 retPoint[1] /= retPoint[3];
595 retPoint[2] /= retPoint[3];
598 /*output this vertex*/
599 /* inMeshStreamInsert(global_ms, retPoint, retNormal);*/
603 glNormal3fv(retNormal);
604 glVertex3fv(retPoint);
610 printf("vertex(%f,%f,%f)\n", retPoint[0],retPoint[1],retPoint[2]);
617 /*Compute point and normal
618 *see the head of inDoDomain2WithDerivs
619 *for the meaning of the arguments
621 void OpenGLSurfaceEvaluator::inDoEvalCoord2NOGE_BU(REAL u, REAL v,
622 REAL *retPoint, REAL *retNormal)
629 assert(global_ev_k>=3 && global_ev_k <= 4);
630 /*compute homegeneous point and partial derivatives*/
631 // inPreEvaluateBU(global_ev_k, global_ev_uorder, global_ev_vorder, (u-global_ev_u1)/(global_ev_u2-global_ev_u1), global_ev_ctlPoints);
632 inDoDomain2WithDerivsBU(global_ev_k, u, v, global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, retPoint, du, dv);
635 #ifdef AVOID_ZERO_NORMAL
637 if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO)
642 REAL u1 = global_ev_u1;
643 REAL u2 = global_ev_u2;
644 if(u-MYDELTA*(u2-u1) < u1)
645 u = u+ MYDELTA*(u2-u1);
647 u = u-MYDELTA*(u2-u1);
648 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);
650 if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO)
654 REAL v1 = global_ev_v1;
655 REAL v2 = global_ev_v2;
656 if(v-MYDELTA*(v2-v1) < v1)
657 v = v+ MYDELTA*(v2-v1);
659 v = v-MYDELTA*(v2-v1);
660 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);
667 inComputeNormal2(du, dv, retNormal);
670 inComputeFirstPartials(retPoint, du, dv);
671 inComputeNormal2(du, dv, retNormal);
672 /*transform the homegeneous coordinate of retPoint into inhomogenous one*/
673 retPoint[0] /= retPoint[3];
674 retPoint[1] /= retPoint[3];
675 retPoint[2] /= retPoint[3];
680 /*Compute point and normal
681 *see the head of inDoDomain2WithDerivs
682 *for the meaning of the arguments
684 void OpenGLSurfaceEvaluator::inDoEvalCoord2NOGE_BV(REAL u, REAL v,
685 REAL *retPoint, REAL *retNormal)
692 assert(global_ev_k>=3 && global_ev_k <= 4);
693 /*compute homegeneous point and partial derivatives*/
694 // inPreEvaluateBV(global_ev_k, global_ev_uorder, global_ev_vorder, (v-global_ev_v1)/(global_ev_v2-global_ev_v1), global_ev_ctlPoints);
696 inDoDomain2WithDerivsBV(global_ev_k, u, v, global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, retPoint, du, dv);
699 #ifdef AVOID_ZERO_NORMAL
701 if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO)
706 REAL u1 = global_ev_u1;
707 REAL u2 = global_ev_u2;
708 if(u-MYDELTA*(u2-u1) < u1)
709 u = u+ MYDELTA*(u2-u1);
711 u = u-MYDELTA*(u2-u1);
712 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);
714 if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO)
718 REAL v1 = global_ev_v1;
719 REAL v2 = global_ev_v2;
720 if(v-MYDELTA*(v2-v1) < v1)
721 v = v+ MYDELTA*(v2-v1);
723 v = v-MYDELTA*(v2-v1);
724 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);
731 inComputeNormal2(du, dv, retNormal);
734 inComputeFirstPartials(retPoint, du, dv);
735 inComputeNormal2(du, dv, retNormal);
736 /*transform the homegeneous coordinate of retPoint into inhomogenous one*/
737 retPoint[0] /= retPoint[3];
738 retPoint[1] /= retPoint[3];
739 retPoint[2] /= retPoint[3];
745 /*Compute point and normal
746 *see the head of inDoDomain2WithDerivs
747 *for the meaning of the arguments
749 void OpenGLSurfaceEvaluator::inDoEvalCoord2NOGE(REAL u, REAL v,
750 REAL *retPoint, REAL *retNormal)
757 assert(global_ev_k>=3 && global_ev_k <= 4);
758 /*compute homegeneous point and partial derivatives*/
759 inDoDomain2WithDerivs(global_ev_k, u, v, global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, retPoint, du, dv);
762 #ifdef AVOID_ZERO_NORMAL
764 if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO)
769 REAL u1 = global_ev_u1;
770 REAL u2 = global_ev_u2;
771 if(u-MYDELTA*(u2-u1) < u1)
772 u = u+ MYDELTA*(u2-u1);
774 u = u-MYDELTA*(u2-u1);
775 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);
777 if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO)
781 REAL v1 = global_ev_v1;
782 REAL v2 = global_ev_v2;
783 if(v-MYDELTA*(v2-v1) < v1)
784 v = v+ MYDELTA*(v2-v1);
786 v = v-MYDELTA*(v2-v1);
787 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);
794 inComputeNormal2(du, dv, retNormal);
797 inComputeFirstPartials(retPoint, du, dv);
798 inComputeNormal2(du, dv, retNormal);
799 /*transform the homegeneous coordinate of retPoint into inhomogenous one*/
800 retPoint[0] /= retPoint[3];
801 retPoint[1] /= retPoint[3];
802 retPoint[2] /= retPoint[3];
805 // glNormal3fv(retNormal);
806 // glVertex3fv(retPoint);
809 void OpenGLSurfaceEvaluator::inPreEvaluateBV(int k, int uorder, int vorder, REAL vprime, REAL *baseData)
815 if(global_vprime != vprime || global_vorder != vorder) {
816 inPreEvaluateWithDeriv(vorder, vprime, global_vcoeff, global_vcoeffDeriv);
817 global_vprime = vprime;
818 global_vorder = vorder;
823 for(row=0; row<uorder; row++){
824 p = global_vcoeff[0] * (*data);
825 pdv = global_vcoeffDeriv[0] * (*data);
827 for(col = 1; col < vorder; col++){
828 p += global_vcoeff[col] * (*data);
829 pdv += global_vcoeffDeriv[col] * (*data);
832 global_BV[row][j] = p;
833 global_PBV[row][j] = pdv;
838 void OpenGLSurfaceEvaluator::inPreEvaluateBU(int k, int uorder, int vorder, REAL uprime, REAL *baseData)
844 if(global_uprime != uprime || global_uorder != uorder) {
845 inPreEvaluateWithDeriv(uorder, uprime, global_ucoeff, global_ucoeffDeriv);
846 global_uprime = uprime;
847 global_uorder = uorder;
852 for(col=0; col<vorder; col++){
853 data = baseData+j + k*col;
854 p = global_ucoeff[0] * (*data);
855 pdu = global_ucoeffDeriv[0] * (*data);
857 for(row = 1; row < uorder; row++){
858 p += global_ucoeff[row] * (*data);
859 pdu += global_ucoeffDeriv[row] * (*data);
862 global_BU[col][j] = p;
863 global_PBU[col][j] = pdu;
868 void OpenGLSurfaceEvaluator::inDoDomain2WithDerivsBU(int k, REAL u, REAL v,
869 REAL u1, REAL u2, int uorder,
870 REAL v1, REAL v2, int vorder,
872 REAL *retPoint, REAL* retdu, REAL *retdv)
879 if((u2 == u1) || (v2 == v1))
882 vprime = (v - v1) / (v2 - v1);
885 if(global_vprime != vprime || global_vorder != vorder) {
886 inPreEvaluateWithDeriv(vorder, vprime, global_vcoeff, global_vcoeffDeriv);
887 global_vprime = vprime;
888 global_vorder = vorder;
894 retPoint[j] = retdu[j] = retdv[j] = 0.0;
895 for (col = 0; col < vorder; col++) {
896 retPoint[j] += global_BU[col][j] * global_vcoeff[col];
897 retdu[j] += global_PBU[col][j] * global_vcoeff[col];
898 retdv[j] += global_BU[col][j] * global_vcoeffDeriv[col];
903 void OpenGLSurfaceEvaluator::inDoDomain2WithDerivsBV(int k, REAL u, REAL v,
904 REAL u1, REAL u2, int uorder,
905 REAL v1, REAL v2, int vorder,
907 REAL *retPoint, REAL* retdu, REAL *retdv)
913 if((u2 == u1) || (v2 == v1))
915 uprime = (u - u1) / (u2 - u1);
918 if(global_uprime != uprime || global_uorder != uorder) {
919 inPreEvaluateWithDeriv(uorder, uprime, global_ucoeff, global_ucoeffDeriv);
920 global_uprime = uprime;
921 global_uorder = uorder;
927 retPoint[j] = retdu[j] = retdv[j] = 0.0;
928 for (row = 0; row < uorder; row++) {
929 retPoint[j] += global_BV[row][j] * global_ucoeff[row];
930 retdu[j] += global_BV[row][j] * global_ucoeffDeriv[row];
931 retdv[j] += global_PBV[row][j] * global_ucoeff[row];
938 *given a Bezier surface, and parameter (u,v), compute the point in the object space,
940 *k: the dimension of the object space: usually 2,3,or 4.
941 *u,v: the paramter pair.
942 *u1,u2,uorder: the Bezier polynomial of u coord is defined on [u1,u2] with order uorder.
943 *v1,v2,vorder: the Bezier polynomial of v coord is defined on [v1,v2] with order vorder.
944 *baseData: contrl points. arranged as: (u,v,k).
945 *retPoint: the computed point (one point) with dimension k.
946 *retdu: the computed partial derivative with respect to u.
947 *retdv: the computed partial derivative with respect to v.
949 void OpenGLSurfaceEvaluator::inDoDomain2WithDerivs(int k, REAL u, REAL v,
950 REAL u1, REAL u2, int uorder,
951 REAL v1, REAL v2, int vorder,
953 REAL *retPoint, REAL *retdu, REAL *retdv)
962 if((u2 == u1) || (v2 == v1))
964 uprime = (u - u1) / (u2 - u1);
965 vprime = (v - v1) / (v2 - v1);
967 /* Compute coefficients for values and derivs */
969 /* Use already cached values if possible */
970 if(global_uprime != uprime || global_uorder != uorder) {
971 inPreEvaluateWithDeriv(uorder, uprime, global_ucoeff, global_ucoeffDeriv);
972 global_uorder = uorder;
973 global_uprime = uprime;
975 if (global_vprime != vprime ||
976 global_vorder != vorder) {
977 inPreEvaluateWithDeriv(vorder, vprime, global_vcoeff, global_vcoeffDeriv);
978 global_vorder = vorder;
979 global_vprime = vprime;
982 for (j = 0; j < k; j++) {
984 retPoint[j] = retdu[j] = retdv[j] = 0.0;
985 for (row = 0; row < uorder; row++) {
987 ** Minor optimization.
988 ** The col == 0 part of the loop is extracted so we don't
989 ** have to initialize p and pdv to 0.
991 p = global_vcoeff[0] * (*data);
992 pdv = global_vcoeffDeriv[0] * (*data);
994 for (col = 1; col < vorder; col++) {
995 /* Incrementally build up p, pdv value */
996 p += global_vcoeff[col] * (*data);
997 pdv += global_vcoeffDeriv[col] * (*data);
1000 /* Use p, pdv value to incrementally add up r, du, dv */
1001 retPoint[j] += global_ucoeff[row] * p;
1002 retdu[j] += global_ucoeffDeriv[row] * p;
1003 retdv[j] += global_ucoeff[row] * pdv;
1010 *compute the Bezier polynomials C[n,j](v) for all j at v with
1011 *return values stored in coeff[], where
1012 * C[n,j](v) = (n,j) * v^j * (1-v)^(n-j),
1016 *coeff : coeff[j]=C[n,j](v), this array store the returned values.
1017 *The algorithm is a recursive scheme:
1019 * C[n,j](v) = (1-v)*C[n-1,j](v) + v*C[n-1,j-1](v), n>=1
1020 *This code is copied from opengl/soft/so_eval.c:PreEvaluate
1022 void OpenGLSurfaceEvaluator::inPreEvaluate(int order, REAL vprime, REAL *coeff)
1026 REAL oneMinusvprime;
1029 * Minor optimization
1030 * Compute orders 1 and 2 outright, and set coeff[0], coeff[1] to
1031 * their i==1 loop values to avoid the initialization and the i==1 loop.
1038 oneMinusvprime = 1-vprime;
1039 coeff[0] = oneMinusvprime;
1041 if (order == 2) return;
1043 for (i = 2; i < order; i++) {
1044 oldval = coeff[0] * vprime;
1045 coeff[0] = oneMinusvprime * coeff[0];
1046 for (j = 1; j < i; j++) {
1048 oldval = coeff[j] * vprime;
1049 coeff[j] = temp + oneMinusvprime * coeff[j];
1056 *compute the Bezier polynomials C[n,j](v) and derivatives for all j at v with
1057 *return values stored in coeff[] and coeffDeriv[].
1058 *see the head of function inPreEvaluate for the definition of C[n,j](v)
1059 *and how to compute the values.
1060 *The algorithm to compute the derivative is:
1062 * dC[n,j](v) = n*(dC[n-1,j-1](v) - dC[n-1,j](v)).
1064 *This code is copied from opengl/soft/so_eval.c:PreEvaluateWidthDeriv
1066 void OpenGLSurfaceEvaluator::inPreEvaluateWithDeriv(int order, REAL vprime,
1067 REAL *coeff, REAL *coeffDeriv)
1071 REAL oneMinusvprime;
1073 oneMinusvprime = 1-vprime;
1075 * Minor optimization
1076 * Compute orders 1 and 2 outright, and set coeff[0], coeff[1] to
1077 * their i==1 loop values to avoid the initialization and the i==1 loop.
1081 coeffDeriv[0] = 0.0;
1083 } else if (order == 2) {
1084 coeffDeriv[0] = -1.0;
1085 coeffDeriv[1] = 1.0;
1086 coeff[0] = oneMinusvprime;
1090 coeff[0] = oneMinusvprime;
1092 for (i = 2; i < order - 1; i++) {
1093 oldval = coeff[0] * vprime;
1094 coeff[0] = oneMinusvprime * coeff[0];
1095 for (j = 1; j < i; j++) {
1097 oldval = coeff[j] * vprime;
1098 coeff[j] = temp + oneMinusvprime * coeff[j];
1102 coeffDeriv[0] = -coeff[0];
1104 ** Minor optimization:
1105 ** Would make this a "for (j=1; j<order-1; j++)" loop, but it is always
1106 ** executed at least once, so this is more efficient.
1110 coeffDeriv[j] = coeff[j-1] - coeff[j];
1112 } while (j < order - 1);
1113 coeffDeriv[j] = coeff[j-1];
1115 oldval = coeff[0] * vprime;
1116 coeff[0] = oneMinusvprime * coeff[0];
1117 for (j = 1; j < i; j++) {
1119 oldval = coeff[j] * vprime;
1120 coeff[j] = temp + oneMinusvprime * coeff[j];
1125 void OpenGLSurfaceEvaluator::inEvalULine(int n_points, REAL v, REAL* u_vals,
1126 int stride, REAL ret_points[][3], REAL ret_normals[][3])
1130 inPreEvaluateBV_intfac(v);
1132 for(i=0,k=0; i<n_points; i++, k += stride)
1134 inDoEvalCoord2NOGE_BV(u_vals[k],v,temp, ret_normals[i]);
1136 ret_points[i][0] = temp[0];
1137 ret_points[i][1] = temp[1];
1138 ret_points[i][2] = temp[2];
1144 void OpenGLSurfaceEvaluator::inEvalVLine(int n_points, REAL u, REAL* v_vals,
1145 int stride, REAL ret_points[][3], REAL ret_normals[][3])
1149 inPreEvaluateBU_intfac(u);
1150 for(i=0,k=0; i<n_points; i++, k += stride)
1152 inDoEvalCoord2NOGE_BU(u, v_vals[k], temp, ret_normals[i]);
1153 ret_points[i][0] = temp[0];
1154 ret_points[i][1] = temp[1];
1155 ret_points[i][2] = temp[2];
1160 /*triangulate a strip bounded by two lines which are parallel to U-axis
1161 *upperVerts: the verteces on the upper line
1162 *lowerVertx: the verteces on the lower line
1166 void OpenGLSurfaceEvaluator::inEvalUStrip(int n_upper, REAL v_upper, REAL* upper_val, int n_lower, REAL v_lower, REAL* lower_val)
1170 typedef REAL REAL3[3];
1172 REAL3* upperXYZ = (REAL3*) malloc(sizeof(REAL3)*n_upper);
1174 REAL3* upperNormal = (REAL3*) malloc(sizeof(REAL3) * n_upper);
1175 assert(upperNormal);
1176 REAL3* lowerXYZ = (REAL3*) malloc(sizeof(REAL3)*n_lower);
1178 REAL3* lowerNormal = (REAL3*) malloc(sizeof(REAL3) * n_lower);
1179 assert(lowerNormal);
1181 inEvalULine(n_upper, v_upper, upper_val, 1, upperXYZ, upperNormal);
1182 inEvalULine(n_lower, v_lower, lower_val, 1, lowerXYZ, lowerNormal);
1187 REAL* leftMostNormal;
1190 *the algorithm works by scanning from left to right.
1191 *leftMostV: the left most of the remaining verteces (on both upper and lower).
1192 * it could an element of upperVerts or lowerVerts.
1193 *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 */
1195 /*initialize i,j,and leftMostV
1197 if(upper_val[0] <= lower_val[0])
1202 leftMostV[0] = upper_val[0];
1203 leftMostV[1] = v_upper;
1204 leftMostXYZ = upperXYZ[0];
1205 leftMostNormal = upperNormal[0];
1212 leftMostV[0] = lower_val[0];
1213 leftMostV[1] = v_lower;
1215 leftMostXYZ = lowerXYZ[0];
1216 leftMostNormal = lowerNormal[0];
1220 *the invariance is that:
1221 *at the beginning of each loop, the meaning of i,j,and leftMostV are
1226 if(i >= n_upper) /*case1: no more in upper*/
1228 if(j<n_lower-1) /*at least two vertices in lower*/
1231 glNormal3fv(leftMostNormal);
1232 glVertex3fv(leftMostXYZ);
1235 glNormal3fv(lowerNormal[j]);
1236 glVertex3fv(lowerXYZ[j]);
1242 break; /*exit the main loop*/
1244 else if(j>= n_lower) /*case2: no more in lower*/
1246 if(i<n_upper-1) /*at least two vertices in upper*/
1249 glNormal3fv(leftMostNormal);
1250 glVertex3fv(leftMostXYZ);
1252 for(k=n_upper-1; k>=i; k--) /*reverse order for two-side lighting*/
1254 glNormal3fv(upperNormal[k]);
1255 glVertex3fv(upperXYZ[k]);
1260 break; /*exit the main loop*/
1262 else /* case3: neither is empty, plus the leftMostV, there is at least one triangle to output*/
1264 if(upper_val[i] <= lower_val[j])
1268 glNormal3fv(lowerNormal[j]);
1269 glVertex3fv(lowerXYZ[j]);
1271 /*find the last k>=i such that
1272 *upperverts[k][0] <= lowerverts[j][0]
1278 if(upper_val[k] > lower_val[j])
1286 for(l=k; l>=i; l--)/*the reverse is for two-side lighting*/
1288 glNormal3fv(upperNormal[l]);
1289 glVertex3fv(upperXYZ[l]);
1292 glNormal3fv(leftMostNormal);
1293 glVertex3fv(leftMostXYZ);
1297 /*update i and leftMostV for next loop
1301 leftMostV[0] = upper_val[k];
1302 leftMostV[1] = v_upper;
1303 leftMostNormal = upperNormal[k];
1304 leftMostXYZ = upperXYZ[k];
1306 else /*upperVerts[i][0] > lowerVerts[j][0]*/
1309 glNormal3fv(upperNormal[i]);
1310 glVertex3fv(upperXYZ[i]);
1312 glNormal3fv(leftMostNormal);
1313 glVertex3fv(leftMostXYZ);
1316 /*find the last k>=j such that
1317 *lowerverts[k][0] < upperverts[i][0]
1322 if(lower_val[k] >= upper_val[i])
1324 glNormal3fv(lowerNormal[k]);
1325 glVertex3fv(lowerXYZ[k]);
1331 /*update j and leftMostV for next loop
1334 leftMostV[0] = lower_val[j-1];
1335 leftMostV[1] = v_lower;
1337 leftMostNormal = lowerNormal[j-1];
1338 leftMostXYZ = lowerXYZ[j-1];
1349 /*triangulate a strip bounded by two lines which are parallel to V-axis
1350 *leftVerts: the verteces on the left line
1351 *rightVertx: the verteces on the right line
1355 void OpenGLSurfaceEvaluator::inEvalVStrip(int n_left, REAL u_left, REAL* left_val, int n_right, REAL u_right, REAL* right_val)
1359 typedef REAL REAL3[3];
1361 REAL3* leftXYZ = (REAL3*) malloc(sizeof(REAL3)*n_left);
1363 REAL3* leftNormal = (REAL3*) malloc(sizeof(REAL3) * n_left);
1365 REAL3* rightXYZ = (REAL3*) malloc(sizeof(REAL3)*n_right);
1367 REAL3* rightNormal = (REAL3*) malloc(sizeof(REAL3) * n_right);
1368 assert(rightNormal);
1370 inEvalVLine(n_left, u_left, left_val, 1, leftXYZ, leftNormal);
1371 inEvalVLine(n_right, u_right, right_val, 1, rightXYZ, rightNormal);
1376 REAL* botMostNormal;
1379 *the algorithm works by scanning from bot to top.
1380 *botMostV: the bot most of the remaining verteces (on both left and right).
1381 * it could an element of leftVerts or rightVerts.
1382 *i: leftVerts[i] is the first vertex to the top of botMostV on left line
1383 *j: rightVerts[j] is the first vertex to the top of botMostV on rightline */
1385 /*initialize i,j,and botMostV
1387 if(left_val[0] <= right_val[0])
1392 botMostV[0] = u_left;
1393 botMostV[1] = left_val[0];
1394 botMostXYZ = leftXYZ[0];
1395 botMostNormal = leftNormal[0];
1402 botMostV[0] = u_right;
1403 botMostV[1] = right_val[0];
1405 botMostXYZ = rightXYZ[0];
1406 botMostNormal = rightNormal[0];
1410 *the invariance is that:
1411 *at the beginning of each loop, the meaning of i,j,and botMostV are
1416 if(i >= n_left) /*case1: no more in left*/
1418 if(j<n_right-1) /*at least two vertices in right*/
1421 glNormal3fv(botMostNormal);
1422 glVertex3fv(botMostXYZ);
1425 glNormal3fv(rightNormal[j]);
1426 glVertex3fv(rightXYZ[j]);
1432 break; /*exit the main loop*/
1434 else if(j>= n_right) /*case2: no more in right*/
1436 if(i<n_left-1) /*at least two vertices in left*/
1439 glNormal3fv(botMostNormal);
1440 glVertex3fv(botMostXYZ);
1442 for(k=n_left-1; k>=i; k--) /*reverse order for two-side lighting*/
1444 glNormal3fv(leftNormal[k]);
1445 glVertex3fv(leftXYZ[k]);
1450 break; /*exit the main loop*/
1452 else /* case3: neither is empty, plus the botMostV, there is at least one triangle to output*/
1454 if(left_val[i] <= right_val[j])
1458 glNormal3fv(rightNormal[j]);
1459 glVertex3fv(rightXYZ[j]);
1461 /*find the last k>=i such that
1462 *leftverts[k][0] <= rightverts[j][0]
1468 if(left_val[k] > right_val[j])
1476 for(l=k; l>=i; l--)/*the reverse is for two-side lighting*/
1478 glNormal3fv(leftNormal[l]);
1479 glVertex3fv(leftXYZ[l]);
1482 glNormal3fv(botMostNormal);
1483 glVertex3fv(botMostXYZ);
1487 /*update i and botMostV for next loop
1491 botMostV[0] = u_left;
1492 botMostV[1] = left_val[k];
1493 botMostNormal = leftNormal[k];
1494 botMostXYZ = leftXYZ[k];
1496 else /*left_val[i] > right_val[j])*/
1499 glNormal3fv(leftNormal[i]);
1500 glVertex3fv(leftXYZ[i]);
1502 glNormal3fv(botMostNormal);
1503 glVertex3fv(botMostXYZ);
1506 /*find the last k>=j such that
1507 *rightverts[k][0] < leftverts[i][0]
1512 if(right_val[k] >= left_val[i])
1514 glNormal3fv(rightNormal[k]);
1515 glVertex3fv(rightXYZ[k]);
1521 /*update j and botMostV for next loop
1524 botMostV[0] = u_right;
1525 botMostV[1] = right_val[j-1];
1527 botMostNormal = rightNormal[j-1];
1528 botMostXYZ = rightXYZ[j-1];
1539 /*-----------------------begin evalMachine-------------------*/
1540 void OpenGLSurfaceEvaluator::inMap2fEM(int which, int k,
1552 surfEvalMachine *temp_em;
1556 temp_em = &em_vertex;
1560 temp_em = &em_normal;
1564 temp_em = &em_color;
1568 temp_em = &em_texcoord;
1572 REAL *data = temp_em->ctlPoints;
1574 temp_em->uprime = -1;//initilized
1575 temp_em->vprime = -1;
1578 temp_em->u1 = ulower;
1579 temp_em->u2 = uupper;
1580 temp_em->ustride = ustride;
1581 temp_em->uorder = uorder;
1582 temp_em->v1 = vlower;
1583 temp_em->v2 = vupper;
1584 temp_em->vstride = vstride;
1585 temp_em->vorder = vorder;
1587 /*copy the contrl points from ctlPoints to global_ev_ctlPoints*/
1588 for (i=0; i<uorder; i++) {
1589 for (j=0; j<vorder; j++) {
1590 for (x=0; x<k; x++) {
1591 data[x] = ctlPoints[x];
1593 ctlPoints += vstride;
1596 ctlPoints += ustride - vstride * vorder;
1600 void OpenGLSurfaceEvaluator::inDoDomain2WithDerivsEM(surfEvalMachine *em, REAL u, REAL v,
1601 REAL *retPoint, REAL *retdu, REAL *retdv)
1610 if((em->u2 == em->u1) || (em->v2 == em->v1))
1612 the_uprime = (u - em->u1) / (em->u2 - em->u1);
1613 the_vprime = (v - em->v1) / (em->v2 - em->v1);
1615 /* Compute coefficients for values and derivs */
1617 /* Use already cached values if possible */
1618 if(em->uprime != the_uprime) {
1619 inPreEvaluateWithDeriv(em->uorder, the_uprime, em->ucoeff, em->ucoeffDeriv);
1620 em->uprime = the_uprime;
1622 if (em->vprime != the_vprime) {
1623 inPreEvaluateWithDeriv(em->vorder, the_vprime, em->vcoeff, em->vcoeffDeriv);
1624 em->vprime = the_vprime;
1627 for (j = 0; j < em->k; j++) {
1628 data=em->ctlPoints+j;
1629 retPoint[j] = retdu[j] = retdv[j] = 0.0;
1630 for (row = 0; row < em->uorder; row++) {
1632 ** Minor optimization.
1633 ** The col == 0 part of the loop is extracted so we don't
1634 ** have to initialize p and pdv to 0.
1636 p = em->vcoeff[0] * (*data);
1637 pdv = em->vcoeffDeriv[0] * (*data);
1639 for (col = 1; col < em->vorder; col++) {
1640 /* Incrementally build up p, pdv value */
1641 p += em->vcoeff[col] * (*data);
1642 pdv += em->vcoeffDeriv[col] * (*data);
1645 /* Use p, pdv value to incrementally add up r, du, dv */
1646 retPoint[j] += em->ucoeff[row] * p;
1647 retdu[j] += em->ucoeffDeriv[row] * p;
1648 retdv[j] += em->ucoeff[row] * pdv;
1653 void OpenGLSurfaceEvaluator::inDoDomain2EM(surfEvalMachine *em, REAL u, REAL v,
1662 if((em->u2 == em->u1) || (em->v2 == em->v1))
1664 the_uprime = (u - em->u1) / (em->u2 - em->u1);
1665 the_vprime = (v - em->v1) / (em->v2 - em->v1);
1667 /* Compute coefficients for values and derivs */
1669 /* Use already cached values if possible */
1670 if(em->uprime != the_uprime) {
1671 inPreEvaluate(em->uorder, the_uprime, em->ucoeff);
1672 em->uprime = the_uprime;
1674 if (em->vprime != the_vprime) {
1675 inPreEvaluate(em->vorder, the_vprime, em->vcoeff);
1676 em->vprime = the_vprime;
1679 for (j = 0; j < em->k; j++) {
1680 data=em->ctlPoints+j;
1682 for (row = 0; row < em->uorder; row++) {
1684 ** Minor optimization.
1685 ** The col == 0 part of the loop is extracted so we don't
1686 ** have to initialize p and pdv to 0.
1688 p = em->vcoeff[0] * (*data);
1690 for (col = 1; col < em->vorder; col++) {
1691 /* Incrementally build up p, pdv value */
1692 p += em->vcoeff[col] * (*data);
1695 /* Use p, pdv value to incrementally add up r, du, dv */
1696 retPoint[j] += em->ucoeff[row] * p;
1702 void OpenGLSurfaceEvaluator::inDoEvalCoord2EM(REAL u, REAL v)
1704 REAL temp_vertex[5];
1705 REAL temp_normal[3];
1707 REAL temp_texcoord[4];
1711 inDoDomain2EM(&em_texcoord, u,v, temp_texcoord);
1712 texcoordCallBack(temp_texcoord, userData);
1716 inDoDomain2EM(&em_color, u,v, temp_color);
1717 colorCallBack(temp_color, userData);
1720 if(normal_flag) //there is a normla map
1722 inDoDomain2EM(&em_normal, u,v, temp_normal);
1723 normalCallBack(temp_normal, userData);
1727 inDoDomain2EM(&em_vertex, u,v,temp_vertex);
1728 if(em_vertex.k == 4)
1730 temp_vertex[0] /= temp_vertex[3];
1731 temp_vertex[1] /= temp_vertex[3];
1732 temp_vertex[2] /= temp_vertex[3];
1736 vertexCallBack(temp_vertex, userData);
1739 else if(auto_normal_flag) //no normal map but there is a normal callbackfunctin
1744 /*compute homegeneous point and partial derivatives*/
1745 inDoDomain2WithDerivsEM(&em_vertex, u,v,temp_vertex,du,dv);
1748 inComputeFirstPartials(temp_vertex, du, dv);
1750 #ifdef AVOID_ZERO_NORMAL
1751 if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO)
1756 REAL u1 = em_vertex.u1;
1757 REAL u2 = em_vertex.u2;
1758 if(u-MYDELTA*(u2-u1) < u1)
1759 u = u+ MYDELTA*(u2-u1);
1761 u = u-MYDELTA*(u2-u1);
1762 inDoDomain2WithDerivsEM(&em_vertex,u,v, tempdata, tempdu, dv);
1765 inComputeFirstPartials(temp_vertex, du, dv);
1767 else if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO)
1771 REAL v1 = em_vertex.v1;
1772 REAL v2 = em_vertex.v2;
1773 if(v-MYDELTA*(v2-v1) < v1)
1774 v = v+ MYDELTA*(v2-v1);
1776 v = v-MYDELTA*(v2-v1);
1777 inDoDomain2WithDerivsEM(&em_vertex,u,v, tempdata, du, tempdv);
1780 inComputeFirstPartials(temp_vertex, du, dv);
1785 switch(em_vertex.k){
1788 inComputeNormal2(du, dv, temp_normal);
1792 // inComputeFirstPartials(temp_vertex, du, dv);
1793 inComputeNormal2(du, dv, temp_normal);
1795 /*transform the homegeneous coordinate of retPoint into inhomogenous one*/
1796 temp_vertex[0] /= temp_vertex[3];
1797 temp_vertex[1] /= temp_vertex[3];
1798 temp_vertex[2] /= temp_vertex[3];
1801 normalCallBack(temp_normal, userData);
1804 vertexCallBack(temp_vertex, userData);
1806 }/*end if auto_normal*/
1807 else //no normal map, and no normal callback function
1811 inDoDomain2EM(&em_vertex, u,v,temp_vertex);
1812 if(em_vertex.k == 4)
1814 temp_vertex[0] /= temp_vertex[3];
1815 temp_vertex[1] /= temp_vertex[3];
1816 temp_vertex[2] /= temp_vertex[3];
1820 vertexCallBack(temp_vertex, userData);
1826 void OpenGLSurfaceEvaluator::inBPMEvalEM(bezierPatchMesh* bpm)
1835 if(bpm->bpatch != NULL)
1837 bezierPatch* p=bpm->bpatch;
1838 ustride = p->dimension * p->vorder;
1839 vstride = p->dimension;
1841 glMap2f( (p->dimension == 3)? GL_MAP2_VERTEX_3 : GL_MAP2_VERTEX_4,
1854 inMap2fEM(0, p->dimension,
1868 if(bpm->bpatch != NULL){
1869 bezierPatch* p = bpm->bpatch;
1870 ustride = p->dimension * p->vorder;
1871 vstride = p->dimension;
1872 inMap2fEM(0, p->dimension,
1883 if(bpm->bpatch_normal != NULL){
1884 bezierPatch* p = bpm->bpatch_normal;
1885 ustride = p->dimension * p->vorder;
1886 vstride = p->dimension;
1887 inMap2fEM(1, p->dimension,
1898 if(bpm->bpatch_color != NULL){
1899 bezierPatch* p = bpm->bpatch_color;
1900 ustride = p->dimension * p->vorder;
1901 vstride = p->dimension;
1902 inMap2fEM(2, p->dimension,
1913 if(bpm->bpatch_texcoord != NULL){
1914 bezierPatch* p = bpm->bpatch_texcoord;
1915 ustride = p->dimension * p->vorder;
1916 vstride = p->dimension;
1917 inMap2fEM(3, p->dimension,
1932 for(i=0; i<bpm->index_length_array; i++)
1935 if(bpm->type_array[i] == GL_POLYGON) //a mesh
1937 GLfloat *temp = bpm->UVarray+k;
1938 GLfloat u0 = temp[0];
1939 GLfloat v0 = temp[1];
1940 GLfloat u1 = temp[2];
1941 GLfloat v1 = temp[3];
1942 GLint nu = (GLint) ( temp[4]);
1943 GLint nv = (GLint) ( temp[5]);
1944 GLint umin = (GLint) ( temp[6]);
1945 GLint vmin = (GLint) ( temp[7]);
1946 GLint umax = (GLint) ( temp[8]);
1947 GLint vmax = (GLint) ( temp[9]);
1949 glMapGrid2f(LOD_eval_level*nu, u0, u1, LOD_eval_level*nv, v0, v1);
1950 glEvalMesh2(GL_FILL, LOD_eval_level*umin, LOD_eval_level*umax, LOD_eval_level*vmin, LOD_eval_level*vmax);
1954 LOD_eval(bpm->length_array[i], bpm->UVarray+k, bpm->type_array[i],
1958 k+= 2*bpm->length_array[i];
1960 #else //undef USE_LOD
1963 if( bpm->bpatch->umin == 2 && bpm->bpatch->umax == 3
1964 && bpm->bpatch->vmin ==2 && bpm->bpatch->vmax == 3)
1969 printf("***number ****1\n");
1972 beginCallBack(GL_QUAD_STRIP, NULL);
1973 inDoEvalCoord2EM(3.0, 3.0);
1974 inDoEvalCoord2EM(2.0, 3.0);
1975 inDoEvalCoord2EM(3.0, 2.7);
1976 inDoEvalCoord2EM(2.0, 2.7);
1977 inDoEvalCoord2EM(3.0, 2.0);
1978 inDoEvalCoord2EM(2.0, 2.0);
1981 beginCallBack(GL_TRIANGLE_STRIP, NULL);
1982 inDoEvalCoord2EM(2.0, 3.0);
1983 inDoEvalCoord2EM(2.0, 2.0);
1984 inDoEvalCoord2EM(2.0, 2.7);
1988 if( bpm->bpatch->umin == 1 && bpm->bpatch->umax == 2
1989 && bpm->bpatch->vmin ==2 && bpm->bpatch->vmax == 3)
1992 printf("***number 3\n");
1994 beginCallBack(GL_QUAD_STRIP, NULL);
1995 inDoEvalCoord2EM(2.0, 3.0);
1996 inDoEvalCoord2EM(1.0, 3.0);
1997 inDoEvalCoord2EM(2.0, 2.3);
1998 inDoEvalCoord2EM(1.0, 2.3);
1999 inDoEvalCoord2EM(2.0, 2.0);
2000 inDoEvalCoord2EM(1.0, 2.0);
2003 beginCallBack(GL_TRIANGLE_STRIP, NULL);
2004 inDoEvalCoord2EM(2.0, 2.3);
2005 inDoEvalCoord2EM(2.0, 2.0);
2006 inDoEvalCoord2EM(2.0, 3.0);
2013 beginCallBack(bpm->type_array[i], userData);
2015 for(j=0; j<bpm->length_array[i]; j++)
2017 u = bpm->UVarray[k];
2018 v = bpm->UVarray[k+1];
2020 LOD_EVAL_COORD(u,v);
2021 // glEvalCoord2f(u,v);
2025 float temp_normal[3];
2026 float temp_vertex[3];
2027 if(temp_signal == 0)
2029 gTessVertexSphere(u,v, temp_normal, temp_vertex);
2030 //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]);
2031 normalCallBack(temp_normal, userData);
2032 vertexCallBack(temp_vertex, userData);
2034 else if(temp_signal == 1)
2036 gTessVertexCyl(u,v, temp_normal, temp_vertex);
2037 //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]);
2038 normalCallBack(temp_normal, userData);
2039 vertexCallBack(temp_vertex, userData);
2042 #endif //GENERIC_TEST
2044 inDoEvalCoord2EM(u,v);
2050 endCallBack(userData);
2056 void OpenGLSurfaceEvaluator::inBPMListEvalEM(bezierPatchMesh* list)
2058 bezierPatchMesh* temp;
2059 for(temp = list; temp != NULL; temp = temp->next)