📄 insurfeval.cc
字号:
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 + -