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; }
//=========================================================================== SplineSurface* LoftSurfaceCreator::loftSurfaceFromUnifiedCurves(vector<shared_ptr<SplineCurve> >::iterator first_curve, vector<double>::iterator first_param, int nmb_crvs) //=========================================================================== { SplineSurface* surf = loftNonrationalSurface(first_curve, first_param, nmb_crvs); if (first_curve[0]->rational()) { int n = surf->numCoefs_u() * surf->numCoefs_v(); int kdim = surf->dimension() + 1; bool all_positive = true; vector<double>::const_iterator it = surf->rcoefs_begin(); it += (kdim - 1); for (int i = 0; i < n; ++i) if (it[kdim * i] <= 0.0) { all_positive = false; break; } if (!all_positive) { delete surf; surf = loftRationalSurface(first_curve, first_param, nmb_crvs); } } return surf; }
//========================================================================== 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; }
//========================================================================== void GeometryTools::findDominant(const SplineSurface& surface, Vector3D& dominant_u, Vector3D& dominant_v) //========================================================================== { int nu = surface.numCoefs_u(); int nv = surface.numCoefs_v(); vector<double>::const_iterator start = surface.coefs_begin(); Vector3D temp; // Dominant in u-direction dominant_u = Vector3D(0.0, 0.0, 0.0); for (int j = 0; j < nv; ++j) { for (int dd = 0; dd < 3; ++dd) { temp[dd] = *(start + 3*(nu*j + (nu-1)) + dd) - *(start + 3*(nu*j) + dd); } dominant_u += temp; } // Dominant in v-direction dominant_v = Vector3D(0.0, 0.0, 0.0); for (int i = 0; i < nu; ++i) { for (int dd = 0; dd < 3; ++dd) { temp[dd] = *(start + 3*(nu*(nv-1) + i) + dd) - *(start + 3*i + dd); } dominant_v += temp; } return; }
//=========================================================================== 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; }
int main() { ObjectHeader header; SplineSurface surf; cin >> header >> surf; PointCloud<3> cloud(surf.coefs_begin(), surf.numCoefs_u()*surf.numCoefs_v()); cloud.writeStandardHeader(cout); cout << cloud; }
//========================================================================== bool GeometryTools::negativeProj(const SplineSurface& surface, const Array<Vector3D, 2>& refvector, const double eps) //========================================================================== { int num_u = surface.numCoefs_u(); int num_v = surface.numCoefs_v(); Vector3D temp; int i = 0, j = 0; while (i < num_u-1) { j = 0; while (j < num_v) { temp[0] = *(surface.coefs_begin() + 3*(num_u*j + i+1)) - *(surface.coefs_begin() + 3*(num_u*j + i)); temp[1] = *(surface.coefs_begin() + 3*(num_u*j + i+1) + 1) - *(surface.coefs_begin() + 3*(num_u*j + i) + 1); temp[2] = *(surface.coefs_begin() + 3*(num_u*j + i+1) + 2) - *(surface.coefs_begin() + 3*(num_u*j + i) + 2); // Positive tolerance means that there must be a small // _nonzero_ negative projection before it is reported as // negative! if (temp * refvector[0] < -eps) return true; ++j; } ++i; } i = 0; while (i < num_u) { j = 0; while (j < num_v-1) { temp[0] = *(surface.coefs_begin() + 3*(num_u*(j+1) + i)) - *(surface.coefs_begin() + 3*(num_u*j + i)); temp[1] = *(surface.coefs_begin() + 3*(num_u*(j+1) + i) + 1) - *(surface.coefs_begin() + 3*(num_u*j + i) +1); temp[2] = *(surface.coefs_begin() + 3*(num_u*(j+1) + i) + 2) - *(surface.coefs_begin() + 3*(num_u*j + i) + 2); // Positive tolerance means that there must be a small // _nonzero_ negative projection before it is reported as // negative! if (temp * refvector[1] < -eps) return true; ++j; } ++i; } return false; }
//========================================================================== 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; }