diff --git a/Shape_detection/include/CGAL/Shape_detection/Region_growing/Region_growing_on_polygon_mesh/Polyline_graph.h b/Shape_detection/include/CGAL/Shape_detection/Region_growing/Region_growing_on_polygon_mesh/Polyline_graph.h index e28285f8b27..8689cd722b9 100644 --- a/Shape_detection/include/CGAL/Shape_detection/Region_growing/Region_growing_on_polygon_mesh/Polyline_graph.h +++ b/Shape_detection/include/CGAL/Shape_detection/Region_growing/Region_growing_on_polygon_mesh/Polyline_graph.h @@ -54,14 +54,10 @@ namespace Polygon_mesh { struct PEdge { std::size_t index = std::size_t(-1); edge_descriptor ed; - std::set sneighbors; - std::set tneighbors; + std::vector neighbors; std::pair regions; }; - using Face_to_index_map = internal::Item_to_index_property_map; - using Edge_to_index_map = internal::Item_to_index_property_map; - struct Transform_pedge { const edge_descriptor operator()(const PEdge& pedge) const { return pedge.ed; @@ -112,7 +108,7 @@ namespace Polygon_mesh { \param pmesh a polygon mesh \param face_to_region_map maps each face of `pmesh` to - the corresponding planar regions id + a corresponding planar region id \param np a sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below @@ -123,12 +119,6 @@ namespace Polygon_mesh { vertex to `Kernel::Point_3`} \cgalParamDefault{`boost::get(CGAL::vertex_point, pmesh)`} \cgalParamNEnd - \cgalParamNBegin{edge_index_map} - \cgalParamDescription{a property map associating to each edge of `pmesh` a unique index between `0` and `num_edges(pmesh) - 1`} - \cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits::%edge_descriptor` - as key type and `std::size_t` as value type} - \cgalParamDefault{an automatically indexed internal map} - \cgalParamNEnd \cgalNamedParamsEnd \pre `faces(pmesh).size() > 0` @@ -146,11 +136,8 @@ namespace Polygon_mesh { { clear(); - std::vector pedge_map( - edges(pmesh).size(), std::size_t(-1)); - - typedef typename GetInitializedEdgeIndexMap::const_type EdgeIndexMap; - EdgeIndexMap eimap = get_initialized_edge_index_map(pmesh, np); + typedef typename boost::property_map >::const_type EdgeIndexMap; + EdgeIndexMap eimap = get(CGAL::dynamic_edge_property_t(), pmesh); // collect edges either on the boundary or having two different incident regions for (const auto& edge : edges(pmesh)) @@ -168,22 +155,37 @@ namespace Polygon_mesh { if (f2 != boost::graph_traits::null_face()) r2 = get(face_to_region_map, f2); - if (r1 == r2) continue; - add_graph_edge(edge, r1, r2, pedge_map, eimap); + if (r1 == r2) + put(eimap, edge, std::size_t(-1)); + else + add_graph_edge(edge, r1, r2, eimap); } // build adjacency between edges - for (std::size_t i = 0; i < m_pedges.size(); ++i) { + typedef typename boost::property_map >::const_type VisitedVertexMap; + VisitedVertexMap visited_vertices = get(CGAL::dynamic_vertex_property_t(), pmesh); + for (std::size_t i = 0; i < m_pedges.size(); ++i) + { + put(visited_vertices, source(m_pedges[i].ed, pmesh), false); + put(visited_vertices, target(m_pedges[i].ed, pmesh), false); + } + + for (std::size_t i = 0; i < m_pedges.size(); ++i) + { auto& pedge = m_pedges[i]; CGAL_precondition(pedge.regions.first != pedge.regions.second); CGAL_precondition(pedge.index != std::size_t(-1)); - const edge_descriptor edge = pedge.ed; - const vertex_descriptor s = source(edge, pmesh); - const vertex_descriptor t = target(edge, pmesh); + std::array vrts = { source(pedge.ed, pmesh), target(pedge.ed, pmesh) }; - add_vertex_neighbors(s, i, pedge_map, pedge.sneighbors, pmesh, eimap); - add_vertex_neighbors(t, i, pedge_map, pedge.tneighbors, pmesh, eimap); + for (int k=0; k<2; ++k) + { + if (!get(visited_vertices, vrts[k])) + { + add_vertex_neighbors(vrts[k], pmesh, eimap); + put(visited_vertices, vrts[k], true); + } + } } } @@ -209,15 +211,12 @@ namespace Polygon_mesh { */ void operator()( const std::size_t query_index, - std::vector& neighbors) const { - + std::vector& neighbors) const + { neighbors.clear(); CGAL_precondition(query_index < segment_range().size()); const auto& pedge = m_pedges[query_index]; - for (const std::size_t sneighbor : pedge.sneighbors) - neighbors.push_back(sneighbor); - for (const std::size_t tneighbor : pedge.tneighbors) - neighbors.push_back(tneighbor); + neighbors=pedge.neighbors; } /*! @@ -240,41 +239,27 @@ namespace Polygon_mesh { /*! \brief returns indices of all edges from `segment_range()`, - which are connected to the source vertex of the edge + which are connected to a vertex of the edge with the index `query_index`. \pre `query_index < segment_range().size()` */ - const std::set& source_neighbors( - const std::size_t query_index) const { - + const std::vector& neighbors( + const std::size_t query_index) const + { CGAL_precondition(query_index < segment_range().size()); - return m_pedges[query_index].sneighbors; + return m_pedges[query_index].neighbors; } /*! - \brief returns indices of all edges from `segment_range()`, - which are connected to the target vertex of the edge - with the index `query_index`. - - \pre `query_index < segment_range().size()` - */ - const std::set& target_neighbors( - const std::size_t query_index) const { - - CGAL_precondition(query_index < segment_range().size()); - return m_pedges[query_index].tneighbors; - } - - /*! - \brief returns the edge index of the original polygon mesh edge, which + \brief returns the edge descriptor which corresponds to the edge from `segment_range()` with the index `query_index`. \pre `query_index < segment_range().size()` */ - std::size_t edge_index(const std::size_t query_index) const { + edge_descriptor descriptor(const std::size_t query_index) const { CGAL_precondition(query_index < segment_range().size()); - return m_pedges[query_index].index; + return m_pedges[query_index].ed; } /*! @@ -311,43 +296,38 @@ namespace Polygon_mesh { template void add_graph_edge( edge_descriptor edge, const std::size_t region1, const std::size_t region2, - std::vector& pedge_map, - EdgeIndexMap eimap) { - + EdgeIndexMap eimap) + { PEdge pedge; CGAL_precondition(region1 != region2); - const std::size_t ei = get(eimap, edge); - CGAL_precondition(ei != std::size_t(-1)); + const std::size_t ei = m_pedges.size(); + put(eimap, edge, ei); pedge.index = ei; pedge.ed = edge; - pedge.regions.first = region1; - pedge.regions.second = region2; - CGAL_precondition(pedge.index < pedge_map.size()); - pedge_map[pedge.index] = m_pedges.size(); + pedge.regions = {region1, region2}; m_pedges.push_back(pedge); } template void add_vertex_neighbors( - const vertex_descriptor vertex, const std::size_t curr_pe, - const std::vector& pedge_map, - std::set& neighbors, + const vertex_descriptor vertex, const PolygonMesh& pmesh, - EdgeIndexMap eimap) const { - - const auto query_hedge = halfedge(vertex, pmesh); - const auto hedges = halfedges_around_target(query_hedge, pmesh); - CGAL_precondition(hedges.size() > 0); - for (const auto& hedge : hedges) { + EdgeIndexMap eimap) + { + std::vector nei; + for (const auto& hedge : halfedges_around_target(vertex, pmesh)) + { const auto e = edge(hedge, pmesh); const std::size_t ei = get(eimap, e); - CGAL_precondition(ei < pedge_map.size()); - const std::size_t pe = pedge_map[ei]; - if (pe == std::size_t(-1)) continue; - if (pe == curr_pe) continue; - CGAL_precondition(pe < m_pedges.size()); - neighbors.insert(pe); + if (ei == std::size_t(-1)) continue; + if (nei.size()==2) return; + nei.push_back(ei); + } + if (nei.size()==2) + { + m_pedges[nei[0]].neighbors.push_back(nei[1]); + m_pedges[nei[1]].neighbors.push_back(nei[0]); } } };