예제 #1
0
//compute the cross point
Point_3 compute_cross_point(Plane_3 plane, Point_3 start, Point_3 end)
{
	Vector_3 normal = plane.orthogonal_vector();
	Vector_3 line_direction = end - start;
	Point_3  p= plane.point();
	double t;
	double a = (start.x() - p.x()) * normal.x() + (start.y() - p.y()) * normal.y() + (start.z() - p.z()) * normal.z();
	double b = line_direction.x() * normal.x() + line_direction.y() * normal.y() + line_direction.z() * normal.z();

	assert(b != 0);
	t = -a / b;

	return start + t * line_direction;
}
Point_3 calculateMove(const Vertex_handle &vertex,
		const Vector_3 &tangient)
{
	DEBUG_START;
	Plane_3 plane = dual(vertex->point());
	Vector_3 u(plane.a(), plane.b(), plane.c());
	if (plane.d() > 0.)
		u = -u;
	double value = tangient * u;
	Plane_3 planeNew(u.x(), u.y(), u.z(), -value);
	Point_3 point = dual(planeNew);
	DEBUG_END;
	return point;
}
static double planeDist(const Plane_3 &p0, const Plane_3 &p1)
{
	double a = p0.a() - p1.a();
	double b = p0.b() - p1.b();
	double c = p0.c() - p1.c();
	double d = p0.d() - p1.d();
	return sqrt(a * a + b * b + c * c + d * d);
}
예제 #4
0
bool on_positive_side(const Plane_3& P, const Point_3& p)
{
  return P.has_on_positive_side(p);

  // typedef CGAL::Cartesian<double> K;
  // typedef CGAL::Plane_3<K> Plane_3;

  // Plane_3 CP(P.A(), P.B(), P.C(), P.D());
  // return CP.has_on_positive_side(to_cgal(p));
}
static std::pair<bool, double> calculateAlpha(const Vector_3 &xOld,
		const Vector_3 &xNew,
		const Plane_3 &planeOuter)
{
	DEBUG_START;
	std::cout << "Calculating alpha for plane " << planeOuter << std::endl; 
	Plane_3 plane = planeOuter;
	Vector_3 u(plane.a(), plane.b(), plane.c());
	double value = -plane.d();
	if (value < 0.)
	{
		u = -u;
		value = -value;
	}
	double length = sqrt(u.squared_length());
	u = u / length;
	std::cout << "  u = " << u << std::endl;
	value = value / length;
	std::cout << "  h initial = " << value << std::endl;
	double productOld = xOld * u;
	std::cout << "  h current = " << productOld << std::endl;
	double productNew = xNew * u;
	std::cout << "  h new     = " << productNew << std::endl;
	double productDifference = productNew - productOld;
	std::cout << "  product difference: " << productDifference
		<< std::endl;
	if (productDifference < 0.)
	{
		std::cout << "Stop strange step processing" << std::endl;
		DEBUG_END;
		return std::make_pair(false, 0.);
	}
	double alpha = (productNew - value) / (productNew - productOld);
	if (alpha > 1.)
	{
		std::cout << "Truncating alpha: "  << alpha << " -> 1."
			<< std::endl;
		alpha = 1.;
	}
	DEBUG_END;
	return std::make_pair(true, alpha);
}
static Plane_3 normalizePlane(const Plane_3 &p)
{
	double a = p.a();
	double b = p.b();
	double c = p.c();
	double d = p.d();
	if (d > 0.)
	{
		a = -a;
		b = -b;
		c = -c;
		d = -d;
	}
	double l = sqrt(a * a + b * b + c * c);
	ASSERT(l > 1e-15);
	a /= l;
	b /= l;
	c /= l;
	d /= l;
	return Plane_3(a, b, c, d);
}
예제 #7
0
/**
 * Finds the exit point of upslope_path on the facet left of h.
 *
 * upslope_path must intersect the boundary of the facet in 2 points or a
 * segment. One of these points must be start_point. If the intersection is a
 * segment, returns the endpoint that is not start_point. Otherwise returns the
 * other intersection point. Updates h so it is the halfedge where the
 * intersection is found.
 */
Point_2 find_exit(Halfedge_handle& h, const Ray_2& upslope_path, 
        const Point_2& start_point)
{
    Point_2 exit;
    Plane_3 plane = h->facet()->plane();
    typedef Facet::Halfedge_around_facet_circulator Circulator;
    Circulator current = h->facet()->facet_begin();
    Circulator end = h->facet()->facet_begin();

    do {
        Point_2 source = plane.to_2d(current->vertex()->point());
        Point_2 target = plane.to_2d(current->opposite()->vertex()->point());
        Segment_2 seg = Segment_2(source, target);
        // Example pulled from http://tinyurl.com/intersect-doc
        CGAL::Object intersect = CGAL::intersection(upslope_path, seg);
        // Return for a point intersection
        if (const CGAL::Point_2<Kernel> *ipoint =
                CGAL::object_cast<CGAL::Point_2<Kernel> >(&intersect)) {
            if (*ipoint != start_point) {
                h = current;
                return *ipoint;
            }
        } 
        // Return the opposite point of the segment for a segment intersection.
        else if (const CGAL::Segment_2<Kernel> *iseg =
                CGAL::object_cast<CGAL::Segment_2<Kernel> >(&intersect)) {
            h = current;
            if (iseg->source() == start_point)
                return iseg->target();
            return iseg->source();
        } 
    } while (++current != end);
    cout << "Failed to find an intersection point." << endl;
    cout << "Start: " << start_point << endl;
    cout << "Upslope path: " << upslope_path << endl;
    print_facet(*h->facet());
    std::abort();
    return exit;
}
예제 #8
0
	void CAT_facet::gl_draw(const Plane_3& pln) const
	{
		for (std::list<Point_3>::const_iterator it = cat_vtx.begin(); it != cat_vtx.end(); ++it)
			if (pln.has_on_negative_side(*it))
				return;

		glColor4f(0.2f, 0.8f, 1.0f, 1.0f);
		glBegin(GL_POLYGON);
		for (std::list<Point_3>::const_iterator it = cat_vtx.begin(); it != cat_vtx.end(); ++it)
			glVertex3d(it->x(), it->y(), it->z());
		glEnd();
		glColor4f(0.1f, 0.1f, 0.1f, 1.0f);
		glBegin(GL_LINE_LOOP);
		for (std::list<Point_3>::const_iterator it = cat_vtx.begin(); it != cat_vtx.end(); ++it)
			glVertex3d(it->x(), it->y(), it->z());
		glEnd();
	}
static Plane_3 centerizePlane(const Plane_3 &p, const Point_3 &C, double sign)
{
	Plane_3 pp(p.a(), p.b(), p.c(),	p.d() + p.a() * C.x() + p.b() * C.y()
			+ p.c() * C.z());

	double a = pp.a();
	double b = pp.b();
	double c = pp.c();
	double d = pp.d();
	if (sign * signedDist(pp, C) < 0.)
	{
		a = -a;
		b = -b;
		c = -c;
		d = -d;
	}

	pp = Plane_3(a, b, c, d);

	return pp;
}
예제 #10
0
/**
 * Determines whether a plane is flat.
 */
bool is_flat_plane(const Plane_3& h)
{
    return h.a() == 0.0 && h.b() == 0.0;
}
예제 #11
0
// compute one cross point between 1-ring of c_vh and cutPlane
bool vertexTo(Vertex_handle &c_vh, Halfedge_handle &c_hh, Vertex_handle center, 
			  Halfedge_vertex_circulator &optimal_start_spoke, 
			  const Plane_3 &cutPlane, Polyhedron* mesh, std::list<Point_3> &cross_points,
			  int nthTarget)
{
	bool result(false);
	Halfedge_vertex_circulator  hc;
	if ( c_vh == center )
		hc =  optimal_start_spoke;
	else
		hc =  c_vh->vertex_begin();

	Halfedge_vertex_circulator end  =  hc;			
	CGAL_For_all(hc,end)
	{
		Vertex_handle lvh = hc->opposite()->vertex();
		Vertex_handle rvh = hc->next()->vertex();
		Point_3 lp = lvh->point();
		Point_3 rp = rvh->point();
		int il = cutPlane.oriented_side(lp);
		int ir = cutPlane.oriented_side(rp);
		int tmp = il*ir;
		if ( tmp<0)//异侧
		{
			Halfedge_handle lrhh = hc->next()->next();
			if (lrhh->tag()==nthTarget)//在找这次的target的过程中已经用过了
			{
				continue;
			}
			else
			{
				lrhh->tag(nthTarget);
				lrhh->opposite()->tag(nthTarget);
			}

			if ( c_vh == center )
			{
				optimal_start_spoke = hc;// ++optimal_start_spoke;
			}

			Point_3 cp = compute_cross_point(cutPlane,lp,rp);
			cross_points.push_back(cp);
			
			c_hh = hc->next()->next()->opposite();
			c_vh = 0;
			result = true;
			break;
		}
		else if(tmp>0)//同侧
		{
			continue;
		}

		if (ir)//lp is on the cut plane
		{		
			if (lvh->tag()==nthTarget)//在找这次的target的过程中已经用过了
			{
				continue;
			}
			else
			{
				lvh->tag(nthTarget);
			}
			if ( c_vh == center)
			{
				optimal_start_spoke = hc;// ++optimal_start_spoke;
			}
			c_vh = lvh;			
		}
		else
		{	
			if (rvh->tag()==nthTarget)//在找这次的target的过程中已经用过了
			{
				continue;
			}
			else
			{
				rvh->tag(nthTarget);
			}
			if ( c_vh == center)
			{
				optimal_start_spoke = hc; ++optimal_start_spoke; //++optimal_start_spoke;
			}
			c_vh = rvh;			
		}				
		cross_points.push_back(c_vh->point());
		c_hh = 0;
		result = true;
		break;
	}
/* FIXME: Copied from Polyhedron_io.cpp with slight modifications. */
static std::shared_ptr<Polyhedron> convertWithAssociation(Polyhedron_3 p,
		const Point_3 &C, const std::vector<Plane_3> &initPlanes)
{
	/* Check for non-emptiness. */
	ASSERT(p.size_of_vertices());
	ASSERT(p.size_of_facets());

	int numVertices = p.size_of_vertices();
	int numFacets = p.size_of_facets();

	/* Allocate memory for arrays. */
	Vector3d *vertices = new Vector3d[numVertices];
	Facet *facets = new Facet[numFacets];

	/* Transform vertexes. */
	int iVertex = 0;
	for (auto vertex = p.vertices_begin(); vertex != p.vertices_end(); ++vertex)
	{
		Point_3 point = C + vertex->point();
		vertices[iVertex++] = Vector3d(point.x(), point.y(), point.z());
	}

	/*
	 * Transform facets.
	 * This algorithm is based on example kindly provided at CGAL online user
	 * manual. See example Polyhedron/polyhedron_prog_off.cpp
	 */
	int iFacet = 0;
	auto plane = p.planes_begin();
	auto facet = p.facets_begin();
	/* Iterate through the std::lists of planes and facets. */
	do
	{
		int id = p.indexPlanes_[iFacet];

		facets[id].id = id;

		/* Transform current plane. */
		Plane_3 pi = centerizePlane(*plane,
				Point_3(-C.x(), -C.y(), -C.z()),
				signedDist(initPlanes[id], C));
		facets[id].plane = Plane(Vector3d(pi.a(), pi.b(), pi.c()),
				pi.d());

		/*
		 * Iterate through the std::list of halfedges incident to the curent CGAL
		 * facet.
		 */
		auto halfedge = facet->facet_begin();

		/* Facets in polyhedral surfaces are at least triangles. 	*/
		CGAL_assertion(CGAL::circulator_size(halfedge) >= 3);

		facets[id].numVertices = CGAL::circulator_size(halfedge);
		facets[id].indVertices =
			new int[3 * facets[id].numVertices + 1];
		/*
		 * TODO: It's too unsafe architecture if we do such things as setting
		 * the size of internal array outside the API functions. Moreover, it
		 * can cause us to write memory leaks.
		 * indFacets and numFacets should no be public members.
		 */

		int iFacetVertex = 0;
		do
		{
			facets[id].indVertices[iFacetVertex++] =
				std::distance(p.vertices_begin(), halfedge->vertex());
		} while (++halfedge != facet->facet_begin());

		/* Add cycling vertex to avoid assertion during printing. */
		facets[id].indVertices[facets[id].numVertices] =
			facets[id].indVertices[0];

		ASSERT(facets[id].correctPlane());

		/* Increment the ID of facet. */
		++iFacet;

	} while (++plane != p.planes_end() && ++facet != p.facets_end());

	return std::make_shared<Polyhedron>(numVertices, numFacets, vertices,
			facets);
}
static double signedDist(const Plane_3 &p, const Point_3 &C)
{
	return p.a() * C.x() + p.b() * C.y() + p.c() * C.z() + p.d();
}
예제 #14
0
float
sdf( const Point& q, const Mesh &mesh, const vector<double>& weights,
     KdTree& kd_tree, const Triangulation& triang )
{
  VECTOR3 query (CGAL::to_double(q.x()),
                 CGAL::to_double(q.y()),
                 CGAL::to_double(q.z()));
  kd_tree.queryPosition(query);
  // Initialize the search structure, and search all N points
  int n_vid = kd_tree.getNeighbourPositionIndex(0);
  if(n_vid == -1) throw std::runtime_error("No nearest neighbor. MDS empty?");
  CGAL_assertion( ! mesh.vert_list[n_vid].iso());
  MVertex nv = mesh.vert_list[n_vid];
  double min_sq_d = HUGE;
  int n_fid = -1;
  for(int i = 0; i < nv.num_inc_face; i ++)
  {
     MFace f = mesh.face_list[nv.inc_face(i)];
     Point p[3] = {mesh.vert_list[f.get_corner(0)].point(),
                   mesh.vert_list[f.get_corner(1)].point(),
                   mesh.vert_list[f.get_corner(2)].point()};
     Triangle_3 t (p[0], p[1], p[2]);
     Plane_3 H (p[0], p[1], p[2]);
     Point _q = H.projection(q);
     // check if _q is inside t.
     if( t.has_on(_q) )
     {
        double sq_d = CGAL::to_double((q-_q)*(q-_q));
        if( sq_d < min_sq_d ) { min_sq_d = sq_d; n_fid = nv.inc_face(i); }
     }
     else
     {
        for(int j = 0; j < 3; j ++)
        {
           double _d = CGAL::to_double(CGAL::squared_distance(_q,Segment(p[j], p[(j+1)%3])));
           double sq_d = CGAL::to_double((q-_q)*(q-_q)) + _d;
           if( sq_d < min_sq_d ) { min_sq_d = sq_d; n_fid = nv.inc_face(i); }
        }
     }
  }

  // locate the query point in the triang which is already tagged
  // with in-out flag by the reconstruction.
  bool is_q_outside = false;
  Triangulation::Locate_type lt;
  int u = -1, v = -1;
  Cell_handle c = triang.locate(q, lt, u, v);
  if( lt == Triangulation::OUTSIDE_AFFINE_HULL )
  {
     is_q_outside = true;
     cerr << "Point " << q << " is outside the affine hull." << endl;
  }
  else if( lt == Triangulation::OUTSIDE_CONVEX_HULL )
     is_q_outside = true;
  else
  {
     if( lt == Triangulation::CELL )
     {
        if( c->outside )
           is_q_outside = true;
        else
           is_q_outside = false;
     }
     else if( lt == Triangulation::FACET )
     {
        Cell_handle _c = c->neighbor(u);
        if( c->outside && _c->outside )
           is_q_outside = true;
        else
           is_q_outside = false;
     }
     else if( lt == Triangulation::EDGE )
     {
        if( is_outside_VF(triang, Edge(c, u, v)) )
           is_q_outside = true;
        else
           is_q_outside = false;
     }
     else
     {
        CGAL_assertion( lt == Triangulation::VERTEX );
        is_q_outside = false;
     }
  }

  double w;
  if(weights.size() && mesh.face_list[n_fid].label != -1) w = weights[mesh.face_list[n_fid].label];
  else w = 1.0;
  // double w = mesh.face_list[n_fid].w;

  double gen_sdf = 0;
  if( is_q_outside ) gen_sdf = w*sqrt(min_sq_d);
  else gen_sdf = -w*min_sq_d;

#if 0
  double MAX = 10, MIN = -10;

  if( gen_sdf > MAX ) gen_sdf = MAX;
  if( gen_sdf < MIN ) gen_sdf = MIN;
#endif
  return gen_sdf;
}