Home | History | Annotate | Line # | Download | only in interface
      1 /*
      2 ** License Applicability. Except to the extent portions of this file are
      3 ** made subject to an alternative license as permitted in the SGI Free
      4 ** Software License B, Version 1.1 (the "License"), the contents of this
      5 ** file are subject only to the provisions of the License. You may not use
      6 ** this file except in compliance with the License. You may obtain a copy
      7 ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
      8 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
      9 **
     10 ** http://oss.sgi.com/projects/FreeB
     11 **
     12 ** Note that, as provided in the License, the Software is distributed on an
     13 ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
     14 ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
     15 ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
     16 ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
     17 **
     18 ** Original Code. The Original Code is: OpenGL Sample Implementation,
     19 ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
     20 ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
     21 ** Copyright in any portions created by third parties is as indicated
     22 ** elsewhere herein. All Rights Reserved.
     23 **
     24 ** Additional Notice Provisions: The application programming interfaces
     25 ** established by SGI in conjunction with the Original Code are The
     26 ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
     27 ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
     28 ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
     29 ** Window System(R) (Version 1.3), released October 19, 1998. This software
     30 ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
     31 ** published by SGI, but has not been independently verified as being
     32 ** compliant with the OpenGL(R) version 1.2.1 Specification.
     33 */
     34 
     35 /*
     36  * glsurfeval.c++
     37  *
     38  */
     39 
     40 /* Polynomial Evaluator Interface */
     41 #include "gluos.h"
     42 #include <stdio.h>
     43 #include "glimports.h"
     44 #include "glrenderer.h"
     45 #include "glsurfeval.h"
     46 #include "nurbsconsts.h"
     47 #include "bezierPatchMesh.h"
     48 
     49 
     50 //extern int surfcount;
     51 //int surfcount=0;
     52 
     53 /*#define USE_INTERNAL_EVAL*/ //use internal evaluator
     54 
     55 /*whether do evaluation or not*/
     56 /*#define NO_EVALUATION*/
     57 
     58 //#define USE_LOD //for LOD test, have to turn on USE_LOD in insurfeval.c++ too
     59 
     60 /*for statistics*/
     61 //#define STATISTICS
     62 #ifdef STATISTICS
     63 static int STAT_num_of_triangles=0;
     64 static int STAT_num_of_eval_vertices=0;
     65 static int STAT_num_of_quad_strips=0;
     66 #endif
     67 
     68 /*for output triangles*/
     69 /*#define OUTPUT_TRIANGLES*/
     70 
     71 
     72 /*#define FOR_CHRIS*/
     73 #ifdef FOR_CHRIS
     74 extern "C"  {  void                evalUStripExt(int n_upper, REAL v_upper, REAL* upper_val,
     75 				   int n_lower, REAL v_lower, REAL* lower_val);}
     76 
     77 extern "C" {   void                evalVStripExt(int n_left, REAL u_left, REAL* left_val,
     78 				   int n_right, REAL u_right, REAL* right_val);
     79 	     }
     80 #endif
     81 
     82 
     83 /**************begin for LOD_eval_list***********/
     84 void OpenGLSurfaceEvaluator::LOD_eval_list(int level)
     85 {
     86   if(level == 0)
     87     LOD_eval_level = 1;
     88   else if(level == 1)
     89     LOD_eval_level = 2;
     90   else if(level == 2)
     91     LOD_eval_level = 4;
     92   else
     93     LOD_eval_level = 8;
     94 
     95   inBPMListEvalEM(global_bpm);
     96 }
     97 
     98 
     99 OpenGLSurfaceEvaluator::OpenGLSurfaceEvaluator()
    100 {
    101     int i;
    102 
    103     for (i=0; i<VERTEX_CACHE_SIZE; i++) {
    104 	vertexCache[i] = new StoredVertex;
    105     }
    106     tmeshing = 0;
    107     which = 0;
    108     vcount = 0;
    109 
    110     global_uorder = 0;
    111     global_vorder = 0;
    112     global_uprime = -1.0;
    113     global_vprime = -1.0;
    114     global_vprime_BV = -1.0;
    115     global_uprime_BU = -1.0;
    116     global_uorder_BU = 0;
    117     global_vorder_BU = 0;
    118     global_uorder_BV = 0;
    119     global_vorder_BV = 0;
    120     global_baseData = NULL;
    121 
    122     global_bpm = NULL;
    123     output_triangles = 0; //don't output triangles by default
    124 
    125     //no default callback functions
    126     beginCallBackN = NULL;
    127     endCallBackN = NULL;
    128     vertexCallBackN = NULL;
    129     normalCallBackN = NULL;
    130     colorCallBackN = NULL;
    131     texcoordCallBackN = NULL;
    132     beginCallBackData = NULL;
    133     endCallBackData = NULL;
    134     vertexCallBackData = NULL;
    135     normalCallBackData = NULL;
    136     colorCallBackData = NULL;
    137     texcoordCallBackData = NULL;
    138 
    139     userData = NULL;
    140 
    141     auto_normal_flag = 0;
    142     callback_auto_normal = 0; //default of GLU_CALLBACK_AUTO_NORMAL is 0
    143     vertex_flag = 0;
    144     normal_flag = 0;
    145     color_flag = 0;
    146     texcoord_flag = 0;
    147 
    148     em_vertex.uprime = -1.0;
    149     em_vertex.vprime = -1.0;
    150     em_normal.uprime = -1.0;
    151     em_normal.vprime = -1.0;
    152     em_color.uprime = -1.0;
    153     em_color.vprime = -1.0;
    154     em_texcoord.uprime = -1.0;
    155     em_texcoord.vprime = -1.0;
    156 
    157 #ifdef USE_LOD
    158     LOD_eval_level = 1;
    159 #endif
    160 }
    161 
    162 OpenGLSurfaceEvaluator::~OpenGLSurfaceEvaluator()
    163 {
    164    for (int ii= 0; ii< VERTEX_CACHE_SIZE; ii++) {
    165       delete vertexCache[ii];
    166       vertexCache[ii]= 0;
    167    }
    168 }
    169 
    170 /*---------------------------------------------------------------------------
    171  * disable - turn off a map
    172  *---------------------------------------------------------------------------
    173  */
    174 void
    175 OpenGLSurfaceEvaluator::disable(long type)
    176 {
    177     glDisable((GLenum) type);
    178 }
    179 
    180 /*---------------------------------------------------------------------------
    181  * enable - turn on a map
    182  *---------------------------------------------------------------------------
    183  */
    184 void
    185 OpenGLSurfaceEvaluator::enable(long type)
    186 {
    187     glEnable((GLenum) type);
    188 }
    189 
    190 /*-------------------------------------------------------------------------
    191  * mapgrid2f - define a lattice of points with origin and offset
    192  *-------------------------------------------------------------------------
    193  */
    194 void
    195 OpenGLSurfaceEvaluator::mapgrid2f(long nu, REAL u0, REAL u1, long nv, REAL v0, REAL v1)
    196 {
    197 #ifdef USE_INTERNAL_EVAL
    198   inMapGrid2f((int) nu, (REAL) u0, (REAL) u1, (int) nv,
    199 	      (REAL) v0, (REAL) v1);
    200 #else
    201 
    202   if(output_triangles)
    203     {
    204       global_grid_u0 = u0;
    205       global_grid_u1 = u1;
    206       global_grid_nu = nu;
    207       global_grid_v0 = v0;
    208       global_grid_v1 = v1;
    209       global_grid_nv = nv;
    210     }
    211   else
    212     glMapGrid2d((GLint) nu, (GLdouble) u0, (GLdouble) u1, (GLint) nv,
    213 	    (GLdouble) v0, (GLdouble) v1);
    214 
    215 #endif
    216 }
    217 
    218 void
    219 OpenGLSurfaceEvaluator::polymode(long style)
    220 {
    221   if(! output_triangles)
    222     {
    223       switch(style) {
    224       default:
    225       case N_MESHFILL:
    226 
    227 	glPolygonMode((GLenum) GL_FRONT_AND_BACK, (GLenum) GL_FILL);
    228 	break;
    229       case N_MESHLINE:
    230 	glPolygonMode((GLenum) GL_FRONT_AND_BACK, (GLenum) GL_LINE);
    231 	break;
    232       case N_MESHPOINT:
    233 	glPolygonMode((GLenum) GL_FRONT_AND_BACK, (GLenum) GL_POINT);
    234 	break;
    235       }
    236     }
    237 }
    238 
    239 void
    240 OpenGLSurfaceEvaluator::bgnline(void)
    241 {
    242   if(output_triangles)
    243     bezierPatchMeshBeginStrip(global_bpm, GL_LINE_STRIP);
    244   else
    245     glBegin((GLenum) GL_LINE_STRIP);
    246 }
    247 
    248 void
    249 OpenGLSurfaceEvaluator::endline(void)
    250 {
    251   if(output_triangles)
    252     bezierPatchMeshEndStrip(global_bpm);
    253   else
    254     glEnd();
    255 }
    256 
    257 void
    258 OpenGLSurfaceEvaluator::range2f(long type, REAL *from, REAL *to)
    259 {
    260 }
    261 
    262 void
    263 OpenGLSurfaceEvaluator::domain2f(REAL ulo, REAL uhi, REAL vlo, REAL vhi)
    264 {
    265 }
    266 
    267 void
    268 OpenGLSurfaceEvaluator::bgnclosedline(void)
    269 {
    270   if(output_triangles)
    271     bezierPatchMeshBeginStrip(global_bpm, GL_LINE_LOOP);
    272   else
    273     glBegin((GLenum) GL_LINE_LOOP);
    274 }
    275 
    276 void
    277 OpenGLSurfaceEvaluator::endclosedline(void)
    278 {
    279   if(output_triangles)
    280     bezierPatchMeshEndStrip(global_bpm);
    281   else
    282     glEnd();
    283 }
    284 
    285 
    286 
    287 
    288 
    289 void
    290 OpenGLSurfaceEvaluator::bgntmesh(void)
    291 {
    292 
    293     tmeshing = 1;
    294     which = 0;
    295     vcount = 0;
    296 
    297     if(output_triangles)
    298       bezierPatchMeshBeginStrip(global_bpm, GL_TRIANGLES);
    299     else
    300       glBegin((GLenum) GL_TRIANGLES);
    301 
    302 }
    303 
    304 void
    305 OpenGLSurfaceEvaluator::swaptmesh(void)
    306 {
    307     which = 1 - which;
    308 
    309 }
    310 
    311 void
    312 OpenGLSurfaceEvaluator::endtmesh(void)
    313 {
    314     tmeshing = 0;
    315 
    316 
    317     if(output_triangles)
    318       bezierPatchMeshEndStrip(global_bpm);
    319     else
    320       glEnd();
    321 }
    322 
    323 void
    324 OpenGLSurfaceEvaluator::bgntfan(void)
    325 {
    326 
    327   if(output_triangles)
    328     bezierPatchMeshBeginStrip(global_bpm, GL_TRIANGLE_FAN);
    329   else
    330     glBegin((GLenum) GL_TRIANGLE_FAN);
    331 
    332 }
    333 void
    334 OpenGLSurfaceEvaluator::endtfan(void)
    335 {
    336   if(output_triangles)
    337 	bezierPatchMeshEndStrip(global_bpm);
    338   else
    339     glEnd();
    340 }
    341 
    342 void
    343 OpenGLSurfaceEvaluator::evalUStrip(int n_upper, REAL v_upper, REAL* upper_val, int n_lower, REAL v_lower, REAL* lower_val)
    344 {
    345 #ifdef USE_INTERNAL_EVAL
    346   inEvalUStrip(n_upper, v_upper, upper_val,
    347 	n_lower, v_lower, lower_val);
    348 #else
    349 
    350 #ifdef FOR_CHRIS
    351   evalUStripExt(n_upper, v_upper, upper_val,
    352 		 n_lower, v_lower, lower_val);
    353   return;
    354 
    355 #endif
    356   int i,j,k,l;
    357   REAL leftMostV[2];
    358 
    359   /*
    360    *the algorithm works by scanning from left to right.
    361    *leftMostV: the left most of the remaining verteces (on both upper and lower).
    362    *	       it could an element of upperVerts or lowerVerts.
    363    *i: upperVerts[i] is the first vertex to the right of leftMostV on upper line
    364    *j: lowerVerts[j] is the first vertex to the right of leftMostV on lower line
    365    */
    366 
    367   /*initialize i,j,and leftMostV
    368    */
    369   if(upper_val[0] <= lower_val[0])
    370     {
    371       i=1;
    372       j=0;
    373 
    374       leftMostV[0] = upper_val[0];
    375       leftMostV[1] = v_upper;
    376     }
    377   else
    378     {
    379       i=0;
    380       j=1;
    381 
    382       leftMostV[0] = lower_val[0];
    383       leftMostV[1] = v_lower;
    384 
    385     }
    386 
    387   /*the main loop.
    388    *the invariance is that:
    389    *at the beginning of each loop, the meaning of i,j,and leftMostV are
    390    *maintained
    391    */
    392   while(1)
    393     {
    394       if(i >= n_upper) /*case1: no more in upper*/
    395 	{
    396 	  if(j<n_lower-1) /*at least two vertices in lower*/
    397 	    {
    398 	      bgntfan();
    399 	      coord2f(leftMostV[0], leftMostV[1]);
    400 //	      glNormal3fv(leftMostNormal);
    401 //		glVertex3fv(leftMostXYZ);
    402 
    403 	      while(j<n_lower){
    404 		coord2f(lower_val[j], v_lower);
    405 //		glNormal3fv(lowerNormal[j]);
    406 //		glVertex3fv(lowerXYZ[j]);
    407 		j++;
    408 
    409 	      }
    410 	      endtfan();
    411 	    }
    412 	  break; /*exit the main loop*/
    413 	}
    414       else if(j>= n_lower) /*case2: no more in lower*/
    415 	{
    416 	  if(i<n_upper-1) /*at least two vertices in upper*/
    417 	    {
    418 	      bgntfan();
    419 	      coord2f(leftMostV[0], leftMostV[1]);
    420 //	      glNormal3fv(leftMostNormal);
    421 //	      glVertex3fv(leftMostXYZ);
    422 
    423 	      for(k=n_upper-1; k>=i; k--) /*reverse order for two-side lighting*/
    424 		{
    425 		  coord2f(upper_val[k], v_upper);
    426 //		  glNormal3fv(upperNormal[k]);
    427 //		  glVertex3fv(upperXYZ[k]);
    428 		}
    429 
    430 	      endtfan();
    431 	    }
    432 	  break; /*exit the main loop*/
    433 	}
    434       else /* case3: neither is empty, plus the leftMostV, there is at least one triangle to output*/
    435 	{
    436 	  if(upper_val[i] <= lower_val[j])
    437 	    {
    438 	      bgntfan();
    439 	      coord2f(lower_val[j], v_lower);
    440 //	      glNormal3fv(lowerNormal[j]);
    441 //	      glVertex3fv(lowerXYZ[j]);
    442 
    443 	      /*find the last k>=i such that
    444 	       *upperverts[k][0] <= lowerverts[j][0]
    445 	       */
    446 	      k=i;
    447 
    448 	      while(k<n_upper)
    449 		{
    450 		  if(upper_val[k] > lower_val[j])
    451 		    break;
    452 		  k++;
    453 
    454 		}
    455 	      k--;
    456 
    457 
    458 	      for(l=k; l>=i; l--)/*the reverse is for two-side lighting*/
    459 		{
    460 		  coord2f(upper_val[l], v_upper);
    461 //		  glNormal3fv(upperNormal[l]);
    462 //		  glVertex3fv(upperXYZ[l]);
    463 
    464 		}
    465 	      coord2f(leftMostV[0], leftMostV[1]);
    466 //	      glNormal3fv(leftMostNormal);
    467 //	      glVertex3fv(leftMostXYZ);
    468 
    469 	      endtfan();
    470 
    471 	      /*update i and leftMostV for next loop
    472 	       */
    473 	      i = k+1;
    474 
    475 	      leftMostV[0] = upper_val[k];
    476 	      leftMostV[1] = v_upper;
    477 //	      leftMostNormal = upperNormal[k];
    478 //	      leftMostXYZ = upperXYZ[k];
    479 	    }
    480 	  else /*upperVerts[i][0] > lowerVerts[j][0]*/
    481 	    {
    482 	      bgntfan();
    483 	      coord2f(upper_val[i], v_upper);
    484 //	      glNormal3fv(upperNormal[i]);
    485 //	      glVertex3fv(upperXYZ[i]);
    486 
    487 	      coord2f(leftMostV[0], leftMostV[1]);
    488 //		glNormal3fv(leftMostNormal);
    489 //	      glVertex3fv(leftMostXYZ);
    490 
    491 
    492 	      /*find the last k>=j such that
    493 	       *lowerverts[k][0] < upperverts[i][0]
    494 	       */
    495 	      k=j;
    496 	      while(k< n_lower)
    497 		{
    498 		  if(lower_val[k] >= upper_val[i])
    499 		    break;
    500 		  coord2f(lower_val[k], v_lower);
    501 //		  glNormal3fv(lowerNormal[k]);
    502 //		  glVertex3fv(lowerXYZ[k]);
    503 
    504 		  k++;
    505 		}
    506 	      endtfan();
    507 
    508 	      /*update j and leftMostV for next loop
    509 	       */
    510 	      j=k;
    511 	      leftMostV[0] = lower_val[j-1];
    512 	      leftMostV[1] = v_lower;
    513 
    514 //	      leftMostNormal = lowerNormal[j-1];
    515 //	      leftMostXYZ = lowerXYZ[j-1];
    516 	    }
    517 	}
    518     }
    519   //clean up
    520 //  free(upperXYZ);
    521 //  free(lowerXYZ);
    522 //  free(upperNormal);
    523 //  free(lowerNormal);
    524 #endif
    525 
    526 }
    527 
    528 
    529 void
    530 OpenGLSurfaceEvaluator::evalVStrip(int n_left, REAL u_left, REAL* left_val, int n_right, REAL u_right, REAL* right_val)
    531 {
    532 #ifdef USE_INTERNAL_EVAL
    533 	inEvalVStrip(n_left, u_left, left_val,
    534 	n_right, u_right, right_val);
    535 #else
    536 
    537 #ifdef FOR_CHRIS
    538 	evalVStripExt(n_left, u_left, left_val,
    539 		      n_right, u_right, right_val);
    540 	return;
    541 
    542 #endif
    543 
    544   int i,j,k,l;
    545   REAL botMostV[2];
    546   /*
    547    *the algorithm works by scanning from bot to top.
    548    *botMostV: the bot most of the remaining verteces (on both left and right).
    549    *	       it could an element of leftVerts or rightVerts.
    550    *i: leftVerts[i] is the first vertex to the top of botMostV on left line
    551    *j: rightVerts[j] is the first vertex to the top of botMostV on rightline
    552    */
    553 
    554   /*initialize i,j,and botMostV
    555    */
    556   if(left_val[0] <= right_val[0])
    557     {
    558       i=1;
    559       j=0;
    560 
    561       botMostV[0] = u_left;
    562       botMostV[1] = left_val[0];
    563     }
    564   else
    565     {
    566       i=0;
    567       j=1;
    568 
    569       botMostV[0] = u_right;
    570       botMostV[1] = right_val[0];
    571     }
    572 
    573   /*the main loop.
    574    *the invariance is that:
    575    *at the beginning of each loop, the meaning of i,j,and botMostV are
    576    *maintained
    577    */
    578   while(1)
    579     {
    580       if(i >= n_left) /*case1: no more in left*/
    581 	{
    582 	  if(j<n_right-1) /*at least two vertices in right*/
    583 	    {
    584 	      bgntfan();
    585 	      coord2f(botMostV[0], botMostV[1]);
    586 	      while(j<n_right){
    587 		coord2f(u_right, right_val[j]);
    588 //		glNormal3fv(rightNormal[j]);
    589 //		glVertex3fv(rightXYZ[j]);
    590 		j++;
    591 
    592 	      }
    593 	      endtfan();
    594 	    }
    595 	  break; /*exit the main loop*/
    596 	}
    597       else if(j>= n_right) /*case2: no more in right*/
    598 	{
    599 	  if(i<n_left-1) /*at least two vertices in left*/
    600 	    {
    601 	      bgntfan();
    602 	      coord2f(botMostV[0], botMostV[1]);
    603 //	      glNormal3fv(botMostNormal);
    604 //	      glVertex3fv(botMostXYZ);
    605 
    606 	      for(k=n_left-1; k>=i; k--) /*reverse order for two-side lighting*/
    607 		{
    608 		  coord2f(u_left, left_val[k]);
    609 //		  glNormal3fv(leftNormal[k]);
    610 //		  glVertex3fv(leftXYZ[k]);
    611 		}
    612 
    613 	      endtfan();
    614 	    }
    615 	  break; /*exit the main loop*/
    616 	}
    617       else /* case3: neither is empty, plus the botMostV, there is at least one triangle to output*/
    618 	{
    619 	  if(left_val[i] <= right_val[j])
    620 	    {
    621 	      bgntfan();
    622 	      coord2f(u_right, right_val[j]);
    623 //	      glNormal3fv(rightNormal[j]);
    624 //	      glVertex3fv(rightXYZ[j]);
    625 
    626 	      /*find the last k>=i such that
    627 	       *leftverts[k][0] <= rightverts[j][0]
    628 	       */
    629 	      k=i;
    630 
    631 	      while(k<n_left)
    632 		{
    633 		  if(left_val[k] > right_val[j])
    634 		    break;
    635 		  k++;
    636 
    637 		}
    638 	      k--;
    639 
    640 
    641 	      for(l=k; l>=i; l--)/*the reverse is for two-side lighting*/
    642 		{
    643 		  coord2f(u_left, left_val[l]);
    644 //		  glNormal3fv(leftNormal[l]);
    645 //		  glVertex3fv(leftXYZ[l]);
    646 
    647 		}
    648 	      coord2f(botMostV[0], botMostV[1]);
    649 //	      glNormal3fv(botMostNormal);
    650 //	      glVertex3fv(botMostXYZ);
    651 
    652 	      endtfan();
    653 
    654 	      /*update i and botMostV for next loop
    655 	       */
    656 	      i = k+1;
    657 
    658 	      botMostV[0] = u_left;
    659 	      botMostV[1] = left_val[k];
    660 //	      botMostNormal = leftNormal[k];
    661 //	      botMostXYZ = leftXYZ[k];
    662 	    }
    663 	  else /*left_val[i] > right_val[j])*/
    664 	    {
    665 	      bgntfan();
    666 	      coord2f(u_left, left_val[i]);
    667 //	      glNormal3fv(leftNormal[i]);
    668 //	      glVertex3fv(leftXYZ[i]);
    669 
    670 	      coord2f(botMostV[0], botMostV[1]);
    671 //	      glNormal3fv(botMostNormal);
    672 //	      glVertex3fv(botMostXYZ);
    673 
    674 
    675 	      /*find the last k>=j such that
    676 	       *rightverts[k][0] < leftverts[i][0]
    677 	       */
    678 	      k=j;
    679 	      while(k< n_right)
    680 		{
    681 		  if(right_val[k] >= left_val[i])
    682 		    break;
    683 		  coord2f(u_right, right_val[k]);
    684 //		  glNormal3fv(rightNormal[k]);
    685 //		  glVertex3fv(rightXYZ[k]);
    686 
    687 		  k++;
    688 		}
    689 	      endtfan();
    690 
    691 	      /*update j and botMostV for next loop
    692 	       */
    693 	      j=k;
    694 	      botMostV[0] = u_right;
    695 	      botMostV[1] = right_val[j-1];
    696 
    697 //	      botMostNormal = rightNormal[j-1];
    698 //	      botMostXYZ = rightXYZ[j-1];
    699 	    }
    700 	}
    701     }
    702   //clean up
    703 //  free(leftXYZ);
    704 //  free(leftNormal);
    705 //  free(rightXYZ);
    706 //  free(rightNormal);
    707 #endif
    708 }
    709 
    710 
    711 void
    712 OpenGLSurfaceEvaluator::bgnqstrip(void)
    713 {
    714   if(output_triangles)
    715     bezierPatchMeshBeginStrip(global_bpm, GL_QUAD_STRIP);
    716   else
    717     glBegin((GLenum) GL_QUAD_STRIP);
    718 
    719 #ifdef STATISTICS
    720 	STAT_num_of_quad_strips++;
    721 #endif
    722 }
    723 
    724 void
    725 OpenGLSurfaceEvaluator::endqstrip(void)
    726 {
    727   if(output_triangles)
    728     bezierPatchMeshEndStrip(global_bpm);
    729   else
    730     glEnd();
    731 
    732 }
    733 
    734 /*-------------------------------------------------------------------------
    735  * bgnmap2f - preamble to surface definition and evaluations
    736  *-------------------------------------------------------------------------
    737  */
    738 void
    739 OpenGLSurfaceEvaluator::bgnmap2f(long)
    740 {
    741   if(output_triangles)
    742     {
    743       /*deallocate the space which may has been
    744        *allocated by global_bpm previously
    745        */
    746       if(global_bpm != NULL) {
    747 	bezierPatchMeshListDelete(global_bpm);
    748 	global_bpm = NULL;
    749       }
    750 
    751 
    752       /*
    753 	auto_normal_flag = 1; //always output normal in callback mode.
    754 			      //we could have used the following code,
    755 			      //but Inspector doesn't have gl context
    756 			      //before it calls tessellator.
    757 			      //this way is temporary.
    758 	*/
    759       //NEWCALLBACK
    760       //if one of the two normal callback functions are set,
    761       //then set
    762       if(normalCallBackN != NULL ||
    763 	 normalCallBackData != NULL)
    764 	auto_normal_flag = 1;
    765       else
    766 	auto_normal_flag = 0;
    767 
    768       //initialize so that no maps initially
    769       vertex_flag = 0;
    770       normal_flag = 0;
    771       color_flag = 0;
    772       texcoord_flag = 0;
    773 
    774       /*
    775       if(glIsEnabled(GL_AUTO_NORMAL) == GL_TRUE)
    776 	auto_normal_flag = 1;
    777       else if (callback_auto_normal == 1)
    778 	auto_normal_flag = 1;
    779       else
    780 	auto_normal_flag = 0;
    781 	*/
    782 	  glPushAttrib((GLbitfield) GL_EVAL_BIT);
    783 
    784     }
    785   else
    786     {
    787       glPushAttrib((GLbitfield) GL_EVAL_BIT);
    788 
    789       /*to avoid side effect, we restor the opengl state for GL_POLYGON_MODE
    790        */
    791       glGetIntegerv(GL_POLYGON_MODE, gl_polygon_mode);
    792     }
    793 
    794 }
    795 
    796 /*-------------------------------------------------------------------------
    797  * endmap2f - postamble to a map
    798  *-------------------------------------------------------------------------
    799  */
    800 void
    801 OpenGLSurfaceEvaluator::endmap2f(void)
    802 {
    803 
    804   if(output_triangles)
    805     {
    806       //bezierPatchMeshListDelDeg(global_bpm);
    807 
    808       //    bezierPatchMeshListEval(global_bpm);
    809 
    810       //surfcount++;
    811       //printf("surfcount=%i\n", surfcount);
    812       //if(surfcount == 8) exit(0);
    813 
    814       inBPMListEvalEM(global_bpm);
    815 
    816 
    817 
    818 /*
    819     global_bpm = bezierPatchMeshListReverse(global_bpm);
    820     {
    821       float *vertex_array;
    822       float *normal_array;
    823       int *length_array;
    824       int *type_array;
    825       int num_strips;
    826       bezierPatchMeshListCollect(global_bpm, &vertex_array, &normal_array, &length_array, &type_array, &num_strips);
    827       drawStrips(vertex_array, normal_array, length_array, type_array, num_strips);
    828       free(vertex_array);
    829       free(normal_array);
    830       free(length_array);
    831       free(type_array);
    832     }
    833 */
    834 
    835     //bezierPatchMeshListPrint(global_bpm);
    836     //bezierPatchMeshListDraw(global_bpm);
    837 
    838 //	  printf("num triangles=%i\n", bezierPatchMeshListNumTriangles(global_bpm));
    839 
    840 #ifdef USE_LOD
    841 #else
    842     bezierPatchMeshListDelete(global_bpm);
    843     global_bpm = NULL;
    844 #endif
    845 	glPopAttrib();
    846   }
    847 else
    848   {
    849 #ifndef USE_LOD
    850     glPopAttrib();
    851 #endif
    852 
    853 #ifdef STATISTICS
    854     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);
    855 #endif
    856 
    857     /*to restore the gl_polygon_mode
    858      */
    859 #ifndef USE_LOD
    860     glPolygonMode( GL_FRONT, (GLenum) gl_polygon_mode[0]);
    861     glPolygonMode( GL_BACK,  (GLenum) gl_polygon_mode[1]);
    862 #endif
    863 }
    864 
    865 }
    866 
    867 /*-------------------------------------------------------------------------
    868  * map2f - pass a desription of a surface map
    869  *-------------------------------------------------------------------------
    870  */
    871 void
    872 OpenGLSurfaceEvaluator::map2f(
    873     long _type,
    874     REAL _ulower,	/* u lower domain coord 	*/
    875     REAL _uupper,	/* u upper domain coord 	*/
    876     long _ustride,	/* interpoint distance		*/
    877     long _uorder,	/* parametric order		*/
    878     REAL _vlower,	/* v lower domain coord 	*/
    879     REAL _vupper,	/* v upper domain coord 	*/
    880     long _vstride,	/* interpoint distance		*/
    881     long _vorder,	/* parametric order		*/
    882     REAL *pts)	/* control points		*/
    883 {
    884 #ifdef USE_INTERNAL_EVAL
    885    inMap2f((int) _type, (REAL) _ulower, (REAL) _uupper,
    886 	    (int) _ustride, (int) _uorder, (REAL) _vlower,
    887 	    (REAL) _vupper, (int) _vstride, (int) _vorder,
    888 	    (REAL *) pts);
    889 #else
    890 
    891 
    892 
    893    if(output_triangles)
    894      {
    895        if(global_bpm == NULL)
    896 	 global_bpm = bezierPatchMeshMake2(10,10);
    897        if(
    898 	  (global_bpm->bpatch == NULL &&
    899 	  (_type == GL_MAP2_VERTEX_3 || _type == GL_MAP2_VERTEX_4))
    900 	  ||
    901 	  (global_bpm->bpatch_normal == NULL &&
    902 	   (_type == GL_MAP2_NORMAL))
    903 	  ||
    904 	  (global_bpm->bpatch_color == NULL &&
    905 	   (_type == GL_MAP2_INDEX || _type == GL_MAP2_COLOR_4))
    906 	  ||
    907 	  (global_bpm->bpatch_texcoord == NULL &&
    908 	   (_type == GL_MAP2_TEXTURE_COORD_1 ||
    909 	    _type == GL_MAP2_TEXTURE_COORD_2 ||
    910 	    _type == GL_MAP2_TEXTURE_COORD_3 ||
    911 	    _type == GL_MAP2_TEXTURE_COORD_4 )
    912 	   ))
    913 	 {
    914 	   bezierPatchMeshPutPatch(global_bpm, (int) _type, _ulower, _uupper,(int)  _ustride,(int) _uorder,_vlower, _vupper, (int) _vstride, (int) _vorder, pts);
    915 	 }
    916        else /*new surface patch (with multiple maps) starts*/
    917 	 {
    918 	   bezierPatchMesh *temp = bezierPatchMeshMake2(10,10);
    919 	   bezierPatchMeshPutPatch(temp, (int) _type, _ulower, _uupper,(int)  _ustride,(int) _uorder,_vlower, _vupper, (int) _vstride, (int) _vorder, pts);
    920 	   global_bpm = bezierPatchMeshListInsert(global_bpm, temp);
    921 
    922 	   /*
    923 	   global_bpm = bezierPatchMeshListInsert(global_bpm,
    924 						  bezierPatchMeshMake(
    925 								      (int) _type, _ulower, _uupper,(int)  _ustride, (int) _uorder, _vlower, _vupper, (int) _vstride, (int) _vorder, pts, 10, 10));
    926 	   */
    927 	 }
    928      }
    929    else /*not output triangles*/
    930      {
    931        glMap2f((GLenum) _type, (GLfloat) _ulower, (GLfloat) _uupper,
    932 	       (GLint) _ustride, (GLint) _uorder, (GLfloat) _vlower,
    933 	       (GLfloat) _vupper, (GLint) _vstride, (GLint) _vorder,
    934 	       (const GLfloat *) pts);
    935      }
    936 
    937 #endif
    938 }
    939 
    940 
    941 /*-------------------------------------------------------------------------
    942  * mapmesh2f - evaluate a mesh of points on lattice
    943  *-------------------------------------------------------------------------
    944  */
    945 void
    946 OpenGLSurfaceEvaluator::mapmesh2f(long style, long umin, long umax, long vmin, long vmax)
    947 {
    948 #ifdef NO_EVALUATION
    949 return;
    950 #endif
    951 
    952 #ifdef USE_INTERNAL_EVAL
    953     inEvalMesh2((int)umin, (int)vmin, (int)umax, (int)vmax);
    954 #else
    955 
    956 
    957 
    958 if(output_triangles)
    959 {
    960 #ifdef USE_LOD
    961   bezierPatchMeshBeginStrip(global_bpm, GL_POLYGON);
    962   bezierPatchMeshInsertUV(global_bpm, global_grid_u0, global_grid_v0);
    963   bezierPatchMeshInsertUV(global_bpm, global_grid_u1, global_grid_v1);
    964   bezierPatchMeshInsertUV(global_bpm, (REAL)global_grid_nu, (REAL)global_grid_nv);
    965   bezierPatchMeshInsertUV(global_bpm, (REAL)umin, (REAL)vmin);
    966   bezierPatchMeshInsertUV(global_bpm, (REAL)umax, (REAL)vmax);
    967   bezierPatchMeshEndStrip(global_bpm);
    968 
    969 #else
    970 
    971   REAL du, dv;
    972   long i,j;
    973   if(global_grid_nu == 0 || global_grid_nv == 0)
    974     return; /*no points need to be output*/
    975   du = (global_grid_u1 - global_grid_u0) / (REAL)global_grid_nu;
    976   dv = (global_grid_v1 - global_grid_v0) / (REAL)global_grid_nv;
    977 
    978   if(global_grid_nu >= global_grid_nv){
    979 
    980     for(i=umin; i<umax; i++){
    981       REAL u1 = (i==global_grid_nu)? global_grid_u1:(global_grid_u0 + i*du);
    982       REAL u2 = ((i+1) == global_grid_nu)? global_grid_u1: (global_grid_u0+(i+1)*du);
    983 
    984       bgnqstrip();
    985       for(j=vmax; j>=vmin; j--){
    986 	REAL v1 = (j == global_grid_nv)? global_grid_v1: (global_grid_v0 +j*dv);
    987 
    988 	coord2f(u1, v1);
    989 	coord2f(u2, v1);
    990       }
    991       endqstrip();
    992     }
    993   }
    994   else{
    995 
    996     for(i=vmin; i<vmax; i++){
    997       REAL v1 = (i==global_grid_nv)? global_grid_v1:(global_grid_v0 + i*dv);
    998       REAL v2 = ((i+1) == global_grid_nv)? global_grid_v1: (global_grid_v0+(i+1)*dv);
    999 
   1000       bgnqstrip();
   1001       for(j=umax; j>=umin; j--){
   1002 	REAL u1 = (j == global_grid_nu)? global_grid_u1: (global_grid_u0 +j*du);
   1003 	coord2f(u1, v2);
   1004 	coord2f(u1, v1);
   1005       }
   1006       endqstrip();
   1007     }
   1008   }
   1009 #endif
   1010 }
   1011 else
   1012 {
   1013     switch(style) {
   1014     default:
   1015     case N_MESHFILL:
   1016 	glEvalMesh2((GLenum) GL_FILL, (GLint) umin, (GLint) umax,
   1017 		(GLint) vmin, (GLint) vmax);
   1018 	break;
   1019     case N_MESHLINE:
   1020 	glEvalMesh2((GLenum) GL_LINE, (GLint) umin, (GLint) umax,
   1021 		(GLint) vmin, (GLint) vmax);
   1022 	break;
   1023     case N_MESHPOINT:
   1024 	glEvalMesh2((GLenum) GL_POINT, (GLint) umin, (GLint) umax,
   1025 		(GLint) vmin, (GLint) vmax);
   1026 	break;
   1027     }
   1028   }
   1029 
   1030 #endif
   1031 
   1032 #ifdef STATISTICS
   1033 	STAT_num_of_quad_strips += (umax-umin)*(vmax-vmin);
   1034 #endif
   1035 }
   1036 
   1037 /*-------------------------------------------------------------------------
   1038  * evalcoord2f - evaluate a point on a surface
   1039  *-------------------------------------------------------------------------
   1040  */
   1041 void
   1042 OpenGLSurfaceEvaluator::evalcoord2f(long, REAL u, REAL v)
   1043 {
   1044 
   1045 
   1046 #ifdef NO_EVALUATION
   1047 return;
   1048 #endif
   1049 
   1050 
   1051     newtmeshvert(u, v);
   1052 }
   1053 
   1054 /*-------------------------------------------------------------------------
   1055  * evalpoint2i - evaluate a grid point
   1056  *-------------------------------------------------------------------------
   1057  */
   1058 void
   1059 OpenGLSurfaceEvaluator::evalpoint2i(long u, long v)
   1060 {
   1061 #ifdef NO_EVALUATION
   1062 return;
   1063 #endif
   1064 
   1065     newtmeshvert(u, v);
   1066 }
   1067 
   1068 void
   1069 OpenGLSurfaceEvaluator::point2i( long u, long v )
   1070 {
   1071 #ifdef NO_EVALUATION
   1072 return;
   1073 #else
   1074 
   1075 #ifdef USE_INTERNAL_EVAL
   1076     inEvalPoint2( (int)u,  (int)v);
   1077 #else
   1078 
   1079 
   1080 if(output_triangles)
   1081 {
   1082 
   1083   REAL du, dv;
   1084   REAL fu,fv;
   1085   du = (global_grid_u1 - global_grid_u0) / (REAL)global_grid_nu;
   1086   dv = (global_grid_v1 - global_grid_v0) / (REAL)global_grid_nv;
   1087   fu = (u==global_grid_nu)? global_grid_u1:(global_grid_u0 + u*du);
   1088   fv = (v == global_grid_nv)? global_grid_v1: (global_grid_v0 +v*dv);
   1089   coord2f(fu,fv);
   1090 }
   1091 else
   1092     glEvalPoint2((GLint) u, (GLint) v);
   1093 
   1094 
   1095 #endif
   1096 
   1097 #ifdef STATISTICS
   1098   STAT_num_of_eval_vertices++;
   1099 #endif
   1100 
   1101 #endif
   1102 
   1103 }
   1104 
   1105 void
   1106 OpenGLSurfaceEvaluator::coord2f( REAL u, REAL v )
   1107 {
   1108 #ifdef NO_EVALUATION
   1109 return;
   1110 #else
   1111 
   1112 #ifdef USE_INTERNAL_EVAL
   1113     inEvalCoord2f( u, v);
   1114 #else
   1115 
   1116 
   1117 if(output_triangles)
   1118     bezierPatchMeshInsertUV(global_bpm, u,v);
   1119 else
   1120     glEvalCoord2f((GLfloat) u, (GLfloat) v);
   1121 
   1122 
   1123 #endif
   1124 
   1125 
   1126 #ifdef STATISTICS
   1127   STAT_num_of_eval_vertices++;
   1128 #endif
   1129 
   1130 #endif
   1131 }
   1132 
   1133 void
   1134 OpenGLSurfaceEvaluator::newtmeshvert( long u, long v )
   1135 {
   1136 #ifdef NO_EVALUATION
   1137 return;
   1138 #else
   1139 
   1140     if (tmeshing) {
   1141 
   1142 	if (vcount == 2) {
   1143 	    vertexCache[0]->invoke(this);
   1144 	    vertexCache[1]->invoke(this);
   1145 	    point2i( u,  v);
   1146 
   1147 	} else {
   1148 	    vcount++;
   1149 	}
   1150 
   1151 	vertexCache[which]->saveEvalPoint(u, v);
   1152 	which = 1 - which;
   1153     } else {
   1154 	point2i( u,  v);
   1155     }
   1156 #endif
   1157 }
   1158 
   1159 void
   1160 OpenGLSurfaceEvaluator::newtmeshvert( REAL u, REAL v )
   1161 {
   1162 #ifdef NO_EVALUATION
   1163 return;
   1164 #else
   1165     if (tmeshing) {
   1166 
   1167 
   1168 	if (vcount == 2) {
   1169 	    vertexCache[0]->invoke(this);
   1170 	    vertexCache[1]->invoke(this);
   1171 	    coord2f(u,v);
   1172 
   1173 	} else {
   1174 	    vcount++;
   1175 	}
   1176 
   1177 	vertexCache[which]->saveEvalCoord(u, v);
   1178 	which = 1 - which;
   1179     } else {
   1180 
   1181 	coord2f( u,  v);
   1182     }
   1183 #endif
   1184 
   1185 }
   1186 
   1187 #ifdef _WIN32
   1188 void OpenGLSurfaceEvaluator::putCallBack(GLenum which, void (GLAPIENTRY *fn)() )
   1189 #else
   1190 void OpenGLSurfaceEvaluator::putCallBack(GLenum which, _GLUfuncptr fn )
   1191 #endif
   1192 {
   1193   switch(which)
   1194     {
   1195     case GLU_NURBS_BEGIN:
   1196       beginCallBackN = (void (GLAPIENTRY *) (GLenum)) fn;
   1197       break;
   1198     case GLU_NURBS_END:
   1199       endCallBackN = (void (GLAPIENTRY *) (void)) fn;
   1200       break;
   1201     case GLU_NURBS_VERTEX:
   1202       vertexCallBackN = (void (GLAPIENTRY *) (const GLfloat*)) fn;
   1203       break;
   1204     case GLU_NURBS_NORMAL:
   1205       normalCallBackN = (void (GLAPIENTRY *) (const GLfloat*)) fn;
   1206       break;
   1207     case GLU_NURBS_COLOR:
   1208       colorCallBackN = (void (GLAPIENTRY *) (const GLfloat*)) fn;
   1209       break;
   1210     case GLU_NURBS_TEXTURE_COORD:
   1211       texcoordCallBackN = (void (GLAPIENTRY *) (const GLfloat*)) fn;
   1212       break;
   1213     case GLU_NURBS_BEGIN_DATA:
   1214       beginCallBackData = (void (GLAPIENTRY *) (GLenum, void*)) fn;
   1215       break;
   1216     case GLU_NURBS_END_DATA:
   1217       endCallBackData = (void (GLAPIENTRY *) (void*)) fn;
   1218       break;
   1219     case GLU_NURBS_VERTEX_DATA:
   1220       vertexCallBackData = (void (GLAPIENTRY *) (const GLfloat*, void*)) fn;
   1221       break;
   1222     case GLU_NURBS_NORMAL_DATA:
   1223       normalCallBackData = (void (GLAPIENTRY *) (const GLfloat*, void*)) fn;
   1224       break;
   1225     case GLU_NURBS_COLOR_DATA:
   1226       colorCallBackData = (void (GLAPIENTRY *) (const GLfloat*, void*)) fn;
   1227       break;
   1228     case GLU_NURBS_TEXTURE_COORD_DATA:
   1229       texcoordCallBackData = (void (GLAPIENTRY *) (const GLfloat*, void*)) fn;
   1230       break;
   1231 
   1232     }
   1233 }
   1234 
   1235 
   1236 void
   1237 OpenGLSurfaceEvaluator::beginCallBack(GLenum which, void *data)
   1238 {
   1239   if(beginCallBackData)
   1240     beginCallBackData(which, data);
   1241   else if(beginCallBackN)
   1242     beginCallBackN(which);
   1243 }
   1244 
   1245 void
   1246 OpenGLSurfaceEvaluator::endCallBack(void *data)
   1247 {
   1248   if(endCallBackData)
   1249     endCallBackData(data);
   1250   else if(endCallBackN)
   1251     endCallBackN();
   1252 }
   1253 
   1254 void
   1255 OpenGLSurfaceEvaluator::vertexCallBack(const GLfloat *vert, void* data)
   1256 {
   1257   if(vertexCallBackData)
   1258     vertexCallBackData(vert, data);
   1259   else if(vertexCallBackN)
   1260     vertexCallBackN(vert);
   1261 }
   1262 
   1263 
   1264 void
   1265 OpenGLSurfaceEvaluator::normalCallBack(const GLfloat *normal, void* data)
   1266 {
   1267   if(normalCallBackData)
   1268     normalCallBackData(normal, data);
   1269   else if(normalCallBackN)
   1270     normalCallBackN(normal);
   1271 }
   1272 
   1273 void
   1274 OpenGLSurfaceEvaluator::colorCallBack(const GLfloat *color, void* data)
   1275 {
   1276   if(colorCallBackData)
   1277     colorCallBackData(color, data);
   1278   else if(colorCallBackN)
   1279     colorCallBackN(color);
   1280 }
   1281 
   1282 void
   1283 OpenGLSurfaceEvaluator::texcoordCallBack(const GLfloat *texcoord, void* data)
   1284 {
   1285   if(texcoordCallBackData)
   1286     texcoordCallBackData(texcoord, data);
   1287   else if(texcoordCallBackN)
   1288     texcoordCallBackN(texcoord);
   1289 }
   1290 
   1291 
   1292 
   1293 
   1294