// 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; }
//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;; } }
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; }
// 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; }
void Convert ( OffSurface_mesh& off, char const* gts_name ) { std::ofstream gts(gts_name); if ( gts ) { std::cout << "Writting " << gts_name << std::endl ; gts << off.size_of_vertices() << " " << (off.size_of_halfedges()/2) << " " << off.size_of_facets() << std::endl ; int vid = 1 ; for ( Vertex_iterator vit = off.vertices_begin() ; vit != off.vertices_end() ; ++ vit ) { Vertex_handle v = vit ; gts << v->point().x() << " " << v->point().y() << " " << v->point().z() << std::endl ; v->id() = vid ++ ; } int eid = 1 ; for ( Edge_iterator eit = off.edges_begin(); eit != off.edges_end() ; ++ eit ) { Halfedge_handle e = eit ; Vertex_handle s = e->opposite()->vertex(); Vertex_handle t = e->vertex(); gts << s->id() << " " << t->id() << std::endl ; e ->id() = eid ; e->opposite()->id() = eid ; ++ eid ; } for ( Facet_iterator fit = off.facets_begin(); fit != off.facets_end() ; ++ fit ) { Facet_handle f = fit ; Halfedge_handle e0 = f->halfedge(); Halfedge_handle e1 = e0->next(); Halfedge_handle e2 = e1->next(); gts << e0->id() << " " << e1->id() << " " << e2->id() << std::endl ; } } else std::cerr << "Unable to open output file: " << gts_name << std::endl ; }
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::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; }
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); } }
void printHalfedge( const Halfedge_handle & hh ) { cerr << setw( 3 ) << hh->opposite()->vertex()->id() << " == " << setw( 3 ) << hh->vertex()->id() << endl; }
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; } } }
// Description : To find a correspondent type to retriangulate. int Find_Type(const Halfedge_handle &h,const unsigned int &valence) { int type = 0; if (valence == 3) { if ((h->vertex()->Vertex_Sign_S == MINUS) && (h->opposite()->vertex()->Vertex_Sign_S == PLUS)) type = 1; else if ((h->vertex()->Vertex_Sign_S == PLUS) && (h->opposite()->vertex()->Vertex_Sign_S == MINUS)) type = 2; else if ((h->vertex()->Vertex_Sign_S == PLUS) && (h->opposite()->vertex()->Vertex_Sign_S == PLUS)) type = 3; else if ((h->vertex()->Vertex_Sign_S == MINUS) && (h->opposite()->vertex()->Vertex_Sign_S == MINUS)) type = 4; } else if (valence == 4) { if ((h->vertex()->Vertex_Sign_S == MINUS) && (h->opposite()->vertex()->Vertex_Sign_S == PLUS)) type = 5; else if ((h->vertex()->Vertex_Sign_S == PLUS) && (h->opposite()->vertex()->Vertex_Sign_S == MINUS)) type = 6; else if ((h->vertex()->Vertex_Sign_S == PLUS) && (h->opposite()->vertex()->Vertex_Sign_S == PLUS)) type = 7; else if ((h->vertex()->Vertex_Sign_S == MINUS) && (h->opposite()->vertex()->Vertex_Sign_S == MINUS)) type = 8; } else if (valence == 5) { if ((h->vertex()->Vertex_Sign_S == MINUS) && (h->opposite()->vertex()->Vertex_Sign_S == PLUS)) type = 9; else if ((h->vertex()->Vertex_Sign_S == PLUS) && (h->opposite()->vertex()->Vertex_Sign_S == MINUS)) type = 10; else if ((h->vertex()->Vertex_Sign_S == PLUS) && (h->opposite()->vertex()->Vertex_Sign_S == PLUS)) type = 11; else if ((h->vertex()->Vertex_Sign_S == MINUS) && (h->opposite()->vertex()->Vertex_Sign_S == MINUS)) type = 12; } else if (valence == 6) { if ((h->vertex()->Vertex_Sign_S == MINUS) && (h->opposite()->vertex()->Vertex_Sign_S == PLUS)) type = 13; else if ((h->vertex()->Vertex_Sign_S == PLUS) && (h->opposite()->vertex()->Vertex_Sign_S == MINUS)) type = 14; else if ((h->vertex()->Vertex_Sign_S == PLUS) && (h->opposite()->vertex()->Vertex_Sign_S == PLUS)) type = 15; else if ((h->vertex()->Vertex_Sign_S == MINUS) && (h->opposite()->vertex()->Vertex_Sign_S == MINUS)) type = 16; } return type; }
// 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; }
// Annule les T Vertices sur les faces adjacentes void DegradeAnObject::noTVertice(Halfedge_handle hh1, Halfedge_handle hh2, Halfedge_handle hh3, int index) { Halfedge_handle h = polys[index].split_facet(hh1->opposite(), hh1->opposite()->next()->next()); h = polys[index].split_facet(hh2->opposite(), hh2->opposite()->next()->next()); h = polys[index].split_facet(hh3->opposite(), hh3->opposite()->next()->next()); }
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)); }
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)); }
void DegradeAnObject::noTVertice(Halfedge_handle hh1, Halfedge_handle hh2, Halfedge_handle hh3, int index) { barycentricMesh(*(hh1->opposite()->facet()), index); barycentricMesh(*(hh2->opposite()->facet()), index); barycentricMesh(*(hh3->opposite()->facet()), index); }