41 #include <libnurbs2.h>
46 #include "glsurfeval.h"
52 #define AVOID_ZERO_NORMAL
54 #ifdef AVOID_ZERO_NORMAL
55 #define myabs(x) ((x>0)? x: (-x))
56 #define MYZERO 0.000001
63 #define LOD_EVAL_COORD(u,v) glEvalCoord2f(u,v)
65 static void LOD_interpolate(REAL A[2], REAL B[2], REAL C[2],
int j,
int k,
int pow2_level,
70 a = ((REAL) j) / ((REAL) pow2_level);
75 b = ((REAL) k) / ((REAL)j);
89 u = x*A[0] + y*B[0] + z*C[0];
90 v = x*A[1] + y*B[1] + z*C[1];
93 void OpenGLSurfaceEvaluator::LOD_triangle(REAL A[2], REAL B[2], REAL C[2],
101 for(j=0; j<level; j++)
103 for(j=0; j<=pow2_level-1; j++)
108 glBegin(GL_TRIANGLE_STRIP);
109 LOD_interpolate(A,B,C, j+1, j+1, pow2_level, u,v);
114 inDoEvalCoord2EM(u,v);
119 LOD_interpolate(A,B,C,j,j-k,pow2_level, u,v);
124 inDoEvalCoord2EM(u,v);
127 LOD_interpolate(A,B,C,j+1,j-k,pow2_level, u,v);
133 inDoEvalCoord2EM(u,v);
141 void OpenGLSurfaceEvaluator::LOD_eval(
int num_vert, REAL* verts,
int type,
147 case GL_TRIANGLE_STRIP:
149 for(i=2, k=4; i<=num_vert-2; i+=2, k+=4)
151 LOD_triangle(verts+k-4, verts+k-2, verts+k,
154 LOD_triangle(verts+k-2, verts+k+2, verts+k,
160 LOD_triangle(verts+2*(num_vert-3), verts+2*(num_vert-2), verts+2*(num_vert-1),
165 case GL_TRIANGLE_FAN:
166 for(i=1, k=2; i<=num_vert-2; i++, k+=2)
168 LOD_triangle(verts,verts+k, verts+k+2,
175 fprintf(stderr,
"typy not supported in LOD_\n");
184 extern float xmin, xmax, ymin, ymax, zmin, zmax;
185 extern int temp_signal;
187 static void gTessVertexSphere(
float u,
float v,
float temp_normal[3],
float temp_vertex[3])
190 float Ox = 0.5*(xmin+xmax);
191 float Oy = 0.5*(ymin+ymax);
192 float Oz = 0.5*(zmin+zmax);
193 float nx = cos(v) * sin(u);
194 float ny = sin(v) * sin(u);
211 static void gTessVertexCyl(
float u,
float v,
float temp_normal[3],
float temp_vertex[3])
214 float Ox = 0.5*(xmin+xmax);
215 float Oy = 0.5*(ymin+ymax);
216 float Oz = 0.5*(zmin+zmax);
237 #endif //GENERIC_TEST
242 for(temp = list; temp != NULL; temp = temp->next)
253 int ustride = bpm->bpatch->dimension * bpm->bpatch->vorder;
254 int vstride = bpm->bpatch->dimension;
256 (bpm->bpatch->dimension == 3)? GL_MAP2_VERTEX_3 : GL_MAP2_VERTEX_4,
265 bpm->bpatch->ctlpoints);
267 bpm->vertex_array = (
float*) malloc(
sizeof(
float)* (bpm->index_UVarray/2) * 3+1);
268 assert(bpm->vertex_array);
269 bpm->normal_array = (
float*) malloc(
sizeof(
float)* (bpm->index_UVarray/2) * 3);
270 assert(bpm->normal_array);
272 if( global_ev_u1 ==2 && global_ev_u2 == 3
273 && global_ev_v1 ==2 && global_ev_v2 == 3)
278 printf(
"***number 1\n");
281 beginCallBack(GL_QUAD_STRIP, NULL);
282 inEvalCoord2f(3.0, 3.0);
283 inEvalCoord2f(2.0, 3.0);
284 inEvalCoord2f(3.0, 2.7);
285 inEvalCoord2f(2.0, 2.7);
286 inEvalCoord2f(3.0, 2.0);
287 inEvalCoord2f(2.0, 2.0);
291 beginCallBack(GL_TRIANGLE_STRIP, NULL);
292 inEvalCoord2f(2.0, 3.0);
293 inEvalCoord2f(2.0, 2.0);
294 inEvalCoord2f(2.0, 2.7);
314 if( global_ev_u1 ==1 && global_ev_u2 == 2
315 && global_ev_v1 ==2 && global_ev_v2 == 3)
318 printf(
"***number 3\n");
320 beginCallBack(GL_QUAD_STRIP, NULL);
321 inEvalCoord2f(2.0, 3.0);
322 inEvalCoord2f(1.0, 3.0);
323 inEvalCoord2f(2.0, 2.3);
324 inEvalCoord2f(1.0, 2.3);
325 inEvalCoord2f(2.0, 2.0);
326 inEvalCoord2f(1.0, 2.0);
329 beginCallBack(GL_TRIANGLE_STRIP, NULL);
330 inEvalCoord2f(2.0, 2.3);
331 inEvalCoord2f(2.0, 2.0);
332 inEvalCoord2f(2.0, 3.0);
342 for(i=0; i<bpm->index_length_array; i++)
344 beginCallBack(bpm->type_array[i], userData);
345 for(j=0; j<bpm->length_array[i]; j++)
348 v = bpm->UVarray[k+1];
349 inDoEvalCoord2NOGE(u,v,
351 bpm->normal_array+l);
353 normalCallBack(bpm->normal_array+l, userData);
354 vertexCallBack(bpm->vertex_array+l, userData);
359 endCallBack(userData);
363 void OpenGLSurfaceEvaluator::inEvalPoint2(
int i,
int j)
369 du = (global_grid_u1 - global_grid_u0) / (REAL)global_grid_nu;
370 dv = (global_grid_v1 - global_grid_v0) / (REAL)global_grid_nv;
371 u = (i==global_grid_nu)? global_grid_u1:(global_grid_u0 + i*du);
372 v = (j == global_grid_nv)? global_grid_v1: (global_grid_v0 +j*dv);
373 inDoEvalCoord2(u,v,point,normal);
376 void OpenGLSurfaceEvaluator::inEvalCoord2f(REAL u, REAL v)
381 inDoEvalCoord2(u,v,point, normal);
390 void OpenGLSurfaceEvaluator::inMapGrid2f(
int nu, REAL u0, REAL u1,
391 int nv, REAL v0, REAL v1)
401 void OpenGLSurfaceEvaluator::inEvalMesh2(
int lowU,
int lowV,
int highU,
int highV)
407 if(global_grid_nu == 0 || global_grid_nv == 0)
409 du = (global_grid_u1 - global_grid_u0) / (REAL)global_grid_nu;
410 dv = (global_grid_v1 - global_grid_v0) / (REAL)global_grid_nv;
412 if(global_grid_nu >= global_grid_nv){
413 for(i=lowU; i<highU; i++){
414 REAL u1 = (i==global_grid_nu)? global_grid_u1:(global_grid_u0 + i*du);
415 REAL u2 = ((i+1) == global_grid_nu)? global_grid_u1: (global_grid_u0+(i+1)*du);
418 for(j=highV; j>=lowV; j--){
419 REAL v1 = (j == global_grid_nv)? global_grid_v1: (global_grid_v0 +j*dv);
421 inDoEvalCoord2(u1, v1, point, normal);
422 inDoEvalCoord2(u2, v1, point, normal);
429 for(i=lowV; i<highV; i++){
430 REAL v1 = (i==global_grid_nv)? global_grid_v1:(global_grid_v0 + i*dv);
431 REAL v2 = ((i+1) == global_grid_nv)? global_grid_v1: (global_grid_v0+(i+1)*dv);
434 for(j=highU; j>=lowU; j--){
435 REAL u1 = (j == global_grid_nu)? global_grid_u1: (global_grid_u0 +j*du);
436 inDoEvalCoord2(u1, v2, point, normal);
437 inDoEvalCoord2(u1, v1, point, normal);
445 void OpenGLSurfaceEvaluator::inMap2f(
int k,
457 REAL *data = global_ev_ctlPoints;
461 if(k == GL_MAP2_VERTEX_3) k=3;
462 else if (k==GL_MAP2_VERTEX_4) k =4;
464 printf(
"error in inMap2f, maptype=%i is wrong, k,map is not updated\n", k);
469 global_ev_u1 = ulower;
470 global_ev_u2 = uupper;
471 global_ev_ustride = ustride;
472 global_ev_uorder = uorder;
473 global_ev_v1 = vlower;
474 global_ev_v2 = vupper;
475 global_ev_vstride = vstride;
476 global_ev_vorder = vorder;
479 for (i=0; i<uorder; i++) {
480 for (j=0; j<vorder; j++) {
481 for (x=0; x<k; x++) {
482 data[x] = ctlPoints[x];
484 ctlPoints += vstride;
487 ctlPoints += ustride - vstride * vorder;
502 void OpenGLSurfaceEvaluator::inComputeFirstPartials(REAL *p, REAL *pu, REAL *pv)
504 pu[0] = pu[0]*p[3] - pu[3]*p[0];
505 pu[1] = pu[1]*p[3] - pu[3]*p[1];
506 pu[2] = pu[2]*p[3] - pu[3]*p[2];
508 pv[0] = pv[0]*p[3] - pv[3]*p[0];
509 pv[1] = pv[1]*p[3] - pv[3]*p[1];
510 pv[2] = pv[2]*p[3] - pv[3]*p[2];
519 void OpenGLSurfaceEvaluator::inComputeNormal2(REAL *pu, REAL *pv, REAL *n)
523 n[0] = pu[1]*pv[2] - pu[2]*pv[1];
524 n[1] = pu[2]*pv[0] - pu[0]*pv[2];
525 n[2] = pu[0]*pv[1] - pu[1]*pv[0];
527 mag = sqrt(n[0]*n[0] + n[1]*n[1] + n[2]*n[2]);
542 void OpenGLSurfaceEvaluator::inDoEvalCoord2(REAL u, REAL v,
543 REAL *retPoint, REAL *retNormal)
550 assert(global_ev_k>=3 && global_ev_k <= 4);
552 inDoDomain2WithDerivs(global_ev_k, u, v, global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, retPoint, du, dv);
554 #ifdef AVOID_ZERO_NORMAL
556 if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO)
561 REAL u1 = global_ev_u1;
562 REAL u2 = global_ev_u2;
563 if(u-MYDELTA*(u2-u1) < u1)
564 u = u+ MYDELTA*(u2-u1);
566 u = u-MYDELTA*(u2-u1);
567 inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, tempdu, dv);
569 if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO)
573 REAL v1 = global_ev_v1;
574 REAL v2 = global_ev_v2;
575 if(v-MYDELTA*(v2-v1) < v1)
576 v = v+ MYDELTA*(v2-v1);
578 v = v-MYDELTA*(v2-v1);
579 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);
587 inComputeNormal2(du, dv, retNormal);
591 inComputeFirstPartials(retPoint, du, dv);
592 inComputeNormal2(du, dv, retNormal);
594 retPoint[0] /= retPoint[3];
595 retPoint[1] /= retPoint[3];
596 retPoint[2] /= retPoint[3];
604 glNormal3fv(retNormal);
605 glVertex3fv(retPoint);
611 printf(
"vertex(%f,%f,%f)\n", retPoint[0],retPoint[1],retPoint[2]);
622 void OpenGLSurfaceEvaluator::inDoEvalCoord2NOGE_BU(REAL u, REAL v,
623 REAL *retPoint, REAL *retNormal)
630 assert(global_ev_k>=3 && global_ev_k <= 4);
633 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);
636 #ifdef AVOID_ZERO_NORMAL
638 if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO)
643 REAL u1 = global_ev_u1;
644 REAL u2 = global_ev_u2;
645 if(u-MYDELTA*(u2-u1) < u1)
646 u = u+ MYDELTA*(u2-u1);
648 u = u-MYDELTA*(u2-u1);
649 inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, tempdu, dv);
651 if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO)
655 REAL v1 = global_ev_v1;
656 REAL v2 = global_ev_v2;
657 if(v-MYDELTA*(v2-v1) < v1)
658 v = v+ MYDELTA*(v2-v1);
660 v = v-MYDELTA*(v2-v1);
661 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);
668 inComputeNormal2(du, dv, retNormal);
671 inComputeFirstPartials(retPoint, du, dv);
672 inComputeNormal2(du, dv, retNormal);
674 retPoint[0] /= retPoint[3];
675 retPoint[1] /= retPoint[3];
676 retPoint[2] /= retPoint[3];
685 void OpenGLSurfaceEvaluator::inDoEvalCoord2NOGE_BV(REAL u, REAL v,
686 REAL *retPoint, REAL *retNormal)
693 assert(global_ev_k>=3 && global_ev_k <= 4);
697 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);
700 #ifdef AVOID_ZERO_NORMAL
702 if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO)
707 REAL u1 = global_ev_u1;
708 REAL u2 = global_ev_u2;
709 if(u-MYDELTA*(u2-u1) < u1)
710 u = u+ MYDELTA*(u2-u1);
712 u = u-MYDELTA*(u2-u1);
713 inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, tempdu, dv);
715 if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO)
719 REAL v1 = global_ev_v1;
720 REAL v2 = global_ev_v2;
721 if(v-MYDELTA*(v2-v1) < v1)
722 v = v+ MYDELTA*(v2-v1);
724 v = v-MYDELTA*(v2-v1);
725 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);
732 inComputeNormal2(du, dv, retNormal);
735 inComputeFirstPartials(retPoint, du, dv);
736 inComputeNormal2(du, dv, retNormal);
738 retPoint[0] /= retPoint[3];
739 retPoint[1] /= retPoint[3];
740 retPoint[2] /= retPoint[3];
750 void OpenGLSurfaceEvaluator::inDoEvalCoord2NOGE(REAL u, REAL v,
751 REAL *retPoint, REAL *retNormal)
758 assert(global_ev_k>=3 && global_ev_k <= 4);
760 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);
763 #ifdef AVOID_ZERO_NORMAL
765 if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO)
770 REAL u1 = global_ev_u1;
771 REAL u2 = global_ev_u2;
772 if(u-MYDELTA*(u2-u1) < u1)
773 u = u+ MYDELTA*(u2-u1);
775 u = u-MYDELTA*(u2-u1);
776 inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, tempdu, dv);
778 if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO)
782 REAL v1 = global_ev_v1;
783 REAL v2 = global_ev_v2;
784 if(v-MYDELTA*(v2-v1) < v1)
785 v = v+ MYDELTA*(v2-v1);
787 v = v-MYDELTA*(v2-v1);
788 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);
795 inComputeNormal2(du, dv, retNormal);
798 inComputeFirstPartials(retPoint, du, dv);
799 inComputeNormal2(du, dv, retNormal);
801 retPoint[0] /= retPoint[3];
802 retPoint[1] /= retPoint[3];
803 retPoint[2] /= retPoint[3];
810 void OpenGLSurfaceEvaluator::inPreEvaluateBV(
int k,
int uorder,
int vorder, REAL vprime, REAL *baseData)
816 if(global_vprime != vprime || global_vorder != vorder) {
817 inPreEvaluateWithDeriv(vorder, vprime, global_vcoeff, global_vcoeffDeriv);
818 global_vprime = vprime;
819 global_vorder = vorder;
824 for(row=0; row<uorder; row++){
825 p = global_vcoeff[0] * (*data);
826 pdv = global_vcoeffDeriv[0] * (*data);
828 for(col = 1; col < vorder; col++){
829 p += global_vcoeff[col] * (*data);
830 pdv += global_vcoeffDeriv[col] * (*data);
833 global_BV[row][j] = p;
834 global_PBV[row][j] = pdv;
839 void OpenGLSurfaceEvaluator::inPreEvaluateBU(
int k,
int uorder,
int vorder, REAL uprime, REAL *baseData)
845 if(global_uprime != uprime || global_uorder != uorder) {
846 inPreEvaluateWithDeriv(uorder, uprime, global_ucoeff, global_ucoeffDeriv);
847 global_uprime = uprime;
848 global_uorder = uorder;
853 for(col=0; col<vorder; col++){
854 data = baseData+j + k*col;
855 p = global_ucoeff[0] * (*data);
856 pdu = global_ucoeffDeriv[0] * (*data);
858 for(row = 1; row < uorder; row++){
859 p += global_ucoeff[row] * (*data);
860 pdu += global_ucoeffDeriv[row] * (*data);
863 global_BU[col][j] = p;
864 global_PBU[col][j] = pdu;
869 void OpenGLSurfaceEvaluator::inDoDomain2WithDerivsBU(
int k, REAL u, REAL v,
870 REAL u1, REAL u2,
int uorder,
871 REAL v1, REAL v2,
int vorder,
873 REAL *retPoint, REAL* retdu, REAL *retdv)
880 if((u2 == u1) || (v2 == v1))
883 vprime = (v - v1) / (v2 - v1);
886 if(global_vprime != vprime || global_vorder != vorder) {
887 inPreEvaluateWithDeriv(vorder, vprime, global_vcoeff, global_vcoeffDeriv);
888 global_vprime = vprime;
889 global_vorder = vorder;
895 retPoint[j] = retdu[j] = retdv[j] = 0.0;
896 for (col = 0; col < vorder; col++) {
897 retPoint[j] += global_BU[col][j] * global_vcoeff[col];
898 retdu[j] += global_PBU[col][j] * global_vcoeff[col];
899 retdv[j] += global_BU[col][j] * global_vcoeffDeriv[col];
904 void OpenGLSurfaceEvaluator::inDoDomain2WithDerivsBV(
int k, REAL u, REAL v,
905 REAL u1, REAL u2,
int uorder,
906 REAL v1, REAL v2,
int vorder,
908 REAL *retPoint, REAL* retdu, REAL *retdv)
914 if((u2 == u1) || (v2 == v1))
916 uprime = (u - u1) / (u2 - u1);
919 if(global_uprime != uprime || global_uorder != uorder) {
920 inPreEvaluateWithDeriv(uorder, uprime, global_ucoeff, global_ucoeffDeriv);
921 global_uprime = uprime;
922 global_uorder = uorder;
928 retPoint[j] = retdu[j] = retdv[j] = 0.0;
929 for (row = 0; row < uorder; row++) {
930 retPoint[j] += global_BV[row][j] * global_ucoeff[row];
931 retdu[j] += global_BV[row][j] * global_ucoeffDeriv[row];
932 retdv[j] += global_PBV[row][j] * global_ucoeff[row];
950 void OpenGLSurfaceEvaluator::inDoDomain2WithDerivs(
int k, REAL u, REAL v,
951 REAL u1, REAL u2,
int uorder,
952 REAL v1, REAL v2,
int vorder,
954 REAL *retPoint, REAL *retdu, REAL *retdv)
963 if((u2 == u1) || (v2 == v1))
965 uprime = (u - u1) / (u2 - u1);
966 vprime = (v - v1) / (v2 - v1);
971 if(global_uprime != uprime || global_uorder != uorder) {
972 inPreEvaluateWithDeriv(uorder, uprime, global_ucoeff, global_ucoeffDeriv);
973 global_uorder = uorder;
974 global_uprime = uprime;
976 if (global_vprime != vprime ||
977 global_vorder != vorder) {
978 inPreEvaluateWithDeriv(vorder, vprime, global_vcoeff, global_vcoeffDeriv);
979 global_vorder = vorder;
980 global_vprime = vprime;
983 for (j = 0; j < k; j++) {
985 retPoint[j] = retdu[j] = retdv[j] = 0.0;
986 for (row = 0; row < uorder; row++) {
992 p = global_vcoeff[0] * (*data);
993 pdv = global_vcoeffDeriv[0] * (*data);
995 for (col = 1; col < vorder; col++) {
997 p += global_vcoeff[col] * (*data);
998 pdv += global_vcoeffDeriv[col] * (*data);
1002 retPoint[j] += global_ucoeff[row] * p;
1003 retdu[j] += global_ucoeffDeriv[row] * p;
1004 retdv[j] += global_ucoeff[row] * pdv;
1023 void OpenGLSurfaceEvaluator::inPreEvaluate(
int order, REAL vprime, REAL *coeff)
1027 REAL oneMinusvprime;
1039 oneMinusvprime = 1-vprime;
1040 coeff[0] = oneMinusvprime;
1042 if (order == 2)
return;
1044 for (i = 2; i < order; i++) {
1045 oldval = coeff[0] * vprime;
1046 coeff[0] = oneMinusvprime * coeff[0];
1047 for (j = 1; j < i; j++) {
1049 oldval = coeff[j] * vprime;
1050 coeff[j] = temp + oneMinusvprime * coeff[j];
1067 void OpenGLSurfaceEvaluator::inPreEvaluateWithDeriv(
int order, REAL vprime,
1068 REAL *coeff, REAL *coeffDeriv)
1072 REAL oneMinusvprime;
1074 oneMinusvprime = 1-vprime;
1082 coeffDeriv[0] = 0.0;
1084 }
else if (order == 2) {
1085 coeffDeriv[0] = -1.0;
1086 coeffDeriv[1] = 1.0;
1087 coeff[0] = oneMinusvprime;
1091 coeff[0] = oneMinusvprime;
1093 for (i = 2; i < order - 1; i++) {
1094 oldval = coeff[0] * vprime;
1095 coeff[0] = oneMinusvprime * coeff[0];
1096 for (j = 1; j < i; j++) {
1098 oldval = coeff[j] * vprime;
1099 coeff[j] = temp + oneMinusvprime * coeff[j];
1103 coeffDeriv[0] = -coeff[0];
1111 coeffDeriv[j] = coeff[j-1] - coeff[j];
1113 }
while (j < order - 1);
1114 coeffDeriv[j] = coeff[j-1];
1116 oldval = coeff[0] * vprime;
1117 coeff[0] = oneMinusvprime * coeff[0];
1118 for (j = 1; j < i; j++) {
1120 oldval = coeff[j] * vprime;
1121 coeff[j] = temp + oneMinusvprime * coeff[j];
1126 void OpenGLSurfaceEvaluator::inEvalULine(
int n_points, REAL v, REAL* u_vals,
1127 int stride, REAL ret_points[][3], REAL ret_normals[][3])
1131 inPreEvaluateBV_intfac(v);
1133 for(i=0,k=0; i<n_points; i++, k += stride)
1135 inDoEvalCoord2NOGE_BV(u_vals[k],v,temp, ret_normals[i]);
1137 ret_points[i][0] = temp[0];
1138 ret_points[i][1] = temp[1];
1139 ret_points[i][2] = temp[2];
1145 void OpenGLSurfaceEvaluator::inEvalVLine(
int n_points, REAL u, REAL* v_vals,
1146 int stride, REAL ret_points[][3], REAL ret_normals[][3])
1150 inPreEvaluateBU_intfac(u);
1151 for(i=0,k=0; i<n_points; i++, k += stride)
1153 inDoEvalCoord2NOGE_BU(u, v_vals[k], temp, ret_normals[i]);
1154 ret_points[i][0] = temp[0];
1155 ret_points[i][1] = temp[1];
1156 ret_points[i][2] = temp[2];
1167 void OpenGLSurfaceEvaluator::inEvalUStrip(
int n_upper, REAL v_upper, REAL* upper_val,
int n_lower, REAL v_lower, REAL* lower_val)
1171 typedef REAL REAL3[3];
1173 REAL3* upperXYZ = (REAL3*) malloc(
sizeof(REAL3)*n_upper);
1175 REAL3* upperNormal = (REAL3*) malloc(
sizeof(REAL3) * n_upper);
1176 assert(upperNormal);
1177 REAL3* lowerXYZ = (REAL3*) malloc(
sizeof(REAL3)*n_lower);
1179 REAL3* lowerNormal = (REAL3*) malloc(
sizeof(REAL3) * n_lower);
1180 assert(lowerNormal);
1182 inEvalULine(n_upper, v_upper, upper_val, 1, upperXYZ, upperNormal);
1183 inEvalULine(n_lower, v_lower, lower_val, 1, lowerXYZ, lowerNormal);
1188 REAL* leftMostNormal;
1198 if(upper_val[0] <= lower_val[0])
1203 leftMostV[0] = upper_val[0];
1204 leftMostV[1] = v_upper;
1205 leftMostXYZ = upperXYZ[0];
1206 leftMostNormal = upperNormal[0];
1213 leftMostV[0] = lower_val[0];
1214 leftMostV[1] = v_lower;
1216 leftMostXYZ = lowerXYZ[0];
1217 leftMostNormal = lowerNormal[0];
1233 glNormal3fv(leftMostNormal);
1234 glVertex3fv(leftMostXYZ);
1238 glNormal3fv(lowerNormal[j]);
1239 glVertex3fv(lowerXYZ[j]);
1248 else if(j>= n_lower)
1254 glNormal3fv(leftMostNormal);
1255 glVertex3fv(leftMostXYZ);
1258 for(k=n_upper-1; k>=i; k--)
1261 glNormal3fv(upperNormal[k]);
1262 glVertex3fv(upperXYZ[k]);
1272 if(upper_val[i] <= lower_val[j])
1276 glNormal3fv(lowerNormal[j]);
1277 glVertex3fv(lowerXYZ[j]);
1286 if(upper_val[k] > lower_val[j])
1297 glNormal3fv(upperNormal[l]);
1298 glVertex3fv(upperXYZ[l]);
1302 glNormal3fv(leftMostNormal);
1303 glVertex3fv(leftMostXYZ);
1311 leftMostV[0] = upper_val[k];
1312 leftMostV[1] = v_upper;
1313 leftMostNormal = upperNormal[k];
1314 leftMostXYZ = upperXYZ[k];
1320 glNormal3fv(upperNormal[i]);
1321 glVertex3fv(upperXYZ[i]);
1323 glNormal3fv(leftMostNormal);
1324 glVertex3fv(leftMostXYZ);
1333 if(lower_val[k] >= upper_val[i])
1336 glNormal3fv(lowerNormal[k]);
1337 glVertex3fv(lowerXYZ[k]);
1346 leftMostV[0] = lower_val[j-1];
1347 leftMostV[1] = v_lower;
1349 leftMostNormal = lowerNormal[j-1];
1350 leftMostXYZ = lowerXYZ[j-1];
1367 void OpenGLSurfaceEvaluator::inEvalVStrip(
int n_left, REAL u_left, REAL* left_val,
int n_right, REAL u_right, REAL* right_val)
1371 typedef REAL REAL3[3];
1373 REAL3* leftXYZ = (REAL3*) malloc(
sizeof(REAL3)*n_left);
1375 REAL3* leftNormal = (REAL3*) malloc(
sizeof(REAL3) * n_left);
1377 REAL3* rightXYZ = (REAL3*) malloc(
sizeof(REAL3)*n_right);
1379 REAL3* rightNormal = (REAL3*) malloc(
sizeof(REAL3) * n_right);
1380 assert(rightNormal);
1382 inEvalVLine(n_left, u_left, left_val, 1, leftXYZ, leftNormal);
1383 inEvalVLine(n_right, u_right, right_val, 1, rightXYZ, rightNormal);
1388 REAL* botMostNormal;
1399 if(left_val[0] <= right_val[0])
1404 botMostV[0] = u_left;
1405 botMostV[1] = left_val[0];
1406 botMostXYZ = leftXYZ[0];
1407 botMostNormal = leftNormal[0];
1414 botMostV[0] = u_right;
1415 botMostV[1] = right_val[0];
1417 botMostXYZ = rightXYZ[0];
1418 botMostNormal = rightNormal[0];
1434 glNormal3fv(botMostNormal);
1435 glVertex3fv(botMostXYZ);
1439 glNormal3fv(rightNormal[j]);
1440 glVertex3fv(rightXYZ[j]);
1449 else if(j>= n_right)
1455 glNormal3fv(botMostNormal);
1456 glVertex3fv(botMostXYZ);
1458 for(k=n_left-1; k>=i; k--)
1461 glNormal3fv(leftNormal[k]);
1462 glVertex3fv(leftXYZ[k]);
1472 if(left_val[i] <= right_val[j])
1476 glNormal3fv(rightNormal[j]);
1477 glVertex3fv(rightXYZ[j]);
1486 if(left_val[k] > right_val[j])
1497 glNormal3fv(leftNormal[l]);
1498 glVertex3fv(leftXYZ[l]);
1502 glNormal3fv(botMostNormal);
1503 glVertex3fv(botMostXYZ);
1511 botMostV[0] = u_left;
1512 botMostV[1] = left_val[k];
1513 botMostNormal = leftNormal[k];
1514 botMostXYZ = leftXYZ[k];
1520 glNormal3fv(leftNormal[i]);
1521 glVertex3fv(leftXYZ[i]);
1523 glNormal3fv(botMostNormal);
1524 glVertex3fv(botMostXYZ);
1533 if(right_val[k] >= left_val[i])
1536 glNormal3fv(rightNormal[k]);
1537 glVertex3fv(rightXYZ[k]);
1546 botMostV[0] = u_right;
1547 botMostV[1] = right_val[j-1];
1549 botMostNormal = rightNormal[j-1];
1550 botMostXYZ = rightXYZ[j-1];
1562 void OpenGLSurfaceEvaluator::inMap2fEM(
int which,
int k,
1578 temp_em = &em_vertex;
1582 temp_em = &em_normal;
1586 temp_em = &em_color;
1590 temp_em = &em_texcoord;
1594 REAL *data = temp_em->ctlPoints;
1596 temp_em->uprime = -1;
1597 temp_em->vprime = -1;
1600 temp_em->u1 = ulower;
1601 temp_em->u2 = uupper;
1602 temp_em->ustride = ustride;
1603 temp_em->uorder = uorder;
1604 temp_em->v1 = vlower;
1605 temp_em->v2 = vupper;
1606 temp_em->vstride = vstride;
1607 temp_em->vorder = vorder;
1610 for (i=0; i<uorder; i++) {
1611 for (j=0; j<vorder; j++) {
1612 for (x=0; x<k; x++) {
1613 data[x] = ctlPoints[x];
1615 ctlPoints += vstride;
1618 ctlPoints += ustride - vstride * vorder;
1622 void OpenGLSurfaceEvaluator::inDoDomain2WithDerivsEM(
surfEvalMachine *em, REAL u, REAL v,
1623 REAL *retPoint, REAL *retdu, REAL *retdv)
1632 if((em->u2 == em->u1) || (em->v2 == em->v1))
1634 the_uprime = (u - em->u1) / (em->u2 - em->u1);
1635 the_vprime = (v - em->v1) / (em->v2 - em->v1);
1640 if(em->uprime != the_uprime) {
1641 inPreEvaluateWithDeriv(em->uorder, the_uprime, em->ucoeff, em->ucoeffDeriv);
1642 em->uprime = the_uprime;
1644 if (em->vprime != the_vprime) {
1645 inPreEvaluateWithDeriv(em->vorder, the_vprime, em->vcoeff, em->vcoeffDeriv);
1646 em->vprime = the_vprime;
1649 for (j = 0; j < em->k; j++) {
1650 data=em->ctlPoints+j;
1651 retPoint[j] = retdu[j] = retdv[j] = 0.0;
1652 for (row = 0; row < em->uorder; row++) {
1658 p = em->vcoeff[0] * (*data);
1659 pdv = em->vcoeffDeriv[0] * (*data);
1661 for (col = 1; col < em->vorder; col++) {
1663 p += em->vcoeff[col] * (*data);
1664 pdv += em->vcoeffDeriv[col] * (*data);
1668 retPoint[j] += em->ucoeff[row] * p;
1669 retdu[j] += em->ucoeffDeriv[row] * p;
1670 retdv[j] += em->ucoeff[row] * pdv;
1675 void OpenGLSurfaceEvaluator::inDoDomain2EM(
surfEvalMachine *em, REAL u, REAL v,
1684 if((em->u2 == em->u1) || (em->v2 == em->v1))
1686 the_uprime = (u - em->u1) / (em->u2 - em->u1);
1687 the_vprime = (v - em->v1) / (em->v2 - em->v1);
1692 if(em->uprime != the_uprime) {
1693 inPreEvaluate(em->uorder, the_uprime, em->ucoeff);
1694 em->uprime = the_uprime;
1696 if (em->vprime != the_vprime) {
1697 inPreEvaluate(em->vorder, the_vprime, em->vcoeff);
1698 em->vprime = the_vprime;
1701 for (j = 0; j < em->k; j++) {
1702 data=em->ctlPoints+j;
1704 for (row = 0; row < em->uorder; row++) {
1710 p = em->vcoeff[0] * (*data);
1712 for (col = 1; col < em->vorder; col++) {
1714 p += em->vcoeff[col] * (*data);
1718 retPoint[j] += em->ucoeff[row] * p;
1724 void OpenGLSurfaceEvaluator::inDoEvalCoord2EM(REAL u, REAL v)
1726 REAL temp_vertex[5];
1727 REAL temp_normal[3];
1729 REAL temp_texcoord[4];
1733 inDoDomain2EM(&em_texcoord, u,v, temp_texcoord);
1734 texcoordCallBack(temp_texcoord, userData);
1738 inDoDomain2EM(&em_color, u,v, temp_color);
1739 colorCallBack(temp_color, userData);
1744 inDoDomain2EM(&em_normal, u,v, temp_normal);
1745 normalCallBack(temp_normal, userData);
1749 inDoDomain2EM(&em_vertex, u,v,temp_vertex);
1750 if(em_vertex.k == 4)
1752 temp_vertex[0] /= temp_vertex[3];
1753 temp_vertex[1] /= temp_vertex[3];
1754 temp_vertex[2] /= temp_vertex[3];
1758 vertexCallBack(temp_vertex, userData);
1761 else if(auto_normal_flag)
1767 inDoDomain2WithDerivsEM(&em_vertex, u,v,temp_vertex,du,dv);
1770 inComputeFirstPartials(temp_vertex, du, dv);
1772 #ifdef AVOID_ZERO_NORMAL
1773 if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO)
1778 REAL u1 = em_vertex.u1;
1779 REAL u2 = em_vertex.u2;
1780 if(u-MYDELTA*(u2-u1) < u1)
1781 u = u+ MYDELTA*(u2-u1);
1783 u = u-MYDELTA*(u2-u1);
1784 inDoDomain2WithDerivsEM(&em_vertex,u,v, tempdata, tempdu, dv);
1787 inComputeFirstPartials(temp_vertex, du, dv);
1789 else if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO)
1793 REAL v1 = em_vertex.v1;
1794 REAL v2 = em_vertex.v2;
1795 if(v-MYDELTA*(v2-v1) < v1)
1796 v = v+ MYDELTA*(v2-v1);
1798 v = v-MYDELTA*(v2-v1);
1799 inDoDomain2WithDerivsEM(&em_vertex,u,v, tempdata, du, tempdv);
1802 inComputeFirstPartials(temp_vertex, du, dv);
1807 switch(em_vertex.k){
1810 inComputeNormal2(du, dv, temp_normal);
1815 inComputeNormal2(du, dv, temp_normal);
1818 temp_vertex[0] /= temp_vertex[3];
1819 temp_vertex[1] /= temp_vertex[3];
1820 temp_vertex[2] /= temp_vertex[3];
1823 normalCallBack(temp_normal, userData);
1826 vertexCallBack(temp_vertex, userData);
1833 inDoDomain2EM(&em_vertex, u,v,temp_vertex);
1834 if(em_vertex.k == 4)
1836 temp_vertex[0] /= temp_vertex[3];
1837 temp_vertex[1] /= temp_vertex[3];
1838 temp_vertex[2] /= temp_vertex[3];
1842 vertexCallBack(temp_vertex, userData);
1857 if(bpm->bpatch != NULL)
1860 ustride = p->dimension * p->vorder;
1861 vstride = p->dimension;
1863 glMap2f( (p->dimension == 3)? GL_MAP2_VERTEX_3 : GL_MAP2_VERTEX_4,
1890 if(bpm->bpatch != NULL){
1892 ustride = p->dimension * p->vorder;
1893 vstride = p->dimension;
1894 inMap2fEM(0, p->dimension,
1905 if(bpm->bpatch_normal != NULL){
1907 ustride = p->dimension * p->vorder;
1908 vstride = p->dimension;
1909 inMap2fEM(1, p->dimension,
1920 if(bpm->bpatch_color != NULL){
1922 ustride = p->dimension * p->vorder;
1923 vstride = p->dimension;
1924 inMap2fEM(2, p->dimension,
1935 if(bpm->bpatch_texcoord != NULL){
1937 ustride = p->dimension * p->vorder;
1938 vstride = p->dimension;
1939 inMap2fEM(3, p->dimension,
1954 for(i=0; i<bpm->index_length_array; i++)
1957 if(bpm->type_array[i] == GL_POLYGON)
1959 GLfloat *temp = bpm->UVarray+k;
1960 GLfloat u0 = temp[0];
1961 GLfloat v0 = temp[1];
1962 GLfloat u1 = temp[2];
1963 GLfloat v1 = temp[3];
1964 GLint nu = (GLint) ( temp[4]);
1965 GLint nv = (GLint) ( temp[5]);
1966 GLint umin = (GLint) ( temp[6]);
1967 GLint vmin = (GLint) ( temp[7]);
1968 GLint umax = (GLint) ( temp[8]);
1969 GLint vmax = (GLint) ( temp[9]);
1971 glMapGrid2f(LOD_eval_level*nu, u0, u1, LOD_eval_level*nv, v0, v1);
1972 glEvalMesh2(GL_FILL, LOD_eval_level*umin, LOD_eval_level*umax, LOD_eval_level*vmin, LOD_eval_level*vmax);
1976 LOD_eval(bpm->length_array[i], bpm->UVarray+k, bpm->type_array[i],
1980 k+= 2*bpm->length_array[i];
1982 #else //undef USE_LOD
1985 if( bpm->bpatch->umin == 2 && bpm->bpatch->umax == 3
1986 && bpm->bpatch->vmin ==2 && bpm->bpatch->vmax == 3)
1991 printf(
"***number ****1\n");
1994 beginCallBack(GL_QUAD_STRIP, NULL);
1995 inDoEvalCoord2EM(3.0, 3.0);
1996 inDoEvalCoord2EM(2.0, 3.0);
1997 inDoEvalCoord2EM(3.0, 2.7);
1998 inDoEvalCoord2EM(2.0, 2.7);
1999 inDoEvalCoord2EM(3.0, 2.0);
2000 inDoEvalCoord2EM(2.0, 2.0);
2003 beginCallBack(GL_TRIANGLE_STRIP, NULL);
2004 inDoEvalCoord2EM(2.0, 3.0);
2005 inDoEvalCoord2EM(2.0, 2.0);
2006 inDoEvalCoord2EM(2.0, 2.7);
2010 if( bpm->bpatch->umin == 1 && bpm->bpatch->umax == 2
2011 && bpm->bpatch->vmin ==2 && bpm->bpatch->vmax == 3)
2014 printf(
"***number 3\n");
2016 beginCallBack(GL_QUAD_STRIP, NULL);
2017 inDoEvalCoord2EM(2.0, 3.0);
2018 inDoEvalCoord2EM(1.0, 3.0);
2019 inDoEvalCoord2EM(2.0, 2.3);
2020 inDoEvalCoord2EM(1.0, 2.3);
2021 inDoEvalCoord2EM(2.0, 2.0);
2022 inDoEvalCoord2EM(1.0, 2.0);
2025 beginCallBack(GL_TRIANGLE_STRIP, NULL);
2026 inDoEvalCoord2EM(2.0, 2.3);
2027 inDoEvalCoord2EM(2.0, 2.0);
2028 inDoEvalCoord2EM(2.0, 3.0);
2035 beginCallBack(bpm->type_array[i], userData);
2037 for(j=0; j<bpm->length_array[i]; j++)
2039 u = bpm->UVarray[k];
2040 v = bpm->UVarray[k+1];
2042 LOD_EVAL_COORD(u,v);
2047 float temp_normal[3];
2048 float temp_vertex[3];
2049 if(temp_signal == 0)
2051 gTessVertexSphere(u,v, temp_normal, temp_vertex);
2053 normalCallBack(temp_normal, userData);
2054 vertexCallBack(temp_vertex, userData);
2056 else if(temp_signal == 1)
2058 gTessVertexCyl(u,v, temp_normal, temp_vertex);
2060 normalCallBack(temp_normal, userData);
2061 vertexCallBack(temp_vertex, userData);
2064 #endif //GENERIC_TEST
2066 inDoEvalCoord2EM(u,v);
2072 endCallBack(userData);
2081 for(temp = list; temp != NULL; temp = temp->next)