void Octree::doIterate(int level, Node *node, const func_t &f) const{
   f(level, node);
   if (node->hasChildren()) {
     for (int i = 0; i < 8; ++i) {
       doIterate(level + 1, node->children[i], f);
     }
   }
 }
Esempio n. 2
0
//===========================================================================
//
// Purpose : Given two parametric curve in a simple case situation, iterate
//           to the intersection point, if any. 
//
// Written by : Sverre Briseid, SINTEF, Sep 2004
//
//===========================================================================
int Par1FuncIntersector::updateIntersections()
//===========================================================================
{
  // Fetch already existing intersection points
  vector<shared_ptr<IntersectionPoint> > int_pts;
  int_results_->getIntersectionPoints(int_pts);

  if (int_pts.size() > 0)
    {
      // At most one intersection point is expected. One or more points
      // exist already. Leave it like this.
	// @@sbr Do we expect object to be monotone?
      return 0;
    }

  // Iterate to an intersection point between the two curves
  double par, dist, tmin, tmax;
  doIterate(par, dist, tmin, tmax);

  if ((par != tmin) && (par != tmax) && (dist <= epsge_->getEpsge()))
    {
      // An intersection point is found. Represent it in the data
      // structure
      // @@@ vsk, In sisl there is a check if the found intersection
      // point is very close to the endpoints of the curve. In that case
      // it is dismissed since the intersections at the endpoints are found
      // already. Here we have already checked if there exist any
      // intersection points. Thus, we know that there does not exist any
      // intersection point at the endpoint.
      // @@sbr But for tangential intersections an endpoint may not be discovered ...
      // As the int_pts.size() == 0 and an intersection point nevertheless exist
      // this should be such a (or similar) situation.
      // @@sbr Another approach could be to avoid subdividing if the obj (2d)
      // is monotone in that direction.
      int_results_->addIntersectionPoint(func_int_, 
					 C_,
					 getTolerance(),
					 &par,
					 NULL);
      return 1; // A new point is found
    }

  //#endif // 0

  return 0;
}
 void Octree::iterateNodes(const func_t &f) const {
   doIterate(0, root, f);
 }
Esempio n. 4
0
//===========================================================================
int Par1FuncIntersector::getSubdivisionParameter(int dir, double& par)
//===========================================================================
{
    // Purpose : Return (what seems to be) the most suitable
    // subdivision param.

  int ki, kj, sgn;
//   int nmbdir1 = func_int_->numParams();
//   int nmbdir2 = C_->numParams();
  double ptol = 100.0*epsge_->getRelParRes();
  double gtol = 100.0*epsge_->getEpsge(); //100.0*epsge_->getEpsge();

  // Set pointer to the intersection object corresponding to the parameter
  // direction
  ParamFunctionInt *obj = func_int_.get();
  int pdir = 0;
  double ta = obj->startParam(pdir);
  double tb = obj->endParam(pdir);
  double fac = 0.1;
  double del = fac*(tb - ta);

  // Get critical parameters
  // @@@ Critical parameters of different priority? Sorting?
  vector<double> critical_pars = obj->getCriticalVals(pdir);

  int size = (int)critical_pars.size();
  int is_critical;

  if (size > 0)
    {
      // Check suitability of the critical parameters
      for (ki=0; ki<size; ki++)
	{
//	  is_critical = int_results_->inInfluenceArea(pdir, critical_pars[ki]);
//	  if (is_critical == 0 || is_critical == 2)
	    par = critical_pars[ki];
	    if (par >= ta + del && par <= tb - del)
	    {
		return 1;
	    }
	}
    }

  // Look for a suitable knot in which to subdivide. First fetch
  // the knots sorted according to the distance to the mid-parameter
  vector<double> knot_vals = obj->getInnerKnotVals(pdir, true);
  size = (int)knot_vals.size();
   if (size > 0)
    {
      // Check suitability of the knots
      for (ki=0; ki<size; ki++)
	{
	    par = knot_vals[ki];
//	  is_critical = int_results_->inInfluenceArea(pdir, knot_vals[ki]);
//	  if (is_critical == 0 || is_critical == 2)
	    
	    if (par >= ta + del && par <= tb - del)
	    {
		return 2;
	    }
	}
    }
 
   // Check for inner intersection points in which to subdivide
   vector<double> inner_ints = int_results_->getSortedInnerInts(pdir);
   size = (int)inner_ints.size();
  if (size > 0)
    {
      // Check suitability of the intersection points
      for (ki=size/2, kj=1, sgn=-1; ki<size && ki>=0; 
	   ki+=sgn*kj, kj++, sgn*=-1)
	{
	    par = inner_ints[ki];
// 	  is_critical = int_results_->inInfluenceArea(pdir, inner_ints[ki]);
// 	  if (is_critical == 0 || is_critical == 2)
	    if (par >= ta + del && par <= tb - del)
	    {
		return 3;
	    }
	}
    }

  // If a singularity exist we use that as a subdivision point.

  // Iterate for a closest point in which to subdivide
  if (singularity_info_.get() == 0)
    {
	// Make empty singularity info instance
	singularity_info_ = (shared_ptr<SingularityInfo>)(new SingularityInfo());
    }
  
  // Check if a closest point exist already
  double dist = 2*gtol; // At least larger than gtol.
  if (singularity_info_->hasPoint())
  {
      dist = 0.0;
      par = singularity_info_->getParam(dir);
  }
  else
  {
      // Iterate for a closest point
      double tmin, tmax;
      doIterate(par, dist, tmin, tmax);
      if (dist < gtol) {

	  // We also check if the found parameter lies close to the iso-cv of an
	  // existing int_pt in prev_intersector_.
	  shared_ptr<IntersectionPool> prev_pool = prev_intersector_->getIntPool();
	  vector<shared_ptr<IntersectionPoint> > int_pts;
	  prev_pool->getSortedIntersections(int_pts);
	  Point c_pt;
	  C_->point(c_pt, NULL);
	  double max_knot_dist = epsge_->getEpsge(); //epsge_->getRelParRes(); @@sbr Too large value?
	  for (size_t ki = 0; ki < int_pts.size(); ++ki) {
	      const double* prev_par = int_pts[ki]->getPar1();
	      if (fabs(prev_par[dir] - par) < max_knot_dist) {
		  // We check if par[dir] is close enough, i.e. within epsge_.
		  Point func_pt;
		  func_int_->point(func_pt, &prev_par[dir]);
		  if (c_pt.dist(func_pt) < epsge_->getEpsge()) {
		      par = prev_par[dir];
		  }
	      }
	  }

	  singularity_info_->setSingularPoint(&par, 1);
	  std::cout << setprecision(15) << "Singularity: " << par << std::endl;
      }
  }

  if (dist < gtol && par > ta+ptol && par < tb-ptol)
  {
      // Check the parameter value
      vector<shared_ptr<IntersectionPoint> > int_pts;
      is_critical = int_results_->inInfluenceArea(dir, par);
      if (is_critical == 0 || is_critical == 2)
	  return 4;     
  }


//   // Subdivide in the middle
//   par = 0.5*(ta+tb);
//   return true;
  
    // Subdivide at a suitable parameter
  double divpar = 0.5*(ta+tb);
  del = 0.1*(tb-ta);
  double tint = del;
  for (ki=0, sgn=-1; ki<9; ki++, divpar+=sgn*tint, tint+=del, sgn*=-1)
    {
      is_critical = int_results_->inInfluenceArea(dir, divpar);
      if (is_critical == 0 || is_critical == 2)
	{
	  par = divpar;
	  return 5;
	}
    }

  return 0;  // No subdivision parameter found
}