⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 insurfeval.cc

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 CC
📖 第 1 页 / 共 4 页
字号:
  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(leftXYZ);
  free(rightNormal);
  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)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -