// 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; }
// Place un point p sur la face fs, et relie p aux sommets de fs. Halfedge_handle DegradeAnObject::putAPointOnAFacet(Point_3 p, int index) { Facet fs; getFacetFromPoint(p, fs, index); Halfedge_handle h = polys[index].create_center_vertex(fs.halfedge()); h->vertex()->point() = p; return h; }
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()); }
// 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; }
/** * Trace up one face and modify h to be ready for the next trace. * * h must have the next face to be traced on its left, and its point must be the * next point to be traced from. */ void trace_up_once(Halfedge_handle& h, TraceFlag& flag) { if (flag == TRACE_POINT) { assert(!is_saddle(h->vertex())); h = find_steepest_path(h->vertex()); } Point_3 intersect_point = find_upslope_intersection(h, flag); }
void print_endpoint(Halfedge_handle e, bool is_src) { std::cout << "\t"; if ( is_src ) { if ( e->has_source() ) std::cout << e->source()->point() << std::endl; else std::cout << "point at infinity" << std::endl; } else { if ( e->has_target() ) std::cout << e->target()->point() << std::endl; else std::cout << "point at infinity" << std::endl; } }
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 : 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; }
//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; }
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); }
// Dessine tous les points qui déterminent l'impact à réaliser, en plusieurs couronnes. void DegradeAnObject::drawImpactOnFacet(Point_3 p, double ray, std::vector<Point_3> pts, Facet initFs, int index, int nbCouronnes) { std::vector< std::vector<Point_3> > points; std::vector<Point_3> tmp; std::vector<Halfedge_handle> hhs; Halfedge_handle hh; hh = putAPointOnAFacet(pts[0], index); tmp.push_back(hh->vertex()->point()); for(int i = 1 ; i < pts.size() ; i++) { hh = joinTwoPoints(pts[i], pts[i-1], index, tmp); } joinFirstAndLast(pts[0], pts[pts.size()-1], index, tmp); for(int i = 1 ; i < nbCouronnes ; i++) { hhs = getHalfedgesOfPoints(tmp, index); tmp = drawInsideImpactOnFacet(tmp, hhs, initFs, index); points.push_back(tmp); } impactTheFacetArea(points, initFs, ray, index); }
//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;; } }
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 Map_CreateWithLineData( Pmwx& out_map, const vector<Segment_2>& input_curves, const vector<GIS_halfedge_data>& input_data) { DebugAssert(input_curves.size() == input_data.size()); out_map.clear(); int n; vector<Curve_2> curves; curves.resize(input_curves.size()); for(n = 0; n < input_curves.size(); ++n) curves[n] = Curve_2(input_curves[n], n); CGAL::insert(out_map, curves.begin(), curves.end()); for(Pmwx::Edge_iterator eit = out_map.edges_begin(); eit != out_map.edges_end(); ++eit) { DebugAssert(eit->curve().data().size() >= 1); // CGAL maintains a lot of information for us that makes life easy: // 1. The underlying curve of an edge is a sub-curve of the input curve - it is NEVER flipped. is_directed_right tells whether // it is lex-right.* // 2. Each half-edge's direction tells us if the half-edge is lex-right...strangely, "SMALLER" means lex-right. // Putting these two things together, we can easily detect which of two half-edges is in the same vs. opposite direction of the input // curve. // * lex-right means lexicographically x-y larger...means target is to the right of source UNLESS it's vertical (then UP = true, down = false). Halfedge_handle he = he_is_same_direction(eit) ? eit : eit->twin(); int cid = eit->curve().data().front(); DebugAssert(cid >= 0 && cid < input_data.size()); he->set_data(input_data[cid]); // he->data().mDominant = true; // he->twin()->data().mDominant = false; // Do NOT leave the keys in the map... eit->curve().data().clear(); } }
virtual void after_split_edge (Halfedge_handle h1, Halfedge_handle h2) { std::string str = h1->data(); if (str.compare("") == 0) str = h2->data(); if (str.compare("") == 0) str = h1->twin()->data(); if (str.compare("") == 0) str = h2->twin()->data(); h1->set_data(str); h2->set_data(str); h1->twin()->set_data(str); h2->twin()->set_data(str); }
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; }
/** * 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; }
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 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); }
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); }
// 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); }
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; }
// 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; }
// 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; }
// 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 printHalfedge( const Halfedge_handle & hh ) { cerr << setw( 3 ) << hh->opposite()->vertex()->id() << " == " << setw( 3 ) << hh->vertex()->id() << endl; }
/*! Create an edge e that matches the edge e2, contained in the face f1. */ virtual void create_edge(Face_const_handle f1, Halfedge_const_handle e2, Halfedge_handle e) const { e->set_data(f1->data() + e2->data()); e->twin()->set_data(f1->data() + e2->data()); }
/*! Create an edge e that matches the edge e1, contained in the face f2. */ virtual void create_edge(Halfedge_const_handle e1, Face_const_handle f2, Halfedge_handle e) const { e->set_data(e1->data() + f2->data()); e->twin()->set_data(e1->data() + f2->data()); }
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()); }