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

📄 insurfeval.cc

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 CC
📖 第 1 页 / 共 4 页
字号:
 * n: return normal, of dimension 3
 */
void OpenGLSurfaceEvaluator::inComputeNormal2(REAL *pu, REAL *pv, REAL *n)
{
  REAL mag; 

  n[0] = pu[1]*pv[2] - pu[2]*pv[1];
  n[1] = pu[2]*pv[0] - pu[0]*pv[2];
  n[2] = pu[0]*pv[1] - pu[1]*pv[0];  

  mag = sqrt(n[0]*n[0] + n[1]*n[1] + n[2]*n[2]);

  if (mag > 0.0) {
     n[0] /= mag; 
     n[1] /= mag;
     n[2] /= mag;
  }
}
 


/*Compute point and normal
 *see the head of inDoDomain2WithDerivs
 *for the meaning of the arguments
 */
void OpenGLSurfaceEvaluator::inDoEvalCoord2(REAL u, REAL v,
			   REAL *retPoint, REAL *retNormal)
{

  REAL du[4];
  REAL dv[4];

 
  assert(global_ev_k>=3 && global_ev_k <= 4);
  /*compute homegeneous point and partial derivatives*/
  inDoDomain2WithDerivs(global_ev_k, u, v, global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, retPoint, du, dv);

#ifdef AVOID_ZERO_NORMAL

  if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO)
    {

      REAL tempdu[4];
      REAL tempdata[4];
      REAL u1 = global_ev_u1;
      REAL u2 = global_ev_u2;
      if(u-MYDELTA*(u2-u1) < u1)
	u = u+ MYDELTA*(u2-u1);
      else
	u = u-MYDELTA*(u2-u1);
      inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, tempdu, dv);
    }
  if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO)
    {
      REAL tempdv[4];
      REAL tempdata[4];
      REAL v1 = global_ev_v1;
      REAL v2 = global_ev_v2;
      if(v-MYDELTA*(v2-v1) < v1)
	v = v+ MYDELTA*(v2-v1);
      else
	v = v-MYDELTA*(v2-v1);
      inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, du, tempdv);
    }
#endif


  /*compute normal*/
  switch(global_ev_k){
  case 3:
    inComputeNormal2(du, dv, retNormal);

    break;
  case 4:
    inComputeFirstPartials(retPoint, du, dv);
    inComputeNormal2(du, dv, retNormal);
    /*transform the homegeneous coordinate of retPoint into inhomogenous one*/
    retPoint[0] /= retPoint[3];
    retPoint[1] /= retPoint[3];
    retPoint[2] /= retPoint[3];
    break;
  }
  /*output this vertex*/
/*  inMeshStreamInsert(global_ms, retPoint, retNormal);*/



  glNormal3fv(retNormal);
  glVertex3fv(retPoint);




  #ifdef DEBUG
  printf("vertex(%f,%f,%f)\n", retPoint[0],retPoint[1],retPoint[2]);
  #endif
  


}

/*Compute point and normal
 *see the head of inDoDomain2WithDerivs
 *for the meaning of the arguments
 */
void OpenGLSurfaceEvaluator::inDoEvalCoord2NOGE_BU(REAL u, REAL v,
			   REAL *retPoint, REAL *retNormal)
{

  REAL du[4];
  REAL dv[4];

 
  assert(global_ev_k>=3 && global_ev_k <= 4);
  /*compute homegeneous point and partial derivatives*/
//   inPreEvaluateBU(global_ev_k, global_ev_uorder, global_ev_vorder, (u-global_ev_u1)/(global_ev_u2-global_ev_u1), global_ev_ctlPoints);
  inDoDomain2WithDerivsBU(global_ev_k, u, v, global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, retPoint, du, dv);


#ifdef AVOID_ZERO_NORMAL

  if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO)
    {

      REAL tempdu[4];
      REAL tempdata[4];
      REAL u1 = global_ev_u1;
      REAL u2 = global_ev_u2;
      if(u-MYDELTA*(u2-u1) < u1)
	u = u+ MYDELTA*(u2-u1);
      else
	u = u-MYDELTA*(u2-u1);
      inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, tempdu, dv);
    }
  if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO)
    {
      REAL tempdv[4];
      REAL tempdata[4];
      REAL v1 = global_ev_v1;
      REAL v2 = global_ev_v2;
      if(v-MYDELTA*(v2-v1) < v1)
	v = v+ MYDELTA*(v2-v1);
      else
	v = v-MYDELTA*(v2-v1);
      inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, du, tempdv);
    }
#endif

  /*compute normal*/
  switch(global_ev_k){
  case 3:
    inComputeNormal2(du, dv, retNormal);
    break;
  case 4:
    inComputeFirstPartials(retPoint, du, dv);
    inComputeNormal2(du, dv, retNormal);
    /*transform the homegeneous coordinate of retPoint into inhomogenous one*/
    retPoint[0] /= retPoint[3];
    retPoint[1] /= retPoint[3];
    retPoint[2] /= retPoint[3];
    break;
  }
}

/*Compute point and normal
 *see the head of inDoDomain2WithDerivs
 *for the meaning of the arguments
 */
void OpenGLSurfaceEvaluator::inDoEvalCoord2NOGE_BV(REAL u, REAL v,
			   REAL *retPoint, REAL *retNormal)
{

  REAL du[4];
  REAL dv[4];

 
  assert(global_ev_k>=3 && global_ev_k <= 4);
  /*compute homegeneous point and partial derivatives*/
//   inPreEvaluateBV(global_ev_k, global_ev_uorder, global_ev_vorder, (v-global_ev_v1)/(global_ev_v2-global_ev_v1), global_ev_ctlPoints);

  inDoDomain2WithDerivsBV(global_ev_k, u, v, global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, retPoint, du, dv);


#ifdef AVOID_ZERO_NORMAL

  if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO)
    {

      REAL tempdu[4];
      REAL tempdata[4];
      REAL u1 = global_ev_u1;
      REAL u2 = global_ev_u2;
      if(u-MYDELTA*(u2-u1) < u1)
	u = u+ MYDELTA*(u2-u1);
      else
	u = u-MYDELTA*(u2-u1);
      inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, tempdu, dv);
    }
  if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO)
    {
      REAL tempdv[4];
      REAL tempdata[4];
      REAL v1 = global_ev_v1;
      REAL v2 = global_ev_v2;
      if(v-MYDELTA*(v2-v1) < v1)
	v = v+ MYDELTA*(v2-v1);
      else
	v = v-MYDELTA*(v2-v1);
      inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, du, tempdv);
    }
#endif

  /*compute normal*/
  switch(global_ev_k){
  case 3:
    inComputeNormal2(du, dv, retNormal);
    break;
  case 4:
    inComputeFirstPartials(retPoint, du, dv);
    inComputeNormal2(du, dv, retNormal);
    /*transform the homegeneous coordinate of retPoint into inhomogenous one*/
    retPoint[0] /= retPoint[3];
    retPoint[1] /= retPoint[3];
    retPoint[2] /= retPoint[3];
    break;
  }
}
 

/*Compute point and normal
 *see the head of inDoDomain2WithDerivs
 *for the meaning of the arguments
 */
void OpenGLSurfaceEvaluator::inDoEvalCoord2NOGE(REAL u, REAL v,
			   REAL *retPoint, REAL *retNormal)
{

  REAL du[4];
  REAL dv[4];

 
  assert(global_ev_k>=3 && global_ev_k <= 4);
  /*compute homegeneous point and partial derivatives*/
  inDoDomain2WithDerivs(global_ev_k, u, v, global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, retPoint, du, dv);


#ifdef AVOID_ZERO_NORMAL

  if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO)
    {

      REAL tempdu[4];
      REAL tempdata[4];
      REAL u1 = global_ev_u1;
      REAL u2 = global_ev_u2;
      if(u-MYDELTA*(u2-u1) < u1)
	u = u+ MYDELTA*(u2-u1);
      else
	u = u-MYDELTA*(u2-u1);
      inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, tempdu, dv);
    }
  if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO)
    {
      REAL tempdv[4];
      REAL tempdata[4];
      REAL v1 = global_ev_v1;
      REAL v2 = global_ev_v2;
      if(v-MYDELTA*(v2-v1) < v1)
	v = v+ MYDELTA*(v2-v1);
      else
	v = v-MYDELTA*(v2-v1);
      inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, du, tempdv);
    }
#endif

  /*compute normal*/
  switch(global_ev_k){
  case 3:
    inComputeNormal2(du, dv, retNormal);
    break;
  case 4:
    inComputeFirstPartials(retPoint, du, dv);
    inComputeNormal2(du, dv, retNormal);
    /*transform the homegeneous coordinate of retPoint into inhomogenous one*/
    retPoint[0] /= retPoint[3];
    retPoint[1] /= retPoint[3];
    retPoint[2] /= retPoint[3];
    break;
  }
//  glNormal3fv(retNormal);
//  glVertex3fv(retPoint);
}
 
void OpenGLSurfaceEvaluator::inPreEvaluateBV(int k, int uorder, int vorder, REAL vprime, REAL *baseData)
{
  int j,row,col;
  REAL p, pdv;
  REAL *data;

  if(global_vprime != vprime || global_vorder != vorder) {      
    inPreEvaluateWithDeriv(vorder, vprime, global_vcoeff, global_vcoeffDeriv);
    global_vprime = vprime;
    global_vorder = vorder;
  }

  for(j=0; j<k; j++){
    data = baseData+j;
    for(row=0; row<uorder; row++){
      p = global_vcoeff[0] * (*data);
      pdv = global_vcoeffDeriv[0] * (*data);
      data += k;
      for(col = 1; col < vorder; col++){
	p += global_vcoeff[col] *  (*data);
	pdv += global_vcoeffDeriv[col] * (*data);
	data += k;
      }
      global_BV[row][j]  = p;
      global_PBV[row][j]  = pdv;
    }
  }
}

void OpenGLSurfaceEvaluator::inPreEvaluateBU(int k, int uorder, int vorder, REAL uprime, REAL *baseData)
{
  int j,row,col;
  REAL p, pdu;
  REAL *data;

  if(global_uprime != uprime || global_uorder != uorder) {      
    inPreEvaluateWithDeriv(uorder, uprime, global_ucoeff, global_ucoeffDeriv);
    global_uprime = uprime;
    global_uorder = uorder;
  }

  for(j=0; j<k; j++){
    data = baseData+j;
    for(col=0; col<vorder; col++){
      data = baseData+j + k*col;
      p = global_ucoeff[0] * (*data);
      pdu = global_ucoeffDeriv[0] * (*data);
      data += k*uorder;
      for(row = 1; row < uorder; row++){
	p += global_ucoeff[row] *  (*data);
	pdu += global_ucoeffDeriv[row] * (*data);
	data += k * uorder;
      }
      global_BU[col][j]  = p;
      global_PBU[col][j]  = pdu;
    }
  }
}
 
void OpenGLSurfaceEvaluator::inDoDomain2WithDerivsBU(int k, REAL u, REAL v,
						      REAL u1, REAL u2, int uorder,
						      REAL v1, REAL v2, int vorder,
						      REAL *baseData,
						      REAL *retPoint, REAL* retdu, REAL *retdv)
{
  int j, col;

  REAL vprime;


  if((u2 == u1) || (v2 == v1))
    return;

  vprime = (v - v1) / (v2 - v1);


  if(global_vprime != vprime || global_vorder != vorder) {
    inPreEvaluateWithDeriv(vorder, vprime, global_vcoeff, global_vcoeffDeriv);
    global_vprime = vprime;
    global_vorder = vorder;
  }


  for(j=0; j<k; j++)
    {
      retPoint[j] = retdu[j] = retdv[j] = 0.0;
      for (col = 0; col < vorder; col++)  {
	retPoint[j] += global_BU[col][j] * global_vcoeff[col];
	retdu[j] += global_PBU[col][j] * global_vcoeff[col];
	retdv[j] += global_BU[col][j] * global_vcoeffDeriv[col];
      }
    }
}    
   
void OpenGLSurfaceEvaluator::inDoDomain2WithDerivsBV(int k, REAL u, REAL v,
						      REAL u1, REAL u2, int uorder,
						      REAL v1, REAL v2, int vorder,
						      REAL *baseData,
						      REAL *retPoint, REAL* retdu, REAL *retdv)
{
  int j, row;
  REAL uprime;


  if((u2 == u1) || (v2 == v1))
    return;
  uprime = (u - u1) / (u2 - u1);


  if(global_uprime != uprime || global_uorder != uorder) {
    inPreEvaluateWithDeriv(uorder, uprime, global_ucoeff, global_ucoeffDeriv);
    global_uprime = uprime;
    global_uorder = uorder;
  }


  for(j=0; j<k; j++)
    {
      retPoint[j] = retdu[j] = retdv[j] = 0.0;
      for (row = 0; row < uorder; row++)  {
	retPoint[j] += global_BV[row][j] * global_ucoeff[row];
	retdu[j] += global_BV[row][j] * global_ucoeffDeriv[row];
	retdv[j] += global_PBV[row][j] * global_ucoeff[row];
      }
    }
}
  

/*
 *given a Bezier surface, and parameter (u,v), compute the point in the object space,
 *and the normal
 *k: the dimension of the object space: usually 2,3,or 4.
 *u,v: the paramter pair.
 *u1,u2,uorder: the Bezier polynomial of u coord is defined on [u1,u2] with order uorder.
 *v1,v2,vorder: the Bezier polynomial of v coord is defined on [v1,v2] with order vorder.
 *baseData: contrl points. arranged as: (u,v,k).
 *retPoint:  the computed point (one point) with dimension k.
 *retdu: the computed partial derivative with respect to u.
 *retdv: the computed partial derivative with respect to v.
 */
void OpenGLSurfaceEvaluator::inDoDomain2WithDerivs(int k, REAL u, REAL v, 
				REAL u1, REAL u2, int uorder, 
				REAL v1,  REAL v2, int vorder, 
				REAL *baseData,
				REAL *retPoint, REAL *retdu, REAL *retdv)
{
    int j, row, col;
    REAL uprime;
    REAL vprime;
    REAL p;
    REAL pdv;
    REAL *data;

    if((u2 == u1) || (v2 == v1))
	return;
    uprime = (u - u1) / (u2 - u1);
    vprime = (v - v1) / (v2 - v1);
    
    /* Compute coefficients for values and derivs */

    /* Use already cached values if possible */
    if(global_uprime != uprime || global_uorder != uorder) {
        inPreEvaluateWithDeriv(uorder, uprime, global_ucoeff, global_ucoeffDeriv);
	global_uorder = uorder;
	global_uprime = uprime;
    }
    if (global_vprime != vprime || 
	  global_vorder != vorder) {
	inPreEvaluateWithDeriv(vorder, vprime, global_vcoeff, global_vcoeffDeriv);
	global_vorder = vorder;
	global_vprime = vprime;
    }

    for (j = 0; j < k; j++) {
	data=baseData+j;
	retPoint[j] = retdu[j] = retdv[j] = 0.0;
	for (row = 0; row < uorder; row++)  {
	    /* 
	    ** Minor optimization.
	    ** The col == 0 part of the loop is extracted so we don't
	    ** have to initialize p and pdv to 0.
	    */
	    p = global_vcoeff[0] * (*data);
	    pdv = global_vcoeffDeriv[0] * (*data);
	    data += k;
	    for (col = 1; col < vorder; col++) {
		/* Incrementally build up p, pdv value */
		p += global_vcoeff[col] * (*data);
		pdv += global_vcoeffDeriv[col] * (*data);
		data += k;
	    }
	    /* Use p, pdv value to incrementally add up r, du, dv */
	    retPoint[j] += global_ucoeff[row] * p;
	    retdu[j] += global_ucoeffDeriv[row] * p;
	    retdv[j] += global_ucoeff[row] * pdv;
	}
    }  
}


/*
 *compute the Bezier polynomials C[n,j](v) for all j at v with 
 *return values stored in coeff[], where 
 *  C[n,j](v) = (n,j) * v^j * (1-v)^(n-j),
 *  j=0,1,2,...,n.
 *order : n+1
 *vprime: v
 *coeff : coeff[j]=C[n,j](v), this array store the returned values.
 *The algorithm is a recursive scheme:
 *   C[0,0]=1;
 *   C[n,j](v) = (1-v)*C[n-1,j](v) + v*C[n-1,j-1](v), n>=1
 *This code is copied from opengl/soft/so_eval.c:PreEvaluate
 */
void OpenGLSurfaceEvaluator::inPreEvaluate(int order, REAL vprime, REAL *coeff)
{
  int i, j;
  REAL oldval, temp;
  REAL oneMinusvprime;
  
  /*
   * Minor optimization
   * Compute orders 1 and 2 outright, and set coeff[0], coeff[1] to
     * their i==1 loop values to avoid the initialization and the i==1 loop.
     */

⌨️ 快捷键说明

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