int main(int argc, char *argv[]) { if (argc != 3) { std::cout << "Usage: input_(lr_)spline_sf.g2 ref_lr_spline_sf.g2" << std::endl; return -1; } std::ifstream filein(argv[1]); // Input (regular) spline surface. std::ofstream fileout(argv[2]); // Output refined lr_spline_sf. shared_ptr<Go::ParamSurface> input_sf; Go::ObjectHeader header; filein >> header; shared_ptr<Go::LRSplineSurface> lr_spline_sf(new Go::LRSplineSurface()); int num_coefs_u; int num_coefs_v; int order_u; int order_v; LRSplineSurface::Refinement2D ref_v, ref_u; // ref.d = Go::XFIXED; // Inserting a v/x knot. ref_u.multiplicity = ref_v.multiplicity = 1; LRSplineSurface lrsf; double knot_tol = 1e-05; shared_ptr<Go::SplineSurface> spline_sf(new Go::SplineSurface()); if (header.classType() == Go::Class_SplineSurface) { filein >> *spline_sf; #if 0 MESSAGE("Setting parameter domain to the unit square."); spline_sf->setParameterDomain(0.0, 1.0, 0.0, 1.0); #endif #if 1 // Making the input k-regular results in an error for the refinement (max_dist is 3e-03). MESSAGE("Deactivated making the surface k-regular. Should test that for cone_sf.g2"); #else MESSAGE("Making sure the input surface is k-regular."); // Having some problems with a rational case (cylinder_sf.g2) ... // Example is already k-regular. spline_sf->makeSurfaceKRegular(); // Swpping the parameter directions does not help. // spline_sf->swapParameterDirection(); #endif #if 0 // We refine the input spline surface prior to converting it to the lr format. const BsplineBasis& bas_u = spline_sf->basis_u(); const auto knots = bas_u.begin(); const int deg = bas_u.order() - 1; double w1 = 0.5;//34; double insert_u = w1*knots[deg] + (1.0 - w1)*knots[deg+1]; spline_sf->insertKnot_u(insert_u); #endif #if 0 order_u = spline_sf->order_u(); int raise_u = 0; int raise_v = 0; if (order_u < 4) raise_u = 4 - order_u; order_v = spline_sf->order_v(); if (order_v < 4) raise_v = 4 - order_v; if (raise_u > 0 || raise_v > 0) spline_sf->raiseOrder(raise_u, raise_v); #endif num_coefs_u = spline_sf->numCoefs_u(); num_coefs_v = spline_sf->numCoefs_v(); order_u = spline_sf->order_u(); order_v = spline_sf->order_v(); input_sf = spline_sf; puts("Now we convert from SplineSurface to LRSplineSurface!"); lr_spline_sf = shared_ptr<Go::LRSplineSurface>(new Go::LRSplineSurface(spline_sf->clone(), knot_tol)); puts("Done converting!"); std::ofstream fileout_conv("tmp/file_conv.g2"); lr_spline_sf->writeStandardHeader(fileout_conv); lr_spline_sf->write(fileout_conv); #ifndef NDEBUG { std::vector<LRBSpline2D*> bas_funcs; for (auto iter = lr_spline_sf->basisFunctionsBegin(); iter != lr_spline_sf->basisFunctionsEnd(); ++iter) { bas_funcs.push_back(iter->second.get()); } puts("Remove when done debugging!"); } #endif const Mesh2D& mesh = lr_spline_sf->mesh(); double umin = mesh.minParam(Go::XFIXED); int umin_ind = mesh.getKnotIdx(Go::XFIXED, umin, knot_tol); double w1 = 0.34; // Random value in the range (0.0, 1.0). ref_u.kval = w1*mesh.kval(Go::XFIXED, umin_ind) + (1.0 - w1)*mesh.kval(Go::XFIXED, umin_ind + 1); ref_u.start = mesh.minParam(Go::YFIXED); ref_u.end = mesh.maxParam(Go::YFIXED); ref_u.d = Go::XFIXED; double vmin = mesh.minParam(Go::YFIXED); int vmin_ind = mesh.getKnotIdx(Go::YFIXED, vmin, knot_tol); double w2 = 0.72;// Random value in the range (0.0, 1.0). ref_v.kval = w2*mesh.kval(Go::YFIXED, vmin_ind) + (1.0 - w2)*mesh.kval(Go::YFIXED, vmin_ind + 1); ref_v.start = mesh.minParam(Go::XFIXED); ref_v.end = mesh.maxParam(Go::XFIXED); ref_v.d = Go::YFIXED; }
int main(int argc, char **argv) { #ifdef TIME_LRSPLINE Profiler prof(argv[0]); #endif // set default parameter values const double TOL = 1e-6; const double max_n_linear_depence_testing = 1000; int p1 = 3; int p2 = 2; int p3 = 4; int n1 = 6; int n2 = 5; int n3 = 8; double *knot_u = NULL; double *knot_v = NULL; double *knot_w = NULL; int dim = 4; int nDiagonals = -1; bool rat = false; bool dumpFile = false; bool vol = false; char *lrInitMesh = NULL; char *inputFileName = NULL; stringstream parameters; parameters << " parameters: \n" \ " -p1 <n> polynomial ORDER (degree+1) in first parametric direction\n" \ " -p2 <n> polynomial order in second parametric direction\n" \ " -p3 <n> polynomial order in third parametric direction (only trivariate volumes)\n" \ " -n1 <n> number of basis functions in first parametric direction\n" \ " -n2 <n> number of basis functions in second parametric direction\n" \ " -n3 <n> number of basis functions in third parametric direction (only trivariate volumes)\n" \ " -knot1 <n> space-seperated list of the first knot vector (must specify n1 and p1 first)\n"\ " -knot2 <n> space-seperated list of the second knot vector (must specify n2 and p2 first)\n"\ " -knot3 <n> space-seperated list of the third knot vector (must specify n3 and p3 first)\n"\ " -dim <n> dimension of the controlpoints\n" \ " -diag <n> override inputfile and run diagonal testcase\n"\ " -in: <s> make the LRSplineSurface <s> the initial mesh\n"\ " -dumpfile writes an eps- and txt-file of the LR-mesh (bivariate surfaces only)\n"\ " -help display (this) help screen\n"; parameters << " default values\n"; parameters << " -p = { " << p1 << ", " << p2 << ", " << p3 << " }\n"; parameters << " -n = { " << n1 << ", " << n2 << ", " << n3 << " }\n"; parameters << " -vol = { " << ((vol)?"true":"false") << " }\n"; parameters << " <refine inputfile>\n"\ " inputfile describing meshline insertions.\n"\ " FORMAT:\n"\ " <numb. inserted lines>\n"\ " <is_const_u> <const_par> <start> <stop> <mult> (Surface only)\n"\ " <constParDir> <constPar> <start1> <stop1> <start2> <stop2> <mult> (Volume only)\n"; // read input for(int i=1; i<argc; i++) { if(strcmp(argv[i], "-p1") == 0) p1 = atoi(argv[++i]); else if(strcmp(argv[i], "-p2") == 0) p2 = atoi(argv[++i]); else if(strcmp(argv[i], "-p3") == 0) { p3 = atoi(argv[++i]); vol = true; } else if(strcmp(argv[i], "-n1") == 0) n1 = atoi(argv[++i]); else if(strcmp(argv[i], "-n2") == 0) n2 = atoi(argv[++i]); else if(strcmp(argv[i], "-n3") == 0) { n3 = atoi(argv[++i]); vol = true; } else if(strcmp(argv[i], "-dim") == 0) dim = atoi(argv[++i]); else if(strncmp(argv[i], "-in:", 4) == 0) lrInitMesh = argv[i]+4; else if(strcmp(argv[i], "-diag") == 0) nDiagonals = atoi(argv[++i]); else if(strcmp(argv[i], "-vol") == 0) vol = true; else if(strcmp(argv[i], "-dumpfile") == 0) dumpFile = true; else if(strcmp(argv[i], "-help") == 0) { cout << "usage: " << argv[0] << "[parameters] <refine inputfile>" << endl << parameters.str(); exit(0); } else if(strcmp(argv[i], "-knot1") == 0) { knot_u = new double[n1+p1]; for(int j=0; j<n1+p1; j++) knot_u[j] = atoi(argv[++i]); } else if(strcmp(argv[i], "-knot2") == 0) { knot_v = new double[n2+p2]; for(int j=0; j<n2+p2; j++) knot_v[j] = atoi(argv[++i]); } else if(strcmp(argv[i], "-knot3") == 0) { knot_w = new double[n3+p3]; for(int j=0; j<n3+p3; j++) knot_w[j] = atoi(argv[++i]); } else { if(inputFileName != NULL) { cerr << "usage: " << argv[0] << endl << parameters.str(); exit(1); } else { inputFileName = argv[i]; } } } // do some error testing on input if(n1 < p1) { cerr << "ERROR: n1 must be greater or equal to p1\n"; exit(2); } else if(n2 < p2) { cerr << "ERROR: n2 must be greater or equal to p2\n"; exit(2); } else if(n3 < p3) { cerr << "ERROR: n3 must be greater or equal to p3\n"; exit(2); } else if(nDiagonals==-1 && inputFileName == NULL) { cerr << "ERROR: Specify input file name\n"; cerr << "usage: " << argv[0] << "[parameters] <refine inputfile>" << endl << parameters.str(); exit(3); } #ifdef HAS_GOTOOLS Go::SplineSurface *ss=nullptr; Go::SplineVolume *sv=nullptr; #else LRSplineSurface *ss=nullptr; LRSplineVolume *sv=nullptr; #endif LRSplineSurface *lrs=nullptr; LRSplineVolume *lrv=nullptr; if(lrInitMesh == NULL) { // make a uniform integer knot vector if(knot_u == NULL) { knot_u = new double[n1+p1]; for(int i=0; i<p1+n1; i++) knot_u[i] = (i<p1) ? 0 : (i>n1) ? n1-p1+1 : i-p1+1; } if(knot_v == NULL) { knot_v = new double[n2+p2]; for(int i=0; i<p2+n2; i++) knot_v[i] = (i<p2) ? 0 : (i>n2) ? n2-p2+1 : i-p2+1; } if(knot_w == NULL) { knot_w = new double[n3+p3]; for(int i=0; i<p3+n3; i++) knot_w[i] = (i<p3) ? 0 : (i>n3) ? n3-p3+1 : i-p3+1; } // create a list of random control points (all between 0.1 and 1.1) int nCP = (vol) ? n1*n2*n3 : n1*n2; nCP *= (dim+rat); std::vector<double> cp(nCP); int k=0; for(int i=0; i<nCP; i++) // 839 as a generator over Z_853 gives a period of 425. Should suffice cp[k++] = (i*839 % 853) / 853.0 + 0.1; // rational weights also random and thus we need >0 // make two spline objects (using GoTools for reference if available) if(vol) { #ifdef HAS_GOTOOLS sv = new Go::SplineVolume(n1, n2, n3, p1, p2, p3, knot_u, knot_v, knot_w, cp.begin(), dim, rat); #else sv = new LRSplineVolume (n1, n2, n3, p1, p2, p3, knot_u, knot_v, knot_w, cp.begin(), dim, rat); #endif lrv = new LRSplineVolume (n1, n2, n3, p1, p2, p3, knot_u, knot_v, knot_w, cp.begin(), dim, rat); } else { #ifdef HAS_GOTOOLS ss = new Go::SplineSurface(n1, n2, p1, p2, knot_u, knot_v, cp.begin(), dim, rat); #else ss = new LRSplineSurface (n1, n2, p1, p2, knot_u, knot_v, cp.begin(), dim, rat); #endif lrs = new LRSplineSurface (n1, n2, p1, p2, knot_u, knot_v, cp.begin(), dim, rat); } } else { #ifdef HAS_GOTOOLS ifstream inputfile; inputfile.open(lrInitMesh); if(!inputfile.is_open()) { cerr << "Error: could not open file " << lrInitMesh << endl; exit(3); } Go::ObjectHeader head; ss = new Go::SplineSurface(); sv = new Go::SplineVolume(); inputfile >> head; if(head.classType() == Go::Class_SplineVolume) { vol = true; inputfile >> *sv; lrv = new LRSplineVolume(sv); dim = sv->dimension(); rat = sv->rational(); n1 = sv->numCoefs(0); n2 = sv->numCoefs(1); n3 = sv->numCoefs(2); p1 = sv->order(0); p2 = sv->order(1); p3 = sv->order(2); } else if(head.classType() == Go::Class_SplineSurface) {
bool ObjectSet::addPatchFromStream(std::ifstream &stream, File *file) { Go::ObjectHeader head; QString error = QString("%2 in '%1'").arg(file->fn()); QString logString; try { head.read(stream); } catch (...) { emit log(error.arg("Unrecognized object header"), LL_ERROR); return false; } DisplayObject *obj = NULL; DisplayObject::m.lock(); switch (head.classType()) { case Go::Class_SplineVolume: { Go::SplineVolume *v = new Go::SplineVolume(); try { v->read(stream); } catch (...) { emit log(error.arg("Unable to parse SplineVolume"), LL_ERROR); delete v; return false; } obj = new Volume(v); break; } case Go::Class_SplineSurface: { Go::SplineSurface *s = new Go::SplineSurface(); try { s->read(stream); } catch (...) { emit log(error.arg("Unable to parse SplineSurface"), LL_ERROR); delete s; return false; } obj = new Surface(s); break; } case Go::Class_SplineCurve: { Go::SplineCurve *c = new Go::SplineCurve(); try { c->read(stream); } catch (...) { emit log(error.arg("Unable to parse SplineCurve"), LL_ERROR); delete c; return false; } obj = new Curve(c); break; } default: emit log(error.arg(QString("Unrecognized class type %1").arg(head.classType())), LL_ERROR); } if (!obj) { DisplayObject::m.unlock(); return false; } m.lock(); QModelIndex index = createIndex(file->indexInParent(), 0, file); beginInsertRows(index, file->nChildren(), file->nChildren()); Patch *patch = new Patch(obj, file); endInsertRows(); m.unlock(); DisplayObject::m.unlock(); while (!obj->initialized()) { emit requestInitialization(obj); std::this_thread::sleep_for(std::chrono::milliseconds(10)); } if (!obj->initialized()) { emit log("Failed to initialize display object", LL_ERROR); delete obj; return true; // Can continue } emit update(); return true; }