diff options
Diffstat (limited to 'src/glu/sgi/libnurbs/interface/glsurfeval.cc')
-rw-r--r-- | src/glu/sgi/libnurbs/interface/glsurfeval.cc | 1293 |
1 files changed, 1293 insertions, 0 deletions
diff --git a/src/glu/sgi/libnurbs/interface/glsurfeval.cc b/src/glu/sgi/libnurbs/interface/glsurfeval.cc new file mode 100644 index 00000000000..2fe6ce01c77 --- /dev/null +++ b/src/glu/sgi/libnurbs/interface/glsurfeval.cc @@ -0,0 +1,1293 @@ +/* +** 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. +*/ + +/* + * glsurfeval.c++ + * + * $Date: 2001/03/17 00:25:40 $ $Revision: 1.1 $ + * $Header: /home/krh/git/sync/mesa-cvs-repo/Mesa/src/glu/sgi/libnurbs/interface/glsurfeval.cc,v 1.1 2001/03/17 00:25:40 brianp Exp $ + */ + +/* Polynomial Evaluator Interface */ +#include "gluos.h" +#include <stdio.h> +#include "glimports.h" +#include "glrenderer.h" +#include "glsurfeval.h" +#include "nurbsconsts.h" +#include "bezierPatchMesh.h" + + +//extern int surfcount; +//int surfcount=0; + +/*#define USE_INTERNAL_EVAL*/ //use internal evaluator + +/*whether do evaluation or not*/ +/*#define NO_EVALUATION*/ + +//#define USE_LOD //for LOD test, have to turn on USE_LOD in insurfeval.c++ too + +/*for statistics*/ +//#define STATISTICS +#ifdef STATISTICS +static int STAT_num_of_triangles=0; +static int STAT_num_of_eval_vertices=0; +static int STAT_num_of_quad_strips=0; +#endif + +/*for output triangles*/ +/*#define OUTPUT_TRIANGLES*/ + + +/*#define FOR_CHRIS*/ +#ifdef FOR_CHRIS +extern "C" { void evalUStripExt(int n_upper, REAL v_upper, REAL* upper_val, + int n_lower, REAL v_lower, REAL* lower_val);} + +extern "C" { void evalVStripExt(int n_left, REAL u_left, REAL* left_val, + int n_right, REAL u_right, REAL* right_val); + } +#endif + + +/**************begin for LOD_eval_list***********/ +void OpenGLSurfaceEvaluator::LOD_eval_list(int level) +{ + if(level == 0) + LOD_eval_level = 1; + else if(level == 1) + LOD_eval_level = 2; + else if(level == 2) + LOD_eval_level = 4; + else + LOD_eval_level = 8; + + inBPMListEvalEM(global_bpm); +} + + +OpenGLSurfaceEvaluator::OpenGLSurfaceEvaluator() +{ + int i; + + for (i=0; i<VERTEX_CACHE_SIZE; i++) { + vertexCache[i] = new StoredVertex; + } + tmeshing = 0; + which = 0; + vcount = 0; + + global_uorder = 0; + global_vorder = 0; + global_uprime = -1.0; + global_vprime = -1.0; + global_vprime_BV = -1.0; + global_uprime_BU = -1.0; + global_uorder_BU = 0; + global_vorder_BU = 0; + global_uorder_BV = 0; + global_vorder_BV = 0; + global_baseData = NULL; + + global_bpm = NULL; + output_triangles = 0; //don't output triangles by default + + //no default callback functions + beginCallBackN = NULL; + endCallBackN = NULL; + vertexCallBackN = NULL; + normalCallBackN = NULL; + colorCallBackN = NULL; + texcoordCallBackN = NULL; + beginCallBackData = NULL; + endCallBackData = NULL; + vertexCallBackData = NULL; + normalCallBackData = NULL; + colorCallBackData = NULL; + texcoordCallBackData = NULL; + + userData = NULL; + + auto_normal_flag = 0; + callback_auto_normal = 0; //default of GLU_CALLBACK_AUTO_NORMAL is 0 + vertex_flag = 0; + normal_flag = 0; + color_flag = 0; + texcoord_flag = 0; + + em_vertex.uprime = -1.0; + em_vertex.vprime = -1.0; + em_normal.uprime = -1.0; + em_normal.vprime = -1.0; + em_color.uprime = -1.0; + em_color.vprime = -1.0; + em_texcoord.uprime = -1.0; + em_texcoord.vprime = -1.0; + +#ifdef USE_LOD + LOD_eval_level = 1; +#endif +} + +OpenGLSurfaceEvaluator::~OpenGLSurfaceEvaluator() +{ + for (int ii= 0; ii< VERTEX_CACHE_SIZE; ii++) { + delete vertexCache[ii]; + vertexCache[ii]= 0; + } +} + +/*--------------------------------------------------------------------------- + * disable - turn off a map + *--------------------------------------------------------------------------- + */ +void +OpenGLSurfaceEvaluator::disable(long type) +{ + glDisable((GLenum) type); +} + +/*--------------------------------------------------------------------------- + * enable - turn on a map + *--------------------------------------------------------------------------- + */ +void +OpenGLSurfaceEvaluator::enable(long type) +{ + glEnable((GLenum) type); +} + +/*------------------------------------------------------------------------- + * mapgrid2f - define a lattice of points with origin and offset + *------------------------------------------------------------------------- + */ +void +OpenGLSurfaceEvaluator::mapgrid2f(long nu, REAL u0, REAL u1, long nv, REAL v0, REAL v1) +{ +#ifdef USE_INTERNAL_EVAL + inMapGrid2f((int) nu, (REAL) u0, (REAL) u1, (int) nv, + (REAL) v0, (REAL) v1); +#else + + if(output_triangles) + { + global_grid_u0 = u0; + global_grid_u1 = u1; + global_grid_nu = nu; + global_grid_v0 = v0; + global_grid_v1 = v1; + global_grid_nv = nv; + } + else + glMapGrid2d((GLint) nu, (GLdouble) u0, (GLdouble) u1, (GLint) nv, + (GLdouble) v0, (GLdouble) v1); + +#endif +} + +void +OpenGLSurfaceEvaluator::polymode(long style) +{ + if(! output_triangles) + { + switch(style) { + default: + case N_MESHFILL: + + glPolygonMode((GLenum) GL_FRONT_AND_BACK, (GLenum) GL_FILL); + break; + case N_MESHLINE: + glPolygonMode((GLenum) GL_FRONT_AND_BACK, (GLenum) GL_LINE); + break; + case N_MESHPOINT: + glPolygonMode((GLenum) GL_FRONT_AND_BACK, (GLenum) GL_POINT); + break; + } + } +} + +void +OpenGLSurfaceEvaluator::bgnline(void) +{ + if(output_triangles) + bezierPatchMeshBeginStrip(global_bpm, GL_LINE_STRIP); + else + glBegin((GLenum) GL_LINE_STRIP); +} + +void +OpenGLSurfaceEvaluator::endline(void) +{ + if(output_triangles) + bezierPatchMeshEndStrip(global_bpm); + else + glEnd(); +} + +void +OpenGLSurfaceEvaluator::range2f(long type, REAL *from, REAL *to) +{ +} + +void +OpenGLSurfaceEvaluator::domain2f(REAL ulo, REAL uhi, REAL vlo, REAL vhi) +{ +} + +void +OpenGLSurfaceEvaluator::bgnclosedline(void) +{ + if(output_triangles) + bezierPatchMeshBeginStrip(global_bpm, GL_LINE_LOOP); + else + glBegin((GLenum) GL_LINE_LOOP); +} + +void +OpenGLSurfaceEvaluator::endclosedline(void) +{ + if(output_triangles) + bezierPatchMeshEndStrip(global_bpm); + else + glEnd(); +} + + + + + +void +OpenGLSurfaceEvaluator::bgntmesh(void) +{ + + tmeshing = 1; + which = 0; + vcount = 0; + + if(output_triangles) + bezierPatchMeshBeginStrip(global_bpm, GL_TRIANGLES); + else + glBegin((GLenum) GL_TRIANGLES); + +} + +void +OpenGLSurfaceEvaluator::swaptmesh(void) +{ + which = 1 - which; + +} + +void +OpenGLSurfaceEvaluator::endtmesh(void) +{ + tmeshing = 0; + + + if(output_triangles) + bezierPatchMeshEndStrip(global_bpm); + else + glEnd(); +} + +void +OpenGLSurfaceEvaluator::bgntfan(void) +{ + + if(output_triangles) + bezierPatchMeshBeginStrip(global_bpm, GL_TRIANGLE_FAN); + else + glBegin((GLenum) GL_TRIANGLE_FAN); + +} +void +OpenGLSurfaceEvaluator::endtfan(void) +{ + if(output_triangles) + bezierPatchMeshEndStrip(global_bpm); + else + glEnd(); +} + +void +OpenGLSurfaceEvaluator::evalUStrip(int n_upper, REAL v_upper, REAL* upper_val, int n_lower, REAL v_lower, REAL* lower_val) +{ +#ifdef USE_INTERNAL_EVAL + inEvalUStrip(n_upper, v_upper, upper_val, + n_lower, v_lower, lower_val); +#else + +#ifdef FOR_CHRIS + evalUStripExt(n_upper, v_upper, upper_val, + n_lower, v_lower, lower_val); + return; + +#endif + int i,j,k,l; + REAL leftMostV[2]; + + /* + *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; + } + else + { + i=0; + j=1; + + leftMostV[0] = lower_val[0]; + leftMostV[1] = v_lower; + + } + + /*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(); + coord2f(leftMostV[0], leftMostV[1]); +// glNormal3fv(leftMostNormal); +// glVertex3fv(leftMostXYZ); + + while(j<n_lower){ + coord2f(lower_val[j], v_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(); + coord2f(leftMostV[0], leftMostV[1]); +// glNormal3fv(leftMostNormal); +// glVertex3fv(leftMostXYZ); + + for(k=n_upper-1; k>=i; k--) /*reverse order for two-side lighting*/ + { + coord2f(upper_val[k], v_upper); +// 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(); + coord2f(lower_val[j], v_lower); +// 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*/ + { + coord2f(upper_val[l], v_upper); +// glNormal3fv(upperNormal[l]); +// glVertex3fv(upperXYZ[l]); + + } + coord2f(leftMostV[0], leftMostV[1]); +// 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(); + coord2f(upper_val[i], v_upper); +// glNormal3fv(upperNormal[i]); +// glVertex3fv(upperXYZ[i]); + + coord2f(leftMostV[0], leftMostV[1]); +// 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; + coord2f(lower_val[k], v_lower); +// 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); +#endif + +} + + +void +OpenGLSurfaceEvaluator::evalVStrip(int n_left, REAL u_left, REAL* left_val, int n_right, REAL u_right, REAL* right_val) +{ +#ifdef USE_INTERNAL_EVAL + inEvalVStrip(n_left, u_left, left_val, + n_right, u_right, right_val); +#else + +#ifdef FOR_CHRIS + evalVStripExt(n_left, u_left, left_val, + n_right, u_right, right_val); + return; + +#endif + + int i,j,k,l; + REAL botMostV[2]; + /* + *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]; + } + else + { + i=0; + j=1; + + botMostV[0] = u_right; + botMostV[1] = right_val[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(); + coord2f(botMostV[0], botMostV[1]); + while(j<n_right){ + coord2f(u_right, right_val[j]); +// 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(); + coord2f(botMostV[0], botMostV[1]); +// glNormal3fv(botMostNormal); +// glVertex3fv(botMostXYZ); + + for(k=n_left-1; k>=i; k--) /*reverse order for two-side lighting*/ + { + coord2f(u_left, left_val[k]); +// 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(); + coord2f(u_right, right_val[j]); +// 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*/ + { + coord2f(u_left, left_val[l]); +// glNormal3fv(leftNormal[l]); +// glVertex3fv(leftXYZ[l]); + + } + coord2f(botMostV[0], botMostV[1]); +// 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(); + coord2f(u_left, left_val[i]); +// glNormal3fv(leftNormal[i]); +// glVertex3fv(leftXYZ[i]); + + coord2f(botMostV[0], botMostV[1]); +// 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; + coord2f(u_right, right_val[k]); +// 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(leftNormal); +// free(rightXYZ); +// free(rightNormal); +#endif +} + + +void +OpenGLSurfaceEvaluator::bgnqstrip(void) +{ + if(output_triangles) + bezierPatchMeshBeginStrip(global_bpm, GL_QUAD_STRIP); + else + glBegin((GLenum) GL_QUAD_STRIP); + +#ifdef STATISTICS + STAT_num_of_quad_strips++; +#endif +} + +void +OpenGLSurfaceEvaluator::endqstrip(void) +{ + if(output_triangles) + bezierPatchMeshEndStrip(global_bpm); + else + glEnd(); + +} + +/*------------------------------------------------------------------------- + * bgnmap2f - preamble to surface definition and evaluations + *------------------------------------------------------------------------- + */ +void +OpenGLSurfaceEvaluator::bgnmap2f(long) +{ + if(output_triangles) + { + /*deallocate the space which may has been + *allocated by global_bpm previously + */ + if(global_bpm != NULL) { + bezierPatchMeshListDelete(global_bpm); + global_bpm = NULL; + } + + + /* + auto_normal_flag = 1; //always output normal in callback mode. + //we could have used the following code, + //but Inspector doesn't have gl context + //before it calls tessellator. + //this way is temporary. + */ + //NEWCALLBACK + //if one of the two normal callback functions are set, + //then set + if(normalCallBackN != NULL || + normalCallBackData != NULL) + auto_normal_flag = 1; + else + auto_normal_flag = 0; + + //initialize so that no maps initially + vertex_flag = 0; + normal_flag = 0; + color_flag = 0; + texcoord_flag = 0; + + /* + if(glIsEnabled(GL_AUTO_NORMAL) == GL_TRUE) + auto_normal_flag = 1; + else if (callback_auto_normal == 1) + auto_normal_flag = 1; + else + auto_normal_flag = 0; + */ + + //NEWCALLBACK: no need to worry about gl states when gling clalback + } + else + { + glPushAttrib((GLbitfield) GL_EVAL_BIT); + + /*to avoid side effect, we restor the opengl state for GL_POLYGON_MODE + */ + glGetIntegerv(GL_POLYGON_MODE, gl_polygon_mode); + } + +} + +/*------------------------------------------------------------------------- + * endmap2f - postamble to a map + *------------------------------------------------------------------------- + */ +void +OpenGLSurfaceEvaluator::endmap2f(void) +{ + + if(output_triangles) + { + //bezierPatchMeshListDelDeg(global_bpm); + + // bezierPatchMeshListEval(global_bpm); + + //surfcount++; + //printf("surfcount=%i\n", surfcount); + //if(surfcount == 8) exit(0); + + inBPMListEvalEM(global_bpm); + + + +/* + global_bpm = bezierPatchMeshListReverse(global_bpm); + { + float *vertex_array; + float *normal_array; + int *length_array; + int *type_array; + int num_strips; + bezierPatchMeshListCollect(global_bpm, &vertex_array, &normal_array, &length_array, &type_array, &num_strips); + drawStrips(vertex_array, normal_array, length_array, type_array, num_strips); + free(vertex_array); + free(normal_array); + free(length_array); + free(type_array); + } +*/ + + //bezierPatchMeshListPrint(global_bpm); + //bezierPatchMeshListDraw(global_bpm); + +// printf("num triangles=%i\n", bezierPatchMeshListNumTriangles(global_bpm)); + +#ifdef USE_LOD +#else + bezierPatchMeshListDelete(global_bpm); + global_bpm = NULL; +#endif + + } +else + { +#ifndef USE_LOD +glPopAttrib(); +#endif + +#ifdef STATISTICS + fprintf(stderr, "num_vertices=%i,num_triangles=%i,num_quads_strips=%i\n", STAT_num_of_eval_vertices,STAT_num_of_triangles,STAT_num_of_quad_strips); +#endif + + /*to restore the gl_polygon_mode + */ +#ifndef USE_LOD + glPolygonMode( GL_FRONT, (GLenum) gl_polygon_mode[0]); + glPolygonMode( GL_BACK, (GLenum) gl_polygon_mode[1]); +#endif +} + +} + +/*------------------------------------------------------------------------- + * map2f - pass a desription of a surface map + *------------------------------------------------------------------------- + */ +void +OpenGLSurfaceEvaluator::map2f( + long _type, + REAL _ulower, /* u lower domain coord */ + REAL _uupper, /* u upper domain coord */ + long _ustride, /* interpoint distance */ + long _uorder, /* parametric order */ + REAL _vlower, /* v lower domain coord */ + REAL _vupper, /* v upper domain coord */ + long _vstride, /* interpoint distance */ + long _vorder, /* parametric order */ + REAL *pts) /* control points */ +{ +#ifdef USE_INTERNAL_EVAL + inMap2f((int) _type, (REAL) _ulower, (REAL) _uupper, + (int) _ustride, (int) _uorder, (REAL) _vlower, + (REAL) _vupper, (int) _vstride, (int) _vorder, + (REAL *) pts); +#else + + + + if(output_triangles) + { + if(global_bpm == NULL) + global_bpm = bezierPatchMeshMake2(10,10); + if( + (global_bpm->bpatch == NULL && + (_type == GL_MAP2_VERTEX_3 || _type == GL_MAP2_VERTEX_4)) + || + (global_bpm->bpatch_normal == NULL && + (_type == GL_MAP2_NORMAL)) + || + (global_bpm->bpatch_color == NULL && + (_type == GL_MAP2_INDEX || _type == GL_MAP2_COLOR_4)) + || + (global_bpm->bpatch_texcoord == NULL && + (_type == GL_MAP2_TEXTURE_COORD_1 || + _type == GL_MAP2_TEXTURE_COORD_2 || + _type == GL_MAP2_TEXTURE_COORD_3 || + _type == GL_MAP2_TEXTURE_COORD_4 ) + )) + { + bezierPatchMeshPutPatch(global_bpm, (int) _type, _ulower, _uupper,(int) _ustride,(int) _uorder,_vlower, _vupper, (int) _vstride, (int) _vorder, pts); + } + else /*new surface patch (with multiple maps) starts*/ + { + bezierPatchMesh *temp = bezierPatchMeshMake2(10,10); + bezierPatchMeshPutPatch(temp, (int) _type, _ulower, _uupper,(int) _ustride,(int) _uorder,_vlower, _vupper, (int) _vstride, (int) _vorder, pts); + global_bpm = bezierPatchMeshListInsert(global_bpm, temp); + + /* + global_bpm = bezierPatchMeshListInsert(global_bpm, + bezierPatchMeshMake( + (int) _type, _ulower, _uupper,(int) _ustride, (int) _uorder, _vlower, _vupper, (int) _vstride, (int) _vorder, pts, 10, 10)); + */ + } + } + else /*not output triangles*/ + { + glMap2f((GLenum) _type, (GLfloat) _ulower, (GLfloat) _uupper, + (GLint) _ustride, (GLint) _uorder, (GLfloat) _vlower, + (GLfloat) _vupper, (GLint) _vstride, (GLint) _vorder, + (const GLfloat *) pts); + } + +#endif +} + + +/*------------------------------------------------------------------------- + * mapmesh2f - evaluate a mesh of points on lattice + *------------------------------------------------------------------------- + */ +void +OpenGLSurfaceEvaluator::mapmesh2f(long style, long umin, long umax, long vmin, long vmax) +{ +#ifdef NO_EVALUATION +return; +#endif + +#ifdef USE_INTERNAL_EVAL + inEvalMesh2((int)umin, (int)vmin, (int)umax, (int)vmax); +#else + + + +if(output_triangles) +{ +#ifdef USE_LOD + bezierPatchMeshBeginStrip(global_bpm, GL_POLYGON); + bezierPatchMeshInsertUV(global_bpm, global_grid_u0, global_grid_v0); + bezierPatchMeshInsertUV(global_bpm, global_grid_u1, global_grid_v1); + bezierPatchMeshInsertUV(global_bpm, (REAL)global_grid_nu, (REAL)global_grid_nv); + bezierPatchMeshInsertUV(global_bpm, (REAL)umin, (REAL)vmin); + bezierPatchMeshInsertUV(global_bpm, (REAL)umax, (REAL)vmax); + bezierPatchMeshEndStrip(global_bpm); + +#else + + REAL du, dv; + long i,j; + long row; + 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=umin; i<umax; 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=vmax; j>=vmin; j--){ + REAL v1 = (j == global_grid_nv)? global_grid_v1: (global_grid_v0 +j*dv); + + coord2f(u1, v1); + coord2f(u2, v1); + } + endqstrip(); + } + } + else{ + + for(i=vmin; i<vmax; 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=umax; j>=umin; j--){ + REAL u1 = (j == global_grid_nu)? global_grid_u1: (global_grid_u0 +j*du); + coord2f(u1, v2); + coord2f(u1, v1); + } + endqstrip(); + } + } +#endif +} +else +{ + switch(style) { + default: + case N_MESHFILL: + glEvalMesh2((GLenum) GL_FILL, (GLint) umin, (GLint) umax, + (GLint) vmin, (GLint) vmax); + break; + case N_MESHLINE: + glEvalMesh2((GLenum) GL_LINE, (GLint) umin, (GLint) umax, + (GLint) vmin, (GLint) vmax); + break; + case N_MESHPOINT: + glEvalMesh2((GLenum) GL_POINT, (GLint) umin, (GLint) umax, + (GLint) vmin, (GLint) vmax); + break; + } + } + +#endif + +#ifdef STATISTICS + STAT_num_of_quad_strips += (umax-umin)*(vmax-vmin); +#endif +} + +/*------------------------------------------------------------------------- + * evalcoord2f - evaluate a point on a surface + *------------------------------------------------------------------------- + */ +void +OpenGLSurfaceEvaluator::evalcoord2f(long, REAL u, REAL v) +{ + + +#ifdef NO_EVALUATION +return; +#endif + + + newtmeshvert(u, v); +} + +/*------------------------------------------------------------------------- + * evalpoint2i - evaluate a grid point + *------------------------------------------------------------------------- + */ +void +OpenGLSurfaceEvaluator::evalpoint2i(long u, long v) +{ +#ifdef NO_EVALUATION +return; +#endif + + newtmeshvert(u, v); +} + +void +OpenGLSurfaceEvaluator::point2i( long u, long v ) +{ +#ifdef NO_EVALUATION +return; +#else + +#ifdef USE_INTERNAL_EVAL + inEvalPoint2( (int)u, (int)v); +#else + + +if(output_triangles) +{ + + REAL du, dv; + REAL fu,fv; + du = (global_grid_u1 - global_grid_u0) / (REAL)global_grid_nu; + dv = (global_grid_v1 - global_grid_v0) / (REAL)global_grid_nv; + fu = (u==global_grid_nu)? global_grid_u1:(global_grid_u0 + u*du); + fv = (v == global_grid_nv)? global_grid_v1: (global_grid_v0 +v*dv); + coord2f(fu,fv); +} +else + glEvalPoint2((GLint) u, (GLint) v); + + +#endif + +#ifdef STATISTICS + STAT_num_of_eval_vertices++; +#endif + +#endif + +} + +void +OpenGLSurfaceEvaluator::coord2f( REAL u, REAL v ) +{ +#ifdef NO_EVALUATION +return; +#else + +#ifdef USE_INTERNAL_EVAL + inEvalCoord2f( u, v); +#else + + +if(output_triangles) + bezierPatchMeshInsertUV(global_bpm, u,v); +else + glEvalCoord2f((GLfloat) u, (GLfloat) v); + + +#endif + + +#ifdef STATISTICS + STAT_num_of_eval_vertices++; +#endif + +#endif +} + +void +OpenGLSurfaceEvaluator::newtmeshvert( long u, long v ) +{ +#ifdef NO_EVALUATION +return; +#else + + if (tmeshing) { + + if (vcount == 2) { + vertexCache[0]->invoke(this); + vertexCache[1]->invoke(this); + point2i( u, v); + + } else { + vcount++; + } + + vertexCache[which]->saveEvalPoint(u, v); + which = 1 - which; + } else { + point2i( u, v); + } +#endif +} + +void +OpenGLSurfaceEvaluator::newtmeshvert( REAL u, REAL v ) +{ +#ifdef NO_EVALUATION +return; +#else + if (tmeshing) { + + + if (vcount == 2) { + vertexCache[0]->invoke(this); + vertexCache[1]->invoke(this); + coord2f(u,v); + + } else { + vcount++; + } + + vertexCache[which]->saveEvalCoord(u, v); + which = 1 - which; + } else { + + coord2f( u, v); + } +#endif + +} + +void +OpenGLSurfaceEvaluator::putCallBack(GLenum which, GLvoid (GLAPIENTRY *fn)(...)) +{ + switch(which) + { + case GLU_NURBS_BEGIN: + beginCallBackN = (void (GLAPIENTRY *) (GLenum)) fn; + break; + case GLU_NURBS_END: + endCallBackN = (void (GLAPIENTRY *) (void)) fn; + break; + case GLU_NURBS_VERTEX: + vertexCallBackN = (void (GLAPIENTRY *) (const GLfloat*)) fn; + break; + case GLU_NURBS_NORMAL: + normalCallBackN = (void (GLAPIENTRY *) (const GLfloat*)) fn; + break; + case GLU_NURBS_COLOR: + colorCallBackN = (void (GLAPIENTRY *) (const GLfloat*)) fn; + break; + case GLU_NURBS_TEXTURE_COORD: + texcoordCallBackN = (void (GLAPIENTRY *) (const GLfloat*)) fn; + break; + case GLU_NURBS_BEGIN_DATA: + beginCallBackData = (void (GLAPIENTRY *) (GLenum, void*)) fn; + break; + case GLU_NURBS_END_DATA: + endCallBackData = (void (GLAPIENTRY *) (void*)) fn; + break; + case GLU_NURBS_VERTEX_DATA: + vertexCallBackData = (void (GLAPIENTRY *) (const GLfloat*, void*)) fn; + break; + case GLU_NURBS_NORMAL_DATA: + normalCallBackData = (void (GLAPIENTRY *) (const GLfloat*, void*)) fn; + break; + case GLU_NURBS_COLOR_DATA: + colorCallBackData = (void (GLAPIENTRY *) (const GLfloat*, void*)) fn; + break; + case GLU_NURBS_TEXTURE_COORD_DATA: + texcoordCallBackData = (void (GLAPIENTRY *) (const GLfloat*, void*)) fn; + break; + + } +} + + +void +OpenGLSurfaceEvaluator::beginCallBack(GLenum which, void *data) +{ + if(beginCallBackData) + beginCallBackData(which, data); + else if(beginCallBackN) + beginCallBackN(which); +} + +void +OpenGLSurfaceEvaluator::endCallBack(void *data) +{ + if(endCallBackData) + endCallBackData(data); + else if(endCallBackN) + endCallBackN(); +} + +void +OpenGLSurfaceEvaluator::vertexCallBack(const GLfloat *vert, void* data) +{ + if(vertexCallBackData) + vertexCallBackData(vert, data); + else if(vertexCallBackN) + vertexCallBackN(vert); +} + + +void +OpenGLSurfaceEvaluator::normalCallBack(const GLfloat *normal, void* data) +{ + if(normalCallBackData) + normalCallBackData(normal, data); + else if(normalCallBackN) + normalCallBackN(normal); +} + +void +OpenGLSurfaceEvaluator::colorCallBack(const GLfloat *color, void* data) +{ + if(colorCallBackData) + colorCallBackData(color, data); + else if(colorCallBackN) + colorCallBackN(color); +} + +void +OpenGLSurfaceEvaluator::texcoordCallBack(const GLfloat *texcoord, void* data) +{ + if(texcoordCallBackData) + texcoordCallBackData(texcoord, data); + else if(texcoordCallBackN) + texcoordCallBackN(texcoord); +} + + + + |