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) {
Exemple #3
0
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;
}