예제 #1
0
//===========================================================================
void TrimCrvUtils::translateSurfaceDomain(ParamSurface* sf, 
					  const Point& translate_vec)
//===========================================================================
{
  RectDomain dom = sf->containingDomain();
  BoundedSurface* bdsf = dynamic_cast<BoundedSurface*>(sf);
  if (bdsf)
    dom = bdsf->underlyingSurface()->containingDomain();

  sf->setParameterDomain(dom.umin()+translate_vec[0],
			 dom.umax()+translate_vec[0],
			 dom.vmin()+translate_vec[1],
			 dom.vmax()+translate_vec[1]);
  // if (sf->instanceType() == Class_SplineSurface)
  //   {
  //     SplineSurface* spline_sf = dynamic_cast<SplineSurface*>(sf);
  //     spline_sf->setParameterDomain(spline_sf->startparam_u() + translate_vec[0],
  // 				    spline_sf->endparam_u() + translate_vec[0],
  // 				    spline_sf->startparam_v() + translate_vec[1],
  // 				    spline_sf->endparam_v() + translate_vec[1]);
  //   }
  // else if (sf->instanceType() == Class_LRSplineSurface)
  //   {
  //     LRSplineSurface* lr_spline_sf = dynamic_cast<LRSplineSurface*>(sf);
  //     lr_spline_sf->setParameterDomain(lr_spline_sf->startparam_u() + translate_vec[0],
  // 				       lr_spline_sf->endparam_u() + translate_vec[0],
  // 				       lr_spline_sf->startparam_v() + translate_vec[1],
  // 				       lr_spline_sf->endparam_v() + translate_vec[1]);
  //   }
  // else
  //   {
  //     MESSAGE("Object type " << sf->instanceType() << " is not supported yet.");
  //   }
}
예제 #2
0
//===========================================================================
void CurveBoundedDomain::getInternalPoint(double& upar, double& vpar) const
//===========================================================================
{
  // Make initial guess
  RectDomain dom = containingDomain();
  upar = 0.5*(dom.umin() + dom.umax());
  vpar = 0.5*(dom.vmin() + dom.vmax());

  // Adjust
  double tolerance = 1.0e-4; 
  for (int ki=1; ki<3; ++ki)
    {
      bool succeeded = true;
      vector<pair<double, double> > inside;
      try {
	getInsideIntervals(ki, upar, vpar, tolerance, inside, false);
      }
      catch(...)
	{
	  succeeded = false;
	}

      if (succeeded)
	{
	  if (inside.size() > 0)
	    {
	      // Find the largest interval
	      double max_len = inside[0].second - inside[0].first;
	      size_t max_ix = 0;
	      for (size_t kj=0; kj<inside.size(); ++kj)
		{
		  double len = inside[kj].second - inside[kj].first;
		  if (len > max_len)
		    {
		      max_len = len;
		      max_ix = kj;
		    }
		}
	      if (ki == 1) 
		upar = 0.5*(inside[max_ix].first + inside[max_ix].second);
	      else
		vpar = 0.5*(inside[max_ix].first + inside[max_ix].second);

	      // Check if we have found a boundary point
	      Vector2D ppnt(upar, vpar);
	      bool is_boundary = isOnBoundary(ppnt, tolerance);
	      if (!is_boundary)
		break;
	    }
	}
    }
  return;
}
예제 #3
0
//===========================================================================
ProjectCurve::ProjectCurve(shared_ptr<Go::ParamCurve>& space_crv, 
			   shared_ptr<Go::ParamSurface>& surf,
			   shared_ptr<Go::Point>& start_par_pt, 
			   shared_ptr<Go::Point>& end_par_pt,
			   double epsgeo1,
// 			   double epsgeo2,
			   const RectDomain* domain_of_interest)
    : space_crv_(space_crv), surf_(surf),
      start_par_pt_(start_par_pt), end_par_pt_(end_par_pt),
      epsgeo1_(epsgeo1),
//       epsgeo2_(epsgeo2),
      domain_of_interest_(domain_of_interest)
//===========================================================================
{
    // Test input
    ALWAYS_ERROR_IF(space_crv_.get() == 0 || surf_.get() == 0,
		"Missing input data.");
    ALWAYS_ERROR_IF(space_crv_->dimension() != 3 ||
		space_crv_->dimension() != surf_->dimension(),
		"Dimension mismatch.");

    //// Check spline surfaces for seems
    //shared_ptr<SplineSurface> tmp_srf = 
    //  dynamic_pointer_cast<SplineSurface,ParamSurface>(surf_);
    //if (tmp_srf.get())
    //  SurfaceTools::surfaceClosed(*tmp_srf, closed_dir_u_, closed_dir_v_);
    //else
    //  closed_dir_u_ = closed_dir_v_ = false;  // No particular treatment of seems

    // Check surfaces for seems
    closed_dir_u_ = false;
    closed_dir_v_ = false;
    shared_ptr<SplineSurface> tmp_srf = 
      dynamic_pointer_cast<SplineSurface,ParamSurface>(surf_);
    shared_ptr<ElementarySurface> tmp_srf_el = 
      dynamic_pointer_cast<ElementarySurface,ParamSurface>(surf_);
    if (tmp_srf.get())
      SurfaceTools::surfaceClosed(*tmp_srf, closed_dir_u_, closed_dir_v_);
    else if (tmp_srf_el.get())
        tmp_srf_el->isClosed(closed_dir_u_, closed_dir_v_);

    // Parameter domain
    RectDomain domain = surf_->containingDomain();
    umin_ = domain.umin();
    umax_ = domain.umax();
    vmin_ = domain.vmin();
    vmax_ = domain.vmax();
}
예제 #4
0
//===========================================================================
DirectionCone Torus::normalCone() const
//===========================================================================
{
    RectDomain domain = parameterDomain();
    double umin = domain.umin();
    double umax = domain.umax();
    double vmin = domain.vmin();
    double vmax = domain.vmax();
    Point dir;
    normal(dir, 0.5*(umin+umax), 0.5*(vmin+vmax));

    Point ll, ur;
    normal(ll, umin, vmin);
    normal(ur, umax, vmax);
    double angle = std::max(dir.angle(ll), dir.angle(ur));

    return DirectionCone(dir, angle);
}
예제 #5
0
//===========================================================================
void TesselatorUtils::getResolution(const ParamSurface *surf, 
				    int& u_nmb, int& v_nmb, 
				    int uv_nmb)
//===========================================================================
{
  int min_nmb = 8;

  // Check if the surface is trimmed and trimmed along iso curves. In that
  // case the size of the surface is computed from the smallest possible
  // underlying surface

  double tol2d = 1.0e-4;
  const ParamSurface *sf = surf;
  vector<shared_ptr<ParamSurface> > sfs;
  if (surf->instanceType() == Class_BoundedSurface)
    {
      const BoundedSurface *bd_surf
	  = dynamic_cast<const BoundedSurface*>(surf);
      if (bd_surf->isIsoTrimmed(tol2d))
	{
	  RectDomain domain = bd_surf->containingDomain();
	  RectDomain dom2 = sf->containingDomain();
	  double umin = std::max(domain.umin(), dom2.umin());
	  double umax = std::min(domain.umax(), dom2.umax());
	  double vmin = std::max(domain.vmin(), dom2.vmin());
	  double vmax = std::min(domain.vmax(), dom2.vmax());
    
	  sfs = sf->subSurfaces(umin, vmin, umax, vmax);
	  if (sfs.size() == 1)
	    sf = sfs[0].get();
	}
    }

  // Estimate the size of the surface in the two parameter directions
  double len_u, len_v;
  GeometryTools::estimateSurfaceSize(*sf, len_u, len_v);
  double fac = len_u/len_v;
  double len = sqrt((double)uv_nmb/fac);
  u_nmb = std::max(min_nmb, (int)(fac*len));
  v_nmb = std::max(min_nmb, (int)len);

}
예제 #6
0
파일: Torus.C 프로젝트: 99731/GoTools
//===========================================================================
DirectionCone Torus::tangentCone(bool pardir_is_u) const
//===========================================================================
{
    if (isSwapped())
        pardir_is_u = !pardir_is_u;

    if (pardir_is_u) {
	shared_ptr<Circle> circle = getMajorCircle(0.0);
	return circle->directionCone();
    }
    else {
	DirectionCone normals = normalCone();
	double angle = normals.angle();
        RectDomain domain = parameterDomain();
	double umid = 0.5 * (domain.umax() + domain.umin());
	double vmid = 0.5 * (domain.vmax() + domain.vmin());
	vector<Point> pts(3);
	point(pts, umid, vmid, 1);
	return DirectionCone(pts[2], angle);
    }
}
예제 #7
0
//===========================================================================
SurfaceOnVolume::SurfaceOnVolume(shared_ptr<ParamVolume> vol,
                                 shared_ptr<ParamSurface> spacesurf,
                                 int constdir, double constpar, int boundary,
                                 bool swapped)
    : volume_(vol), spacesurf_(spacesurf), prefer_parameter_(true),
      constdir_(constdir), constval_(constpar), at_bd_(boundary),
      orientation_(0), swap_(swapped)
//===========================================================================
{
    // Make parameter surface
    // @@@ This construction may not be sufficient when trimmed volumes are
    // introduced
    if (constdir > 0)
    {
        Array<double,6> domain = volume_->parameterSpan();
        RectDomain pardom = spacesurf_->containingDomain();
        vector<double> knots1(4);
        vector<double> knots2(4);
        knots1[0] = knots1[1] = (swap_) ? pardom.vmin() : pardom.umin();
        knots1[2] = knots1[3] = (swap_) ? pardom.vmax() : pardom.umax();
        knots2[0] = knots2[1] = (swap_) ? pardom.umin() : pardom.vmin();
        knots2[2] = knots2[3] = (swap_) ? pardom.umax() : pardom.vmax();
        vector<double> coefs(12);
        domain[2*(constdir_-1)] = domain[2*(constdir_-1)+1] = constval_;
        coefs[0] = domain[0];
        coefs[1] = domain[2];
        coefs[2] = domain[4];
        coefs[3] = domain[1];
        coefs[4] = (constdir_ <= 2) ? domain[3] : domain[2];
        coefs[5] = domain[4];
        coefs[6] = domain[0];
        coefs[7] = (constdir_ <= 2) ? domain[2] : domain[3];
        coefs[8] = domain[5];
        coefs[9] = domain[1];
        coefs[10] = domain[3];
        coefs[11] = domain[5];

        psurf_ = shared_ptr<ParamSurface>(new SplineSurface(2, 2, 2, 2, &knots1[0],
                                          &knots2[0], &coefs[0], 3));
        if (swap_)
        {
            psurf_->swapParameterDirection();
        }
    }
}
예제 #8
0
//===========================================================================
void RectangularSurfaceTesselator::tesselateSurface()
//===========================================================================
{
    int m = mesh_->numStrips() + 1;
    int n = mesh_->numVertices()/m;
    /// @@@ We can only tesselate properly rectangular-domain surfaces.
    RectDomain dom = surf_.containingDomain();
    int dim = surf_.dimension();
    Point pt(dim);
    for (int iu = 0; iu < n; ++iu) {
	double ru = double(iu)/double(n-1);
	double u = dom.umin()*(1.0-ru) + ru*dom.umax();
	for (int iv = 0; iv < m; ++iv) {
	    double rv = double(iv)/double(m-1);
	    double v = dom.vmin()*(1.0-rv) + rv*dom.vmax();
	    surf_.point(pt, u, v);
	    //	    std::cout << pt << std::endl;
//	    std::cout << "iu: " << iu << ", iv: " << iv << ", pt: " << pt << std::endl;
	    int j;
	    for (j=0; j<dim; ++j)
	      mesh_->vertexArray()[(iv*n + iu)*3+j] = pt[j];
	    for (; j<3; ++j)
	      mesh_->vertexArray()[(iv*n + iu)*3 + j] = 0.0;
	    mesh_->paramArray()[(iv*n + iu)*2] = u;
	    mesh_->paramArray()[(iv*n + iu)*2+1] = v;
	    if (mesh_->useNormals()) {
		surf_.normal(pt, u, v);
		mesh_->normalArray()[(iv*n + iu)*3] = pt[0];
		mesh_->normalArray()[(iv*n + iu)*3 + 1] = pt[1];
		mesh_->normalArray()[(iv*n + iu)*3 + 2] = pt[2];
	    }
	    if (mesh_->useTexCoords()) {
		mesh_->texcoordArray()[(iv*n + iu)*2] = ru;
		mesh_->texcoordArray()[(iv*n + iu)*2+1] = rv;
	    }
	}
    }
}
예제 #9
0
//===========================================================================
Point SurfaceOnVolume:: volumeParameter(double u_par, double v_par) const
//===========================================================================
{
    Point param(3);
    RectDomain dom = containingDomain();
    if (constdir_ == 1 || constdir_ == 2 || constdir_ == 3)
    {
        int idx1, idx2, idx3;
        idx1 = constdir_ - 1;
        idx2 = (idx1 == 0) ? 1 : 0;
        idx3 = (constdir_ == 3) ? 1 : 2;
        param[idx1] = constval_;
        if (swap_)
        {
            param[idx2] = (orientation_ == 2 || orientation_ == 3) ?
                          dom.vmax() - (v_par - dom.vmin()) : v_par;
            param[idx3] = (orientation_ == 1 || orientation_ == 3) ?
                          dom.umax() - (u_par - dom.umin()) : u_par;
        }
        else
        {
            param[idx3] = (orientation_ == 2 || orientation_ == 3) ?
                          dom.vmax() - (v_par - dom.vmin()) : v_par;
            param[idx2] = (orientation_ == 1 || orientation_ == 3) ?
                          dom.umax() - (u_par - dom.umin()) : u_par;
        }
    }
    else if (psurf_)
        param = psurf_->ParamSurface::point(u_par, v_par);
    else
    {
        // No parameter surface exist. Perform closest point computation
        Point pos = spacesurf_->ParamSurface::point(u_par, v_par);
        double clo_u, clo_v, clo_w, dist;
        Point clo_pt;
        double eps = 1.0e-6;
        volume_->closestPoint(pos, clo_u, clo_v, clo_w, clo_pt, dist, eps);
        param = Point(clo_u, clo_v, clo_w);
    }
    return param;
}
예제 #10
0
//===========================================================================
RectDomain CurveBoundedDomain::containingDomain() const
//===========================================================================
{
    RectDomain dom;
    if ((*loops_[0])[0]->dimension() == 2) {
	// We've got a parametric bound
	BoundingBox b = (*loops_[0])[0]->boundingBox();
	int n1 = (int)loops_.size();
	int i, j;
	for (j=0; j<n1; j++)     {
	    int n2 = loops_[j]->size();
	    for (i = (j==0)?1:0; i < n2; ++i) {
		b.addUnionWith((*loops_[j])[i]->boundingBox());
	    }
	}
	dom = RectDomain(Array<double, 2>(b.low()[0], b.low()[1]),
			   Array<double, 2>(b.high()[0], b.high()[1]));
    } else {
	// We should have a bound consisting of CurveOnSurface objects,
	// and we'll throw an exception if it's not!
	const CurveOnSurface& cv0
	    = dynamic_cast<const CurveOnSurface&>(*(*loops_[0])[0]);
	dom = cv0.containingDomain();
	int n1 = (int)loops_.size();
	int i, j;
	for (j=0; j<n1; j++)     {
	    int n2 = loops_[j]->size();
	    for (i = (j==0)?1:0; i < n2; ++i) {
		const CurveOnSurface& cv1
		    = dynamic_cast<const CurveOnSurface&>(*(*loops_[j])[i]);
		dom.addUnionWith(cv1.containingDomain());
	    }
	}
    }
    return dom;
}
예제 #11
0
//===========================================================================
void RectangularSurfaceTesselator::tesselateIsolines()
//===========================================================================
{
    if (!isolines_) return;
    isolinestrips_.resize(uiso_ + viso_);

    RectDomain dom = surf_.containingDomain();
    Point pt(3);
    for (int i = 0; i < uiso_; ++i) {
	isolinestrips_[i].resize(isores_);
	double ru = double(i)/double(uiso_-1);
	double u = dom.umin()*(1.0-ru) + ru*dom.umax();
	for (int j = 0; j < isores_; ++j) {
	    double rv = double(j)/double(isores_-1);
	    double v = dom.vmin()*(1.0-rv) + rv*dom.vmax();
	    surf_.point(pt, u, v);
	    isolinestrips_[i].vertexArray()[j*3] = pt[0];
	    isolinestrips_[i].vertexArray()[j*3 + 1] = pt[1];
	    isolinestrips_[i].vertexArray()[j*3 + 2] = pt[2];
	    isolinestrips_[i].paramArray()[j] = v;
	}
    }
    for (int i = 0; i < viso_; ++i) {
	isolinestrips_[uiso_ + i].resize(isores_);
	double rv = double(i)/double(viso_-1);
	double v = dom.vmin()*(1.0-rv) + rv*dom.vmax();
	for (int j = 0; j < isores_; ++j) {
	    double ru = double(j)/double(isores_-1);
	    double u = dom.umin()*(1.0-ru) + ru*dom.umax();
	    surf_.point(pt, u, v);
	    isolinestrips_[uiso_ + i].vertexArray()[j*3] = pt[0];
	    isolinestrips_[uiso_ + i].vertexArray()[j*3 + 1] = pt[1];
	    isolinestrips_[uiso_ + i].vertexArray()[j*3 + 2] = pt[2];
	    isolinestrips_[uiso_ + i].paramArray()[j] = u;
	}
    }
}
예제 #12
0
파일: VolumeModel.C 프로젝트: 99731/GoTools
//===========================================================================
void VolumeModel::setBoundarySfs()
//===========================================================================
{
  // Fetch all faces lying at outer boundaries, i.e. all faces with no twin
  vector<shared_ptr<ftSurface> > bd_faces = getBoundaryFaces();

#ifdef DEBUG_VOL2
   std::ofstream of("bd_sfs.g2");
#endif

  // Make copy of all faces to avoid destroying existing topology 
  // information in the shells of the solids
  vector<shared_ptr<ftSurface> > bd_faces2(bd_faces.size());
  for (size_t ki=0; ki<bd_faces.size(); ++ki)
    {
      bd_faces2[ki] = shared_ptr<ftSurface>(new ftSurface(bd_faces[ki]->surface(),
							  (int)ki));
      bd_faces2[ki]->setBody(bd_faces[ki]->getBody());

 #ifdef DEBUG_VOL2
     shared_ptr<ParamSurface> surf = bd_faces[ki]->surface();
      shared_ptr<SurfaceOnVolume> vsurf = 
	dynamic_pointer_cast<SurfaceOnVolume,ParamSurface>(surf);
      if (vsurf.get())
	{
	  vsurf->spaceSurface()->writeStandardHeader(of);
	  vsurf->spaceSurface()->write(of);
	}
      else
	{
	  surf->writeStandardHeader(of);
	  surf->write(of);
	}
#endif
    }

  // Represent the outer boundaries as a SurfaceModel
  shared_ptr<SurfaceModel> sfmodel =
    shared_ptr<SurfaceModel>(new SurfaceModel(toptol_.gap, toptol_.gap,
					      toptol_.neighbour, 
					      toptol_.kink, toptol_.bend,
					      bd_faces2));

  // Fetch all connected models
  vector<shared_ptr<SurfaceModel> > models = sfmodel->getConnectedModels();

  if (models.size() == 1)
    boundary_shells_.push_back(models);
  else
    {
      // Sort models into connected submodels and inner and outer shells
      // First get maximum size of model
      BoundingBox box = boundingBox();
      
      // Classify shells
      for (size_t ki=0; ki<models.size(); ++ki)
	{
	  // Check if the current model is already classified
	  size_t kj, kr;
	  bool found = findBoundaryShell(models[ki], kj, kr);
	  if (found)
	    continue;  // Shell already classified

	  if (models[ki]->nmbEntities() == 0)
	    continue;  // Empty model
	  
	  // Make linear curve through current model
	  shared_ptr<ftSurface> face = models[ki]->getFace(0);
	  
	  // Fetch a point on this face
	  Point pnt, norm;
	  shared_ptr<ParamSurface> srf = face->surface();
	  RectDomain dom = srf->containingDomain();
	  double upar = 0.5*(dom.umin()+dom.umax());
	  double vpar = 0.5*(dom.vmin()+dom.vmax());
	  Point pnt0 = srf->point(upar, vpar);
	  double dist;
	  face->closestPoint(pnt0, upar, vpar, pnt, dist, toptol_.gap);
	  norm = face->normal(upar, vpar);

	  // Make large enough curve
	  double len = box.low().dist(box.high()); // Estimated box size
	  norm.normalize();
	  Point pt1 = pnt - len*norm;
	  Point pt2 = pnt + len*norm;
	  shared_ptr<SplineCurve> crv = 
	    shared_ptr<SplineCurve>(new SplineCurve(pt1, pt2));

	  // Get model intersections
	  vector<intersection_point> int_pts = getIntSfModelsCrv(models, crv);

	  // Sort intersection points according to curve parameter
	  std::sort(int_pts.begin(), int_pts.end(), par_compare);
	  size_t i1, i2, i3, i4;
	  for (kj=0; kj<int_pts.size(); ++kj)
	    {
	      // Find the next intersection with the same model
	      for (kr=kj+1; kr<int_pts.size(); ++kr)
		if (int_pts[kj].shell_idx == int_pts[kr].shell_idx)
		  break;
	      if (kr == int_pts.size())
		kr = kj;

	      found = findBoundaryShell(models[int_pts[kj].shell_idx], 
					i1, i2);
	      if (!found)
		{
		  vector<shared_ptr<SurfaceModel> > curr;
		  curr.push_back(models[int_pts[kj].shell_idx]);
		  boundary_shells_.push_back(curr);
		  i1 = boundary_shells_.size() - 1;
		}

	      // Add inner boundary shells
	      for (size_t kh=kj+1; kh<=kr; ++kh)
		{
		  found = findBoundaryShell(models[int_pts[kh].shell_idx], 
					    i3, i4);
		  if (!found)
		    boundary_shells_[i1].push_back(models[int_pts[kh].shell_idx]);
		}
	    }
	}
    }
}
예제 #13
0
//===========================================================================
void Torus::closestBoundaryPoint(const Point& pt,
				double&        clo_u,
				double&        clo_v, 
				Point&       clo_pt,
				double&        clo_dist,
				double epsilon,
				const RectDomain* rd,
				double *seed) const
//===========================================================================
{
    // Algorithm:
    // 1) Find closest point overall
    // 2) If on boundary, return
    // 3) Else, snap to boundary

    // Find closest point overall
    closestPoint(pt, clo_u, clo_v, clo_pt, clo_dist, epsilon);

    // Check if on boundary
    RectDomain dom = parameterDomain();
    double umin = dom.umin();
    double umax = dom.umax();
    double vmin = dom.vmin();
    double vmax = dom.vmax();
    if (fabs(clo_u - umin) < epsilon ||
        fabs(clo_u - umax) < epsilon ||
        fabs(clo_v - vmin) < epsilon ||
        fabs(clo_v - vmax) < epsilon) {
            return;
    }

    // Overall closest point is in the inner of the patch
    double clo_u_inner = clo_u;
    double clo_v_inner = clo_v;

    // Fist on boundary
    clo_u = umin;
    point(clo_pt, umin, clo_v_inner);
    clo_dist = pt.dist(clo_pt);

    // Second
    Point clo_pt_tmp;
    point(clo_pt_tmp, umax, clo_v_inner);
    double clo_dist_tmp = pt.dist(clo_pt_tmp);
    if (clo_dist_tmp < clo_dist) {
        clo_pt = clo_pt_tmp;
        clo_u = umax;
        clo_v = clo_v_inner;
        clo_dist = clo_dist_tmp;
    }

    // Third
    point(clo_pt_tmp, clo_u_inner, vmin);
    clo_dist_tmp = pt.dist(clo_pt_tmp);
    if (clo_dist_tmp < clo_dist) {
        clo_pt = clo_pt_tmp;
        clo_u = clo_u_inner;
        clo_v = vmin;
        clo_dist = clo_dist_tmp;
    }

    // Fourth
    point(clo_pt_tmp, clo_u_inner, vmax);
    clo_dist_tmp = pt.dist(clo_pt_tmp);
    if (clo_dist_tmp < clo_dist) {
        clo_pt = clo_pt_tmp;
        clo_u = clo_u_inner;
        clo_v = vmax;
        clo_dist = clo_dist_tmp;
    }

    return;
}
예제 #14
0
//===========================================================================
int CurveBoundedDomain::positionPointInDomain(int pardir, double parval1, 
					      double parval2, 
					      double tolerance) const
  // Fetch all intervals in one parameter direction
  // going through a specific point lying inside the 
  // bounded domain.
//
// Return value: -1 : Outside of outer loop
//                0 : Inside domain
//                j>0 : Inside hole number j, i.e. inside loop number j
//===========================================================================
{

  // Get the rectangular domain containing this domain
  RectDomain parbox = containingDomain();

  // Make a constant curve in the parameter domain, in the given
  // direct slightly larger than the found containing domain.
  double par1[2], par2[2], vec[2];
  double parint;
  int par_idx = 0;
  if (pardir == 2)
    {
      // Make constant parameter curve in 2. parameter direction.
      par1[0] = par2[0] = parval1;
      par1[1] = parbox.vmin();
      par2[1] = parbox.vmax();
      parint = std::max(par2[1] - par1[1], 0.1);
      par1[1] -= 0.1*parint;
      par2[1] += 0.1*parint;

      par_idx = 1;
    }
  else if (pardir == 1)
    {
      // Make constant parameter curve in 1. parameter direction.
      par1[1] = par2[1] = parval2;
      par1[0] = parbox.umin();
      par2[0] = parbox.umax();
      parint = std::max(par2[0] - par1[0], 0.1);
      par1[0] -= 0.1*parint;
      par2[0] += 0.1*parint;

      par_idx = 0;
    }
  else 
    {
      // Diagonal parameter curve
      par1[0] = par2[0] = parval1;
      par1[1] = par2[1] = parval2;
      vec[0] = parbox.umax() - parbox.umin();
      vec[1] = parbox.vmax() - parbox.vmin();
      par1[0] -= vec[0];
      par1[1] -= vec[1];
      par2[0] += vec[0];
      par2[1] += vec[1];

      par_idx = 0;  // @@@ VSK, 0309. This is not really correct
    }

  Point pnt1(par1[0], par1[1]);
  Point pnt2(par2[0], par2[1]);
  SplineCurve isopar(pnt1, pnt2);

  vector<intersection_point> intpt;

  findPcurveInsideSegments(isopar, tolerance, intpt);

  int ki;
  int nmbpoint = (int)intpt.size();
  if (nmbpoint == 1)
    {
      // Assuming non-recognized tangential intersection
      return -1;
    }
  else if (nmbpoint%2 != 0) {
    throw std::logic_error("Odd number of intersections."); 
    }

  double ptol = 1.0e-8;
  for (ki=1; ki<nmbpoint; ki+=1)
    {
      // Check if the initial point lies inside the current interval
      Point eval1, eval2;
      isopar.point(eval1, intpt[ki-1].par1);
      isopar.point(eval2, intpt[ki].par1);
      if (eval1[0]-ptol < parval1 && eval2[0]+ptol > parval1 &&
	  eval1[1]-ptol < parval2 && eval2[1]+ptol > parval2)
	{
	  // The point lies inside this interval. Check if the interval
	  // corresponds to an inner loop
	  int loop1 = intpt[ki-1].loop_idx;
	  int loop2 = intpt[ki].loop_idx;
	  if (loop1 != loop2)
	    return 0;  // In the domain
	  else
	    return loop1;
	}
    }

  return -1; // The point lies outside the domain
}
예제 #15
0
//===========================================================================
void CurveBoundedDomain::getInsideIntervals(int pardir, double parval1, 
					    double parval2, double tolerance,
					    vector<pair<double, double> >&
					    insideInts, bool with_bd) const
  // Fetch all intervals in one parameter direction
  // going through a specific point lying inside the 
  // bounded domain.
//===========================================================================
{

  // Get the rectangular domain containing this domain
  RectDomain parbox = containingDomain();
  Point mid(0.5*(parbox.umin()+parbox.umax()), 
	    0.5*(parbox.vmin()+parbox.vmax()));
  Point parpt(parval1, parval2);
  double len1 = (parbox.umax()-parbox.umin())+(parbox.vmax()-parbox.vmin());
  double len2 = mid.dist(parpt);
  if (len1 == 0.0)
  {
      MESSAGE("Degenerate domain!");
      return;
  }

  double mult_fac = 2.0*(len1+len2)/len1;  // The curve with which to intersect
  // should be much larger than the trimmed domain

  // Make a constant curve in the parameter domain, in the given
  // direct slightly larger than the found containing domain.
  double par1[2], par2[2], vec[2];
  double parint;
  int par_idx = 0;
  double len;
  if (pardir == 2)
    {
      // Make constant parameter curve in 2. parameter direction.
      par1[0] = par2[0] = parval1;
      par1[1] = parbox.vmin();
      par2[1] = parbox.vmax();
      parint = std::max(par2[1] - par1[1], 0.1);
      len = mult_fac*parint;
      par1[1] -= len;
      par2[1] += len;

      par_idx = 1;
    }
  else if (pardir == 1)
    {
      // Make constant parameter curve in 1. parameter direction.
      par1[1] = par2[1] = parval2;
      par1[0] = parbox.umin();
      par2[0] = parbox.umax();
      parint = std::max(par2[0] - par1[0], 0.1);
      len = mult_fac*parint;
      par1[0] -= len;
      par2[0] += len;

      par_idx = 0;
    }
  else 
    {
      // Diagonal parameter curve
      par1[0] = par2[0] = parval1;
      par1[1] = par2[1] = parval2;
      vec[0] = parbox.umax() - parbox.umin();
      vec[1] = parbox.vmax() - parbox.vmin();
      len = mult_fac*sqrt(vec[0]*vec[0]+vec[1]*vec[1]);
      par1[0] -= (mult_fac*vec[0]);
      par1[1] -= (mult_fac*vec[1]);
      par2[0] += (mult_fac*vec[0]);
      par2[1] += (mult_fac*vec[1]);

      par_idx = 0;  // @@@ VSK, 0309. This is not really correct
    }

  Point pnt1(par1[0], par1[1]);
  Point pnt2(par2[0], par2[1]);
  SplineCurve isopar(pnt1, -len, pnt2, len);

  vector<intersection_point> intpt;

  findPcurveInsideSegments(isopar, tolerance, intpt, with_bd);

  int ki;
  int nmbpoint = (int)intpt.size();
  if (nmbpoint == 1)
    {
      // Assuming non-recognized tangential intersection
      return;
    }
  else if (nmbpoint%2 != 0) {
    throw std::logic_error("Odd number of intersections."); 
    }

  for (ki=1; ki<nmbpoint; ki+=2)
    {
      Point eval1, eval2;
      isopar.point(eval1, intpt[ki-1].par1);
      isopar.point(eval2, intpt[ki].par1);
      insideInts.push_back(std::make_pair(eval1[par_idx], eval2[par_idx]));
      //      std::cout << eval1[2-pardir] <<" , " << eval2[2-pardir] << std::endl;
    }

  
}
예제 #16
0
파일: GSBarea.C 프로젝트: 99731/GoTools
//===========================================================================
double BoundedSurface::area(double tol) const
//===========================================================================
{
    double fac = 10.0;

    // Get surrounding domain
    RectDomain domain = containingDomain();
    
    // Get smallest surrounding surface
    shared_ptr<ParamSurface> base_sf = surface_;
    while (base_sf->instanceType() == Class_BoundedSurface)
	base_sf = dynamic_pointer_cast<BoundedSurface, ParamSurface>(base_sf)->underlyingSurface();
	
    
    vector<shared_ptr<ParamSurface> > sfs = 
	base_sf->subSurfaces(domain.umin(), domain.vmin(), domain.umax(), domain.vmax());

    double total_area = 0.0;
    size_t kr;
    for (kr=0; kr<sfs.size(); ++kr)
    {
	shared_ptr<SplineSurface> spline_sf = 
	    dynamic_pointer_cast<SplineSurface, ParamSurface>(sfs[kr]);
	if (spline_sf.get())
	    total_area += spline_sf->area(tol);
    }
    if (isIsoTrimmed(0.1*tol))
    {
	// We are finished
	return total_area;
    }

    std::ofstream out_file("tmp_mini_surf.g2");
    // Otherwise, split the current surface into smaller pieces and compare areas
    int nmb_split = 5;
    double u1 = domain.umin();
    double v1 = domain.vmin();
    double u_del = (domain.umax() - u1)/(double)(nmb_split);
    double v_del = (domain.vmax() - v1)/(double)(nmb_split);
    
    int ki, kj;
    double curr_area = 0.0;
    vector<shared_ptr<ParamSurface> > all_sfs;
    for (kj=0; kj<nmb_split; ++kj, v1+=v_del)
	for (ki=0, u1=domain.umin(); ki<nmb_split; ++ki, u1+=u_del)
	{
	    vector<shared_ptr<ParamSurface> > sub_sfs = subSurfaces(u1, v1, u1+u_del, v1+v_del);
	    for (kr=0; kr<sub_sfs.size(); ++kr)
	    {
// 		sub_sfs[ki]->writeStandardHeader(out_file);
// 		sub_sfs[ki]->write(out_file);
		RectDomain dom2 = sub_sfs[kr]->containingDomain();
		vector<shared_ptr<ParamSurface> > tmp_sfs = base_sf->subSurfaces(std::min(u1,dom2.umin()),
										 std::min(v1,dom2.vmin()),
										 std::max(u1+u_del,dom2.umax()),
										 std::max(v1+v_del,dom2.vmax()));
		curr_area += tmp_sfs[0]->area(tol);
	    }
	    all_sfs.insert(all_sfs.end(), sub_sfs.begin(), sub_sfs.end());
	}


    if (total_area/curr_area < 1.0 + fac*tol)
	return curr_area;  // The area is close enough

    // Compute recursively
    curr_area = 0.0;
    for (kr=0; kr<all_sfs.size(); ++kr)
	curr_area += all_sfs[kr]->area(tol);

    return curr_area;
}