//=========================================================================== vector<shared_ptr<SplineSurface> > SurfaceCreators::separateRationalParts(const SplineSurface& sf) //=========================================================================== { bool rat = sf.rational(); ASSERT(rat); int dim= sf.dimension(); int rdim = dim + 1; vector<shared_ptr<SplineSurface> > sep_sfs; vector<double> coefs(sf.coefs_begin(), sf.coefs_end()); int nmb1 = sf.numCoefs_u(); int nmb2 = sf.numCoefs_v(); vector<double> rcoefs; int num_coefs = nmb1*nmb2; vector<double>::const_iterator rcoef_iter = sf.rcoefs_begin(); for (int ki = 0; ki < num_coefs; ++ki) { rcoefs.push_back(rcoef_iter[ki*rdim+1]); for (int kj = 0; kj < dim; ++kj) { coefs[ki*dim+kj] /= (rcoefs.back()); } } sep_sfs.push_back(shared_ptr<SplineSurface> (new SplineSurface(nmb1, nmb2, sf.order_u(), sf.order_v(), sf.basis_u().begin(), sf.basis_v().begin(), coefs.begin(), dim))); sep_sfs.push_back(shared_ptr<SplineSurface> (new SplineSurface(nmb1, nmb2, sf.order_u(), sf.order_v(), sf.basis_u().begin(), sf.basis_v().begin(), rcoefs.begin(), 1))); return sep_sfs; }
//========================================================================== void GeometryTools::splitSurfaceIntoPatches(const SplineSurface& sf, vector<SplineSurface>& pat) //========================================================================== { SplineSurface orig = sf; orig.makeBernsteinKnotsU(); orig.makeBernsteinKnotsV(); int num_u = orig.numCoefs_u(); int num_v = orig.numCoefs_v(); int order_u = orig.order_u(); int order_v = orig.order_v(); int numpat_u = num_u / order_u; int numpat_v = num_v / order_v; pat.resize(numpat_u * numpat_v); typedef vector<double>::const_iterator const_iter; const_iter itu = orig.basis_u().begin(); const_iter itv; for (int i = 0; i < numpat_u; ++i) { itv = orig.basis_v().begin(); for (int j = 0; j < numpat_v; ++j) { shared_ptr<SplineSurface> new_sf(orig.subSurface(*itu, *itv, *(itu+order_u), *(itv+order_v))); pat[numpat_u*j + i] = *new_sf; itv += order_v; } itu += order_u; } return; }
int main(int argc, char** argv) { if (argc < 3) { cerr << "Usage: " << argv[0] << " inputfile outputfile [max_coefs_u max_coefs_v]" << endl; return 1; } ifstream in(argv[1]); ofstream out(argv[2]); if (!in || !out) { cout << "Bad file(s) or filename(s)." << endl; return 1; } ObjectHeader oh; SplineSurface sf; in >> oh >> sf; int m = sf.numCoefs_v() - sf.order_v() + 1; int n = sf.numCoefs_u() - sf.order_u() + 1; if (argc >= 5) { // Note the weird order (v then u) m = min(atoi(argv[4])-sf.numCoefs_v(), m); n = min(atoi(argv[3])-sf.numCoefs_u(), n); } int i; vector<double> newknots_v; vector<double> newknots_u; for (i = 0; i < m; ++i) { vector<double>::const_iterator it = sf.basis_v().begin(); double newknot = 0.5*it[sf.order_v()+i-1] + 0.5*it[sf.order_v()+i]; newknots_v.push_back(newknot); } for (i = 0; i < n; ++i) { vector<double>::const_iterator it = sf.basis_u().begin(); double newknot = 0.5*it[sf.order_u()+i-1] + 0.5*it[sf.order_u()+i]; newknots_u.push_back(newknot); } sf.insertKnot_v(newknots_v); sf.insertKnot_u(newknots_u); out << oh << sf; return 0; }
//=========================================================================== shared_ptr<SplineSurface> SplineUtils::refineToBezier(const SplineSurface& spline_sf) //=========================================================================== { shared_ptr<SplineSurface> bez_sf; const BsplineBasis& bas_u = spline_sf.basis_u(); const BsplineBasis& bas_v = spline_sf.basis_v(); const int order_u = bas_u.order(); const int order_v = bas_v.order(); // We extract the unique knots. vector<double> new_knots_u, new_knots_v; // vector<double> ref_knots_u, ref_knots_v; vector<double>::const_iterator iter = bas_u.begin(); while (iter != bas_u.end() - order_u) { if (iter[0] != iter[1]) { int knot_mult = bas_u.knotMultiplicity(iter[0]); int num_insert = order_u - knot_mult; if (num_insert > 0) { new_knots_u.insert(new_knots_u.end(), num_insert, iter[0]); } } ++iter; } iter = bas_v.begin(); while (iter != bas_v.end() - order_v) { if (iter[0] != iter[1]) { int knot_mult = bas_v.knotMultiplicity(iter[0]); int num_insert = order_v - knot_mult; if (num_insert > 0) { new_knots_v.insert(new_knots_v.end(), num_insert, iter[0]); } } ++iter; } bez_sf = insertKnots(spline_sf, new_knots_u, new_knots_v); return bez_sf; }
//========================================================================== void cart_to_bary(const SplineSurface& sf, const BaryCoordSystem3D& bc, SplineSurface& sf_bc) //========================================================================== { ALWAYS_ERROR_IF(sf.dimension() != 3, "Dimension must be 3."); int nu = sf.numCoefs_u(); int nv = sf.numCoefs_v(); Vector3D cart; Vector4D bary; vector<double> new_coefs; if (!sf.rational()) { new_coefs.resize(4 * nu * nv); for (int iv = 0; iv < nv; ++iv) { for (int iu = 0; iu < nu; ++iu) { int offset = nu * iv + iu; cart = Vector3D(sf.coefs_begin() + 3 * offset); bary = bc.cartToBary(cart); for (int j = 0; j < 4; ++j) { new_coefs[4*offset + j] = bary[j]; } } } } else { new_coefs.resize(5 * nu * nv); for (int iv = 0; iv < nv; ++iv) { for (int iu = 0; iu < nu; ++iu) { int offset = nu * iv + iu; cart = Vector3D(sf.coefs_begin() + 3 * offset); bary = bc.cartToBary(cart); double w = sf.rcoefs_begin()[4*offset + 3]; for (int j = 0; j < 4; ++j) { new_coefs[5*offset + j] = bary[j] * w; } new_coefs[5*offset + 4] = w; } } } sf_bc = SplineSurface(nu, nv, sf.order_u(), sf.order_v(), sf.basis_u().begin(), sf.basis_v().begin(), new_coefs.begin(), 4, sf.rational()); return; }
int main(int argc, char** argv) { if (argc != 6) { cout << "Usage: " << argv[0] << " surfaceinfile surface3doutfile points3doutfile num_u num_v" << endl; exit(-1); } ifstream filein(argv[1]); ALWAYS_ERROR_IF(filein.bad(), "Bad or no curvee input filename"); ObjectHeader head; filein >> head; if (head.classType() != SplineSurface::classType()) { THROW("Not a spline surface"); } SplineSurface sf; filein >> sf; ofstream fileoutsurf(argv[2]); ALWAYS_ERROR_IF(fileoutsurf.bad(), "Bad surface output filename"); ofstream fileoutpts(argv[3]); ALWAYS_ERROR_IF(fileoutpts.bad(), "Bad points output filename"); int num_u = atoi(argv[4]); int num_v = atoi(argv[5]); vector<double> pts, param_u, param_v; sf.gridEvaluator(num_u, num_v, pts, param_u, param_v); vector<double> coefs3d; vector<Point> pts3d; int dim = sf.dimension(); bool rational = sf.rational(); int ctrl_pts = sf.numCoefs_u() * sf.numCoefs_v(); vector<double>::const_iterator it = sf.ctrl_begin(); for (int i = 0; i < ctrl_pts; ++i) { if (dim <= 3) for (int j = 0; j < 3; ++j) { if (j>=dim) coefs3d.push_back(0.0); else { coefs3d.push_back(*it); ++it; } } else { for (int j = 0; j < 3; ++j, ++it) coefs3d.push_back(*it); it += (dim-3); } if (rational) { coefs3d.push_back(*it); ++it; } } int pts_pos = 0; for (int i = 0; i < num_u*num_v; ++i) { double x, y, z; if (dim == 0) x = 0.0; else x = pts[pts_pos]; if (dim <= 1) y = 0.0; else y = pts[pts_pos+1]; if (dim <= 2) z = 0.0; else z = pts[pts_pos+2]; pts_pos += dim; pts3d.push_back(Point(x, y, z)); } SplineSurface sf3d(sf.basis_u(), sf.basis_v(), coefs3d.begin(), 3, rational); sf3d.writeStandardHeader(fileoutsurf); sf3d.write(fileoutsurf); fileoutpts << "400 1 0 4 255 255 0 255" << endl; fileoutpts << pts3d.size() << endl; for (int i = 0; i < (int)pts3d.size(); ++i) fileoutpts << pts3d[i] << endl; }
//=========================================================================== void SplineUtils::refinedBezierCoefsCubic(SplineSurface& spline_sf, int ind_u_min, int ind_v_min, vector<double>& bez_coefs) //=========================================================================== { assert(!spline_sf.rational()); if (bez_coefs.size() != 48) bez_coefs.resize(48); std::fill(bez_coefs.begin(), bez_coefs.end(), 0.0); // Values for inpute spline surface. int dim = spline_sf.dimension(); int order_u = spline_sf.order_u(); int order_v = spline_sf.order_u(); int num_coefs_u = spline_sf.numCoefs_u(); int num_coefs_v = spline_sf.numCoefs_v(); // Checking that input index is within range. assert(ind_u_min >= order_u - 1 && ind_u_min < num_coefs_u); assert(ind_v_min >= order_v - 1 && ind_v_min < num_coefs_v); BsplineBasis& basis_u = spline_sf.basis_u(); BsplineBasis& basis_v = spline_sf.basis_v(); double* knot_u = &basis_u.begin()[0]; double* knot_v = &basis_v.begin()[0]; // We expect the knot index to refer to the last occurence. assert(knot_u[ind_u_min] != knot_u[ind_u_min+1]); assert(knot_v[ind_v_min] != knot_v[ind_v_min+1]); // We expect knot mult to be 1 or 4. int knot_mult_umin = (knot_u[ind_u_min-1] == knot_u[ind_u_min]) ? 4 : 1; int knot_mult_umax = (knot_u[ind_u_min+1] == knot_u[ind_u_min+2]) ? 4 : 1; int knot_mult_vmin = (knot_v[ind_v_min-1] == knot_v[ind_v_min]) ? 4 : 1; int knot_mult_vmax = (knot_v[ind_v_min+1] == knot_v[ind_v_min+2]) ? 4 : 1; bool kreg_at_ustart = (knot_mult_umin == 4); bool kreg_at_uend = (knot_mult_umax == 4); vector<double> transf_mat_u(16, 0.0); // if (!kreg_at_ustart && !kreg_at_uend) splineToBezierTransfMat(knot_u + ind_u_min - 3, transf_mat_u); #ifndef NDEBUG std::cout << "\ntransf_mat_u=" << std::endl; for (size_t kj = 0; kj < 4; ++kj) { for (size_t ki = 0; ki < 4; ++ki) std::cout << transf_mat_u[kj*4+ki] << " "; std::cout << std::endl; } std::cout << std::endl; #endif // NDEBUG // else // cubicTransfMat(knot_u + ind_u_min - 3, // kreg_at_ustart, kreg_at_uend, // transf_mat_u); bool kreg_at_vstart = (knot_mult_vmin == 4); bool kreg_at_vend = (knot_mult_vmax == 4); vector<double> transf_mat_v(16, 0.0); // if (!kreg_at_ustart && !kreg_at_uend) splineToBezierTransfMat(knot_v + ind_v_min - 3, transf_mat_v); #ifndef NDEBUG std::cout << "\ntransf_mat_v=" << std::endl; for (size_t kj = 0; kj < 4; ++kj) { for (size_t ki = 0; ki < 4; ++ki) std::cout << transf_mat_v[kj*4+ki] << " "; std::cout << std::endl; } std::cout << std::endl; #endif // NDEBUG extractBezierCoefs(&spline_sf.coefs_begin()[0], num_coefs_u, num_coefs_v, ind_u_min, ind_v_min, transf_mat_u, transf_mat_v, bez_coefs); return; }