void flip_edge( Polyhedron& P, Halfedge_handle e) {
    if ( e->is_border_edge())
        return;
    Halfedge_handle h = e->next();
    P.join_facet( e);
    P.split_facet( h, h->next()->next());
}
Exemple #2
0
void two_tetrahedrons()
{
  Polyhedron a;

  make_tetrahedron(a, 
                   Point(1.0, 0.0, 0.0),
                   Point(2.0, 0.0, 0.0),
                   Point(1.5, 1.0, 0.0),
                   Point(1.5, .5, 10.0));

  Polyhedron b;
  make_tetrahedron(b,
                   Point(0.0, 0., .5),
                   Point(0.0, 0.0, 1.5),
                   Point(0.0, 1.0, 1.0),
                   Point(10.0, .5, 1.0));

  if (a.is_pure_triangle())
    std::cout << "a is pure triangle" << std::endl;

  if (b.is_pure_triangle())
    std::cout << "b is pure triangle" << std::endl;

  Polyhedron &biggest = a.size_of_facets() > b.size_of_facets() ? a : b;
  Polyhedron &smallest = a.size_of_facets() > b.size_of_facets() ? b : a;

  std::list<std::list<boost::tuple<Facet_handle, Facet_handle, Segment> > > polylines;
  {
    std::list<boost::tuple<Facet_handle, Facet_handle, Segment> > intersections;
    compute_intersections(biggest, smallest, std::back_inserter(intersections));

    for (std::list<boost::tuple<Facet_handle, Facet_handle, Segment> >::iterator it = intersections.begin();
         it != intersections.end(); it++)
    {
      {
        Halfedge_handle h = it->get<0>()->halfedge();
        Triangle t(h->vertex()->point(), h->next()->vertex()->point(), h->next()->next()->vertex()->point());
        assert(t.has_on(it->get<2>().source()));
        assert(t.has_on(it->get<2>().target()));
      }
      {
        Halfedge_handle h = it->get<1>()->halfedge();
        Triangle t(h->vertex()->point(), h->next()->vertex()->point(), h->next()->next()->vertex()->point());
        assert(t.has_on(it->get<2>().source()));
        assert(t.has_on(it->get<2>().target()));
      }
    }
    sort_polylines<Polyhedron>(biggest, smallest, intersections, polylines);
  }

  std::list<std::vector<typename Polyhedron::Halfedge_handle> > intersection_list;

  split_facets<Polyhedron, 0>(biggest,  polylines, intersection_list);
  //split_facets<Polyhedron, 1>(smallest, polylines);

}
// Récupère la liste de tous les points d'une face
std::vector<Point_3> DegradeAnObject::getAllPointsFromFacet(Facet f) {
	std::vector<Point_3> pts;
	Halfedge_handle hh = f.halfedge();
	pts.push_back(hh->vertex()->point());
	hh = hh->next();
	while(hh->vertex()->point() != pts[0]) {
		pts.push_back(hh->vertex()->point());
		hh = hh->next();
	}
	return pts;
}
void DegradeAnObject::splitEdgesOfFacet(Facet fs, int index) {
	Halfedge_handle hh = fs.halfedge();
	Point_3 p1 = hh->vertex()->point();
	Point_3 p2 = hh->next()->vertex()->point();
	Point_3 p3 = hh->next()->next()->vertex()->point();
	Halfedge_handle hh1 = polys[index].split_edge(hh);
	hh1->vertex()->point() = meanPoints(p1, p3);
	hh = hh->next();
	Halfedge_handle hh2 = polys[index].split_edge(hh);
	hh2->vertex()->point() = meanPoints(p2, p1);
	hh = hh->next();
	Halfedge_handle hh3 = polys[index].split_edge(hh);
	hh3->vertex()->point() = meanPoints(p2, p3);
}
void trisect_border_halfedge( Polyhedron& P, Halfedge_handle e) {
    CGAL_precondition( e->is_border());
    // Create two new vertices on e.
    e = e->prev();
    P.split_vertex( e, e->next()->opposite());
    P.split_vertex( e, e->next()->opposite());
    e = e->next();
    // We use later for the smoothing step that e->next()->next()
    // is our original halfedge we started with, i.e., its vertex is
    // from the unrefined mesh.  Split the face twice.
    Halfedge_handle h = e->opposite()->next();
    P.split_facet( e->next()->next()->opposite(), h);
    P.split_facet( e->next()->opposite(), h);
}
Halfedge_handle DegradeAnObject::barycentricMesh(Facet fs, int index) {
	std::vector<Point_3> points;
	Halfedge_handle hh = fs.halfedge();
	Point_3 p1 = hh->vertex()->point();
	points.push_back(p1);
	hh = hh->next();
	while(hh->vertex()->point() != p1) {
		points.push_back(hh->vertex()->point());
		hh = hh->next();
	}
	Halfedge_handle h = polys[index].create_center_vertex(fs.halfedge());
	h->vertex()->point() = meanPoints(points);
	return h;
}
// Relie le premier et le dernier point
Halfedge_handle DegradeAnObject::joinFirstAndLast(Point_3 p1, Point_3 p2, int index, std::vector<Point_3> & pts) {
	Halfedge_handle hh;
	bool chk = false;
	std::vector<Facet> fcts;
	std::vector<int> indexes;
	Halfedge_handle prevHalf;
	Facet fs;
	getFacetsFromPoint(p1, fcts, indexes);
	for(int i = 0 ; i < fcts.size() ; i++) {
		if(twoPointsOnTheFacet(p1, p2, fcts[i], index)) {
			chk = true;
		}
	}
	if(!chk) {
		fcts.clear();
		Segment_3 s(p1, p2);
		getFacetsFromPoint(p2, fcts, indexes);
		hh = getExteriorHalfedge(p2, s, fcts);
		Halfedge_handle previousHalfedge = hh->next();
		Halfedge_handle newEdge = addAndJoinNewPoint(p2, previousHalfedge, hh, s, index);
		pts.push_back(newEdge->vertex()->point());
		prevHalf = joinFirstAndLast(p1, newEdge->vertex()->point(), index, pts);
	}
	
	return prevHalf;
}
//Description : Gives an area of the triangle which contain the halfedge_handle h
double Area_Facet_Triangle(const Halfedge_handle &h)
{

	Point3d P = h->vertex()->point();
	Point3d Q = h->next()->vertex()->point();
	Point3d R = h->next()->next()->vertex()->point();

	Vector PQ=Q-P;
        //Vector PR=R-P; // MT
	Vector QR=R-Q;

	Vector normal =	CGAL::cross_product(PQ,QR);
	double area=0.5*sqrt(normal*normal);

	return area;
}
// Dessine la couronne intérieure
std::vector<Point_3> DegradeAnObject::drawInsideImpactOnFacet(std::vector<Point_3> points, std::vector<Halfedge_handle> hhs, Facet f, int index) {
	std::vector<Point_3> pts;
	for(int i = 0 ; i < points.size() ; i++) {
		int j;
		if(i == points.size()-1) {
			j = 0;
		}
		else {
			j = i+1;
		}
		Vector_3 h(hhs[i]->opposite()->vertex()->point(), hhs[i]->vertex()->point());
		Vector_3 g(hhs[j]->opposite()->vertex()->point(), hhs[j]->vertex()->point());
		Vector_3 norm = getNormalOfFacet(f);
		Vector_3 rh = normalizeVector(rotationVector(h, norm, M_PI/2));
		Vector_3 rg = normalizeVector(rotationVector(g, norm, M_PI/2));
		Vector_3 comb = 0.01*normalizeVector(rh+rg);
		Point_3 newPoint = hhs[i]->vertex()->point() + comb;
		Halfedge_handle hh = polys[index].split_vertex(hhs[j]->opposite(), hhs[i]);
		hh->vertex()->point() = newPoint;
		polys[index].split_facet(hh->opposite()->next()->next(), hh->opposite());
		polys[index].split_facet(hh->next()->next(), hh);
		pts.push_back(newPoint);
	}
	return pts;
}
Exemple #10
0
void two_boxes()
{
  Polyhedron a;
  make_box(0,0,0, 4, 5, 2, a);

  Polyhedron b;
  make_box(1, 1, -1, 2, 2, 1, b);

  if (a.is_pure_triangle())
    std::cout << "a is pure triangle" << std::endl;

  if (b.is_pure_triangle())
    std::cout << "b is pure triangle" << std::endl;

  Polyhedron &biggest = a.size_of_facets() > b.size_of_facets() ? a : b;
  Polyhedron &smallest = a.size_of_facets() > b.size_of_facets() ? b : a;

  std::list<std::list<boost::tuple<Facet_handle, Facet_handle, Segment> > > polylines;
  {
    std::list<boost::tuple<Facet_handle, Facet_handle, Segment> > intersections;
    compute_intersections(biggest, smallest, std::back_inserter(intersections));

    for (std::list<boost::tuple<Facet_handle, Facet_handle, Segment> >::iterator it = intersections.begin();
         it != intersections.end(); it++)
    {
      {
        Halfedge_handle h = it->get<0>()->halfedge();
        Triangle t(h->vertex()->point(), h->next()->vertex()->point(), h->next()->next()->vertex()->point());
        assert(t.has_on(it->get<2>().source()));
        assert(t.has_on(it->get<2>().target()));
      }
      {
        Halfedge_handle h = it->get<1>()->halfedge();
        Triangle t(h->vertex()->point(), h->next()->vertex()->point(), h->next()->next()->vertex()->point());
        assert(t.has_on(it->get<2>().source()));
        assert(t.has_on(it->get<2>().target()));
      }
    }
    sort_polylines<Polyhedron>(biggest, smallest, intersections, polylines);
  }

  std::list<std::vector<Halfedge_handle> > a_edges;
  split_facets<Polyhedron, 0>(biggest, polylines, a_edges);
  check_splitting<Polyhedron, 0>(biggest, polylines, a_edges);
  //split_facets<Polyhedron, 1>(smallest, /* smallest, */ polylines);
}
//Description : Gives a normal vector of the triangle which contain the halfedge_handle h
Vector Triangle_Normal(const Halfedge_handle &h)
{
	Point3d P = h->vertex()->point();
	Point3d Q = h->next()->vertex()->point();
	Point3d R = h->next()->next()->vertex()->point();

	Vector PQ=Q-P;
        //Vector PR=R-P; // MT
	Vector QR=R-Q;

	Vector normal = CGAL::cross_product(PQ,QR);
	double length = std::sqrt(normal*normal);
	if (length != 0.0)
		normal = normal / length;

	return normal;
}
Halfedge_handle DegradeAnObject::addAndJoinNewPoint(Point_3 p, Halfedge_handle previousHalfedge, Halfedge_handle hh, Segment_3 s, int index) {
	Point_3 intersect;
	Halfedge_handle splittedHalfedge;
	Segment_3 seg(hh->opposite()->vertex()->point(), hh->vertex()->point());
	Point_3* chkPt; 
	CGAL::cpp11::result_of<Kernel::Intersect_3(Segment_3, Segment_3)>::type result = CGAL::intersection(s, seg);
	if (result) {
		chkPt = boost::get<Point_3 >(&*result);
		intersect = *chkPt;
	}
	Halfedge_handle split = splitEdge(hh, intersect, index);
	Halfedge_handle hhx = polys[index].split_facet(previousHalfedge, split);
	Halfedge_handle oppositePoint = hhx->next()->opposite();
	polys[index].split_facet(oppositePoint, oppositePoint->next()->next());
	
	return oppositePoint;
}
// Casse les arêtes d'une face triangulaire en 2 et les place au centre de son arête. Retourne la liste des pointeurs de ce point
std::vector<Halfedge_handle> DegradeAnObject::splitEdgesOfFacet(Facet fs, int index) {
	Halfedge_handle hh = fs.halfedge();
	std::vector<Halfedge_handle> hhs;
	Point_3 p1 = hh->vertex()->point();
	Point_3 p2 = hh->next()->vertex()->point();
	Point_3 p3 = hh->next()->next()->vertex()->point();
	Halfedge_handle hh1 = polys[index].split_edge(hh);
	hh1->vertex()->point() = meanPoints(p1, p3);
	hhs.push_back(hh1);
	hh = hh->next();
	Halfedge_handle hh2 = polys[index].split_edge(hh);
	hh2->vertex()->point() = meanPoints(p2, p1);
	hhs.push_back(hh2);
	hh = hh->next();
	Halfedge_handle hh3 = polys[index].split_edge(hh);
	hh3->vertex()->point() = meanPoints(p2, p3);
	hhs.push_back(hh3);
	return hhs;
}
void smooth_border_vertices( Halfedge_handle e, OutputIterator out) {
    CGAL_precondition( e->is_border());
    // We know that the vertex at this edge is from the unrefined mesh.
    // Get the locus vectors of the unrefined vertices in the neighborhood.
    Vector v0 = e->prev()->prev()->opposite()->vertex()->point() -CGAL::ORIGIN;
    Vector v1 = e->vertex()->point() - CGAL::ORIGIN;
    Vector v2 = e->next()->next()->next()->vertex()->point() - CGAL::ORIGIN;
    *out++ = CGAL::ORIGIN + (10.0 * v0 + 16.0 * v1 +        v2) / 27.0;
    *out++ = CGAL::ORIGIN + ( 4.0 * v0 + 19.0 * v1 +  4.0 * v2) / 27.0;
    *out++ = CGAL::ORIGIN + (       v0 + 16.0 * v1 + 10.0 * v2) / 27.0;
}
//Description :: Check if removal of this vertex would violate the manifold_property or not.
bool Check_Manifold_Property(Halfedge_handle h, const int &type,const int &valence)
{
	bool check = false;
	Halfedge_handle g = h;
	int* Points_index = new int[valence];

	// if valence is 3, no new edge is inserted, so always safe to remove.
	if(valence == 3)
	{
		return false;
	}

	else
	{
		// Points_index[] contains all boundary vertices' indices (ordered in counterclockwise)

		Points_index[0] = g->vertex()->Vertex_Number_S;
		g = g->next(); // g points center vertex;

		for(int i=1; i<valence; i++)
		{
			g = g->prev_on_vertex();// around the vertex in the counterclockwise way.
			Points_index[i] = g->opposite()->vertex()->Vertex_Number_S;
		}

		// quadrangle
		if (valence == 4)
		{
			if ((type == 5) || (type == 8))
			{
				g = h->opposite();
				Halfedge_around_vertex_circulator Hvc = g->vertex_begin();
				Halfedge_around_vertex_circulator Hvc_end = Hvc;

				CGAL_For_all(Hvc,Hvc_end)
				{
					if (Hvc->opposite()->vertex()->Vertex_Number_S == Points_index[1])
						check = true;
				}
			}

			else if (( type == 6) || (type == 7))
			{
				g = h;
				Halfedge_around_vertex_circulator Hvc = g->vertex_begin();
				Halfedge_around_vertex_circulator Hvc_end = Hvc;

				CGAL_For_all(Hvc,Hvc_end)
				{
					if (Hvc->opposite()->vertex()->Vertex_Number_S == Points_index[2])
						check = true;;
				}

			}
// Recherche les halfedges des - facets du point - qui ne contiennent pas le point
Halfedge_handle DegradeAnObject::getExteriorHalfedge(Point_3 p, Segment_3 s, std::vector<Facet> fcts) {
	Halfedge_handle retHh;
	for(int i = 0 ; i < fcts.size() ; i++) {
		Halfedge_handle hh = fcts[i].halfedge();
		for(int j = 0 ; j < 3 ; j++) {
			if(hh->vertex()->point() != p && hh->opposite()->vertex()->point() != p) {
				Segment_3 seg(hh->opposite()->vertex()->point(), hh->vertex()->point());
				if(!seg.is_degenerate()) {
					if(CGAL::do_intersect(s, seg)) {
						retHh = hh;
					}
				}
			}
			hh = hh->next();
		}
	}
	return retHh;
}
Exemple #17
0
void gnuplot_print_faces_2(std::ostream& out,
                           CGAL::Straight_skeleton_2<Kernel>::Face_iterator faces_begin,
                           CGAL::Straight_skeleton_2<Kernel>::Face_iterator faces_end)
{
    typedef CGAL::Straight_skeleton_2<Kernel> Ss;
    typedef Ss::Face_iterator Face_iterator;
    typedef Ss::Halfedge_handle   Halfedge_handle;
    typedef Ss::Vertex_handle     Vertex_handle;

    for (Face_iterator fi = faces_begin; fi != faces_end; ++fi)
    {
        Halfedge_handle halfedge = fi->halfedge();
        Halfedge_handle first = halfedge;
        do
        {
            Vertex_handle s = halfedge->opposite()->vertex();
            Vertex_handle t = halfedge->vertex();
            const Point_2& sp(s->point());
            const Point_2& tp(t->point());
            sp.insert(out) << endl;
            tp.insert(out) << endl;
//       out << sp << endl;
//       out << tp << endl;
            out << endl << endl;

//       // Add polygon vertices to triangulation
//       CDT::Vertex_handle ds = cdt.insert(s->point());
//       CDT::Vertex_handle dt = cdt.insert(t->point());
//       ds->info() = s->is_contour();
//       dt->info() = t->is_contour();
//       cdt.insert_constraint(ds, dt);

            halfedge = halfedge->next();
        } while (halfedge != first);
    }
}
// Relie 2 points dans un polyèdre. p2 est le point PRECEDENT à p1.
Halfedge_handle DegradeAnObject::joinTwoPoints(Point_3 p1, Point_3 p2, int index, std::vector<Point_3> & pts) {
	Halfedge_handle hh;
	std::vector<Facet> fcts;
	std::vector<int> indexes;
	Halfedge_handle prevHalf;
	Facet fs;
	getFacetFromPoint(p1, fs, index);
	if(twoPointsOnTheFacet(p1, p2, fs, index)) {
		prevHalf = putAPointOnAFacet(p1, index);
		pts.push_back(prevHalf->vertex()->point());
	}
	else {
		fcts.clear();
		Segment_3 s(p1, p2);
		getFacetsFromPoint(p2, fcts, indexes);
		hh = getExteriorHalfedge(p2, s, fcts);
		Halfedge_handle previousHalfedge = hh->next();
		Halfedge_handle newEdge = addAndJoinNewPoint(p2, previousHalfedge, hh, s, index);
		pts.push_back(newEdge->vertex()->point());
		prevHalf = joinTwoPoints(p1, newEdge->vertex()->point(), index, pts);
	}
	
	return prevHalf;
}
void geometryUtils::subdivide_flip_edge(Polyhedron& P, Halfedge_handle e) {
    Halfedge_handle h = e->next();
    P.join_facet(e);
    P.split_facet(h, h->next()->next());
}
void Boolean_Operations_Component::SubdiviserPolyedre(PolyhedronPtr pMesh)
{
	//Each facet must be triangular
	if(!pMesh->is_pure_triangle())
	{
		pMesh->triangulate();
		return;
	}
	
	Facet_iterator pFacet;
	Vector Vcenter;

	//Initialization of the tags
	for (pFacet = pMesh->facets_begin(); pFacet != pMesh->facets_end(); pFacet++)
	{
		Halfedge_around_facet_circulator pHEcirc = pFacet->facet_begin();
		pFacet->Issub = false;
		pHEcirc->Isnew = false;
		pHEcirc->vertex()->Isnew = false;
		pHEcirc++;
		pHEcirc->Isnew = false;
		pHEcirc->vertex()->Isnew = false;
		pHEcirc++;
		pHEcirc->Isnew = false;
		pHEcirc->vertex()->Isnew = false;
	}
	//For each facet of the polyhedron
	for (pFacet = pMesh->facets_begin(); pFacet != pMesh->facets_end(); pFacet++)
	{
		//We subdivide the facet if it is not already done
		if(!(pFacet->Issub))
		{
			Halfedge_handle pHE = pFacet->facet_begin();
			for(unsigned int i = 0;i!=5;i++)
			{
				if(!pHE->Isnew)
				{
					//each edge is splited in its center
					Vcenter = Vector(0.0, 0.0, 0.0);
					Vcenter = ( (pHE->vertex()->point() - CGAL::ORIGIN) + (pHE->opposite()->vertex()->point() - CGAL::ORIGIN) ) / 2;
					pHE = pMesh->split_edge(pHE);
					pHE->vertex()->point() = CGAL::ORIGIN + Vcenter;
					//update of the tags (the new vertex and the four new halfedges
					pHE->vertex()->Isnew = true;
					pHE->Isnew = true;
					pHE->opposite()->Isnew = true;
					pHE->next()->Isnew = true;
					pHE->next()->opposite()->Isnew = true;
				}
				pHE = pHE->next();
			}
			//Three new edges are build between the three new vertices, and the tags of the facets are updated
			if(!pHE->vertex()->Isnew) pHE = pHE->next();
			pHE = pMesh->split_facet(pHE, pHE->next()->next());
			pHE->opposite()->facet()->Issub = true;
			pHE = pMesh->split_facet(pHE, pHE->next()->next());
			pHE->opposite()->facet()->Issub = true;
			pHE = pMesh->split_facet(pHE, pHE->next()->next());
			pHE->opposite()->facet()->Issub = true;
			pHE->facet()->Issub = true;
		}
	}
}
typename Poly::Halfedge_handle make_cube_3( Poly& P) {
    // appends a cube of size [0,1]^3 to the polyhedron P.
    CGAL_precondition( P.is_valid());
    typedef typename Poly::Point_3         Point;
    typedef typename Poly::Plane_3         Plane;
    typedef typename Poly::Halfedge_handle Halfedge_handle;
    Halfedge_handle h = P.make_tetrahedron( Point( 1, 0, 0),
                                            Point( 0, 0, 1),
                                            Point( 0, 0, 0),
                                            Point( 0, 1, 0));
    Halfedge_handle g = h->next()->opposite()->next();
    P.split_edge( h->next());
    P.split_edge( g->next());
    P.split_edge( g);
    h->next()->vertex()->point()     = Point( 1, 0, 1);
    g->next()->vertex()->point()     = Point( 0, 1, 1);
    g->opposite()->vertex()->point() = Point( 1, 1, 0);
    Halfedge_handle f = P.split_facet( g->next(), g->next()->next()->next());
    Halfedge_handle e = P.split_edge( f);
    e->vertex()->point() = Point( 1, 1, 1);
    P.split_facet( e, f->next()->next());
    CGAL_postcondition( P.is_valid());
    g = h;
    g->facet()->plane() = Plane( g->vertex()->point(),
                                 g->next()->vertex()->point(),
                                 g->next()->next()->vertex()->point());
    g = h->opposite();
    g->facet()->plane() = Plane( g->vertex()->point(),
                                 g->next()->vertex()->point(),
                                 g->next()->next()->vertex()->point());
    g = h->next()->opposite();
    g->facet()->plane() = Plane( g->vertex()->point(),
                                 g->next()->vertex()->point(),
                                 g->next()->next()->vertex()->point());
    g = h->next()->next()->opposite();
    g->facet()->plane() = Plane( g->vertex()->point(),
                                 g->next()->vertex()->point(),
                                 g->next()->next()->vertex()->point());
    g = h->next()->next()->next()->opposite();
    g->facet()->plane() = Plane( g->vertex()->point(),
                                 g->next()->vertex()->point(),
                                 g->next()->next()->vertex()->point());
    g = g->next()->next()->opposite();
    g->facet()->plane() = Plane( g->vertex()->point(),
                                 g->next()->vertex()->point(),
                                 g->next()->next()->vertex()->point());
    return h;
}
Exemple #22
0
void test_HalfedgeDS_decorator2() {
    // Instantiation of the halfedge data structure using vector
    // with max-bases for a polyhedral surface.
    typedef CGAL::HalfedgeDS_vector< Dummy_traits_3,
                                           CGAL::Polyhedron_items_3> HDS;
    typedef CGAL::HalfedgeDS_decorator<HDS> Decorator;
    typedef HDS::Halfedge_handle            Halfedge_handle;
    typedef HDS::Face_handle                Face_handle;
    HDS hds(4,10,3);
    Decorator  decorator(hds);
    // Check create single loop.
    Halfedge_handle h = decorator.create_loop();
    hds.normalize_border();
    assert( hds.size_of_vertices() == 1);
    assert( hds.size_of_halfedges() == 2);
    assert( hds.size_of_faces() == 2);
    assert( decorator.is_valid( false, 4));

    // Restart with open segment.
    hds.clear();
    hds.normalize_border();
    assert( decorator.is_valid( false, 4));
    h = decorator.create_segment();
    assert( hds.size_of_vertices() == 2);
    assert( hds.size_of_halfedges() == 2);
    assert( hds.size_of_faces() == 1);
    assert( decorator.is_valid( false, 3));
    hds.normalize_border();
    assert( decorator.is_valid( false, 4));

    // Create border edge and check normalization.
    decorator.set_face( h->opposite(), Face_handle());
    hds.normalize_border();
    assert( hds.size_of_border_halfedges() == 1);
    assert( hds.size_of_border_edges() == 1);
    assert( decorator.normalized_border_is_valid());
    decorator.set_face( h->opposite(), h->face());
    hds.normalize_border();
    assert( hds.size_of_border_halfedges() == 0);
    assert( hds.size_of_border_edges() == 0);
    assert( decorator.is_valid( false, 4));

    // Extend edge to two triangles.
    Halfedge_handle g = decorator.split_vertex( h, h);
    assert( decorator.is_valid( false, 3));
    hds.normalize_border();
    assert( decorator.is_valid( false, 4));
    assert( h != g);
    assert( h->next()->next() == g);
    assert( h == g->next()->next());
    assert( h->opposite() == g->next());
    assert( g->opposite() == h->next());
    Halfedge_handle g2 = decorator.split_face(h->opposite(),g->opposite());
    hds.normalize_border();
    assert( decorator.is_valid( false, 4));
    assert( h->opposite()->next() == g2);
    assert( g2->next() == g);
    decorator.split_vertex( g2, g->opposite());
    assert( decorator.is_valid( false, 3));
    hds.normalize_border();
    assert( decorator.is_valid( false, 4));
    assert( g->next()->next()->next()->next() == g);
    Halfedge_handle g3 = 
        decorator.split_face( g2->next()->opposite(), h);
    hds.normalize_border();
    assert( decorator.is_valid( false, 4));
    assert( g->next()->next()->next()->next() == g);
    assert( h->next()->next()->next() == h);
    assert( g3->next()->next()->next() == g3);
    assert( g3->next() == g->opposite());
    assert( g3->opposite()->next() == g2->opposite());
    assert( g3->opposite() == h->next());

    // Edge flip within the triangle.
    Halfedge_handle g4 = decorator.flip_edge( g3);
    assert( decorator.is_valid( false, 3));
    hds.normalize_border();
    assert( decorator.is_valid( false, 4));
    assert( g4 == g3);
    assert( g3->next()->next() == g2->opposite());
    assert( g3->opposite()->next() == h);
    assert( g->next()->next()->next()->next() == g);
    assert( h->next()->next()->next() == h);
    assert( g3->next()->next()->next() == g3);

    // Reverse face orientation.
    decorator.inside_out();
    assert( decorator.is_valid( false, 4));
}
Exemple #23
0
void test_HalfedgeDS_decorator() {
    // Simple instantiation of the default halfedge data structure.
    typedef CGAL_HALFEDGEDS_DEFAULT<Dummy_traits_2>  HDS;
    typedef CGAL::HalfedgeDS_decorator<HDS>          Decorator;
    typedef HDS::Halfedge_handle                     Halfedge_handle;
    typedef HDS::Face_handle                         Face_handle;
    HDS hds;
    Decorator  decorator(hds);
    // Check create single loop.
    Halfedge_handle h = decorator.create_loop();
    hds.normalize_border();
    assert( hds.size_of_vertices() == 1);
    assert( hds.size_of_halfedges() == 2);
    assert( hds.size_of_faces() == 2);
    assert( decorator.is_valid( false, 4));

    // Restart with open segment.
    hds.clear();
    hds.normalize_border();
    assert( decorator.is_valid( false, 4));
    h = decorator.create_segment();
    assert( hds.size_of_vertices() == 2);
    assert( hds.size_of_halfedges() == 2);
    assert( hds.size_of_faces() == 1);
    assert( decorator.is_valid( false, 4));

    // Create border edge and check normalization.
    decorator.set_face( h->opposite(), Face_handle());
    hds.normalize_border();
    assert( hds.size_of_border_halfedges() == 1);
    assert( hds.size_of_border_edges() == 1);
    assert( decorator.normalized_border_is_valid());
    decorator.set_face( h->opposite(), h->face());
    hds.normalize_border();
    assert( hds.size_of_border_halfedges() == 0);
    assert( hds.size_of_border_edges() == 0);
    assert( decorator.is_valid( false, 4));

    // Extend edge to two triangles.
    Halfedge_handle g = decorator.split_vertex( h, h);
    assert( decorator.is_valid( false, 4));
    assert( h != g);
    assert( h->next()->next() == g);
    assert( h == g->next()->next());
    assert( h->opposite() == g->next());
    assert( g->opposite() == h->next());
    Halfedge_handle g2 = decorator.split_face(h->opposite(),g->opposite());
    assert( decorator.is_valid( false, 4));
    assert( h->opposite()->next() == g2);
    assert( g2->next() == g);
    decorator.split_vertex( g2, g->opposite());
    assert( decorator.is_valid( false, 4));
    assert( g->next()->next()->next()->next() == g);
    Halfedge_handle g3 = 
        decorator.split_face( g2->next()->opposite(), h);
    assert( decorator.is_valid( false, 4));
    assert( g->next()->next()->next()->next() == g);
    assert( h->next()->next()->next() == h);
    assert( g3->next()->next()->next() == g3);
    assert( g3->next() == g->opposite());
    assert( g3->opposite()->next() == g2->opposite());
    assert( g3->opposite() == h->next());

    // Edge flip within the triangle.
    Halfedge_handle g4 = decorator.flip_edge( g3);
    assert( decorator.is_valid( false, 4));
    assert( g4 == g3);
    assert( g3->next()->next() == g2->opposite());
    assert( g3->opposite()->next() == h);
    assert( g->next()->next()->next()->next() == g);
    assert( h->next()->next()->next() == h);
    assert( g3->next()->next()->next() == g3);

    // Reverse face orientation.
    decorator.inside_out();
    assert( decorator.is_valid( false, 4));
    decorator.inside_out();
    assert( decorator.is_valid( false, 4));

    // Check hole manipulations.
    decorator.make_hole(g);
    hds.normalize_border();
    assert( hds.size_of_border_halfedges() == 4);
    assert( hds.size_of_border_edges() == 4);
    assert( decorator.is_valid( false, 4));

    // Reverse face orientation, deal also with the hole..
    decorator.inside_out();
    assert( decorator.is_valid( false, 3));
    hds.normalize_border();
    assert( decorator.is_valid( false, 4));

    // Check add_face_to_border.
    hds.clear();
    h = decorator.create_loop();
    decorator.make_hole( h->opposite());
    hds.normalize_border();
    assert( decorator.is_valid( false, 4));
    decorator.add_face_to_border( h->opposite(), h->opposite());
    assert( hds.size_of_halfedges() == 4);
    assert( hds.size_of_faces() == 2);
    assert( decorator.is_valid( false, 3));
}