void nurbsfit::IncreaseDimension( const ON_NurbsSurface& src, ON_NurbsSurface& dest, int dim ) { dest.m_dim = dim; dest.m_is_rat = src.m_is_rat; dest.m_order[0] = src.m_order[0]; dest.m_order[1] = src.m_order[1]; dest.m_cv_count[0] = src.m_cv_count[0]; dest.m_cv_count[1] = src.m_cv_count[1]; dest.m_cv_stride[1] = dest.m_is_rat ? dest.m_dim+1 : dest.m_dim; dest.m_cv_stride[0] = dest.m_cv_count[1]*dest.m_cv_stride[1]; if ( src.m_knot[0] ) { // copy knot array dest.ReserveKnotCapacity( 0, dest.KnotCount(0) ); memcpy( dest.m_knot[0], src.m_knot[0], dest.KnotCount(0)*sizeof(*dest.m_knot[0]) ); } if ( src.m_knot[1] ) { // copy knot array dest.ReserveKnotCapacity( 1, dest.KnotCount(1) ); memcpy( dest.m_knot[1], src.m_knot[1], dest.KnotCount(1)*sizeof(*dest.m_knot[1]) ); } if ( src.m_cv ) { // copy cv array dest.ReserveCVCapacity( dest.m_cv_count[0]*dest.m_cv_count[1]*dest.m_cv_stride[1] ); const int dst_cv_size = dest.CVSize()*sizeof(*dest.m_cv); const int src_stride[2] = {src.m_cv_stride[0],src.m_cv_stride[1]}; if ( src_stride[0] == dest.m_cv_stride[0] && src_stride[1] == dest.m_cv_stride[1] ) { memcpy( dest.m_cv, src.m_cv, dest.m_cv_count[0]*dest.m_cv_count[1]*dest.m_cv_stride[1]*sizeof(*dest.m_cv) ); } else { const double *src_cv; double *dst_cv = dest.m_cv; int i, j; for ( i = 0; i < dest.m_cv_count[0]; i++ ) { src_cv = src.CV(i,0); for ( j = 0; j < dest.m_cv_count[1]; j++ ) { memcpy( dst_cv, src_cv, dst_cv_size ); dst_cv += dest.m_cv_stride[1]; src_cv += src_stride[1]; } } } } }
void ON_GL( const ON_NurbsSurface& s, GLUnurbsObj* nobj, // created with gluNewNurbsRenderer ) GLenum type, // = 0 (and type is automatically set) int bPermitKnotScaling, double* knot_scale0, double* knot_scale1 ) { int i, j, k; // The "bPermitScaling" parameters to the ON_GL() call that // fills in the knot vectors is set to false because any // rescaling that is applied to a surface domain must also // be applied to parameter space trimming curve geometry. // GL "s" knots GLint sknot_count = s.KnotCount(0) + 2; GLfloat* sknot = (GLfloat*)onmalloc( sknot_count*sizeof(*sknot) ); ON_GL( s.Order(0), s.CVCount(0), s.Knot(0), sknot, bPermitKnotScaling, knot_scale0 ); // GL "t" knots GLint tknot_count = s.KnotCount(1) + 2; GLfloat* tknot = (GLfloat*)onmalloc( tknot_count*sizeof(*tknot) ); ON_GL( s.Order(1), s.CVCount(1), s.Knot(1), tknot, bPermitKnotScaling, knot_scale1 ); // control vertices const int cv_size= s.CVSize(); const int cv_count[2] = {s.CVCount(0), s.CVCount(1)}; GLint s_stride = cv_size*cv_count[1]; GLint t_stride = cv_size; GLfloat* ctlarray = (GLfloat*)onmalloc( s_stride*cv_count[0]*sizeof(*ctlarray) ); for ( i = 0; i < cv_count[0]; i++ ) { for ( j = 0; j < cv_count[1]; j++ ) { const double* cv = s.CV(i,j); GLfloat* gl_cv = ctlarray + s_stride*i + t_stride*j; for ( k = 0; k < cv_size; k++ ) { gl_cv[k] = (GLfloat)cv[k]; } } } GLint sorder = s.Order(0); GLint torder = s.Order(1); if ( type == 0 ) { // set GL surface type for 3d CVs in homogeneous/euclidean form. type = ( s.IsRational() ) ? GL_MAP2_VERTEX_4 : GL_MAP2_VERTEX_3; } gluNurbsSurface ( nobj, sknot_count, sknot, tknot_count, tknot, s_stride, t_stride, ctlarray, sorder, torder, type ); onfree( ctlarray ); onfree( tknot ); onfree( sknot ); }