diff options
Diffstat (limited to 'mesalib/src/glu/sgi/libnurbs/interface/insurfeval.cc')
-rw-r--r-- | mesalib/src/glu/sgi/libnurbs/interface/insurfeval.cc | 2064 |
1 files changed, 0 insertions, 2064 deletions
diff --git a/mesalib/src/glu/sgi/libnurbs/interface/insurfeval.cc b/mesalib/src/glu/sgi/libnurbs/interface/insurfeval.cc deleted file mode 100644 index 9d0c82a91..000000000 --- a/mesalib/src/glu/sgi/libnurbs/interface/insurfeval.cc +++ /dev/null @@ -1,2064 +0,0 @@ -/* -** License Applicability. Except to the extent portions of this file are -** made subject to an alternative license as permitted in the SGI Free -** Software License B, Version 1.1 (the "License"), the contents of this -** file are subject only to the provisions of the License. You may not use -** this file except in compliance with the License. You may obtain a copy -** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 -** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: -** -** http://oss.sgi.com/projects/FreeB -** -** Note that, as provided in the License, the Software is distributed on an -** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS -** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND -** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A -** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. -** -** Original Code. The Original Code is: OpenGL Sample Implementation, -** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, -** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. -** Copyright in any portions created by third parties is as indicated -** elsewhere herein. All Rights Reserved. -** -** Additional Notice Provisions: The application programming interfaces -** established by SGI in conjunction with the Original Code are The -** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released -** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version -** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X -** Window System(R) (Version 1.3), released October 19, 1998. This software -** was created using the OpenGL(R) version 1.2.1 Sample Implementation -** published by SGI, but has not been independently verified as being -** compliant with the OpenGL(R) version 1.2.1 Specification. -** -*/ -/* -*/ - -#include "gluos.h" -#include <stdlib.h> -#include <stdio.h> -#include <GL/gl.h> -#include <math.h> -#include <assert.h> - -#include "glsurfeval.h" - -//extern int surfcount; - -//#define CRACK_TEST - -#define AVOID_ZERO_NORMAL - -#ifdef AVOID_ZERO_NORMAL -#define myabs(x) ((x>0)? x: (-x)) -#define MYZERO 0.000001 -#define MYDELTA 0.001 -#endif - -//#define USE_LOD -#ifdef USE_LOD -//#define LOD_EVAL_COORD(u,v) inDoEvalCoord2EM(u,v) -#define LOD_EVAL_COORD(u,v) glEvalCoord2f(u,v) - -static void LOD_interpolate(REAL A[2], REAL B[2], REAL C[2], int j, int k, int pow2_level, - REAL& u, REAL& v) -{ - REAL a,a1,b,b1; - - a = ((REAL) j) / ((REAL) pow2_level); - a1 = 1-a; - - if(j != 0) - { - b = ((REAL) k) / ((REAL)j); - b1 = 1-b; - } - REAL x,y,z; - x = a1; - if(j==0) - { - y=0; z=0; - } - else{ - y = b1*a; - z = b *a; - } - - u = x*A[0] + y*B[0] + z*C[0]; - v = x*A[1] + y*B[1] + z*C[1]; -} - -void OpenGLSurfaceEvaluator::LOD_triangle(REAL A[2], REAL B[2], REAL C[2], - int level) -{ - int k,j; - int pow2_level; - /*compute 2^level*/ - pow2_level = 1; - - for(j=0; j<level; j++) - pow2_level *= 2; - for(j=0; j<=pow2_level-1; j++) - { - REAL u,v; - -/* beginCallBack(GL_TRIANGLE_STRIP);*/ -glBegin(GL_TRIANGLE_STRIP); - LOD_interpolate(A,B,C, j+1, j+1, pow2_level, u,v); -#ifdef USE_LOD - LOD_EVAL_COORD(u,v); -// glEvalCoord2f(u,v); -#else - inDoEvalCoord2EM(u,v); -#endif - - for(k=0; k<=j; k++) - { - LOD_interpolate(A,B,C,j,j-k,pow2_level, u,v); -#ifdef USE_LOD - LOD_EVAL_COORD(u,v); -// glEvalCoord2f(u,v); -#else - inDoEvalCoord2EM(u,v); -#endif - - LOD_interpolate(A,B,C,j+1,j-k,pow2_level, u,v); - -#ifdef USE_LOD - LOD_EVAL_COORD(u,v); -// glEvalCoord2f(u,v); -#else - inDoEvalCoord2EM(u,v); -#endif - } -// endCallBack(); -glEnd(); - } -} - -void OpenGLSurfaceEvaluator::LOD_eval(int num_vert, REAL* verts, int type, - int level - ) -{ - int i,k; - switch(type){ - case GL_TRIANGLE_STRIP: - case GL_QUAD_STRIP: - for(i=2, k=4; i<=num_vert-2; i+=2, k+=4) - { - LOD_triangle(verts+k-4, verts+k-2, verts+k, - level - ); - LOD_triangle(verts+k-2, verts+k+2, verts+k, - level - ); - } - if(num_vert % 2 ==1) - { - LOD_triangle(verts+2*(num_vert-3), verts+2*(num_vert-2), verts+2*(num_vert-1), - level - ); - } - break; - case GL_TRIANGLE_FAN: - for(i=1, k=2; i<=num_vert-2; i++, k+=2) - { - LOD_triangle(verts,verts+k, verts+k+2, - level - ); - } - break; - - default: - fprintf(stderr, "typy not supported in LOD_\n"); - } -} - - -#endif //USE_LOD - -//#define GENERIC_TEST -#ifdef GENERIC_TEST -extern float xmin, xmax, ymin, ymax, zmin, zmax; /*bounding box*/ -extern int temp_signal; - -static void gTessVertexSphere(float u, float v, float temp_normal[3], float temp_vertex[3]) -{ - float r=2.0; - float Ox = 0.5*(xmin+xmax); - float Oy = 0.5*(ymin+ymax); - float Oz = 0.5*(zmin+zmax); - float nx = cos(v) * sin(u); - float ny = sin(v) * sin(u); - float nz = cos(u); - float x= Ox+r * nx; - float y= Oy+r * ny; - float z= Oz+r * nz; - - temp_normal[0] = nx; - temp_normal[1] = ny; - temp_normal[2] = nz; - temp_vertex[0] = x; - temp_vertex[1] = y; - temp_vertex[2] = z; - -// glNormal3f(nx,ny,nz); -// glVertex3f(x,y,z); -} - -static void gTessVertexCyl(float u, float v, float temp_normal[3], float temp_vertex[3]) -{ - float r=2.0; - float Ox = 0.5*(xmin+xmax); - float Oy = 0.5*(ymin+ymax); - float Oz = 0.5*(zmin+zmax); - float nx = cos(v); - float ny = sin(v); - float nz = 0; - float x= Ox+r * nx; - float y= Oy+r * ny; - float z= Oz - 2*u; - - temp_normal[0] = nx; - temp_normal[1] = ny; - temp_normal[2] = nz; - temp_vertex[0] = x; - temp_vertex[1] = y; - temp_vertex[2] = z; - -/* - glNormal3f(nx,ny,nz); - glVertex3f(x,y,z); -*/ -} - -#endif //GENERIC_TEST - -void OpenGLSurfaceEvaluator::inBPMListEval(bezierPatchMesh* list) -{ - bezierPatchMesh* temp; - for(temp = list; temp != NULL; temp = temp->next) - { - inBPMEval(temp); - } -} - -void OpenGLSurfaceEvaluator::inBPMEval(bezierPatchMesh* bpm) -{ - int i,j,k,l; - float u,v; - - int ustride = bpm->bpatch->dimension * bpm->bpatch->vorder; - int vstride = bpm->bpatch->dimension; - inMap2f( - (bpm->bpatch->dimension == 3)? GL_MAP2_VERTEX_3 : GL_MAP2_VERTEX_4, - bpm->bpatch->umin, - bpm->bpatch->umax, - ustride, - bpm->bpatch->uorder, - bpm->bpatch->vmin, - bpm->bpatch->vmax, - vstride, - bpm->bpatch->vorder, - bpm->bpatch->ctlpoints); - - 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.*/ - assert(bpm->vertex_array); - bpm->normal_array = (float*) malloc(sizeof(float)* (bpm->index_UVarray/2) * 3); - assert(bpm->normal_array); -#ifdef CRACK_TEST -if( global_ev_u1 ==2 && global_ev_u2 == 3 - && global_ev_v1 ==2 && global_ev_v2 == 3) -{ -REAL vertex[4]; -REAL normal[4]; -#ifdef DEBUG -printf("***number 1\n"); -#endif - -beginCallBack(GL_QUAD_STRIP, NULL); -inEvalCoord2f(3.0, 3.0); -inEvalCoord2f(2.0, 3.0); -inEvalCoord2f(3.0, 2.7); -inEvalCoord2f(2.0, 2.7); -inEvalCoord2f(3.0, 2.0); -inEvalCoord2f(2.0, 2.0); -endCallBack(NULL); - - -beginCallBack(GL_TRIANGLE_STRIP, NULL); -inEvalCoord2f(2.0, 3.0); -inEvalCoord2f(2.0, 2.0); -inEvalCoord2f(2.0, 2.7); -endCallBack(NULL); - -} - -/* -if( global_ev_u1 ==2 && global_ev_u2 == 3 - && global_ev_v1 ==1 && global_ev_v2 == 2) -{ -#ifdef DEBUG -printf("***number 2\n"); -#endif -beginCallBack(GL_QUAD_STRIP); -inEvalCoord2f(2.0, 2.0); -inEvalCoord2f(2.0, 1.0); -inEvalCoord2f(3.0, 2.0); -inEvalCoord2f(3.0, 1.0); -endCallBack(); -} -*/ -if( global_ev_u1 ==1 && global_ev_u2 == 2 - && global_ev_v1 ==2 && global_ev_v2 == 3) -{ -#ifdef DEBUG -printf("***number 3\n"); -#endif -beginCallBack(GL_QUAD_STRIP, NULL); -inEvalCoord2f(2.0, 3.0); -inEvalCoord2f(1.0, 3.0); -inEvalCoord2f(2.0, 2.3); -inEvalCoord2f(1.0, 2.3); -inEvalCoord2f(2.0, 2.0); -inEvalCoord2f(1.0, 2.0); -endCallBack(NULL); - -beginCallBack(GL_TRIANGLE_STRIP, NULL); -inEvalCoord2f(2.0, 2.3); -inEvalCoord2f(2.0, 2.0); -inEvalCoord2f(2.0, 3.0); -endCallBack(NULL); - -} -return; -#endif - - k=0; - l=0; - - for(i=0; i<bpm->index_length_array; i++) - { - beginCallBack(bpm->type_array[i], userData); - for(j=0; j<bpm->length_array[i]; j++) - { - u = bpm->UVarray[k]; - v = bpm->UVarray[k+1]; - inDoEvalCoord2NOGE(u,v, - bpm->vertex_array+l, - bpm->normal_array+l); - - normalCallBack(bpm->normal_array+l, userData); - vertexCallBack(bpm->vertex_array+l, userData); - - k += 2; - l += 3; - } - endCallBack(userData); - } -} - -void OpenGLSurfaceEvaluator::inEvalPoint2(int i, int j) -{ - REAL du, dv; - REAL point[4]; - REAL normal[3]; - REAL u,v; - du = (global_grid_u1 - global_grid_u0) / (REAL)global_grid_nu; - dv = (global_grid_v1 - global_grid_v0) / (REAL)global_grid_nv; - u = (i==global_grid_nu)? global_grid_u1:(global_grid_u0 + i*du); - v = (j == global_grid_nv)? global_grid_v1: (global_grid_v0 +j*dv); - inDoEvalCoord2(u,v,point,normal); -} - -void OpenGLSurfaceEvaluator::inEvalCoord2f(REAL u, REAL v) -{ - - REAL point[4]; - REAL normal[3]; - inDoEvalCoord2(u,v,point, normal); -} - - - -/*define a grid. store the values into the global variabls: - * global_grid_* - *These values will be used later by evaluating functions - */ -void OpenGLSurfaceEvaluator::inMapGrid2f(int nu, REAL u0, REAL u1, - int nv, REAL v0, REAL v1) -{ - global_grid_u0 = u0; - global_grid_u1 = u1; - global_grid_nu = nu; - global_grid_v0 = v0; - global_grid_v1 = v1; - global_grid_nv = nv; -} - -void OpenGLSurfaceEvaluator::inEvalMesh2(int lowU, int lowV, int highU, int highV) -{ - REAL du, dv; - int i,j; - REAL point[4]; - REAL normal[3]; - if(global_grid_nu == 0 || global_grid_nv == 0) - return; /*no points need to be output*/ - du = (global_grid_u1 - global_grid_u0) / (REAL)global_grid_nu; - dv = (global_grid_v1 - global_grid_v0) / (REAL)global_grid_nv; - - if(global_grid_nu >= global_grid_nv){ - for(i=lowU; i<highU; i++){ - REAL u1 = (i==global_grid_nu)? global_grid_u1:(global_grid_u0 + i*du); - REAL u2 = ((i+1) == global_grid_nu)? global_grid_u1: (global_grid_u0+(i+1)*du); - - bgnqstrip(); - for(j=highV; j>=lowV; j--){ - REAL v1 = (j == global_grid_nv)? global_grid_v1: (global_grid_v0 +j*dv); - - inDoEvalCoord2(u1, v1, point, normal); - inDoEvalCoord2(u2, v1, point, normal); - } - endqstrip(); - } - } - - else{ - for(i=lowV; i<highV; i++){ - REAL v1 = (i==global_grid_nv)? global_grid_v1:(global_grid_v0 + i*dv); - REAL v2 = ((i+1) == global_grid_nv)? global_grid_v1: (global_grid_v0+(i+1)*dv); - - bgnqstrip(); - for(j=highU; j>=lowU; j--){ - REAL u1 = (j == global_grid_nu)? global_grid_u1: (global_grid_u0 +j*du); - inDoEvalCoord2(u1, v2, point, normal); - inDoEvalCoord2(u1, v1, point, normal); - } - endqstrip(); - } - } - -} - -void OpenGLSurfaceEvaluator::inMap2f(int k, - REAL ulower, - REAL uupper, - int ustride, - int uorder, - REAL vlower, - REAL vupper, - int vstride, - int vorder, - REAL *ctlPoints) -{ - int i,j,x; - REAL *data = global_ev_ctlPoints; - - - - if(k == GL_MAP2_VERTEX_3) k=3; - else if (k==GL_MAP2_VERTEX_4) k =4; - else { - printf("error in inMap2f, maptype=%i is wrong, k,map is not updated\n", k); - return; - } - - global_ev_k = k; - global_ev_u1 = ulower; - global_ev_u2 = uupper; - global_ev_ustride = ustride; - global_ev_uorder = uorder; - global_ev_v1 = vlower; - global_ev_v2 = vupper; - global_ev_vstride = vstride; - global_ev_vorder = vorder; - - /*copy the contrl points from ctlPoints to global_ev_ctlPoints*/ - for (i=0; i<uorder; i++) { - for (j=0; j<vorder; j++) { - for (x=0; x<k; x++) { - data[x] = ctlPoints[x]; - } - ctlPoints += vstride; - data += k; - } - ctlPoints += ustride - vstride * vorder; - } - -} - - -/* - *given a point p with homegeneous coordiante (x,y,z,w), - *let pu(x,y,z,w) be its partial derivative vector with - *respect to u - *and pv(x,y,z,w) be its partial derivative vector with repect to v. - *This function returns the partial derivative vectors of the - *inhomegensous coordinates, i.e., - * (x/w, y/w, z/w) with respect to u and v. - */ -void OpenGLSurfaceEvaluator::inComputeFirstPartials(REAL *p, REAL *pu, REAL *pv) -{ - pu[0] = pu[0]*p[3] - pu[3]*p[0]; - pu[1] = pu[1]*p[3] - pu[3]*p[1]; - pu[2] = pu[2]*p[3] - pu[3]*p[2]; - - pv[0] = pv[0]*p[3] - pv[3]*p[0]; - pv[1] = pv[1]*p[3] - pv[3]*p[1]; - pv[2] = pv[2]*p[3] - pv[3]*p[2]; -} - -/*compute the cross product of pu and pv and normalize. - *the normal is returned in retNormal - * pu: dimension 3 - * pv: dimension 3 - * n: return normal, of dimension 3 - */ -void OpenGLSurfaceEvaluator::inComputeNormal2(REAL *pu, REAL *pv, REAL *n) -{ - REAL mag; - - n[0] = pu[1]*pv[2] - pu[2]*pv[1]; - n[1] = pu[2]*pv[0] - pu[0]*pv[2]; - n[2] = pu[0]*pv[1] - pu[1]*pv[0]; - - mag = sqrt(n[0]*n[0] + n[1]*n[1] + n[2]*n[2]); - - if (mag > 0.0) { - n[0] /= mag; - n[1] /= mag; - n[2] /= mag; - } -} - - - -/*Compute point and normal - *see the head of inDoDomain2WithDerivs - *for the meaning of the arguments - */ -void OpenGLSurfaceEvaluator::inDoEvalCoord2(REAL u, REAL v, - REAL *retPoint, REAL *retNormal) -{ - - REAL du[4]; - REAL dv[4]; - - - assert(global_ev_k>=3 && global_ev_k <= 4); - /*compute homegeneous point and partial derivatives*/ - 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); - -#ifdef AVOID_ZERO_NORMAL - - if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO) - { - - REAL tempdu[4]; - REAL tempdata[4]; - REAL u1 = global_ev_u1; - REAL u2 = global_ev_u2; - if(u-MYDELTA*(u2-u1) < u1) - u = u+ MYDELTA*(u2-u1); - else - u = u-MYDELTA*(u2-u1); - 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); - } - if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO) - { - REAL tempdv[4]; - REAL tempdata[4]; - REAL v1 = global_ev_v1; - REAL v2 = global_ev_v2; - if(v-MYDELTA*(v2-v1) < v1) - v = v+ MYDELTA*(v2-v1); - else - v = v-MYDELTA*(v2-v1); - 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); - } -#endif - - - /*compute normal*/ - switch(global_ev_k){ - case 3: - inComputeNormal2(du, dv, retNormal); - - break; - case 4: - inComputeFirstPartials(retPoint, du, dv); - inComputeNormal2(du, dv, retNormal); - /*transform the homegeneous coordinate of retPoint into inhomogenous one*/ - retPoint[0] /= retPoint[3]; - retPoint[1] /= retPoint[3]; - retPoint[2] /= retPoint[3]; - break; - } - /*output this vertex*/ -/* inMeshStreamInsert(global_ms, retPoint, retNormal);*/ - - - - glNormal3fv(retNormal); - glVertex3fv(retPoint); - - - - - #ifdef DEBUG - printf("vertex(%f,%f,%f)\n", retPoint[0],retPoint[1],retPoint[2]); - #endif - - - -} - -/*Compute point and normal - *see the head of inDoDomain2WithDerivs - *for the meaning of the arguments - */ -void OpenGLSurfaceEvaluator::inDoEvalCoord2NOGE_BU(REAL u, REAL v, - REAL *retPoint, REAL *retNormal) -{ - - REAL du[4]; - REAL dv[4]; - - - assert(global_ev_k>=3 && global_ev_k <= 4); - /*compute homegeneous point and partial derivatives*/ -// inPreEvaluateBU(global_ev_k, global_ev_uorder, global_ev_vorder, (u-global_ev_u1)/(global_ev_u2-global_ev_u1), global_ev_ctlPoints); - 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); - - -#ifdef AVOID_ZERO_NORMAL - - if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO) - { - - REAL tempdu[4]; - REAL tempdata[4]; - REAL u1 = global_ev_u1; - REAL u2 = global_ev_u2; - if(u-MYDELTA*(u2-u1) < u1) - u = u+ MYDELTA*(u2-u1); - else - u = u-MYDELTA*(u2-u1); - 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); - } - if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO) - { - REAL tempdv[4]; - REAL tempdata[4]; - REAL v1 = global_ev_v1; - REAL v2 = global_ev_v2; - if(v-MYDELTA*(v2-v1) < v1) - v = v+ MYDELTA*(v2-v1); - else - v = v-MYDELTA*(v2-v1); - 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); - } -#endif - - /*compute normal*/ - switch(global_ev_k){ - case 3: - inComputeNormal2(du, dv, retNormal); - break; - case 4: - inComputeFirstPartials(retPoint, du, dv); - inComputeNormal2(du, dv, retNormal); - /*transform the homegeneous coordinate of retPoint into inhomogenous one*/ - retPoint[0] /= retPoint[3]; - retPoint[1] /= retPoint[3]; - retPoint[2] /= retPoint[3]; - break; - } -} - -/*Compute point and normal - *see the head of inDoDomain2WithDerivs - *for the meaning of the arguments - */ -void OpenGLSurfaceEvaluator::inDoEvalCoord2NOGE_BV(REAL u, REAL v, - REAL *retPoint, REAL *retNormal) -{ - - REAL du[4]; - REAL dv[4]; - - - assert(global_ev_k>=3 && global_ev_k <= 4); - /*compute homegeneous point and partial derivatives*/ -// inPreEvaluateBV(global_ev_k, global_ev_uorder, global_ev_vorder, (v-global_ev_v1)/(global_ev_v2-global_ev_v1), global_ev_ctlPoints); - - 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); - - -#ifdef AVOID_ZERO_NORMAL - - if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO) - { - - REAL tempdu[4]; - REAL tempdata[4]; - REAL u1 = global_ev_u1; - REAL u2 = global_ev_u2; - if(u-MYDELTA*(u2-u1) < u1) - u = u+ MYDELTA*(u2-u1); - else - u = u-MYDELTA*(u2-u1); - 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); - } - if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO) - { - REAL tempdv[4]; - REAL tempdata[4]; - REAL v1 = global_ev_v1; - REAL v2 = global_ev_v2; - if(v-MYDELTA*(v2-v1) < v1) - v = v+ MYDELTA*(v2-v1); - else - v = v-MYDELTA*(v2-v1); - 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); - } -#endif - - /*compute normal*/ - switch(global_ev_k){ - case 3: - inComputeNormal2(du, dv, retNormal); - break; - case 4: - inComputeFirstPartials(retPoint, du, dv); - inComputeNormal2(du, dv, retNormal); - /*transform the homegeneous coordinate of retPoint into inhomogenous one*/ - retPoint[0] /= retPoint[3]; - retPoint[1] /= retPoint[3]; - retPoint[2] /= retPoint[3]; - break; - } -} - - -/*Compute point and normal - *see the head of inDoDomain2WithDerivs - *for the meaning of the arguments - */ -void OpenGLSurfaceEvaluator::inDoEvalCoord2NOGE(REAL u, REAL v, - REAL *retPoint, REAL *retNormal) -{ - - REAL du[4]; - REAL dv[4]; - - - assert(global_ev_k>=3 && global_ev_k <= 4); - /*compute homegeneous point and partial derivatives*/ - 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); - - -#ifdef AVOID_ZERO_NORMAL - - if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO) - { - - REAL tempdu[4]; - REAL tempdata[4]; - REAL u1 = global_ev_u1; - REAL u2 = global_ev_u2; - if(u-MYDELTA*(u2-u1) < u1) - u = u+ MYDELTA*(u2-u1); - else - u = u-MYDELTA*(u2-u1); - 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); - } - if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO) - { - REAL tempdv[4]; - REAL tempdata[4]; - REAL v1 = global_ev_v1; - REAL v2 = global_ev_v2; - if(v-MYDELTA*(v2-v1) < v1) - v = v+ MYDELTA*(v2-v1); - else - v = v-MYDELTA*(v2-v1); - 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); - } -#endif - - /*compute normal*/ - switch(global_ev_k){ - case 3: - inComputeNormal2(du, dv, retNormal); - break; - case 4: - inComputeFirstPartials(retPoint, du, dv); - inComputeNormal2(du, dv, retNormal); - /*transform the homegeneous coordinate of retPoint into inhomogenous one*/ - retPoint[0] /= retPoint[3]; - retPoint[1] /= retPoint[3]; - retPoint[2] /= retPoint[3]; - break; - } -// glNormal3fv(retNormal); -// glVertex3fv(retPoint); -} - -void OpenGLSurfaceEvaluator::inPreEvaluateBV(int k, int uorder, int vorder, REAL vprime, REAL *baseData) -{ - int j,row,col; - REAL p, pdv; - REAL *data; - - if(global_vprime != vprime || global_vorder != vorder) { - inPreEvaluateWithDeriv(vorder, vprime, global_vcoeff, global_vcoeffDeriv); - global_vprime = vprime; - global_vorder = vorder; - } - - for(j=0; j<k; j++){ - data = baseData+j; - for(row=0; row<uorder; row++){ - p = global_vcoeff[0] * (*data); - pdv = global_vcoeffDeriv[0] * (*data); - data += k; - for(col = 1; col < vorder; col++){ - p += global_vcoeff[col] * (*data); - pdv += global_vcoeffDeriv[col] * (*data); - data += k; - } - global_BV[row][j] = p; - global_PBV[row][j] = pdv; - } - } -} - -void OpenGLSurfaceEvaluator::inPreEvaluateBU(int k, int uorder, int vorder, REAL uprime, REAL *baseData) -{ - int j,row,col; - REAL p, pdu; - REAL *data; - - if(global_uprime != uprime || global_uorder != uorder) { - inPreEvaluateWithDeriv(uorder, uprime, global_ucoeff, global_ucoeffDeriv); - global_uprime = uprime; - global_uorder = uorder; - } - - for(j=0; j<k; j++){ - data = baseData+j; - for(col=0; col<vorder; col++){ - data = baseData+j + k*col; - p = global_ucoeff[0] * (*data); - pdu = global_ucoeffDeriv[0] * (*data); - data += k*uorder; - for(row = 1; row < uorder; row++){ - p += global_ucoeff[row] * (*data); - pdu += global_ucoeffDeriv[row] * (*data); - data += k * uorder; - } - global_BU[col][j] = p; - global_PBU[col][j] = pdu; - } - } -} - -void OpenGLSurfaceEvaluator::inDoDomain2WithDerivsBU(int k, REAL u, REAL v, - REAL u1, REAL u2, int uorder, - REAL v1, REAL v2, int vorder, - REAL *baseData, - REAL *retPoint, REAL* retdu, REAL *retdv) -{ - int j, col; - - REAL vprime; - - - if((u2 == u1) || (v2 == v1)) - return; - - vprime = (v - v1) / (v2 - v1); - - - if(global_vprime != vprime || global_vorder != vorder) { - inPreEvaluateWithDeriv(vorder, vprime, global_vcoeff, global_vcoeffDeriv); - global_vprime = vprime; - global_vorder = vorder; - } - - - for(j=0; j<k; j++) - { - retPoint[j] = retdu[j] = retdv[j] = 0.0; - for (col = 0; col < vorder; col++) { - retPoint[j] += global_BU[col][j] * global_vcoeff[col]; - retdu[j] += global_PBU[col][j] * global_vcoeff[col]; - retdv[j] += global_BU[col][j] * global_vcoeffDeriv[col]; - } - } -} - -void OpenGLSurfaceEvaluator::inDoDomain2WithDerivsBV(int k, REAL u, REAL v, - REAL u1, REAL u2, int uorder, - REAL v1, REAL v2, int vorder, - REAL *baseData, - REAL *retPoint, REAL* retdu, REAL *retdv) -{ - int j, row; - REAL uprime; - - - if((u2 == u1) || (v2 == v1)) - return; - uprime = (u - u1) / (u2 - u1); - - - if(global_uprime != uprime || global_uorder != uorder) { - inPreEvaluateWithDeriv(uorder, uprime, global_ucoeff, global_ucoeffDeriv); - global_uprime = uprime; - global_uorder = uorder; - } - - - for(j=0; j<k; j++) - { - retPoint[j] = retdu[j] = retdv[j] = 0.0; - for (row = 0; row < uorder; row++) { - retPoint[j] += global_BV[row][j] * global_ucoeff[row]; - retdu[j] += global_BV[row][j] * global_ucoeffDeriv[row]; - retdv[j] += global_PBV[row][j] * global_ucoeff[row]; - } - } -} - - -/* - *given a Bezier surface, and parameter (u,v), compute the point in the object space, - *and the normal - *k: the dimension of the object space: usually 2,3,or 4. - *u,v: the paramter pair. - *u1,u2,uorder: the Bezier polynomial of u coord is defined on [u1,u2] with order uorder. - *v1,v2,vorder: the Bezier polynomial of v coord is defined on [v1,v2] with order vorder. - *baseData: contrl points. arranged as: (u,v,k). - *retPoint: the computed point (one point) with dimension k. - *retdu: the computed partial derivative with respect to u. - *retdv: the computed partial derivative with respect to v. - */ -void OpenGLSurfaceEvaluator::inDoDomain2WithDerivs(int k, REAL u, REAL v, - REAL u1, REAL u2, int uorder, - REAL v1, REAL v2, int vorder, - REAL *baseData, - REAL *retPoint, REAL *retdu, REAL *retdv) -{ - int j, row, col; - REAL uprime; - REAL vprime; - REAL p; - REAL pdv; - REAL *data; - - if((u2 == u1) || (v2 == v1)) - return; - uprime = (u - u1) / (u2 - u1); - vprime = (v - v1) / (v2 - v1); - - /* Compute coefficients for values and derivs */ - - /* Use already cached values if possible */ - if(global_uprime != uprime || global_uorder != uorder) { - inPreEvaluateWithDeriv(uorder, uprime, global_ucoeff, global_ucoeffDeriv); - global_uorder = uorder; - global_uprime = uprime; - } - if (global_vprime != vprime || - global_vorder != vorder) { - inPreEvaluateWithDeriv(vorder, vprime, global_vcoeff, global_vcoeffDeriv); - global_vorder = vorder; - global_vprime = vprime; - } - - for (j = 0; j < k; j++) { - data=baseData+j; - retPoint[j] = retdu[j] = retdv[j] = 0.0; - for (row = 0; row < uorder; row++) { - /* - ** Minor optimization. - ** The col == 0 part of the loop is extracted so we don't - ** have to initialize p and pdv to 0. - */ - p = global_vcoeff[0] * (*data); - pdv = global_vcoeffDeriv[0] * (*data); - data += k; - for (col = 1; col < vorder; col++) { - /* Incrementally build up p, pdv value */ - p += global_vcoeff[col] * (*data); - pdv += global_vcoeffDeriv[col] * (*data); - data += k; - } - /* Use p, pdv value to incrementally add up r, du, dv */ - retPoint[j] += global_ucoeff[row] * p; - retdu[j] += global_ucoeffDeriv[row] * p; - retdv[j] += global_ucoeff[row] * pdv; - } - } -} - - -/* - *compute the Bezier polynomials C[n,j](v) for all j at v with - *return values stored in coeff[], where - * C[n,j](v) = (n,j) * v^j * (1-v)^(n-j), - * j=0,1,2,...,n. - *order : n+1 - *vprime: v - *coeff : coeff[j]=C[n,j](v), this array store the returned values. - *The algorithm is a recursive scheme: - * C[0,0]=1; - * C[n,j](v) = (1-v)*C[n-1,j](v) + v*C[n-1,j-1](v), n>=1 - *This code is copied from opengl/soft/so_eval.c:PreEvaluate - */ -void OpenGLSurfaceEvaluator::inPreEvaluate(int order, REAL vprime, REAL *coeff) -{ - int i, j; - REAL oldval, temp; - REAL oneMinusvprime; - - /* - * Minor optimization - * Compute orders 1 and 2 outright, and set coeff[0], coeff[1] to - * their i==1 loop values to avoid the initialization and the i==1 loop. - */ - if (order == 1) { - coeff[0] = 1.0; - return; - } - - oneMinusvprime = 1-vprime; - coeff[0] = oneMinusvprime; - coeff[1] = vprime; - if (order == 2) return; - - for (i = 2; i < order; i++) { - oldval = coeff[0] * vprime; - coeff[0] = oneMinusvprime * coeff[0]; - for (j = 1; j < i; j++) { - temp = oldval; - oldval = coeff[j] * vprime; - coeff[j] = temp + oneMinusvprime * coeff[j]; - } - coeff[j] = oldval; - } -} - -/* - *compute the Bezier polynomials C[n,j](v) and derivatives for all j at v with - *return values stored in coeff[] and coeffDeriv[]. - *see the head of function inPreEvaluate for the definition of C[n,j](v) - *and how to compute the values. - *The algorithm to compute the derivative is: - * dC[0,0](v) = 0. - * dC[n,j](v) = n*(dC[n-1,j-1](v) - dC[n-1,j](v)). - * - *This code is copied from opengl/soft/so_eval.c:PreEvaluateWidthDeriv - */ -void OpenGLSurfaceEvaluator::inPreEvaluateWithDeriv(int order, REAL vprime, - REAL *coeff, REAL *coeffDeriv) -{ - int i, j; - REAL oldval, temp; - REAL oneMinusvprime; - - oneMinusvprime = 1-vprime; - /* - * Minor optimization - * Compute orders 1 and 2 outright, and set coeff[0], coeff[1] to - * their i==1 loop values to avoid the initialization and the i==1 loop. - */ - if (order == 1) { - coeff[0] = 1.0; - coeffDeriv[0] = 0.0; - return; - } else if (order == 2) { - coeffDeriv[0] = -1.0; - coeffDeriv[1] = 1.0; - coeff[0] = oneMinusvprime; - coeff[1] = vprime; - return; - } - coeff[0] = oneMinusvprime; - coeff[1] = vprime; - for (i = 2; i < order - 1; i++) { - oldval = coeff[0] * vprime; - coeff[0] = oneMinusvprime * coeff[0]; - for (j = 1; j < i; j++) { - temp = oldval; - oldval = coeff[j] * vprime; - coeff[j] = temp + oneMinusvprime * coeff[j]; - } - coeff[j] = oldval; - } - coeffDeriv[0] = -coeff[0]; - /* - ** Minor optimization: - ** Would make this a "for (j=1; j<order-1; j++)" loop, but it is always - ** executed at least once, so this is more efficient. - */ - j=1; - do { - coeffDeriv[j] = coeff[j-1] - coeff[j]; - j++; - } while (j < order - 1); - coeffDeriv[j] = coeff[j-1]; - - oldval = coeff[0] * vprime; - coeff[0] = oneMinusvprime * coeff[0]; - for (j = 1; j < i; j++) { - temp = oldval; - oldval = coeff[j] * vprime; - coeff[j] = temp + oneMinusvprime * coeff[j]; - } - coeff[j] = oldval; -} - -void OpenGLSurfaceEvaluator::inEvalULine(int n_points, REAL v, REAL* u_vals, - int stride, REAL ret_points[][3], REAL ret_normals[][3]) -{ - int i,k; - REAL temp[4]; -inPreEvaluateBV_intfac(v); - - for(i=0,k=0; i<n_points; i++, k += stride) - { - inDoEvalCoord2NOGE_BV(u_vals[k],v,temp, ret_normals[i]); - - ret_points[i][0] = temp[0]; - ret_points[i][1] = temp[1]; - ret_points[i][2] = temp[2]; - - } - -} - -void OpenGLSurfaceEvaluator::inEvalVLine(int n_points, REAL u, REAL* v_vals, - int stride, REAL ret_points[][3], REAL ret_normals[][3]) -{ - int i,k; - REAL temp[4]; -inPreEvaluateBU_intfac(u); - for(i=0,k=0; i<n_points; i++, k += stride) - { - inDoEvalCoord2NOGE_BU(u, v_vals[k], temp, ret_normals[i]); - ret_points[i][0] = temp[0]; - ret_points[i][1] = temp[1]; - ret_points[i][2] = temp[2]; - } -} - - -/*triangulate a strip bounded by two lines which are parallel to U-axis - *upperVerts: the verteces on the upper line - *lowerVertx: the verteces on the lower line - *n_upper >=1 - *n_lower >=1 - */ -void OpenGLSurfaceEvaluator::inEvalUStrip(int n_upper, REAL v_upper, REAL* upper_val, int n_lower, REAL v_lower, REAL* lower_val) -{ - int i,j,k,l; - REAL leftMostV[2]; - typedef REAL REAL3[3]; - - REAL3* upperXYZ = (REAL3*) malloc(sizeof(REAL3)*n_upper); - assert(upperXYZ); - REAL3* upperNormal = (REAL3*) malloc(sizeof(REAL3) * n_upper); - assert(upperNormal); - REAL3* lowerXYZ = (REAL3*) malloc(sizeof(REAL3)*n_lower); - assert(lowerXYZ); - REAL3* lowerNormal = (REAL3*) malloc(sizeof(REAL3) * n_lower); - assert(lowerNormal); - - inEvalULine(n_upper, v_upper, upper_val, 1, upperXYZ, upperNormal); - inEvalULine(n_lower, v_lower, lower_val, 1, lowerXYZ, lowerNormal); - - - - REAL* leftMostXYZ; - REAL* leftMostNormal; - - /* - *the algorithm works by scanning from left to right. - *leftMostV: the left most of the remaining verteces (on both upper and lower). - * it could an element of upperVerts or lowerVerts. - *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 */ - - /*initialize i,j,and leftMostV - */ - if(upper_val[0] <= lower_val[0]) - { - i=1; - j=0; - - leftMostV[0] = upper_val[0]; - leftMostV[1] = v_upper; - leftMostXYZ = upperXYZ[0]; - leftMostNormal = upperNormal[0]; - } - else - { - i=0; - j=1; - - leftMostV[0] = lower_val[0]; - leftMostV[1] = v_lower; - - leftMostXYZ = lowerXYZ[0]; - leftMostNormal = lowerNormal[0]; - } - - /*the main loop. - *the invariance is that: - *at the beginning of each loop, the meaning of i,j,and leftMostV are - *maintained - */ - while(1) - { - if(i >= n_upper) /*case1: no more in upper*/ - { - if(j<n_lower-1) /*at least two vertices in lower*/ - { - bgntfan(); - glNormal3fv(leftMostNormal); - glVertex3fv(leftMostXYZ); - - while(j<n_lower){ - glNormal3fv(lowerNormal[j]); - glVertex3fv(lowerXYZ[j]); - j++; - - } - endtfan(); - } - break; /*exit the main loop*/ - } - else if(j>= n_lower) /*case2: no more in lower*/ - { - if(i<n_upper-1) /*at least two vertices in upper*/ - { - bgntfan(); - glNormal3fv(leftMostNormal); - glVertex3fv(leftMostXYZ); - - for(k=n_upper-1; k>=i; k--) /*reverse order for two-side lighting*/ - { - glNormal3fv(upperNormal[k]); - glVertex3fv(upperXYZ[k]); - } - - endtfan(); - } - break; /*exit the main loop*/ - } - else /* case3: neither is empty, plus the leftMostV, there is at least one triangle to output*/ - { - if(upper_val[i] <= lower_val[j]) - { - bgntfan(); - - glNormal3fv(lowerNormal[j]); - glVertex3fv(lowerXYZ[j]); - - /*find the last k>=i such that - *upperverts[k][0] <= lowerverts[j][0] - */ - k=i; - - while(k<n_upper) - { - if(upper_val[k] > lower_val[j]) - break; - k++; - - } - k--; - - - for(l=k; l>=i; l--)/*the reverse is for two-side lighting*/ - { - glNormal3fv(upperNormal[l]); - glVertex3fv(upperXYZ[l]); - - } - glNormal3fv(leftMostNormal); - glVertex3fv(leftMostXYZ); - - endtfan(); - - /*update i and leftMostV for next loop - */ - i = k+1; - - leftMostV[0] = upper_val[k]; - leftMostV[1] = v_upper; - leftMostNormal = upperNormal[k]; - leftMostXYZ = upperXYZ[k]; - } - else /*upperVerts[i][0] > lowerVerts[j][0]*/ - { - bgntfan(); - glNormal3fv(upperNormal[i]); - glVertex3fv(upperXYZ[i]); - - glNormal3fv(leftMostNormal); - glVertex3fv(leftMostXYZ); - - - /*find the last k>=j such that - *lowerverts[k][0] < upperverts[i][0] - */ - k=j; - while(k< n_lower) - { - if(lower_val[k] >= upper_val[i]) - break; - glNormal3fv(lowerNormal[k]); - glVertex3fv(lowerXYZ[k]); - - k++; - } - endtfan(); - - /*update j and leftMostV for next loop - */ - j=k; - leftMostV[0] = lower_val[j-1]; - leftMostV[1] = v_lower; - - leftMostNormal = lowerNormal[j-1]; - leftMostXYZ = lowerXYZ[j-1]; - } - } - } - //clean up - free(upperXYZ); - free(lowerXYZ); - free(upperNormal); - free(lowerNormal); -} - -/*triangulate a strip bounded by two lines which are parallel to V-axis - *leftVerts: the verteces on the left line - *rightVertx: the verteces on the right line - *n_left >=1 - *n_right >=1 - */ -void OpenGLSurfaceEvaluator::inEvalVStrip(int n_left, REAL u_left, REAL* left_val, int n_right, REAL u_right, REAL* right_val) -{ - int i,j,k,l; - REAL botMostV[2]; - typedef REAL REAL3[3]; - - REAL3* leftXYZ = (REAL3*) malloc(sizeof(REAL3)*n_left); - assert(leftXYZ); - REAL3* leftNormal = (REAL3*) malloc(sizeof(REAL3) * n_left); - assert(leftNormal); - REAL3* rightXYZ = (REAL3*) malloc(sizeof(REAL3)*n_right); - assert(rightXYZ); - REAL3* rightNormal = (REAL3*) malloc(sizeof(REAL3) * n_right); - assert(rightNormal); - - inEvalVLine(n_left, u_left, left_val, 1, leftXYZ, leftNormal); - inEvalVLine(n_right, u_right, right_val, 1, rightXYZ, rightNormal); - - - - REAL* botMostXYZ; - REAL* botMostNormal; - - /* - *the algorithm works by scanning from bot to top. - *botMostV: the bot most of the remaining verteces (on both left and right). - * it could an element of leftVerts or rightVerts. - *i: leftVerts[i] is the first vertex to the top of botMostV on left line - *j: rightVerts[j] is the first vertex to the top of botMostV on rightline */ - - /*initialize i,j,and botMostV - */ - if(left_val[0] <= right_val[0]) - { - i=1; - j=0; - - botMostV[0] = u_left; - botMostV[1] = left_val[0]; - botMostXYZ = leftXYZ[0]; - botMostNormal = leftNormal[0]; - } - else - { - i=0; - j=1; - - botMostV[0] = u_right; - botMostV[1] = right_val[0]; - - botMostXYZ = rightXYZ[0]; - botMostNormal = rightNormal[0]; - } - - /*the main loop. - *the invariance is that: - *at the beginning of each loop, the meaning of i,j,and botMostV are - *maintained - */ - while(1) - { - if(i >= n_left) /*case1: no more in left*/ - { - if(j<n_right-1) /*at least two vertices in right*/ - { - bgntfan(); - glNormal3fv(botMostNormal); - glVertex3fv(botMostXYZ); - - while(j<n_right){ - glNormal3fv(rightNormal[j]); - glVertex3fv(rightXYZ[j]); - j++; - - } - endtfan(); - } - break; /*exit the main loop*/ - } - else if(j>= n_right) /*case2: no more in right*/ - { - if(i<n_left-1) /*at least two vertices in left*/ - { - bgntfan(); - glNormal3fv(botMostNormal); - glVertex3fv(botMostXYZ); - - for(k=n_left-1; k>=i; k--) /*reverse order for two-side lighting*/ - { - glNormal3fv(leftNormal[k]); - glVertex3fv(leftXYZ[k]); - } - - endtfan(); - } - break; /*exit the main loop*/ - } - else /* case3: neither is empty, plus the botMostV, there is at least one triangle to output*/ - { - if(left_val[i] <= right_val[j]) - { - bgntfan(); - - glNormal3fv(rightNormal[j]); - glVertex3fv(rightXYZ[j]); - - /*find the last k>=i such that - *leftverts[k][0] <= rightverts[j][0] - */ - k=i; - - while(k<n_left) - { - if(left_val[k] > right_val[j]) - break; - k++; - - } - k--; - - - for(l=k; l>=i; l--)/*the reverse is for two-side lighting*/ - { - glNormal3fv(leftNormal[l]); - glVertex3fv(leftXYZ[l]); - - } - glNormal3fv(botMostNormal); - glVertex3fv(botMostXYZ); - - endtfan(); - - /*update i and botMostV for next loop - */ - i = k+1; - - botMostV[0] = u_left; - botMostV[1] = left_val[k]; - botMostNormal = leftNormal[k]; - botMostXYZ = leftXYZ[k]; - } - else /*left_val[i] > right_val[j])*/ - { - bgntfan(); - glNormal3fv(leftNormal[i]); - glVertex3fv(leftXYZ[i]); - - glNormal3fv(botMostNormal); - glVertex3fv(botMostXYZ); - - - /*find the last k>=j such that - *rightverts[k][0] < leftverts[i][0] - */ - k=j; - while(k< n_right) - { - if(right_val[k] >= left_val[i]) - break; - glNormal3fv(rightNormal[k]); - glVertex3fv(rightXYZ[k]); - - k++; - } - endtfan(); - - /*update j and botMostV for next loop - */ - j=k; - botMostV[0] = u_right; - botMostV[1] = right_val[j-1]; - - botMostNormal = rightNormal[j-1]; - botMostXYZ = rightXYZ[j-1]; - } - } - } - //clean up - free(leftXYZ); - free(rightXYZ); - free(leftNormal); - free(rightNormal); -} - -/*-----------------------begin evalMachine-------------------*/ -void OpenGLSurfaceEvaluator::inMap2fEM(int which, int k, - REAL ulower, - REAL uupper, - int ustride, - int uorder, - REAL vlower, - REAL vupper, - int vstride, - int vorder, - REAL *ctlPoints) -{ - int i,j,x; - surfEvalMachine *temp_em; - switch(which){ - case 0: //vertex - vertex_flag = 1; - temp_em = &em_vertex; - break; - case 1: //normal - normal_flag = 1; - temp_em = &em_normal; - break; - case 2: //color - color_flag = 1; - temp_em = &em_color; - break; - default: - texcoord_flag = 1; - temp_em = &em_texcoord; - break; - } - - REAL *data = temp_em->ctlPoints; - - temp_em->uprime = -1;//initilized - temp_em->vprime = -1; - - temp_em->k = k; - temp_em->u1 = ulower; - temp_em->u2 = uupper; - temp_em->ustride = ustride; - temp_em->uorder = uorder; - temp_em->v1 = vlower; - temp_em->v2 = vupper; - temp_em->vstride = vstride; - temp_em->vorder = vorder; - - /*copy the contrl points from ctlPoints to global_ev_ctlPoints*/ - for (i=0; i<uorder; i++) { - for (j=0; j<vorder; j++) { - for (x=0; x<k; x++) { - data[x] = ctlPoints[x]; - } - ctlPoints += vstride; - data += k; - } - ctlPoints += ustride - vstride * vorder; - } -} - -void OpenGLSurfaceEvaluator::inDoDomain2WithDerivsEM(surfEvalMachine *em, REAL u, REAL v, - REAL *retPoint, REAL *retdu, REAL *retdv) -{ - int j, row, col; - REAL the_uprime; - REAL the_vprime; - REAL p; - REAL pdv; - REAL *data; - - if((em->u2 == em->u1) || (em->v2 == em->v1)) - return; - the_uprime = (u - em->u1) / (em->u2 - em->u1); - the_vprime = (v - em->v1) / (em->v2 - em->v1); - - /* Compute coefficients for values and derivs */ - - /* Use already cached values if possible */ - if(em->uprime != the_uprime) { - inPreEvaluateWithDeriv(em->uorder, the_uprime, em->ucoeff, em->ucoeffDeriv); - em->uprime = the_uprime; - } - if (em->vprime != the_vprime) { - inPreEvaluateWithDeriv(em->vorder, the_vprime, em->vcoeff, em->vcoeffDeriv); - em->vprime = the_vprime; - } - - for (j = 0; j < em->k; j++) { - data=em->ctlPoints+j; - retPoint[j] = retdu[j] = retdv[j] = 0.0; - for (row = 0; row < em->uorder; row++) { - /* - ** Minor optimization. - ** The col == 0 part of the loop is extracted so we don't - ** have to initialize p and pdv to 0. - */ - p = em->vcoeff[0] * (*data); - pdv = em->vcoeffDeriv[0] * (*data); - data += em->k; - for (col = 1; col < em->vorder; col++) { - /* Incrementally build up p, pdv value */ - p += em->vcoeff[col] * (*data); - pdv += em->vcoeffDeriv[col] * (*data); - data += em->k; - } - /* Use p, pdv value to incrementally add up r, du, dv */ - retPoint[j] += em->ucoeff[row] * p; - retdu[j] += em->ucoeffDeriv[row] * p; - retdv[j] += em->ucoeff[row] * pdv; - } - } -} - -void OpenGLSurfaceEvaluator::inDoDomain2EM(surfEvalMachine *em, REAL u, REAL v, - REAL *retPoint) -{ - int j, row, col; - REAL the_uprime; - REAL the_vprime; - REAL p; - REAL *data; - - if((em->u2 == em->u1) || (em->v2 == em->v1)) - return; - the_uprime = (u - em->u1) / (em->u2 - em->u1); - the_vprime = (v - em->v1) / (em->v2 - em->v1); - - /* Compute coefficients for values and derivs */ - - /* Use already cached values if possible */ - if(em->uprime != the_uprime) { - inPreEvaluate(em->uorder, the_uprime, em->ucoeff); - em->uprime = the_uprime; - } - if (em->vprime != the_vprime) { - inPreEvaluate(em->vorder, the_vprime, em->vcoeff); - em->vprime = the_vprime; - } - - for (j = 0; j < em->k; j++) { - data=em->ctlPoints+j; - retPoint[j] = 0.0; - for (row = 0; row < em->uorder; row++) { - /* - ** Minor optimization. - ** The col == 0 part of the loop is extracted so we don't - ** have to initialize p and pdv to 0. - */ - p = em->vcoeff[0] * (*data); - data += em->k; - for (col = 1; col < em->vorder; col++) { - /* Incrementally build up p, pdv value */ - p += em->vcoeff[col] * (*data); - data += em->k; - } - /* Use p, pdv value to incrementally add up r, du, dv */ - retPoint[j] += em->ucoeff[row] * p; - } - } -} - - -void OpenGLSurfaceEvaluator::inDoEvalCoord2EM(REAL u, REAL v) -{ - REAL temp_vertex[5]; - REAL temp_normal[3]; - REAL temp_color[4]; - REAL temp_texcoord[4]; - - if(texcoord_flag) - { - inDoDomain2EM(&em_texcoord, u,v, temp_texcoord); - texcoordCallBack(temp_texcoord, userData); - } - if(color_flag) - { - inDoDomain2EM(&em_color, u,v, temp_color); - colorCallBack(temp_color, userData); - } - - if(normal_flag) //there is a normla map - { - inDoDomain2EM(&em_normal, u,v, temp_normal); - normalCallBack(temp_normal, userData); - - if(vertex_flag) - { - inDoDomain2EM(&em_vertex, u,v,temp_vertex); - if(em_vertex.k == 4) - { - temp_vertex[0] /= temp_vertex[3]; - temp_vertex[1] /= temp_vertex[3]; - temp_vertex[2] /= temp_vertex[3]; - } - temp_vertex[3]=u; - temp_vertex[4]=v; - vertexCallBack(temp_vertex, userData); - } - } - else if(auto_normal_flag) //no normal map but there is a normal callbackfunctin - { - REAL du[4]; - REAL dv[4]; - - /*compute homegeneous point and partial derivatives*/ - inDoDomain2WithDerivsEM(&em_vertex, u,v,temp_vertex,du,dv); - - if(em_vertex.k ==4) - inComputeFirstPartials(temp_vertex, du, dv); - -#ifdef AVOID_ZERO_NORMAL - if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO) - { - - REAL tempdu[4]; - REAL tempdata[4]; - REAL u1 = em_vertex.u1; - REAL u2 = em_vertex.u2; - if(u-MYDELTA*(u2-u1) < u1) - u = u+ MYDELTA*(u2-u1); - else - u = u-MYDELTA*(u2-u1); - inDoDomain2WithDerivsEM(&em_vertex,u,v, tempdata, tempdu, dv); - - if(em_vertex.k ==4) - inComputeFirstPartials(temp_vertex, du, dv); - } - else if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO) - { - REAL tempdv[4]; - REAL tempdata[4]; - REAL v1 = em_vertex.v1; - REAL v2 = em_vertex.v2; - if(v-MYDELTA*(v2-v1) < v1) - v = v+ MYDELTA*(v2-v1); - else - v = v-MYDELTA*(v2-v1); - inDoDomain2WithDerivsEM(&em_vertex,u,v, tempdata, du, tempdv); - - if(em_vertex.k ==4) - inComputeFirstPartials(temp_vertex, du, dv); - } -#endif - - /*compute normal*/ - switch(em_vertex.k){ - case 3: - - inComputeNormal2(du, dv, temp_normal); - break; - case 4: - -// inComputeFirstPartials(temp_vertex, du, dv); - inComputeNormal2(du, dv, temp_normal); - - /*transform the homegeneous coordinate of retPoint into inhomogenous one*/ - temp_vertex[0] /= temp_vertex[3]; - temp_vertex[1] /= temp_vertex[3]; - temp_vertex[2] /= temp_vertex[3]; - break; - } - normalCallBack(temp_normal, userData); - temp_vertex[3] = u; - temp_vertex[4] = v; - vertexCallBack(temp_vertex, userData); - - }/*end if auto_normal*/ - else //no normal map, and no normal callback function - { - if(vertex_flag) - { - inDoDomain2EM(&em_vertex, u,v,temp_vertex); - if(em_vertex.k == 4) - { - temp_vertex[0] /= temp_vertex[3]; - temp_vertex[1] /= temp_vertex[3]; - temp_vertex[2] /= temp_vertex[3]; - } - temp_vertex[3] = u; - temp_vertex[4] = v; - vertexCallBack(temp_vertex, userData); - } - } -} - - -void OpenGLSurfaceEvaluator::inBPMEvalEM(bezierPatchMesh* bpm) -{ - int i,j,k; - float u,v; - - int ustride; - int vstride; - -#ifdef USE_LOD - if(bpm->bpatch != NULL) - { - bezierPatch* p=bpm->bpatch; - ustride = p->dimension * p->vorder; - vstride = p->dimension; - - glMap2f( (p->dimension == 3)? GL_MAP2_VERTEX_3 : GL_MAP2_VERTEX_4, - p->umin, - p->umax, - ustride, - p->uorder, - p->vmin, - p->vmax, - vstride, - p->vorder, - p->ctlpoints); - - -/* - inMap2fEM(0, p->dimension, - p->umin, - p->umax, - ustride, - p->uorder, - p->vmin, - p->vmax, - vstride, - p->vorder, - p->ctlpoints); -*/ - } -#else - - if(bpm->bpatch != NULL){ - bezierPatch* p = bpm->bpatch; - ustride = p->dimension * p->vorder; - vstride = p->dimension; - inMap2fEM(0, p->dimension, - p->umin, - p->umax, - ustride, - p->uorder, - p->vmin, - p->vmax, - vstride, - p->vorder, - p->ctlpoints); - } - if(bpm->bpatch_normal != NULL){ - bezierPatch* p = bpm->bpatch_normal; - ustride = p->dimension * p->vorder; - vstride = p->dimension; - inMap2fEM(1, p->dimension, - p->umin, - p->umax, - ustride, - p->uorder, - p->vmin, - p->vmax, - vstride, - p->vorder, - p->ctlpoints); - } - if(bpm->bpatch_color != NULL){ - bezierPatch* p = bpm->bpatch_color; - ustride = p->dimension * p->vorder; - vstride = p->dimension; - inMap2fEM(2, p->dimension, - p->umin, - p->umax, - ustride, - p->uorder, - p->vmin, - p->vmax, - vstride, - p->vorder, - p->ctlpoints); - } - if(bpm->bpatch_texcoord != NULL){ - bezierPatch* p = bpm->bpatch_texcoord; - ustride = p->dimension * p->vorder; - vstride = p->dimension; - inMap2fEM(3, p->dimension, - p->umin, - p->umax, - ustride, - p->uorder, - p->vmin, - p->vmax, - vstride, - p->vorder, - p->ctlpoints); - } -#endif - - - k=0; - for(i=0; i<bpm->index_length_array; i++) - { -#ifdef USE_LOD - if(bpm->type_array[i] == GL_POLYGON) //a mesh - { - GLfloat *temp = bpm->UVarray+k; - GLfloat u0 = temp[0]; - GLfloat v0 = temp[1]; - GLfloat u1 = temp[2]; - GLfloat v1 = temp[3]; - GLint nu = (GLint) ( temp[4]); - GLint nv = (GLint) ( temp[5]); - GLint umin = (GLint) ( temp[6]); - GLint vmin = (GLint) ( temp[7]); - GLint umax = (GLint) ( temp[8]); - GLint vmax = (GLint) ( temp[9]); - - glMapGrid2f(LOD_eval_level*nu, u0, u1, LOD_eval_level*nv, v0, v1); - glEvalMesh2(GL_FILL, LOD_eval_level*umin, LOD_eval_level*umax, LOD_eval_level*vmin, LOD_eval_level*vmax); - } - else - { - LOD_eval(bpm->length_array[i], bpm->UVarray+k, bpm->type_array[i], - 0 - ); - } - k+= 2*bpm->length_array[i]; - -#else //undef USE_LOD - -#ifdef CRACK_TEST -if( bpm->bpatch->umin == 2 && bpm->bpatch->umax == 3 - && bpm->bpatch->vmin ==2 && bpm->bpatch->vmax == 3) -{ -REAL vertex[4]; -REAL normal[4]; -#ifdef DEBUG -printf("***number ****1\n"); -#endif - -beginCallBack(GL_QUAD_STRIP, NULL); -inDoEvalCoord2EM(3.0, 3.0); -inDoEvalCoord2EM(2.0, 3.0); -inDoEvalCoord2EM(3.0, 2.7); -inDoEvalCoord2EM(2.0, 2.7); -inDoEvalCoord2EM(3.0, 2.0); -inDoEvalCoord2EM(2.0, 2.0); -endCallBack(NULL); - -beginCallBack(GL_TRIANGLE_STRIP, NULL); -inDoEvalCoord2EM(2.0, 3.0); -inDoEvalCoord2EM(2.0, 2.0); -inDoEvalCoord2EM(2.0, 2.7); -endCallBack(NULL); - -} -if( bpm->bpatch->umin == 1 && bpm->bpatch->umax == 2 - && bpm->bpatch->vmin ==2 && bpm->bpatch->vmax == 3) -{ -#ifdef DEBUG -printf("***number 3\n"); -#endif -beginCallBack(GL_QUAD_STRIP, NULL); -inDoEvalCoord2EM(2.0, 3.0); -inDoEvalCoord2EM(1.0, 3.0); -inDoEvalCoord2EM(2.0, 2.3); -inDoEvalCoord2EM(1.0, 2.3); -inDoEvalCoord2EM(2.0, 2.0); -inDoEvalCoord2EM(1.0, 2.0); -endCallBack(NULL); - -beginCallBack(GL_TRIANGLE_STRIP, NULL); -inDoEvalCoord2EM(2.0, 2.3); -inDoEvalCoord2EM(2.0, 2.0); -inDoEvalCoord2EM(2.0, 3.0); -endCallBack(NULL); - -} -return; -#endif //CRACK_TEST - - beginCallBack(bpm->type_array[i], userData); - - for(j=0; j<bpm->length_array[i]; j++) - { - u = bpm->UVarray[k]; - v = bpm->UVarray[k+1]; -#ifdef USE_LOD - LOD_EVAL_COORD(u,v); -// glEvalCoord2f(u,v); -#else - -#ifdef GENERIC_TEST - float temp_normal[3]; - float temp_vertex[3]; - if(temp_signal == 0) - { - gTessVertexSphere(u,v, temp_normal, temp_vertex); -//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]); - normalCallBack(temp_normal, userData); - vertexCallBack(temp_vertex, userData); - } - else if(temp_signal == 1) - { - gTessVertexCyl(u,v, temp_normal, temp_vertex); -//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]); - normalCallBack(temp_normal, userData); - vertexCallBack(temp_vertex, userData); - } - else -#endif //GENERIC_TEST - - inDoEvalCoord2EM(u,v); - -#endif //USE_LOD - - k += 2; - } - endCallBack(userData); - -#endif //USE_LOD - } -} - -void OpenGLSurfaceEvaluator::inBPMListEvalEM(bezierPatchMesh* list) -{ - bezierPatchMesh* temp; - for(temp = list; temp != NULL; temp = temp->next) - { - inBPMEvalEM(temp); - } -} - |