int main(int argc, char* argv[] ) { ALWAYS_ERROR_IF(argc != 7, "Usage: " << argv[0] << " curve1infile curve2infile surfaceoutfile point_x point_y point_z" << endl); // Open input curve 1 file ifstream is1(argv[1]); ALWAYS_ERROR_IF(is1.bad(), "Bad or no curve 1 input filename"); // Open input curve 2 file ifstream is2(argv[2]); ALWAYS_ERROR_IF(is2.bad(), "Bad or no curve 2 input filename"); // Open output surface file ofstream os(argv[3]); ALWAYS_ERROR_IF(os.bad(), "Bad output filename"); Point pt(atof(argv[4]), atof(argv[5]), atof(argv[6])); // Read curves from file SplineCurve curv1, curv2; ObjectHeader head; is1 >> head >> curv1; is2 >> head >> curv2; SplineSurface* surf = SweepSurfaceCreator::linearSweptSurface(curv1, curv2, pt); surf->writeStandardHeader(os); surf->write(os); }
//=========================================================================== SplineSurface* Torus::createNonRationalSpline(double eps) const //=========================================================================== { // First fetch the first circular boundary curve in the minor // direction shared_ptr<Circle> circ = getMinorCircle(domain_.vmin()); // Feth non-rational spline approximation shared_ptr<SplineCurve> crv(circ->createNonRationalSpline(0.5*eps)); // Rotate this circle the valid angle around the main axis to // create the non-rational spline surface // Note that the result will be rational if the tolerance is equal to zero int status; SISLCurve *qc = Curve2SISL(*crv); double *point = const_cast<double*>(location_.begin()); double *axis = const_cast<double*>(z_axis_.begin()); SISLSurf *qs = NULL; s1302(qc, 0.5*eps, parbound_.umax()-parbound_.umin(), point, axis, &qs, &status); if (status < 0 || qs == NULL) return NULL; // Approximation failed SplineSurface *surf = SISLSurf2Go(qs); surf->setParameterDomain(domain_.umin(), domain_.umax(), domain_.vmin(), domain_.vmax()); if (isSwapped()) surf->swapParameterDirection(); freeSurf(qs); return surf; }
int main(int argc, char* argv[] ) { ALWAYS_ERROR_IF(argc != 10, "Usage: " << argv[0] << " curveinfile surfaceoutfile angle point_x point_y point_z axis_x axis_y axis_z" << endl); // Open input curve file ifstream is(argv[1]); ALWAYS_ERROR_IF(is.bad(), "Bad or no curve input filename"); // Open output surface file ofstream os(argv[2]); ALWAYS_ERROR_IF(os.bad(), "Bad output filename"); double angle = atof(argv[3]); Point pt(atof(argv[4]), atof(argv[5]), atof(argv[6])); Point axis(atof(argv[7]), atof(argv[8]), atof(argv[9])); // Read curve from file SplineCurve curve; ObjectHeader head; is >> head >> curve; SplineSurface* surf = SweepSurfaceCreator::rotationalSweptSurface(curve, angle, pt, axis); surf->writeStandardHeader(os); surf->write(os); }
//=========================================================================== 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; }
int main(int argc, char* argv[] ) { ALWAYS_ERROR_IF(argc < 3, "Usage: " << argv[0] << " inputsurf inputpoints" << endl); // Open input surface file ifstream is(argv[1]); ALWAYS_ERROR_IF(is.bad(), "Bad or no input filename"); // Read surface from file SplineSurface sf; is >> sf; // Get points ifstream pts(argv[2]); ALWAYS_ERROR_IF(pts.bad(), "Bad or no input filename"); int n; pts >> n; vector<double> pt(n*2); for (int i = 0; i < n; ++i) { pts >> pt[2*i] >> pt[2*i+1]; } std::vector<Point> p(3, Point(sf.dimension())); for (int i = 0; i < 10000; ++i) { for (int j = 0; j < n; ++j) { sf.point(p, pt[2*j], pt[2*j+1], 0); } } // cout << p[0] << p[1] << p[2] << (p[1] % p[2]); }
//========================================================================== 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; }
//=========================================================================== BoundingBox Torus::boundingBox() const //=========================================================================== { // A rather unefficient hack... SplineSurface* tmp = geometrySurface(); BoundingBox box = tmp->boundingBox(); delete tmp; return box; }
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; }
//=========================================================================== 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; }
// ============================================================================ vector<CurveVec> SSurfTraceIsocontours(const SplineSurface& ss, const vector<double>& isovals, const double tol, bool include_3D_curves, bool use_sisl_marching) // ============================================================================ { assert(ss.dimension() == 1); // only intended to work for spline functions // Compute topology for each requested level-set. We use SISL for this SISLSurf* sislsurf1D = GoSurf2SISL(ss, false); SISLSurf* sislsurf3D = use_sisl_marching ? make_sisl_3D(ss) : nullptr; // Defining function tracing out the level set for a specified isovalue const function<CurveVec(double)> comp_lset = [&] (double ival) {return compute_levelset(ss, sislsurf1D, sislsurf3D, ival, tol, include_3D_curves, use_sisl_marching);}; // Computing all level-set curves for all isovalues ("transforming" each // isovalue into its corresponding level-set) const vector<CurveVec> result = apply_transform(isovals, comp_lset); // Cleaning up after use of SISL objects freeSurf(sislsurf1D); if (sislsurf3D) freeSurf(sislsurf3D); // Returning result return result; }
//========================================================================== void create_bary_coord_system3D(const SplineSurface& surface, BaryCoordSystem3D& bc) //========================================================================== { BoundingBox box = surface.boundingBox(); create_bary_coord_system3D(box, bc); return; }
//=========================================================================== SplineSurface* Torus::createSplineSurface() const //=========================================================================== { double umin = domain_.umin(); double umax = domain_.umax(); shared_ptr<Circle> circle = getMinorCircle(umin); shared_ptr<SplineCurve> sccircle(circle->geometryCurve()); double angle = parbound_.umax() - parbound_.umin(); SplineSurface* sstorus = SweepSurfaceCreator::rotationalSweptSurface(*sccircle, angle, location_, z_axis_); sstorus->basis_u().rescale(umin, umax); if (isSwapped()) sstorus->swapParameterDirection(); return sstorus; }
int main(int argc, char** argv) { if (argc < 3) { cerr << "Usage: " << argv[0] << " u_res v_res" << endl; return 1; } int ures = atoi(argv[1]); int vres = atoi(argv[2]); ObjectHeader head; cin >> head; ASSERT(head.classType() == SplineSurface::classType()); SplineSurface sf; cin >> sf; vector<double> points; vector<double> param_u; vector<double> param_v; sf.gridEvaluator(ures, vres, points, param_u, param_v); RectGrid grid(ures, vres, sf.dimension(), &points[0]); grid.writeStandardHeader(cout); grid.write(cout); }
int main(int argc, char** argv) { // Read the curve from file std::ifstream input(argv[1]); if (input.bad()) { std::cerr << "File error (no file or corrupt file specified)." << std::endl; return 1; } ObjectHeader header; SplineSurface surface; input >> header >> surface; // Loop through parameter space const int samples = 50; double increment_u = (surface.endparam_u() - surface.startparam_u()) / (samples-1); double increment_v = (surface.endparam_v() - surface.startparam_v()) / (samples-1); Point result; double param_u = surface.startparam_u(); int prec = (int)std::cout.precision(15); for (int i = 0; i < samples; ++i) { double param_v = surface.startparam_v(); for (int j = 0; j < samples; ++j) { surface.point(result, param_u, param_v); std::cout << result[0] << "\t" << result[1] << "\t" << result[2] << std::endl; param_v += increment_v; } std::cout << std::endl; param_u += increment_u; } std::cout.precision(prec); return 0; }
//=========================================================================== shared_ptr<SplineSurface> SurfaceCreators::mergeRationalParts(const SplineSurface& nom_sf, const SplineSurface& den_sf, bool weights_in_first) //=========================================================================== { ASSERT((!nom_sf.rational()) && (!den_sf.rational())); ASSERT(den_sf.dimension() == 1); int dim = nom_sf.dimension(); // We first make sure they share spline space. vector<shared_ptr<SplineSurface> > sfs; sfs.push_back(shared_ptr<SplineSurface>(nom_sf.clone())); sfs.push_back(shared_ptr<SplineSurface>(den_sf.clone())); double knot_diff_tol = 1e-06; GeometryTools::unifySurfaceSplineSpace(sfs, knot_diff_tol); vector<double> rcoefs; vector<double>::const_iterator iter = sfs[0]->coefs_begin(); vector<double>::const_iterator riter = sfs[1]->coefs_begin(); int num_coefs = sfs[0]->numCoefs_u()*sfs[0]->numCoefs_v(); for (int ki = 0; ki < num_coefs; ++ki) { for (int kj = 0; kj < dim; ++kj) { if (weights_in_first) { rcoefs.push_back(iter[ki*dim+kj]); } else { rcoefs.push_back(iter[ki*dim+kj]*riter[ki]); } } rcoefs.push_back(riter[ki]); } shared_ptr<SplineSurface> rat_sf(new SplineSurface (sfs[0]->numCoefs_u(), sfs[0]->numCoefs_v(), sfs[0]->order_u(), sfs[0]->order_v(), sfs[0]->basis_u().begin(), sfs[0]->basis_v().begin(), rcoefs.begin(), dim, true)); return rat_sf; }
//=========================================================================== shared_ptr<SplineSurface> SurfaceCreators::mult1DBezierPatches(const SplineSurface& patch1, const SplineSurface& patch2) //=========================================================================== { // @@sbr This should be fixed shortly. Nothing more than separating the // spatial and rational components. ASSERT(!patch1.rational() && !patch2.rational()); // We should of course also check the actual knots, but why bother (trusting the user). // ASSERT(basis1_u.numCoefs() == basis2_u.numCoefs() && // basis1_v.numCoefs() == basis2_v.numCoefs() && // basis1_u.order() == basis2_u.order() && // basis1_v.order() == basis2_v.order()); ASSERT((patch1.dimension() == 1) && (patch2.dimension() == 1)); // @@sbr Suppose we could allow for differing orders (but equal parameter domain). // Ported from SISL routine s6multsfs(). int order = max(2*(patch1.order_u() - 1) + 1, 2*(patch1.order_v() - 1) + 1);; vector<double> pascal((order+1)*(order+2)/2, 0.0); // Binomial coefficients (Pascal's triangle) int ki, kj; vector<double>::iterator psl1; /* Pointer used in Pascals triangle */ vector<double>::iterator psl2; /* Pointer used in Pascals triangle */ for(ki = 0, psl2 = pascal.begin(); ki <= order ; ki++, psl1 = psl2, psl2 += ki) { psl2[0] = 1.0; for(kj = 1; kj < ki; kj++) psl2[kj] = psl1[kj-1] + psl1[kj]; psl2[ki] = 1.0; } int order11 = patch1.order_u(); int order12 = patch1.order_v(); int order21 = patch2.order_u(); int order22 = patch2.order_v(); vector<double>::const_iterator c1 = patch1.coefs_begin(); vector<double>::const_iterator c2 = patch2.coefs_begin(); // vector<double> mult_coefs(patch1.numCoefs_u()*patch1.numCoefs_v()*patch1.dimension(), 0.0); int p1,p2,r1,r2; int kgrad11 = order11-1; int kgrad12 = order12-1; int kgrad21 = order21-1; int kgrad22 = order22-1; int kgrad1 = kgrad11 + kgrad21; // Degree of mult basis functions in 1st dir. int kgrad2 = kgrad12 + kgrad22; int kstop2 = order12+order22-1; int kstop1 = order11+order21-1; vector<double> mult_coefs(kstop1*kstop2, 0.0); vector<double>::const_iterator psl_kgrad11 = pascal.begin()+kgrad11*(kgrad11+1)/2; vector<double>::const_iterator psl_kgrad12 = pascal.begin()+kgrad12*(kgrad12+1)/2; vector<double>::const_iterator psl_kgrad21 = pascal.begin()+kgrad21*(kgrad21+1)/2; vector<double>::const_iterator psl_kgrad22 = pascal.begin()+kgrad22*(kgrad22+1)/2; vector<double>::const_iterator psl_kgrad1 = pascal.begin()+kgrad1 *(kgrad1 +1)/2; vector<double>::const_iterator psl_kgrad2 = pascal.begin()+kgrad2 *(kgrad2 +1)/2; vector<double>::const_iterator qsc1, qsc2; double tsum, sumi; vector<double>::iterator temp = mult_coefs.begin(); double tdiv, t2; int kstop3, kstop4; for (p2 = 0; p2 < kstop2; ++p2) for (p1 = 0; p1 <kstop1; p1++, temp++) { tdiv = psl_kgrad1[p1]*psl_kgrad2[p2]; kstop4 = min(p2,kgrad12); for (r2 = max(0,p2-kgrad22),tsum = 0.0; r2 <= kstop4; r2++) { t2 = psl_kgrad12[r2]*psl_kgrad22[p2-r2]; kstop3 = min(p1,kgrad11); for (r1 = max(0,p1-kgrad21),sumi = 0.0, qsc1 = c1+r2*order11,qsc2 = c2+(p2-r2)*order21; r1 <= kstop3; r1++) sumi += psl_kgrad11[r1]*psl_kgrad21[p1-r1]*qsc1[r1]*qsc2[p1-r1]; tsum += t2*sumi; } tsum /= tdiv; *temp = tsum; } // *order_newsurf1 = kstop1; // *order_newsurf2 = kstop2; // We must add knots to input basises according to new order. vector<double> new_knots_u, new_knots_v; new_knots_u.insert(new_knots_u.begin(), kstop1, patch1.startparam_u()); new_knots_u.insert(new_knots_u.end(), kstop1, patch1.endparam_u()); new_knots_v.insert(new_knots_v.begin(), kstop2, patch1.startparam_v()); new_knots_v.insert(new_knots_v.end(), kstop2, patch1.endparam_v()); // Finally we create the spline sf with the multiplied coefs. shared_ptr<SplineSurface> mult_sf(new SplineSurface(kstop1, kstop2, kstop1, kstop2, new_knots_u.begin(), new_knots_v.begin(), mult_coefs.begin(), patch1.dimension(), patch1.rational())); // SplineSurface* mult_sf = new SplineSurface(patch1.numCoefs_u(), patch1.numCoefs_v(), // patch1.order_u(), patch1.order_v(), // patch1.basis_u().begin(), patch1.basis_v().begin(), // mult_coefs.begin(), patch1.dimension(), // patch1.rational()); return mult_sf; }
int main(int argc, char** argv) { // Read the surface from a file in Go-format. string filename("degenerate_sf.g2"); cout << "\nProgram " << argv[0] << " using file " << filename.c_str() << endl; ifstream file(filename.c_str()); if (!file) { cerr << "\nFile error. Could not open file: " << filename.c_str() << endl; return 1; } ObjectHeader head; SplineSurface surf; file >> head; if (!head.classType() == SplineSurface::classType()) { THROW("Object type is NOT SplineSurface."); } file >> surf; file.close(); // Read the points from a file. xyz-coordinates. string point_filename("inp_degen_surf_close_points.dat"); ifstream pfile(point_filename.c_str()); if (!pfile) { cerr << "\nFile error. Could not open file: " << point_filename.c_str() << endl; return 1; } vector<Point> points; while (1) { Point p(3); pfile >> p; if (!pfile) break; points.push_back(p); } pfile.close(); int N = (int)points.size(); cout << "\nProgram '" << argv[0] << "' using input files '" << filename.c_str() << "' and '" << point_filename.c_str() << ", and output file 'degen_surf_close_points.g2'." << endl; // Find the points on the surface closest to these points. double close_u; // Closest point's u parameter. double close_v; // Closest point's v parameter. Point close_pt(3); // Closest point's coordinates. double close_dist; // Distance between the two points. double epsilon = 1e-8; // Parameter tolerance // Write to file vectors from a point to the closest point on the surface. ofstream fout2("degenerate_sf_close_points.g2"); // Class_LineCloud=410 MAJOR_VERSION=1 MINOR_VERSION=1 auxillary data=4 // The four auxillary data values defines the colour (r g b alpha) fout2 << "410 1 0 4 255 0 0 255" << endl; // Header. fout2 << N << endl; // Find closest point using the whole surface. (The two last arguments // 'RectDomain* domain_of_interest' and 'double *seed' are by default // equal to 0). cout << "\nClosest points from inputfile points to points on the surface "; for (int i=0; i<N; ++i) { surf.closestPoint(points[i], close_u, close_v, close_pt, close_dist, epsilon); fout2 << points[i] << ' ' << close_pt << endl; // write vector cout << "Point: " << points[i] << " Closest point: " << close_pt << "\nParameter values= " << close_u << " , " << close_v << " Closest distance= " << close_dist << endl; } fout2.close(); // Find closest point from points on the surface. Should be 0 + some tolerance. cout << "\nClosest points from points on the surface." << endl; const int nsp = 9; double du = (surf.endparam_u() - surf.startparam_u()) / (nsp-1); double dv = (surf.endparam_v() - surf.startparam_v()) / (nsp-1); cout << "Parameter u from " << surf.startparam_u() << " to " << surf.endparam_u() << " step " << du << endl; cout << "Parameter v from " << surf.startparam_v() << " to " << surf.endparam_v() << " step " << dv << endl; double max_dist = 0.0; Point point; for (double v=surf.startparam_v(); v<=surf.endparam_v(); v += dv) { for (double u=surf.startparam_u(); u<=surf.endparam_u(); u += du) { surf.point(point, u, v); // interpolate at u,v surf.closestPoint(point, close_u, close_v, close_pt, close_dist, epsilon); #ifdef DEBUG cout << "\n Point: " << point << "\nClosest point: " << close_pt << "\nParameter values= " << close_u << " , " << close_v << " Closest distance= " << close_dist << endl; #endif } max_dist = std::max(close_dist, max_dist); } cout << "\nMaximum distance between an interpolated point and the " << "corresponding input point is " << max_dist << '\n' << endl; }
shared_ptr<SplineSurface> GeometryTools::surfaceSum(const SplineSurface& sf1, double fac1, const SplineSurface& sf2, double fac2, double num_tol) //******************************************************************** // Addition of two signed SplineSurfaces, i.e. this function can // also be used for subtraction. The surfaces is assumed to live on // the same parameter domain, but may have different knot vectors. //******************************************************************** { // Check input ALWAYS_ERROR_IF(fabs(sf1.startparam_u() - sf2.startparam_u()) > num_tol || fabs(sf1.endparam_u() - sf2.endparam_u()) > num_tol || fabs(sf1.startparam_v() - sf2.startparam_v()) > num_tol || fabs(sf1.endparam_v() - sf2.endparam_v()) > num_tol, "Inconsistent parameter domain."); // For the time being if (sf1.rational() || sf2.rational()) { THROW("Sum of rational surfaces is not implemented"); } // Make copy of surfaces vector<shared_ptr<SplineSurface> > surfaces; surfaces.reserve(2); shared_ptr<SplineSurface> sf; // #ifdef _MSC_VER // sf = shared_ptr<SplineSurface>(dynamic_cast<SplineSurface*>(sf1.clone())); // #else sf = shared_ptr<SplineSurface>(sf1.clone()); // #endif surfaces.push_back(sf); // #ifdef _MSC_VER // sf = shared_ptr<SplineSurface>(dynamic_cast<SplineSurface*>(sf2.clone())); // #else sf = shared_ptr<SplineSurface>(sf2.clone()); // #endif surfaces.push_back(sf); // Make sure that the surfaces live on the same knot vector GeometryTools::unifySurfaceSplineSpace(surfaces, num_tol); // Add signed coefficients vector<double> coefs; int nmb_coefs_u = surfaces[0]->numCoefs_u(); int nmb_coefs_v = surfaces[0]->numCoefs_v(); int dim = surfaces[0]->dimension(); coefs.resize(dim*nmb_coefs_u*nmb_coefs_v); int ki; std::vector<double>::iterator s1 = surfaces[0]->coefs_begin(); std::vector<double>::iterator s2 = surfaces[1]->coefs_begin(); for (ki=0; ki<dim*nmb_coefs_u*nmb_coefs_v; ki++) coefs[ki] = fac1*s1[ki] + fac2*s2[ki]; // Create output curve shared_ptr<SplineSurface> surfacesum(new SplineSurface(nmb_coefs_u, nmb_coefs_v, surfaces[0]->order_u(), surfaces[0]->order_v(), surfaces[0]->basis_u().begin(), surfaces[0]->basis_v().begin(), &coefs[0], dim, false)); return surfacesum; }
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; }
int main(int argc, char** argv) { const string inp_curve_filename("approj_curve.g2"); cout << "\nRunning program '" << argv[0] << "'\nSpline curve filename= '" << inp_curve_filename.c_str() << "'." << endl; // Read spline curve file ifstream cfile(inp_curve_filename.c_str()); if (!cfile) { cerr << "\nFile error. Could not open file: " << inp_curve_filename.c_str() << endl; return 1; } shared_ptr<SplineCurve> curve(new SplineCurve); ObjectHeader header; cfile >> header; if (!header.classType() == SplineCurve::classType()) { THROW("Object type is NOT SplineCurve."); } cfile >> (*curve); cfile.close(); // Print some curve information Point pnt3d(3); curve->point(pnt3d, curve->startparam()); cout << "\nSplineCurve: Dim= " << curve->dimension() << "\nStart. Param= " << curve->startparam() << " Point= " << pnt3d << endl; curve->point(pnt3d, curve->endparam()); cout << "End. Param= " << curve->endparam() << " Point= " << pnt3d << endl; cout << "Bounding box = " << curve->boundingBox() << endl; // Create a surface by rotating the curve around the axis an angle of 2PI. double angle = 2.0*M_PI; Point point_on_axis(0.0, 5.0, 200.0); Point axis_dir(1.0, 0.0, 0.0); SplineSurface* surf = SweepSurfaceCreator::rotationalSweptSurface(*curve, angle, point_on_axis, axis_dir); cout << "\nSurface: Dim= " << surf->dimension() << endl; cout << "Bounding box = " << surf->boundingBox() << endl; cout << "Point on axis = " << point_on_axis << endl; cout << "Axis direction = " << axis_dir << endl; // Open output file ofstream fout("rotational_swept_surface.g2"); // Write curve to file. Colour=red. fout << "100 1 0 4 255 0 0 255" << endl; curve->write(fout); // Write surface to file. Default colour=blue. surf->writeStandardHeader(fout); surf->write(fout); // Write axis to file. Colour=green. double dlength = 1.2*(surf->boundingBox().high()[0] - surf->boundingBox().low()[0]); Point endp = point_on_axis + dlength*axis_dir; SplineCurve* axis = new SplineCurve(point_on_axis, endp); fout << "100 1 0 4 0 255 0 255" << endl; axis->write(fout); // cout << "Open the file 'rotational_swept_surface.g2' in 'goview' to look" // << " at the results" << endl; delete surf; delete axis; return 0; }
//========================================================================== void make_matrix(const SplineSurface& surf, int deg, vector<vector<double> >& mat) //========================================================================== { // Create BernsteinMulti. In the rational case the weights are // included in an "extra" coordinate. int dim = surf.dimension(); bool rational = surf.rational(); vector<BernsteinMulti> beta; spline_to_bernstein(surf, beta); // Make vector of basis functions (with the surface plugged in) by // using recursion int num = (deg+1) * (deg+2) * (deg+3) / 6; vector<BernsteinMulti> basis(num); vector<BernsteinMulti> tmp(num); basis[0] = BernsteinMulti(1.0); BernsteinMulti zero_multi = BernsteinMulti(0.0); for (int r = 1; r <= deg; ++r) { int m = -1; int tmp_num = (r + 1) * (r + 2) * (r + 3) / 6; fill(tmp.begin(), tmp.begin() + tmp_num, zero_multi); for (int i = 0; i < r; ++i) { int k = (i + 1) * (i + 2) / 2; for (int j = 0; j <= i; ++j) { for (int l = 0; l <= j; ++l) { ++m; tmp[m] += beta[0] * basis[m]; tmp[m + k] += beta[1] * basis[m]; tmp[m + 1 + j + k] += beta[2] * basis[m]; tmp[m + 2 + j + k] += beta[3] * basis[m]; } } } basis.swap(tmp); } // Fill up the matrix mat int deg_u = surf.order_u() - 1; int deg_v = surf.order_v() - 1; int numbas = (deg * deg_u + 1) * (deg * deg_v + 1); mat.resize(numbas); for (int row = 0; row < numbas; ++row) { mat[row].resize(num); for (int col = 0; col < num; ++col) { mat[row][col] = basis[col][row]; } } // If rational, include diagonal scaling matrix. Dividing the // D-matrix by the weights has the same effect as multiplying the // basis with the same weights. (Included for numerical reasons only - // it makes the basis a partition of unity.) if (rational) { BernsteinMulti weights = BernsteinMulti(1.0); for (int i = 1; i <= deg; ++i) weights *= beta[dim]; for (int row = 0; row < numbas; ++row) { double scaling = 1.0 / weights[row]; for (int col = 0; col < num; ++col) { mat[row][col] *= scaling; } } } // // Check Frobenius norm // double norm = 0.0; // for (int irow = 0; irow < numbas; ++irow) { // for (int icol = 0; icol < num; ++icol) { // norm += mat[irow][icol] * mat[irow][icol]; // } // } // norm = sqrt(norm); // cout << "Frobenius norm = " << norm << endl; return; }
//=========================================================================== 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; }
//========================================================================== 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; }
//=========================================================================== shared_ptr<SplineSurface> SurfaceCreators::insertParamDomain(const SplineSurface& sf_1d) //=========================================================================== { shared_ptr<SplineSurface> sf_1d_cp(sf_1d.clone()); int dim = sf_1d.dimension(); ASSERT(dim == 1); bool rat = sf_1d_cp->rational(); // The returned object should be linear in the first two directions. // We create an additional 1d-sf describing the linear param space. vector<double> lin_knots_u(4, sf_1d_cp->startparam_u()); lin_knots_u[2] = lin_knots_u[3] = sf_1d_cp->endparam_u(); vector<double> lin_knots_v(4, sf_1d_cp->startparam_v()); lin_knots_v[2] = lin_knots_v[3] = sf_1d_cp->endparam_v(); int rdim = (rat) ? dim + 1 : dim; vector<double> lin_coefs_u(4, 1.0); lin_coefs_u[0] = lin_coefs_u[2] = lin_knots_u[0]; lin_coefs_u[1] = lin_coefs_u[3] = lin_knots_u[2]; shared_ptr<SplineSurface> lin_sf_u(new SplineSurface(2, 2, 2, 2, lin_knots_u.begin(), lin_knots_v.begin(), lin_coefs_u.begin(), 1)); vector<double> lin_coefs_v(4*rdim, 1.0); lin_coefs_v[0] = lin_coefs_v[1] = lin_knots_v[0]; lin_coefs_v[2] = lin_coefs_v[3] = lin_knots_v[2]; shared_ptr<SplineSurface> lin_sf_v(new SplineSurface(2, 2, 2, 2, lin_knots_u.begin(), lin_knots_v.begin(), lin_coefs_v.begin(), 1)); if (rat) { // We extract the rational part (i.e. the denominator sf) and mult it the linear parts. vector<shared_ptr<SplineSurface> > rat_parts = separateRationalParts(*sf_1d_cp); lin_sf_u = SurfaceCreators::mult1DSurfaces(*lin_sf_u, *rat_parts[1]); lin_sf_v = SurfaceCreators::mult1DSurfaces(*lin_sf_v, *rat_parts[1]); // We must then raise the order of sf_1d_cp by 1. rat_parts[0]->raiseOrder(1, 1); rat_parts[1]->raiseOrder(1, 1); sf_1d_cp = mergeRationalParts(*rat_parts[0], *rat_parts[1], false); } else { int raise_u = sf_1d_cp->order_u() - 2; int raise_v = sf_1d_cp->order_v() - 2; lin_sf_u->raiseOrder(raise_u, raise_v); lin_sf_v->raiseOrder(raise_u, raise_v); } // If not bezier we must also refine the space. int ik1 = sf_1d_cp->order_u(); int ik2 = sf_1d_cp->order_v(); int in1 = sf_1d_cp->numCoefs_u(); int in2 = sf_1d_cp->numCoefs_v(); if (ik1 < in1 || ik2 < in2) { vector<double> new_knots_u(sf_1d_cp->basis_u().begin() + ik1, sf_1d_cp->basis_u().begin() + in1); vector<double> new_knots_v(sf_1d_cp->basis_v().begin() + ik2, sf_1d_cp->basis_v().begin() + in2); lin_sf_u->insertKnot_u(new_knots_u); lin_sf_u->insertKnot_v(new_knots_v); lin_sf_v->insertKnot_u(new_knots_u); lin_sf_v->insertKnot_v(new_knots_v); } // Finally we create our space sf (i.e. living in a 3-dimensional env). vector<double> all_coefs; int coefs_size = sf_1d_cp->numCoefs_u()*sf_1d_cp->numCoefs_v(); for (int ki = 0; ki < coefs_size; ++ki) { if (rat) { all_coefs.push_back(lin_sf_u->coefs_begin()[ki*dim]); all_coefs.push_back(lin_sf_v->coefs_begin()[ki*dim]); all_coefs.push_back(sf_1d_cp->rcoefs_begin()[ki*rdim]); all_coefs.push_back(sf_1d_cp->rcoefs_begin()[ki*rdim+1]); } else { all_coefs.push_back(lin_sf_u->coefs_begin()[ki*dim]); all_coefs.push_back(lin_sf_v->coefs_begin()[ki*dim]); all_coefs.push_back(sf_1d_cp->coefs_begin()[ki*dim]); } } shared_ptr<SplineSurface> return_sf(new SplineSurface(sf_1d_cp->numCoefs_u(), sf_1d_cp->numCoefs_v(), sf_1d_cp->order_u(), sf_1d_cp->order_v(), sf_1d_cp->basis_u().begin(), sf_1d_cp->basis_v().begin(), all_coefs.begin(), 3, rat)); return return_sf; }
//=========================================================================== 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(int argc, char** argv) { bool surface_model = true; char* infile = 0; for (int i = 1; i < argc; i++) if (!infile) infile = argv[i]; else std::cerr <<" ** Unknown option ignored: "<< argv[i] << std::endl; size_t i = 0; while (i < strlen(infile) && isspace(infile[i])) i++; std::ifstream isp(infile+i); // For spline surface models std::vector<SplineSurface*> in_surf; // For spline volume models std::vector<SplineVolume*> in_vol; ObjectHeader head; int n = 0; while (!isp.eof()) { head.read(isp); if (head.classType() == Class_SplineVolume) { SplineVolume* v(new SplineVolume()); v->read(isp); in_vol.push_back(v); surface_model = false; } else if (head.classType() == Class_SplineSurface) { SplineSurface* s(new SplineSurface()); s->read(isp); in_surf.push_back(s); surface_model = true; } else std::cerr << "Unknown spline model" << std::endl; // Ignore blanks ws(isp); } if (surface_model) { std::vector<SplineSurface*> out_surf; for (i = 0;i < in_surf.size();i++) { SplineSurface* s_it = in_surf[i]; // basis1 should be one degree higher than basis2 and C^p-1 continuous int ndim = s_it->dimension(); Go::BsplineBasis b1 = s_it->basis(0).extendedBasis(s_it->order_u()+1); Go::BsplineBasis b2 = s_it->basis(1).extendedBasis(s_it->order_v()+1); // Note: Currently this is implemented for non-rational splines only. // TODO: Ask the splines people how to fix this properly, that is, how // may be obtain the correct weights for basis1 when *surf is a NURBS? if (s_it->rational()) std::cerr <<"WARNING: The geometry basis is rational (using NURBS)\n." <<" The basis for the unknown fields of one degree" <<" higher will however be non-rational.\n" <<" This may affect accuracy.\n"<< std::endl; // Compute parameter values of the Greville points size_t k; std::vector<double> ug(b1.numCoefs()), vg(b2.numCoefs()); for (k = 0; k < ug.size(); k++) ug[k] = b1.grevilleParameter(k); for (k = 0; k < vg.size(); k++) vg[k] = b2.grevilleParameter(k); // Evaluate the spline surface at all points std::vector<double> XYZ(ndim*ug.size()*vg.size()); s_it->gridEvaluator(XYZ,ug,vg); // Project the coordinates onto the new basis (the 2nd XYZ is dummy here) SplineSurface* s; s = Go::SurfaceInterpolator::regularInterpolation(b1,b2, ug,vg,XYZ, ndim,false,XYZ); out_surf.push_back(s); s->writeStandardHeader(std::cout); s->write(std::cout); } for (i = 0;i < out_surf.size();i++) { delete in_surf[i]; delete out_surf[i]; } } else { std::vector<SplineVolume*> out_vol; for (i = 0;i < in_vol.size();i++) { SplineVolume* v_it = in_vol[i]; // basis1 should be one degree higher than basis2 and C^p-1 continuous int ndim = v_it->dimension(); Go::BsplineBasis b1 = v_it->basis(0).extendedBasis(v_it->order(0)+1); Go::BsplineBasis b2 = v_it->basis(1).extendedBasis(v_it->order(1)+1); Go::BsplineBasis b3 = v_it->basis(2).extendedBasis(v_it->order(2)+1); // Note: Currently this is implemented for non-rational splines only. // TODO: Ask the splines people how to fix this properly, that is, how // may be obtain the correct weights for basis1 when *v_it is a NURBS? if (v_it->rational()) std::cerr <<"WARNING: The geometry basis is rational (using NURBS)\n." <<" The basis for the unknown fields of one degree" <<" higher will however be non-rational.\n" <<" This may affect accuracy.\n"<< std::endl; // Compute parameter values of the Greville points size_t k; std::vector<double> ug(b1.numCoefs()), vg(b2.numCoefs()), wg(b3.numCoefs()); for (k = 0; i < ug.size(); k++) ug[k] = b1.grevilleParameter(k); for (k = 0; i < vg.size(); k++) vg[k] = b2.grevilleParameter(k); for (k = 0; i < wg.size(); k++) wg[k] = b3.grevilleParameter(k); // Evaluate the spline surface at all points std::vector<double> XYZ(ndim*ug.size()*vg.size()*wg.size()); v_it->gridEvaluator(ug,vg,wg,XYZ); // Project the coordinates onto the new basis (the 2nd XYZ is dummy here) SplineVolume* v; v = Go::VolumeInterpolator::regularInterpolation(b1,b2,b3, ug,vg,wg,XYZ, ndim,false,XYZ); out_vol.push_back(v); v->writeStandardHeader(std::cout); v->write(std::cout); } for (i = 0;i < out_vol.size();i++) { delete in_vol[i]; delete out_vol[i]; } } return 0; }
int main(int argc, char** argv) { if (argc != 4) { cout << "Usage: " << argv[0] << " FileSf FileCv aepsge" << endl; return 0; } ObjectHeader header; // Read the first curve from file ifstream input1(argv[1]); if (input1.bad()) { cerr << "File #1 error (no file or corrupt file specified)." << std::endl; return 1; } header.read(input1); SplineSurface surf; surf.read(input1); input1.close(); // Read the second curve from file ifstream input2(argv[2]); if (input2.bad()) { cerr << "File #2 error (no file or corrupt file specified)." << std::endl; return 1; } header.read(input2); SplineCurve curve; curve.read(input2); input2.close(); double aepsge; aepsge = atof(argv[3]); // Set up and run the intersection algorithm SISLCurve* pcurve = Curve2SISL(curve); SISLSurf* psurf = GoSurf2SISL(surf); double astart1 = curve.startparam(); double estart2[] = { surf.startparam_u(), surf.startparam_v() }; double aend1 = curve.endparam(); double eend2[] = { surf.endparam_u(), surf.endparam_v() }; cout << "astart1 = " << astart1 << endl << "estart2[] = { " << estart2[0] << ", " << estart2[1] << " }" << endl << "aend1 = " << aend1 << endl << "eend2[] = { " << eend2[0] << ", " << eend2[1] << " }" << endl; double anext1 = astart1; double enext2[] = { estart2[0], estart2[1] }; // double anext1 = 0.0; // double enext2[] = { 2.0, 0.0 }; cout << "anext1 = " << anext1 << endl << "enext2[] = { " << enext2[0] << ", " << enext2[1] << " }" << endl; double cpos1; double gpos2[2]; int jstat = 0; cout << "jstat = " << jstat << endl; s1772(pcurve, psurf, aepsge, astart1, estart2, aend1, eend2, anext1, enext2, &cpos1, gpos2, &jstat); // Write the results cout << "Results s1772:" << endl << "jstat = " << jstat << endl << "cpos1 = " << cpos1 << endl << "gpos2[] = { " << gpos2[0] << ", " << gpos2[1] << " }" << endl; return 0; }
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; }