📄 insurfeval.cc
字号:
/*** 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.**** $Date: 2004/05/12 15:29:36 $ $Revision: 1.3 $*//*** $Header: /home/krh/git/sync/mesa-cvs-repo/Mesa/src/glu/sgi/libnurbs/interface/insurfeval.cc,v 1.3 2004/05/12 15:29:36 brianp Exp $*/#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_TESTextern 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_TESTvoid 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_TESTif( global_ev_u1 ==2 && global_ev_u2 == 3 && global_ev_v1 ==2 && global_ev_v2 == 3){REAL vertex[4];REAL normal[4];#ifdef DEBUGprintf("***number 1\n");#endifbeginCallBack(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 DEBUGprintf("***number 2\n");#endifbeginCallBack(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 DEBUGprintf("***number 3\n");#endifbeginCallBack(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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -