📄 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(rightXYZ); free(leftNormal); 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 + -