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; }
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; }
//=========================================================================== 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) { 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; }