From dc3fabfb66f31c4c8e86b573d1f9c97d0a6d063a Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Mon, 3 Feb 2025 15:42:44 +0100 Subject: [PATCH] use shortest_path_between_two_vertices() in demo --- .../Lab/Scene_polyhedron_selection_item.cpp | 105 +++--------------- 1 file changed, 17 insertions(+), 88 deletions(-) diff --git a/Lab/demo/Lab/Scene_polyhedron_selection_item.cpp b/Lab/demo/Lab/Scene_polyhedron_selection_item.cpp index 7df511b6169..6bac6f095c6 100644 --- a/Lab/demo/Lab/Scene_polyhedron_selection_item.cpp +++ b/Lab/demo/Lab/Scene_polyhedron_selection_item.cpp @@ -31,6 +31,7 @@ #include "triangulate_primitive.h" #include #include +#include #include using namespace CGAL::Three; @@ -1486,103 +1487,31 @@ void Scene_polyhedron_selection_item::emitTempInstruct() Q_EMIT updateInstructions(QString("%1").arg(d->m_temp_instructs)); } -/// An exception used while catching a throw that stops Dijkstra's algorithm -/// once the shortest path to a target has been found. -class Dijkstra_end_exception : public std::exception -{ - const char* what() const throw () - { - return "Dijkstra shortest path: reached the target vertex."; - } -}; - -/// Visitor to stop Dijkstra's algorithm once the given target turns 'BLACK', -/// that is when the target has been examined through all its incident edges and -/// the shortest path is thus known. -class Stop_at_target_Dijkstra_visitor : boost::default_dijkstra_visitor -{ - fg_vertex_descriptor destination_vd; - -public: - Stop_at_target_Dijkstra_visitor(fg_vertex_descriptor destination_vd) - : destination_vd(destination_vd) - { } - - void initialize_vertex(const fg_vertex_descriptor& /*s*/, const Face_graph& /*mesh*/) const { } - void examine_vertex(const fg_vertex_descriptor& /*s*/, const Face_graph& /*mesh*/) const { } - void examine_edge(const fg_edge_descriptor& /*e*/, const Face_graph& /*mesh*/) const { } - void edge_relaxed(const fg_edge_descriptor& /*e*/, const Face_graph& /*mesh*/) const { } - void discover_vertex(const fg_vertex_descriptor& /*s*/, const Face_graph& /*mesh*/) const { } - void edge_not_relaxed(const fg_edge_descriptor& /*e*/, const Face_graph& /*mesh*/) const { } - void finish_vertex(const fg_vertex_descriptor &vd, const Face_graph& /* mesh*/) const - { - if(vd == destination_vd) - throw Dijkstra_end_exception(); - } -}; void Scene_polyhedron_selection_item_priv::computeAndDisplayPath() { + const auto& mesh = *item->polyhedron(); + std::vector path_halfedges; + for(auto it = constrained_vertices.begin(); it!=constrained_vertices.end()-1; ++it) + { + fg_vertex_descriptor t(*it), s(*(it+1)); + + CGAL::shortest_path_between_two_vertices(s, t, mesh, + std::back_inserter(path_halfedges)); + } + item->temp_selected_edges.clear(); path.clear(); - typedef std::unordered_map Pred_umap; - typedef boost::associative_property_map Pred_pmap; - - Pred_umap predecessor; - Pred_pmap pred_pmap(predecessor); - - vertex_on_path vop; - QList::iterator it; - for(it = constrained_vertices.begin(); it!=constrained_vertices.end()-1; ++it) - { - fg_vertex_descriptor t(*it), s(*(it+1)); - Stop_at_target_Dijkstra_visitor vis(t); - - try - { - boost::dijkstra_shortest_paths(*item->polyhedron(), s, - boost::predecessor_map(pred_pmap).visitor(vis)); - } - catch (const std::exception& e) - { - std::cout << e.what() << std::endl; - } - - // Walk back from target to source and collect vertices along the way - do - { - vop.vertex = t; - if(constrained_vertices.contains(t)) - { - vop.is_constrained = true; - } - else - vop.is_constrained = false; - path.append(vop); - t = get(pred_pmap, t); - } - while(t != s); - } - - // Add the last vertex - vop.vertex = constrained_vertices.last(); - vop.is_constrained = true; - path.append(vop); - // Display path double path_length = 0; - QList::iterator path_it; - for(path_it = path.begin(); path_it!=path.end()-1; ++path_it) + VPmap vpm = get(CGAL::vertex_point, mesh); + for(auto h : path_halfedges) { - std::pair h = halfedge((path_it+1)->vertex,path_it->vertex,*item->polyhedron()); - if(h.second) - { - VPmap vpm = get(CGAL::vertex_point,*polyhedron()); - Point p1(get(vpm, (path_it+1)->vertex)), p2(get(vpm, path_it->vertex)); - path_length += CGAL::sqrt(Vector(p1,p2).squared_length()); - item->temp_selected_edges.insert(edge(h.first, *item->polyhedron())); - } + const Point& p1 = get(vpm, target(h, mesh)); + const Point& p2 = get(vpm, source(h, mesh)); + path_length += CGAL::approximate_sqrt(CGAL::squared_distance(p1, p2)); + item->temp_selected_edges.insert(edge(h, *item->polyhedron())); } item->printMessage(QString("New path length: %1").arg(path_length)); }