From 5ababe9c33947cfbc2750ea133ea3f21952b6611 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 20 Jan 2017 11:20:56 +0100 Subject: [PATCH 01/38] Add an adapter: - Create an adapter for FaceListGraphs that takes a patch_id and a FaceIndexMap and acts as if the specified patch was a whole graph. --- .../boost/graph/connected_component_graph.h | 605 ++++++++++++++++++ BGL/test/BGL/CMakeLists.txt | 4 + ...raph_concept_Connected_component_graph.cpp | 53 ++ .../BGL/test_Connected_component_graph.cpp | 410 ++++++++++++ 4 files changed, 1072 insertions(+) create mode 100644 BGL/include/CGAL/boost/graph/connected_component_graph.h create mode 100644 BGL/test/BGL/graph_concept_Connected_component_graph.cpp create mode 100644 BGL/test/BGL/test_Connected_component_graph.cpp diff --git a/BGL/include/CGAL/boost/graph/connected_component_graph.h b/BGL/include/CGAL/boost/graph/connected_component_graph.h new file mode 100644 index 00000000000..265114a2bc0 --- /dev/null +++ b/BGL/include/CGAL/boost/graph/connected_component_graph.h @@ -0,0 +1,605 @@ +#ifndef CGAL_BOOST_GRAPH_Connected_component_graph_H +#define CGAL_BOOST_GRAPH_Connected_component_graph_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace CGAL +{ + +template +struct Connected_component_graph +{ + typedef boost::graph_traits gt; + typedef typename gt::vertex_descriptor vertex_descriptor; + typedef typename gt::halfedge_descriptor halfedge_descriptor; + typedef typename gt::edge_descriptor edge_descriptor; + typedef typename gt::face_descriptor face_descriptor; + typedef Connected_component_graph Self; + + + Connected_component_graph(const Graph& graph, + FaceComponentMap fccmap, + typename boost::property_traits::value_type pid) + : _graph(graph), property_map(fccmap), patch_index(pid) + { + } + + + Connected_component_graph(const Connected_component_graph&f) + : _graph(f.graph()), property_map(f.propertyMap()), patch_index(f.patchIndex()) + { + } + + const Graph& graph()const{ return _graph; } + + FaceComponentMap propertyMap()const{ return property_map; } + + typename boost::property_traits::value_type patchIndex()const{ return patch_index; } + + struct Is_simplex_valid + { + Is_simplex_valid(const Self* graph) + :adapter(graph) + {} + + Is_simplex_valid() + :adapter(NULL) + {} + template + bool operator()(Simplex s) + { + return (is_valid(s, *adapter)); + } + const Self* adapter; + }; + +private: + const Graph& _graph; + FaceComponentMap property_map; + typename boost::property_traits::value_type patch_index; +}; + +} // namespace CGAL + +namespace boost +{ + +template +struct graph_traits< CGAL::Connected_component_graph > +{ + typedef CGAL::Connected_component_graph G; + typedef boost::graph_traits BGTG; + typedef typename BGTG::vertex_descriptor vertex_descriptor; + typedef typename BGTG::halfedge_descriptor halfedge_descriptor; + typedef typename BGTG::edge_descriptor edge_descriptor; + typedef typename BGTG::face_descriptor face_descriptor; + + typedef boost::filter_iterator vertex_iterator; + typedef boost::filter_iterator halfedge_iterator; + typedef boost::filter_iterator edge_iterator; + typedef boost::filter_iterator face_iterator; + + typedef boost::filter_iterator out_edge_iterator; + typedef boost::filter_iterator in_edge_iterator; + + typedef typename BGTG::directed_category directed_category; + typedef typename BGTG::edge_parallel_category edge_parallel_category; + typedef typename BGTG::traversal_category traversal_category; + typedef typename BGTG::vertices_size_type vertices_size_type; + typedef typename BGTG::edges_size_type edges_size_type; + typedef typename BGTG::halfedges_size_type halfedges_size_type; + typedef typename BGTG::faces_size_type faces_size_type; + typedef typename BGTG::degree_size_type degree_size_type; + + static vertex_descriptor null_vertex() + { + return vertex_descriptor(BGTG::null_vertex()); + } + + static halfedge_descriptor null_halfedge() + { + return halfedge_descriptor(BGTG::null_halfedge()); + } + + static edge_descriptor null_edge() + { + return edge_descriptor(BGTG::null_halfedge()); + } + + static face_descriptor null_face() + { + return face_descriptor(BGTG::null_face()); + } +}; + +template +struct graph_traits< const CGAL::Connected_component_graph > + : public graph_traits< CGAL::Connected_component_graph > +{}; + + +} // namespace boost + + +namespace CGAL { +template +bool +is_valid(const typename boost::graph_traits< Connected_component_graph >::face_descriptor f, + const Connected_component_graph & w) +{ + return boost::get(w.propertyMap(), f) == w.patchIndex(); +} + +template +bool +is_valid(const typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor h, + const Connected_component_graph & w) +{ + return is_valid(face(h, w.graph()), w) || + is_valid(face(opposite(h, w.graph()), w.graph()), w); +} + +template +bool +is_valid(const typename boost::graph_traits< Connected_component_graph >::edge_descriptor e, + const Connected_component_graph & w) +{ + return is_valid(halfedge(e, w.graph()), w); +} + +template +bool +is_valid(const typename boost::graph_traits< Connected_component_graph >::vertex_descriptor v, + const Connected_component_graph & w) +{ + typename boost::graph_traits >::halfedge_descriptor h = halfedge(v, w.graph()); + typename boost::graph_traits >::halfedge_descriptor hcirc = h; + do + { + if(is_valid(face(hcirc, w.graph()), w)) + return true; + hcirc = opposite(next(hcirc, w.graph()), w.graph()); + }while(hcirc != h); + return false; +} + + +template +typename boost::graph_traits::vertices_size_type +num_vertices(const Connected_component_graph& w) +{ + return num_vertices(w.graph()); +} + +template +typename boost::graph_traits::edges_size_type +num_edges(const Connected_component_graph& w) +{ + return num_edges(w.graph()); +} + +template +typename boost::graph_traits::degree_size_type +degree(typename boost::graph_traits >::vertex_descriptor v, + const Connected_component_graph& w) +{ + CGAL_assertion(is_valid(v, w)); + typename boost::graph_traits::degree_size_type v_deg = 0; + typename boost::graph_traits >::halfedge_descriptor h = halfedge(v, w); + typename boost::graph_traits >::halfedge_descriptor hcirc = h; + do + { + if(is_valid(hcirc, w)) + ++v_deg; + hcirc = opposite(next(hcirc, w.graph()), w.graph()); + }while(hcirc != h); + return v_deg; +} + +template +typename boost::graph_traits::degree_size_type +out_degree(typename boost::graph_traits >::vertex_descriptor v, + const Connected_component_graph& w) +{ + CGAL_assertion(is_valid(v, w)); + return std::distance(out_edges(v, w).first ,out_edges(v, w).second); +} + +template +typename boost::graph_traits::degree_size_type +in_degree(typename boost::graph_traits >::vertex_descriptor v, + const Connected_component_graph& w) +{ + CGAL_assertion(is_valid(v, w)); + return std::distance(in_edges(v, w).first ,in_edges(v, w).second); +} + +template +typename boost::graph_traits >::vertex_descriptor +source(typename boost::graph_traits >::edge_descriptor e, + const Connected_component_graph & w) +{ + CGAL_assertion(is_valid(e, w)); + return source(e, w.graph()); +} + +template +typename boost::graph_traits >::vertex_descriptor +target(typename boost::graph_traits >::edge_descriptor e, + const Connected_component_graph & w) +{ + CGAL_assertion(is_valid(e, w)); + return target(e, w.graph()); +} + +template +std::pair >::edge_descriptor, bool> +edge(typename boost::graph_traits >::vertex_descriptor u, + typename boost::graph_traits >::vertex_descriptor v, + const Connected_component_graph & w) +{ + CGAL_assertion(is_valid(u, w) && is_valid(v, w)); + typename boost::graph_traits >::edge_descriptor e = edge(u, v, w.graph()).first; + bool res = is_valid(e, w); + return std::make_pair(e, res); +} + + +template +std::pair >::vertex_iterator, +typename boost::graph_traits >::vertex_iterator> +vertices(const Connected_component_graph & w) +{ + typedef typename boost::graph_traits >::vertex_iterator vertex_iterator; + typedef typename boost::graph_traits::vertex_iterator g_vertex_iterator; + + typename Connected_component_graph ::Is_simplex_valid predicate(&w); + std::pair original_vertices = vertices(w.graph()); + + return make_range(vertex_iterator(predicate, original_vertices.first, original_vertices.second), + vertex_iterator(predicate, original_vertices.second, original_vertices.second)); +} + +template +std::pair >::edge_iterator, +typename boost::graph_traits >::edge_iterator> +edges(const Connected_component_graph & w) +{ + typedef typename boost::graph_traits >::edge_iterator edge_iterator; + typedef typename boost::graph_traits::edge_iterator g_edge_iterator; + + typename Connected_component_graph ::Is_simplex_valid predicate(&w); + std::pair original_edges = edges(w.graph()); + + return make_range(edge_iterator(predicate, original_edges.first, original_edges.second), + edge_iterator(predicate, original_edges.second, original_edges.second)); +} + +template +std::pair >::out_edge_iterator, +typename boost::graph_traits >::out_edge_iterator> +out_edges(typename boost::graph_traits >::vertex_descriptor v, + const Connected_component_graph & w) +{ + + typedef typename boost::graph_traits >::out_edge_iterator out_edge_iterator; + typedef typename boost::graph_traits::out_edge_iterator g_out_edge_iterator; + + typename Connected_component_graph ::Is_simplex_valid predicate(&w); + g_out_edge_iterator b,e; + boost::tie(b,e) = out_edges(v, w.graph()); + return make_range(out_edge_iterator(predicate, b, e), + out_edge_iterator(predicate, e, e)); +} + +template +std::pair >::in_edge_iterator, +typename boost::graph_traits >::in_edge_iterator> +in_edges(typename boost::graph_traits >::vertex_descriptor v, + const Connected_component_graph & w) +{ + + typedef typename boost::graph_traits >::in_edge_iterator in_edge_iterator; + typedef typename boost::graph_traits::in_edge_iterator g_in_edge_iterator; + + typename Connected_component_graph ::Is_simplex_valid predicate(&w); + g_in_edge_iterator b,e; + boost::tie(b,e) = in_edges(v, w.graph()); + return make_range(in_edge_iterator(predicate, b, e), + in_edge_iterator(predicate, e, e)); +} + +// +// HalfedgeGraph +// +template +typename boost::graph_traits< Connected_component_graph >::edge_descriptor +edge(typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor h, + const Connected_component_graph & w) +{ + CGAL_assertion(CGAL::is_valid(h, w)); + return edge(h, w.graph()); +} + +template +typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor +halfedge(typename boost::graph_traits< Connected_component_graph >::edge_descriptor e, + const Connected_component_graph & w) +{ + CGAL_assertion(CGAL::is_valid(e, w)); + return halfedge(e, w.graph()); +} + +template +typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor +halfedge(typename boost::graph_traits< Connected_component_graph >::vertex_descriptor v, + const Connected_component_graph & w) +{ + CGAL_assertion(is_valid(v, w)); + typename boost::graph_traits >::halfedge_descriptor h = halfedge(v, w.graph()); + typename boost::graph_traits >::halfedge_descriptor hcirc = h; + do + { + if(is_valid(hcirc, w)) + return hcirc; + hcirc = opposite(next(hcirc, w.graph()), w.graph()); + }while(hcirc != h); + return boost::graph_traits< CGAL::Connected_component_graph >::null_halfedge(); +} + + +template +std::pair >::halfedge_descriptor, bool> +halfedge(typename boost::graph_traits< Connected_component_graph >::vertex_descriptor u, + typename boost::graph_traits< Connected_component_graph >::vertex_descriptor v, + const Connected_component_graph & w) +{ + CGAL_assertion(is_valid(u, w) && is_valid(v, w)); + typename boost::graph_traits >::halfedge_descriptor h = halfedge(u, v, w.graph()).first; + return std::make_pair(h, is_valid(h, w)); +} + + +template +typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor +opposite(typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor h, + const Connected_component_graph & w) +{ + CGAL_assertion(is_valid(h, w) ); + return opposite(h, w.graph()); +} + +template +typename boost::graph_traits< Connected_component_graph >::vertex_descriptor +source(typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor h, + const Connected_component_graph & w) +{ + CGAL_assertion(is_valid(h, w) ); + return source(h, w.graph()); +} + +template +typename boost::graph_traits< Connected_component_graph >::vertex_descriptor +target(typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor h, + const Connected_component_graph & w) +{ + CGAL_assertion(is_valid(h, w) ); + return target(h, w.graph()); +} + +template +typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor +next(typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor h, + const Connected_component_graph & w) +{ + CGAL_assertion(is_valid(h, w)); + if(is_valid(face(h, w.graph()), w)) + return next(h, w.graph()); + + //act as a border + typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor hcirc = h; + do + { + if(is_valid(hcirc, w)) + { + return hcirc; + } + hcirc = opposite(next(hcirc,w.graph()),w.graph()); + }while(hcirc != h); + return boost::graph_traits< CGAL::Connected_component_graph >::null_halfedge(); +} + +template +typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor +prev(typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor h, + const Connected_component_graph & w) +{ + + CGAL_assertion(is_valid(h, w)); + if(is_valid(face(h, w.graph()), w)) + return prev(h, w.graph()); + + //act as a border + typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor hcirc = h; + do + { + if(is_valid(hcirc, w)) + { + return hcirc; + } + hcirc = opposite(prev(hcirc,w.graph()), w.graph()); + }while(hcirc != h); + return boost::graph_traits< CGAL::Connected_component_graph >::null_halfedge(); +} + +// +// HalfedgeListGraph +// + +template +std::pair >::halfedge_iterator, +typename boost::graph_traits >::halfedge_iterator> +halfedges(const Connected_component_graph & w) +{ + typedef typename boost::graph_traits >::halfedge_iterator halfedge_iterator; + typedef typename boost::graph_traits::halfedge_iterator g_halfedge_iterator; + + typename Connected_component_graph ::Is_simplex_valid predicate(&w); + std::pair original_halfedges = halfedges(w.graph()); + + return make_range(halfedge_iterator(predicate, original_halfedges.first, original_halfedges.second), + halfedge_iterator(predicate, original_halfedges.second, original_halfedges.second)); +} + + +template +typename boost::graph_traits::halfedges_size_type +num_halfedges(const Connected_component_graph & w) +{ + return num_halfedges(w.graph()); +} + +// FaceGraph +template +typename boost::graph_traits< Connected_component_graph >::face_descriptor +face(typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor h, + const Connected_component_graph & w) +{ + CGAL_assertion(CGAL::is_valid(h, w)); + return face(h,w.graph()); +} + +template +typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor +halfedge(typename boost::graph_traits< Connected_component_graph >::face_descriptor f, + const Connected_component_graph & w) +{ + CGAL_assertion(CGAL::is_valid(f, w)); + return halfedge(f,w.graph()); +} + + +template +std::pair >::face_iterator, +typename boost::graph_traits >::face_iterator> +faces(const Connected_component_graph & w) +{ + typedef typename boost::graph_traits >::face_iterator face_iterator; + typedef typename boost::graph_traits::face_iterator g_face_iterator; + + typename Connected_component_graph ::Is_simplex_valid predicate(&w); + std::pair original_faces = faces(w.graph()); + + return make_range(face_iterator(predicate, original_faces.first, original_faces.second), + face_iterator(predicate, original_faces.second, original_faces.second)); +} + + + +template +typename boost::graph_traits::vertices_size_type +num_faces(const Connected_component_graph & w) +{ + return num_faces(w.graph()); +} + + +template +bool +is_valid(const Connected_component_graph & w, bool verbose = false) +{ + return is_valid(w.graph(),verbose); +} + +template +struct Connected_component_graph_property_map { + + typedef typename boost::property_traits::category category; + typedef typename boost::property_traits::value_type value_type; + typedef typename boost::property_traits::reference reference; + typedef typename boost::property_traits::key_type key_type; + + Graph* graph; + PM pm; + + Connected_component_graph_property_map() + : graph(NULL) + {} + + Connected_component_graph_property_map(const Graph& graph, const PM& pm) + : graph(const_cast(&graph)), pm(pm) + {} + + friend + reference + get(const Connected_component_graph_property_map& gpm, const key_type& k) + { + CGAL_assertion(gpm.graph!=NULL); + return get(gpm.pm, k); + } + + friend + void + put(const Connected_component_graph_property_map& gpm, const key_type& k, const value_type& v) + { + CGAL_assertion(gpm.graph!=NULL); + put(gpm.pm, k, v); + } +}; // class Connected_component_graph_property_map + + + +template +Connected_component_graph_property_map::type> +get(PropertyTag ptag, const Connected_component_graph& w) +{ + typedef typename boost::property_map::type PM; + typedef Connected_component_graph_property_map GPM; + return GPM(w.graph(), get(ptag,w.graph())); +} + + +template +typename boost::property_traits::type>::value_type +get(PropertyTag ptag, + const Connected_component_graph& w, + const typename boost::property_traits::type>::key_type& k) +{ + return get(ptag, w.graph(), k); +} + + +template +void +put(PropertyTag ptag, const Connected_component_graph& w, + const typename boost::property_traits::type>::key_type& k, + typename boost::property_traits::type>::value_type& v) +{ + put(ptag, w.graph(), k, v); +} + +}//end namespace CGAL + +namespace boost { + template + struct property_map,PropertyTag> { + typedef CGAL::Connected_component_graph_property_map::type> type; + typedef CGAL::Connected_component_graph_property_map::const_type> const_type; + }; + + template + struct graph_has_property, PropertyTag> + : graph_has_property {}; + +}// namespace boost + +#endif // CGAL_BOOST_GRAPH_Connected_component_graph_H diff --git a/BGL/test/BGL/CMakeLists.txt b/BGL/test/BGL/CMakeLists.txt index 8b92375ef40..182e64ac01f 100644 --- a/BGL/test/BGL/CMakeLists.txt +++ b/BGL/test/BGL/CMakeLists.txt @@ -87,6 +87,10 @@ create_single_source_cgal_program( "test_Has_member_id.cpp" ) create_single_source_cgal_program( "test_cgal_bgl_named_params.cpp" ) +create_single_source_cgal_program( "test_Connected_component_graph.cpp" ) + +create_single_source_cgal_program( "graph_concept_Connected_component_graph.cpp" ) + diff --git a/BGL/test/BGL/graph_concept_Connected_component_graph.cpp b/BGL/test/BGL/graph_concept_Connected_component_graph.cpp new file mode 100644 index 00000000000..9cb75f5256e --- /dev/null +++ b/BGL/test/BGL/graph_concept_Connected_component_graph.cpp @@ -0,0 +1,53 @@ +#include +#include +#include +#include + +#include +#include + +typedef CGAL::Simple_cartesian K; +typedef CGAL::Surface_mesh SM; +typedef CGAL::Connected_component_graph::face_descriptor , std::size_t> > Adapter; +typedef boost::graph_traits< Adapter > Traits; +typedef Traits::edge_descriptor edge_descriptor; +typedef Traits::halfedge_descriptor halfedge_descriptor; +typedef Traits::vertex_descriptor vertex_descriptor; +typedef Traits::face_descriptor face_descriptor; + +void concept_check_adapter() +{ + boost::function_requires< boost::GraphConcept >(); + boost::function_requires< boost::VertexListGraphConcept >(); + boost::function_requires< boost::EdgeListGraphConcept >(); + boost::function_requires< boost::IncidenceGraphConcept >(); + boost::function_requires< boost::AdjacencyMatrixConcept >(); + boost::function_requires< boost::BidirectionalGraphConcept >(); + boost::function_requires< CGAL::HalfedgeGraphConcept >(); + boost::function_requires< CGAL::HalfedgeListGraphConcept >(); + boost::function_requires< CGAL::FaceGraphConcept >(); + boost::function_requires< CGAL::FaceListGraphConcept >(); + + boost::function_requires< boost::concepts::ReadablePropertyGraph< + Adapter, halfedge_descriptor, CGAL::halfedge_index_t> >(); + boost::function_requires< boost::concepts::ReadablePropertyGraph< + Adapter, edge_descriptor, boost::edge_index_t> >(); + boost::function_requires< boost::concepts::ReadablePropertyGraph< + Adapter, edge_descriptor, boost::edge_weight_t> >(); + boost::function_requires< boost::concepts::PropertyGraph< + Adapter, vertex_descriptor, CGAL::vertex_point_t> >(); + boost::function_requires< boost::concepts::ReadablePropertyGraph< + Adapter, vertex_descriptor, boost::vertex_index_t> >(); + boost::function_requires< boost::concepts::ReadablePropertyGraph< + Adapter, face_descriptor, CGAL::face_index_t> >(); + + // null + boost::graph_traits::null_vertex(); + boost::graph_traits::null_face(); +} + +int main() +{ + concept_check_adapter(); + return 0; +} diff --git a/BGL/test/BGL/test_Connected_component_graph.cpp b/BGL/test/BGL/test_Connected_component_graph.cpp new file mode 100644 index 00000000000..bcf66b89c0d --- /dev/null +++ b/BGL/test/BGL/test_Connected_component_graph.cpp @@ -0,0 +1,410 @@ +#include + +#include "test_Prefix.h" +#include +#include +#include +#include + +typedef boost::unordered_set id_map; + +template +void test_halfedge_around_vertex_iterator(const Graph& g) +{ + typedef typename boost::graph_traits::face_descriptor g_face_descriptor; + typedef boost::associative_property_map< std::map< g_face_descriptor, std::size_t > >FCMap; + typedef CGAL::Connected_component_graph Adapter; + CGAL_GRAPH_TRAITS_MEMBERS(Adapter); + std::map map; + CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); + + + Adapter fg(g, boost::make_assoc_property_map(map), 0); + typename boost::graph_traits::vertex_iterator vit, vend; + for(boost::tie(vit, vend) = vertices(fg); vit != vend; ++vit) { + halfedge_around_target_iterator havit, havend; + for(boost::tie(havit, havend) = CGAL::halfedges_around_target(halfedge(*vit, fg), fg); + havit != havend; ++havit) { + assert(target(*havit, fg) == *vit); + + // check if we are really moving clockwise + halfedge_around_target_iterator step = boost::next(havit); + if(step != havend) { + halfedge_descriptor stepd = *step; + assert(stepd == opposite(next(*havit, fg), fg)); + } + } + } +} + +template +void test_halfedge_around_face_iterator(const Graph& g) +{ + typedef typename boost::graph_traits::face_descriptor g_face_descriptor; + typedef boost::associative_property_map< std::map< g_face_descriptor, std::size_t > >FCMap; + typedef CGAL::Connected_component_graph Adapter; + CGAL_GRAPH_TRAITS_MEMBERS(Adapter); + std::map map; + CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); + Adapter fg(g, boost::make_assoc_property_map(map), 0); + face_iterator fit, fend; + for(boost::tie(fit, fend) = faces(fg); fit != fend; ++fit) { + halfedge_around_face_iterator hafit, hafend; + boost::tie(hafit, hafend) = CGAL::halfedges_around_face(halfedge(*fit, fg), fg); + assert(std::distance(hafit, hafend) != 0); + for(boost::tie(hafit, hafend) = CGAL::halfedges_around_face(halfedge(*fit, fg), fg); hafit != hafend; ++hafit) { + assert(face(*hafit, fg) == *fit); + } + } +} + +template +void test_edge_iterators(const Graph& g) +{ + typedef typename boost::graph_traits::face_descriptor g_face_descriptor; + typedef boost::associative_property_map< std::map< g_face_descriptor, std::size_t > >FCMap; + typedef CGAL::Connected_component_graph Adapter; + CGAL_GRAPH_TRAITS_MEMBERS(Adapter); + std::map map; + CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); + Adapter fg(g, boost::make_assoc_property_map(map), 0); + + // do we iterate as many as that? + edge_iterator eb, ee; + boost::tie(eb, ee) = edges(fg); + assert(boost::numeric_cast(std::distance(eb, ee)) == num_edges(g)); + id_map ids; + unsigned int count = 0; + for(boost::tie(eb, ee) = edges(fg); eb != ee; ++eb) { + edge_descriptor e = *eb; + std::pair r = ids.insert(get(boost::edge_index, g, e)); + // unique? + assert(r.second); + ++count; + } + assert(count == num_edges(fg)); +} + +template +void test_vertex_iterators(Graph& g) +{ + typedef typename boost::graph_traits::face_descriptor g_face_descriptor; + typedef boost::associative_property_map< std::map< g_face_descriptor, std::size_t > >FCMap; + typedef CGAL::Connected_component_graph Adapter; + CGAL_GRAPH_TRAITS_MEMBERS(Adapter); + std::map map; + CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); + Adapter fg(g, boost::make_assoc_property_map(map), 0); + vertex_iterator vb, ve; + std::size_t count = 0; + for(boost::tie(vb, ve) = vertices(fg); vb != ve; ++vb){ + ++count; + } + + assert(count == num_vertices(fg)); + + // check that the iterators reach uniques + id_map ids; + + count = 0; + for(boost::tie(vb, ve) = vertices(fg); vb != ve; ++vb) { + std::pair r = ids.insert(get(boost::vertex_index, g, *vb)); + assert(r.second); + ++count; + } + assert(count == num_vertices(fg)); +} + + +template +void test_out_edges(const Graph& g) +{ + typedef typename boost::graph_traits::face_descriptor g_face_descriptor; + typedef boost::associative_property_map< std::map< g_face_descriptor, std::size_t > >FCMap; + typedef CGAL::Connected_component_graph Adapter; + CGAL_GRAPH_TRAITS_MEMBERS(Adapter); + std::map map; + CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); + Adapter fg(g, boost::make_assoc_property_map(map), 0); + + vertex_iterator vb, ve; + for(boost::tie(vb, ve) = vertices(fg); vb != ve; ++vb) { + id_map v_ids; + + vertex_descriptor around = *vb; + out_edge_iterator oeb, oee; + for(boost::tie(oeb, oee) = out_edges(*vb, fg); oeb != oee; ++oeb) { + vertex_descriptor t = target(*oeb, fg); + vertex_descriptor s = source(*oeb, fg); + assert(s != t); + assert(s == around); + assert(t != around); + std::pair r = + v_ids.insert(get(boost::vertex_index, g, target(*oeb, fg))); + assert(r.second); + } + } +} + +template +void test_in_edges(const Graph& g) +{ + typedef typename boost::graph_traits::face_descriptor g_face_descriptor; + typedef boost::associative_property_map< std::map< g_face_descriptor, std::size_t > >FCMap; + typedef CGAL::Connected_component_graph Adapter; + CGAL_GRAPH_TRAITS_MEMBERS(Adapter); + std::map map; + CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); + Adapter fg(g, boost::make_assoc_property_map(map), 0); + + vertex_iterator vb, ve; + for(boost::tie(vb, ve) = vertices(fg); vb != ve; ++vb) { + id_map v_ids; + vertex_descriptor around = *vb; + in_edge_iterator ieb, iee; + for(boost::tie(ieb, iee) = in_edges(*vb, fg); ieb != iee; ++ieb) { + vertex_descriptor t = target(*ieb, fg); + vertex_descriptor s = source(*ieb, fg); + assert(t == around); + assert(s != around); + std::pair r = + v_ids.insert(get(boost::vertex_index, g, source(*ieb, fg))); + assert(r.second); + } + } +} + +template +void test_in_out_edges(const Graph& g) +{ + typedef typename boost::graph_traits::face_descriptor g_face_descriptor; + typedef boost::associative_property_map< std::map< g_face_descriptor, std::size_t > >FCMap; + typedef CGAL::Connected_component_graph Adapter; + CGAL_GRAPH_TRAITS_MEMBERS(Adapter); + std::map map; + CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); + Adapter fg(g, boost::make_assoc_property_map(map), 0); + + // check that the sets of in out edges are the same + vertex_iterator vb, ve; + for(boost::tie(vb, ve) = vertices(fg); vb != ve; ++vb) { + id_map v_ids; + std::vector in, out; + in_edge_iterator ieb, iee; + for(boost::tie(ieb, iee) = in_edges(*vb, fg); ieb != iee; ++ieb) { + std::pair r = + v_ids.insert(get(boost::vertex_index, g, source(*ieb, fg))); + assert(r.second); + in.push_back(source(*ieb, fg)); + } + out_edge_iterator oeb, oee; + for(boost::tie(oeb, oee) = out_edges(*vb, fg); oeb != oee; ++oeb) { + std::pair r = + v_ids.insert(get(boost::vertex_index, g, target(*oeb, fg))); + // insertion must fail + assert(!r.second); + out.push_back(target(*oeb, fg)); + } + // did we walk the vertices in the same order? + assert(in.size() == out.size()); + assert(std::equal(in.begin(), in.end(), out.begin())); + assert(in.size() == in_degree(*vb, fg)); + assert(out.size() == out_degree(*vb, fg)); + assert(in.size() == degree(*vb, fg)); + assert(degree(*vb, fg) == in_degree(*vb, fg)); + assert(degree(*vb, fg) == out_degree(*vb, fg)); + } +} + +// check that every edge can be found through edge(u, v, g) +template +void test_edge_find(const Graph& g) +{ + typedef typename boost::graph_traits::face_descriptor g_face_descriptor; + typedef boost::associative_property_map< std::map< g_face_descriptor, std::size_t > >FCMap; + typedef CGAL::Connected_component_graph Adapter; + CGAL_GRAPH_TRAITS_MEMBERS(Adapter); + std::map map; + CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); + Adapter fg(g, boost::make_assoc_property_map(map), 0); + typedef std::pair ret; + + edge_iterator eb, ee; + for(boost::tie(eb, ee) = edges(fg); eb != ee; ++eb) { + vertex_descriptor s = source(*eb, fg); + vertex_descriptor t = target(*eb, fg); + ret found = edge(s, t, fg); + ret found2 = edge(t, s, fg); + assert(found.second); + assert(found2.second); + assert(found.first == *eb); + assert(found2.first == *eb); + } +} + +template +void test_faces(const Graph& g) +{ + typedef typename boost::graph_traits::face_descriptor g_face_descriptor; + typedef boost::associative_property_map< std::map< g_face_descriptor, std::size_t > >FCMap; + typedef CGAL::Connected_component_graph Adapter; + CGAL_GRAPH_TRAITS_MEMBERS(Adapter); + std::map map; + CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); + Adapter fg(g, boost::make_assoc_property_map(map), 0); + + unsigned int count = 0; + face_iterator fb, fe; + for(boost::tie(fb, fe) = faces(fg); fb != fe; ++fb) { + ++count; + // reverse look-up + halfedge_descriptor assoc = halfedge(*fb, fg); + assert(face(assoc, fg) == *fb); + // check the enclosure + halfedge_around_face_iterator encb, ence; + for(boost::tie(encb, ence) = CGAL::halfedges_around_face(halfedge(*fb, fg), fg); encb != ence; ++encb) { + assert(face(*encb, fg) == *fb); + } + } + assert(count == num_faces(fg)); +} + +template +void test_read(const Graph& g) +{ + typedef typename boost::graph_traits::face_descriptor g_face_descriptor; + typedef boost::associative_property_map< std::map< g_face_descriptor, std::size_t > >FCMap; + typedef CGAL::Connected_component_graph Adapter; + CGAL_GRAPH_TRAITS_MEMBERS(Adapter); + std::map map; + CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); + Adapter fg(g, boost::make_assoc_property_map(map), 0); + assert(CGAL::is_valid(fg)); +} + +template +void +test(const std::vector& graphs) +{ + BOOST_FOREACH(Graph p, graphs){ + test_read(p); + test_vertex_iterators(p); + test_out_edges(p); + test_in_edges(p); + test_in_out_edges(p); + test_edge_find(p); + test_faces(p); + test_edge_iterators(p); + test_halfedge_around_face_iterator(p); + test_halfedge_around_vertex_iterator(p); + } +} + + +typedef SM::Point Point_3; + +template +struct Constraint : public boost::put_get_helper > +{ + typedef typename boost::graph_traits::edge_descriptor edge_descriptor; + typedef boost::readable_property_map_tag category; + typedef bool value_type; + typedef bool reference; + typedef edge_descriptor key_type; + + + Constraint() + :g_(NULL) + {} + + Constraint(SM& g, VertexPointPMap vpp) + : g_(&g), vppmap(vpp) + {} + + bool operator[](edge_descriptor e) const + { + const SM& g = *g_; + if( + (boost::get(vppmap, target(e, g)) == Point_3(1,1,1) || + boost::get(vppmap, source(e, g)) == Point_3(1,1,1)) && + (boost::get(vppmap, target(e, g)) == Point_3(0,0,0) || + boost::get(vppmap, source(e, g)) == Point_3(0,0,0)) + || + (boost::get(vppmap, target(e, g)) == Point_3(1,1,1) || + boost::get(vppmap, source(e, g)) == Point_3(1,1,1)) && + (boost::get(vppmap, target(e, g)) == Point_3(0,0,1) || + boost::get(vppmap, source(e, g)) == Point_3(0,0,1)) + || + (boost::get(vppmap, target(e, g)) == Point_3(0,0,1) || + boost::get(vppmap, source(e, g)) == Point_3(0,0,1)) && + (boost::get(vppmap, target(e, g)) == Point_3(0,0,0) || + boost::get(vppmap, source(e, g)) == Point_3(0,0,0)) + ) + return true; + else + return false; + } + + const SM* g_; + VertexPointPMap vppmap; +}; + + +int +main() +{ + typedef CGAL::Connected_component_graph::face_descriptor , std::size_t> > Adapter; + test(sm_data()); + //Make a tetrahedron and test the adapter for a patch that only contains the front face + SM* sm = new SM(); + CGAL::make_tetrahedron( + Point_3(1,1,1), + Point_3(0,0,0), + Point_3(0,0,1), + Point_3(1,0,1), + *sm); + SM::Property_map::face_descriptor , std::size_t> fccmap = + sm->add_property_map::face_descriptor, std::size_t>("f:CC").first; + CGAL::Properties::Property_map::vertex_descriptor, SM::Point> positions = + sm->points(); + CGAL::Polygon_mesh_processing::connected_components(*sm, fccmap, CGAL::Polygon_mesh_processing::parameters:: + edge_is_constrained_map(Constraint::vertex_descriptor, + SM::Point> >(*sm, positions))); + + Adapter fga(*sm, fccmap, boost::get(fccmap, *faces(*sm).first)); + CGAL_GRAPH_TRAITS_MEMBERS(Adapter); + //check that there is the right number of simplices in fga + CGAL_assertion(CGAL::is_valid(fga)); + CGAL_assertion(std::distance(faces(fga).first,faces(fga).second) == 1); + CGAL_assertion(std::distance(edges(fga).first,edges(fga).second) == 3); + CGAL_assertion(std::distance(halfedges(fga).first,halfedges(fga).second) == 6); + CGAL_assertion(std::distance(vertices(fga).first,vertices(fga).second) == 3); + halfedge_descriptor h = halfedge(*faces(fga).first, fga); + vertex_descriptor v = target(h, fga); + //check that next() works inside the patch + CGAL_assertion( + next(next(next(h, fga), fga), fga) == h + ); + //check that next() works on bordure of the patch + h = opposite(h, fga); + CGAL_assertion( + next(next(next(h, fga), fga), fga) == h + ); + //check that prev() works inside the patch + h = halfedge(*faces(fga).first, fga); + CGAL_assertion( + prev(prev(prev(h, fga), fga), fga) == h + ); + //check that prev() works on bordure of the patch + h = opposite(h, fga); + CGAL_assertion( + prev(prev(prev(h, fga), fga), fga) == h + ); + + //check degree + CGAL_assertion(degree(v, fga) == 2); + //check in_edges and out_edges + CGAL_assertion(std::distance(in_edges(v, fga).first ,in_edges(v, fga).second) == 2 ); + CGAL_assertion(std::distance(out_edges(v, fga).first ,out_edges(v, fga).second) == 2 ); + return 0; +} From 00af50049848aff37e5dd478c09a3483c27b944b Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 26 Jan 2017 14:21:06 +0100 Subject: [PATCH 02/38] Add a function to copy a patch and document the Connected_component_graph --- BGL/doc/BGL/Doxyfile.in | 3 + BGL/doc/BGL/PackageDescription.txt | 2 + ...nt_graph.h => Connected_component_graph.h} | 68 ++--- .../CGAL/boost/graph/copy_face_graph_patch.h | 260 ++++++++++++++++++ ...raph_concept_Connected_component_graph.cpp | 2 +- .../BGL/test_Connected_component_graph.cpp | 3 +- 6 files changed, 292 insertions(+), 46 deletions(-) rename BGL/include/CGAL/boost/graph/{connected_component_graph.h => Connected_component_graph.h} (93%) create mode 100644 BGL/include/CGAL/boost/graph/copy_face_graph_patch.h diff --git a/BGL/doc/BGL/Doxyfile.in b/BGL/doc/BGL/Doxyfile.in index 6fccfa0fda7..94cc0d31684 100644 --- a/BGL/doc/BGL/Doxyfile.in +++ b/BGL/doc/BGL/Doxyfile.in @@ -7,13 +7,16 @@ INPUT += ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/Euler_operations.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/selection.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/split_graph_into_polylines.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/copy_face_graph.h \ + ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/copy_face_graph_patch.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/Graph_with_descriptor_with_graph.h \ + ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/connected_component_graph.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/Dual.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/convert_nef_polyhedron_to_polygon_mesh.h EXAMPLE_PATH = ${CGAL_Surface_mesh_skeletonization_EXAMPLE_DIR} \ ${CGAL_BGL_EXAMPLE_DIR} ALIASES += "bgllink{1}=\1" +ALIASES += "cgalNamedParamsBegin=
Named Parameters
" EXTRACT_ALL=NO HIDE_UNDOC_MEMBERS = YES HIDE_UNDOC_CLASSES = YES diff --git a/BGL/doc/BGL/PackageDescription.txt b/BGL/doc/BGL/PackageDescription.txt index cba2f490e72..0c1a13847b5 100644 --- a/BGL/doc/BGL/PackageDescription.txt +++ b/BGL/doc/BGL/PackageDescription.txt @@ -316,6 +316,7 @@ user might encounter. - `CGAL::Dual` - `CGAL::Graph_with_descriptor_with_graph` - `CGAL::Graph_with_descriptor_with_graph_property_map` +- `CGAL::Connected_component_graph` ## Helper Functions ## - `CGAL::is_border()` @@ -343,6 +344,7 @@ user might encounter. - `CGAL::clear()` - `CGAL::copy_face_graph()` - `CGAL::reserve()` +- `CGAL::copy_face_graph_patch()` ## Iterators ## - `CGAL::Halfedge_around_source_iterator` diff --git a/BGL/include/CGAL/boost/graph/connected_component_graph.h b/BGL/include/CGAL/boost/graph/Connected_component_graph.h similarity index 93% rename from BGL/include/CGAL/boost/graph/connected_component_graph.h rename to BGL/include/CGAL/boost/graph/Connected_component_graph.h index 265114a2bc0..394efd5eada 100644 --- a/BGL/include/CGAL/boost/graph/connected_component_graph.h +++ b/BGL/include/CGAL/boost/graph/Connected_component_graph.h @@ -15,6 +15,26 @@ namespace CGAL { +/*! +\ingroup PkgBGLHelper + +The class `Connected_component_graph` wraps a graph into another graph in such a way that only the specified connected component is seen from the outside. + +For example, calling `vertices(graph)` will return an iterator range of all but only the vertices that belong to the connected component whose id in `fccmap` is `pid`. + +\attention The functions `num_vertices()`, `num_edges()`, `num_halfedges()`, `num_faces()`, are forwarded from the underlying graph, +which means that `num_vertices(graph)` is different from `std::distance(vertices(graph).first,vertices(graph).second)` + +Property maps can be wrapped with `Connected_component_graph_property_map`. +\tparam Graph must be a model of a `FaceListGraph` and `HalfedgeListGraph`. +\tparam FaceComponentMap a model of `WritablePropertyMap` with + `boost::graph_traits::%face_descriptor` as key type and + `graph_traits::faces_size_type` as value type. + +\cgalModels `FaceListGraph` +\cgalModels `HalfedgeListGraph` +*/ + template struct Connected_component_graph { @@ -520,51 +540,11 @@ is_valid(const Connected_component_graph & w, bool verb return is_valid(w.graph(),verbose); } -template -struct Connected_component_graph_property_map { - - typedef typename boost::property_traits::category category; - typedef typename boost::property_traits::value_type value_type; - typedef typename boost::property_traits::reference reference; - typedef typename boost::property_traits::key_type key_type; - - Graph* graph; - PM pm; - - Connected_component_graph_property_map() - : graph(NULL) - {} - - Connected_component_graph_property_map(const Graph& graph, const PM& pm) - : graph(const_cast(&graph)), pm(pm) - {} - - friend - reference - get(const Connected_component_graph_property_map& gpm, const key_type& k) - { - CGAL_assertion(gpm.graph!=NULL); - return get(gpm.pm, k); - } - - friend - void - put(const Connected_component_graph_property_map& gpm, const key_type& k, const value_type& v) - { - CGAL_assertion(gpm.graph!=NULL); - put(gpm.pm, k, v); - } -}; // class Connected_component_graph_property_map - - - template -Connected_component_graph_property_map::type> +typename boost::property_map::type get(PropertyTag ptag, const Connected_component_graph& w) { - typedef typename boost::property_map::type PM; - typedef Connected_component_graph_property_map GPM; - return GPM(w.graph(), get(ptag,w.graph())); + return get(ptag, w.graph()); } @@ -592,8 +572,8 @@ put(PropertyTag ptag, const Connected_component_graph& namespace boost { template struct property_map,PropertyTag> { - typedef CGAL::Connected_component_graph_property_map::type> type; - typedef CGAL::Connected_component_graph_property_map::const_type> const_type; + typedef typename boost::property_map::type type; + typedef typename boost::property_map::const_type const_type; }; template diff --git a/BGL/include/CGAL/boost/graph/copy_face_graph_patch.h b/BGL/include/CGAL/boost/graph/copy_face_graph_patch.h new file mode 100644 index 00000000000..d9d17da7cd9 --- /dev/null +++ b/BGL/include/CGAL/boost/graph/copy_face_graph_patch.h @@ -0,0 +1,260 @@ +// Copyright (c) 2017 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Maxime Gimeno + +#ifndef COPY_FACE_GRAPH_PATCH_H +#define COPY_FACE_GRAPH_PATCH_H + +#include +#include +#include +#include + +namespace CGAL { + +/*! + \ingroup PkgBGLHelperFct + + copies a connected component of a source model of `FaceListGraph` into a target model of a + `FaceListGraph`. `OutputIterators` can be provided to produce a + mapping between source and target elements. The target graph is not + cleared. + + \tparam SourceMesh a model of `FaceListGraph`. + The descriptor types `boost::graph_traits::%vertex_descriptor` + and `boost::graph_traits::%face_descriptor` must be + models of `Hashable`. + \tparam TargetMesh a model of `FaceListGraph` + \tparam FaceComponentMap a model of `WritablePropertyMap` with + `boost::graph_traits::%face_descriptor` as key type and + `graph_traits::faces_size_type` as value type. + \tparam V2V a model of `OutputIterator` accepting `std::pair` + \tparam H2H a model of `OutputIterator` accepting `std::pair` + \tparam F2F a model of `OutputIterator` accepting `std::pair` + \tparam Src_vpm a model of `ReadablePropertyMap` with `sm_vertex_descriptor` as key + \tparam Tgt_vpm a model of `WritablePropertyMap` with `tm_vertex_descriptor` as key + where the prefix `sm_` and `tm_` mean belonging to the source and + target mesh respectively. + + The types `sm_vertex_descriptor` and `sm_face_descriptor` must be models of the concept `Hashable`. + + \param sm the source mesh + \param fccmap the property map containing the faces of `sm` and the index of their connected component. + \param pid the index in `fccmap` of the connected component to copy + \param tm the target mesh + \param v2v pairs of `vertex_descriptors` from `sm` and corresponding `vertex_descriptors` in `tm` are added to `v2v` + \param h2h pairs of `halfedge_descriptors` from `sm` and corresponding `halfedge_descriptors` in `tm` are added to `h2h` + \param f2f pairs of `face_descriptors` from `sm` and corresponding `face_descriptors` in `tm` are added to `f2f` + \param sm_vpm vertex point map for `sm` + \param tm_vpm vertex point map for `tm` + + The points from `sm` to `tm` are converted using + `CGAL::Cartesian_converter`. + `SourceKernel` and `TargetKernel` are deduced using `CGAL::Kernel_traits` + from the value types of `Src_vpm` and `Tgt_vpm`. + + Other properties are not copied. +*/ + +#if defined(DOXYGEN_RUNNING) // Use template default arguments +template ::const_type, + typename Tgt_vpm = typename boost::property_map::type> +void copy_face_graph_patch(const SourceMesh& sm, + FaceComponentMap fccmap, + typename boost::graph_traits::faces_size_type pid, + TargetMesh& tm, + V2V v2v = V2V(), H2H h2h = H2H(), F2F f2f = F2F(), + Src_vpm sm_vpm = get(vertex_point, sm), + Tgt_vpm tm_vpm = get(vertex_point, tm) ) +#else // use the overloads +template +void copy_face_graph_patch(const SourceMesh& sm, FaceComponentMap fccmap, typename boost::graph_traits::faces_size_type pid, TargetMesh& tm, + V2V v2v, H2H h2h, F2F f2f, + Src_vpm sm_vpm, Tgt_vpm tm_vpm ) +#endif +{ + typedef CGAL::Connected_component_graph Adapter; + + copy_face_graph(Adapter(sm, fccmap, pid), tm, v2v, h2h, f2f, sm_vpm, tm_vpm); +} + + +/*! + \ingroup PkgBGLHelperFct + + copies the connected component containg `seed_face` of a source model of `FaceListGraph` into a target model of a + `FaceListGraph`. `OutputIterators` can be provided to produce a + mapping between source and target elements. The target graph is not + cleared. + + \tparam SourceMesh a model of `FaceListGraph`. + The descriptor types `boost::graph_traits::%vertex_descriptor` + and `boost::graph_traits::%face_descriptor` must be + models of `Hashable`. + \tparam TargetMesh a model of `FaceListGraph` + \tparam NamedParameters a sequence of \ref namedparameters + \tparam V2V a model of `OutputIterator` accepting `std::pair` + \tparam H2H a model of `OutputIterator` accepting `std::pair` + \tparam F2F a model of `OutputIterator` accepting `std::pair` + \tparam Src_vpm a model of `ReadablePropertyMap` with `sm_vertex_descriptor` as key + \tparam Tgt_vpm a model of `WritablePropertyMap` with `tm_vertex_descriptor` as key + where the prefix `sm_` and `tm_` mean belonging to the source and + target mesh respectively. + + The types `sm_vertex_descriptor` and `sm_face_descriptor` must be models of the concept `Hashable`. + + \param sm the source mesh + \param tm the target mesh + \param seed_face a face of `sm` belonging to the connected component to copy + \param np optional \ref namedparameters described below +* +* \cgalNamedParamsBegin +* \cgalParamBegin{edge_is_constrained_map} a property map containing the constrained-or-not status of each edge of `pmesh` \cgalParamEnd +* \cgalNamedParamsEnd + + \param v2v pairs of `vertex_descriptors` from `sm` and corresponding `vertex_descriptors` in `tm` are added to `v2v` + \param h2h pairs of `halfedge_descriptors` from `sm` and corresponding `halfedge_descriptors` in `tm` are added to `h2h` + \param f2f pairs of `face_descriptors` from `sm` and corresponding `face_descriptors` in `tm` are added to `f2f` + \param sm_vpm vertex point map for `sm` + \param tm_vpm vertex point map for `tm` + + The points from `sm` to `tm` are converted using + `CGAL::Cartesian_converter`. + `SourceKernel` and `TargetKernel` are deduced using `CGAL::Kernel_traits` + from the value types of `Src_vpm` and `Tgt_vpm`. + + Other properties are not copied. + +*/ +#if defined(DOXYGEN_RUNNING) // Use template default arguments +template ::const_type, + typename Tgt_vpm = typename boost::property_map::type> +void copy_face_graph_patch(const SourceMesh& sm, + const typename boost::graph_traits:: + face_descriptor& seed_face, + const NamedParameters& np = boost::parameter::all_default(), + TargetMesh& tm, + V2V v2v = V2V(), H2H h2h = H2H(), F2F f2f = F2F(), + Src_vpm sm_vpm = get(vertex_point, sm), + Tgt_vpm tm_vpm = get(vertex_point, tm) ) +#else // use the overloads + +template +void copy_face_graph_patch(const SourceMesh& sm, const typename boost::graph_traits:: + face_descriptor& seed_face, + const NamedParameters& np, TargetMesh& tm, V2V v2v, H2H h2h, F2F f2f, + Src_vpm sm_vpm, Tgt_vpm tm_vpm ) +#endif +{ + + typedef typename boost::graph_traits::face_descriptor g_face_descriptor; + typedef typename boost::graph_traits::faces_size_type faces_size_t; + typedef boost::associative_property_map< std::map< g_face_descriptor, faces_size_t> >FCMap; + typedef CGAL::Connected_component_graph Adapter; + + std::map map; + Polygon_mesh_processing::connected_components(sm, boost::make_assoc_property_map(map), np); + copy_face_graph(Adapter(sm, boost::make_assoc_property_map(map), map[seed_face]), tm, v2v, h2h, f2f, sm_vpm, tm_vpm); +} + +#if !defined(DOXYGEN_RUNNING) +template +void copy_face_graph_patch(const SourceMesh& sm, FaceComponentMap fccmap, typename boost::graph_traits::faces_size_type pid, TargetMesh& tm) +{ copy_face_graph_patch(sm, fccmap, pid, tm, Emptyset_iterator(), Emptyset_iterator(), Emptyset_iterator(), + get(vertex_point, sm), get(vertex_point, tm)); } + +template +void copy_face_graph_patch(const SourceMesh& sm, FaceComponentMap fccmap, typename boost::graph_traits::faces_size_type pid, TargetMesh& tm, V2V v2v) +{ copy_face_graph_patch(sm, fccmap, pid, tm, v2v, Emptyset_iterator(), Emptyset_iterator(), + get(vertex_point, sm), get(vertex_point, tm)); } + +template +void copy_face_graph_patch(const SourceMesh& sm, FaceComponentMap fccmap, typename boost::graph_traits::faces_size_type pid, TargetMesh& tm, V2V v2v, H2H h2h) +{ copy_face_graph_patch(sm, fccmap, pid, tm, v2v, h2h, Emptyset_iterator(), + get(vertex_point, sm), get(vertex_point, tm)); } + +template +void copy_face_graph_patch(const SourceMesh& sm, FaceComponentMap fccmap, typename boost::graph_traits::faces_size_type pid, TargetMesh& tm, V2V v2v, H2H h2h, F2F f2f) +{ copy_face_graph_patch(sm, fccmap, pid, tm, v2v, h2h, f2f, + get(vertex_point, sm), get(vertex_point, tm)); } + +template +void copy_face_graph_patch(const SourceMesh& sm, FaceComponentMap fccmap, typename boost::graph_traits::faces_size_type pid, TargetMesh& tm, V2V v2v, H2H h2h, F2F f2f, Src_vpm sm_vpm) +{ copy_face_graph_patch(sm, fccmap, pid, tm, v2v, h2h, f2f, + sm_vpm, get(vertex_point, tm)); } + + +template +void copy_face_graph_patch(const SourceMesh& sm, const typename boost::graph_traits:: + face_descriptor& seed_face, TargetMesh& tm) +{ copy_face_graph_patch(sm, seed_face, Polygon_mesh_processing::parameters::all_default(), tm, Emptyset_iterator(), Emptyset_iterator(), Emptyset_iterator(), + get(vertex_point, sm), get(vertex_point, tm)); } + +template +void copy_face_graph_patch(const SourceMesh& sm, const typename boost::graph_traits:: + face_descriptor& seed_face, + const NamedParameters& np, TargetMesh& tm) +{ copy_face_graph_patch(sm, seed_face, np, tm, Emptyset_iterator(), Emptyset_iterator(), Emptyset_iterator(), + get(vertex_point, sm), get(vertex_point, tm)); } + +template +void copy_face_graph_patch(const SourceMesh& sm, const typename boost::graph_traits:: + face_descriptor& seed_face, + const NamedParameters& np, TargetMesh& tm, V2V v2v) +{ copy_face_graph_patch(sm, seed_face, np, tm, v2v, Emptyset_iterator(), Emptyset_iterator(), + get(vertex_point, sm), get(vertex_point, tm)); } + +template +void copy_face_graph_patch(const SourceMesh& sm, const typename boost::graph_traits:: + face_descriptor& seed_face, + const NamedParameters& np, TargetMesh& tm, V2V v2v, H2H h2h) +{ copy_face_graph_patch(sm, seed_face, np, tm, v2v, h2h, Emptyset_iterator(), + get(vertex_point, sm), get(vertex_point, tm)); } + +template +void copy_face_graph_patch(const SourceMesh& sm, const typename boost::graph_traits:: + face_descriptor& seed_face, + const NamedParameters& np, TargetMesh& tm, V2V v2v, H2H h2h, F2F f2f) +{ copy_face_graph_patch(sm, seed_face, np, tm, v2v, h2h, f2f, + get(vertex_point, sm), get(vertex_point, tm)); } + +template +void copy_face_graph_patch(const SourceMesh& sm, const typename boost::graph_traits:: + face_descriptor& seed_face, + const NamedParameters& np, TargetMesh& tm, V2V v2v, H2H h2h, F2F f2f, Src_vpm sm_vpm) +{ copy_face_graph_patch(sm, seed_face, np, tm, v2v, h2h, f2f, + sm_vpm, get(vertex_point, tm)); } +#endif +}//end CGAL +#endif // COPY_FACE_GRAPH_PATCH_H diff --git a/BGL/test/BGL/graph_concept_Connected_component_graph.cpp b/BGL/test/BGL/graph_concept_Connected_component_graph.cpp index 9cb75f5256e..b5194153d03 100644 --- a/BGL/test/BGL/graph_concept_Connected_component_graph.cpp +++ b/BGL/test/BGL/graph_concept_Connected_component_graph.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include diff --git a/BGL/test/BGL/test_Connected_component_graph.cpp b/BGL/test/BGL/test_Connected_component_graph.cpp index bcf66b89c0d..e10774c67b1 100644 --- a/BGL/test/BGL/test_Connected_component_graph.cpp +++ b/BGL/test/BGL/test_Connected_component_graph.cpp @@ -1,4 +1,4 @@ -#include +#include #include "test_Prefix.h" #include @@ -406,5 +406,6 @@ main() //check in_edges and out_edges CGAL_assertion(std::distance(in_edges(v, fga).first ,in_edges(v, fga).second) == 2 ); CGAL_assertion(std::distance(out_edges(v, fga).first ,out_edges(v, fga).second) == 2 ); + return 0; } From be5103c1a1ef0530a6bc95243a6f803a7c70aa8a Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 26 Jan 2017 14:58:05 +0100 Subject: [PATCH 03/38] Fix license and include guards --- .../boost/graph/Connected_component_graph.h | 24 ++++++++++++++++--- .../CGAL/boost/graph/copy_face_graph_patch.h | 6 ++--- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/BGL/include/CGAL/boost/graph/Connected_component_graph.h b/BGL/include/CGAL/boost/graph/Connected_component_graph.h index 394efd5eada..17f5e41ce8b 100644 --- a/BGL/include/CGAL/boost/graph/Connected_component_graph.h +++ b/BGL/include/CGAL/boost/graph/Connected_component_graph.h @@ -1,5 +1,23 @@ -#ifndef CGAL_BOOST_GRAPH_Connected_component_graph_H -#define CGAL_BOOST_GRAPH_Connected_component_graph_H +// Copyright (c) 2017 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Maxime Gimeno +#ifndef CGAL_BOOST_GRAPH_CONNECTED_COMPONENT_GRAPH_H +#define CGAL_BOOST_GRAPH_CONNECTED_COMPONENT_GRAPH_H #include #include @@ -582,4 +600,4 @@ namespace boost { }// namespace boost -#endif // CGAL_BOOST_GRAPH_Connected_component_graph_H +#endif // CGAL_BOOST_GRAPH_CONNECTED_COMPONENT_GRAPH_H diff --git a/BGL/include/CGAL/boost/graph/copy_face_graph_patch.h b/BGL/include/CGAL/boost/graph/copy_face_graph_patch.h index d9d17da7cd9..2c8dbccc87e 100644 --- a/BGL/include/CGAL/boost/graph/copy_face_graph_patch.h +++ b/BGL/include/CGAL/boost/graph/copy_face_graph_patch.h @@ -17,8 +17,8 @@ // // Author(s) : Maxime Gimeno -#ifndef COPY_FACE_GRAPH_PATCH_H -#define COPY_FACE_GRAPH_PATCH_H +#ifndef CGAL_BOOST_GRAPH_COPY_FACE_GRAPH_PATCH_H +#define CGAL_BOOST_GRAPH_COPY_FACE_GRAPH_PATCH_H #include #include @@ -257,4 +257,4 @@ void copy_face_graph_patch(const SourceMesh& sm, const typename boost::graph_tra sm_vpm, get(vertex_point, tm)); } #endif }//end CGAL -#endif // COPY_FACE_GRAPH_PATCH_H +#endif // CGAL_BOOST_GRAPH_COPY_FACE_GRAPH_PATCH_H From f7c3c48c07731ad95c0f0e7e7daa87346140b4f2 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 26 Jan 2017 15:18:10 +0100 Subject: [PATCH 04/38] Fixes --- .../CGAL/boost/graph/Connected_component_graph.h | 11 +++++------ BGL/include/CGAL/boost/graph/copy_face_graph_patch.h | 4 ++-- BGL/test/BGL/test_Connected_component_graph.cpp | 5 +++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/BGL/include/CGAL/boost/graph/Connected_component_graph.h b/BGL/include/CGAL/boost/graph/Connected_component_graph.h index 17f5e41ce8b..e0c94b6ac75 100644 --- a/BGL/include/CGAL/boost/graph/Connected_component_graph.h +++ b/BGL/include/CGAL/boost/graph/Connected_component_graph.h @@ -72,11 +72,6 @@ struct Connected_component_graph } - Connected_component_graph(const Connected_component_graph&f) - : _graph(f.graph()), property_map(f.propertyMap()), patch_index(f.patchIndex()) - { - } - const Graph& graph()const{ return _graph; } FaceComponentMap propertyMap()const{ return property_map; } @@ -95,6 +90,7 @@ struct Connected_component_graph template bool operator()(Simplex s) { + CGAL_assertion(adapter!=NULL); return (is_valid(s, *adapter)); } const Self* adapter; @@ -513,7 +509,10 @@ face(typename boost::graph_traits< Connected_component_graph & w) { CGAL_assertion(CGAL::is_valid(h, w)); - return face(h,w.graph()); + if(is_valid(face(h,w.graph()), w)) + return face(h,w.graph()); + else + return boost::graph_traits< CGAL::Connected_component_graph >::null_face(); } template diff --git a/BGL/include/CGAL/boost/graph/copy_face_graph_patch.h b/BGL/include/CGAL/boost/graph/copy_face_graph_patch.h index 2c8dbccc87e..fe0c808d356 100644 --- a/BGL/include/CGAL/boost/graph/copy_face_graph_patch.h +++ b/BGL/include/CGAL/boost/graph/copy_face_graph_patch.h @@ -180,10 +180,10 @@ void copy_face_graph_patch(const SourceMesh& sm, const typename boost::graph_tra typedef typename boost::graph_traits::face_descriptor g_face_descriptor; typedef typename boost::graph_traits::faces_size_type faces_size_t; - typedef boost::associative_property_map< std::map< g_face_descriptor, faces_size_t> >FCMap; + typedef boost::associative_property_map< boost::unordered_map< g_face_descriptor, faces_size_t> >FCMap; typedef CGAL::Connected_component_graph Adapter; - std::map map; + boost::unordered_map map(CGAL::num_faces(sm)); Polygon_mesh_processing::connected_components(sm, boost::make_assoc_property_map(map), np); copy_face_graph(Adapter(sm, boost::make_assoc_property_map(map), map[seed_face]), tm, v2v, h2h, f2f, sm_vpm, tm_vpm); } diff --git a/BGL/test/BGL/test_Connected_component_graph.cpp b/BGL/test/BGL/test_Connected_component_graph.cpp index e10774c67b1..8ee86e35392 100644 --- a/BGL/test/BGL/test_Connected_component_graph.cpp +++ b/BGL/test/BGL/test_Connected_component_graph.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include typedef boost::unordered_set id_map; @@ -12,10 +13,10 @@ template void test_halfedge_around_vertex_iterator(const Graph& g) { typedef typename boost::graph_traits::face_descriptor g_face_descriptor; - typedef boost::associative_property_map< std::map< g_face_descriptor, std::size_t > >FCMap; + typedef boost::associative_property_map< boost::unordered_map< g_face_descriptor, std::size_t > >FCMap; typedef CGAL::Connected_component_graph Adapter; CGAL_GRAPH_TRAITS_MEMBERS(Adapter); - std::map map; + boost::unordered_map map(CGAL::num_faces(g)); CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); From 904b673da6de4d3a2eb3fa8e57b5284499e8b7c0 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 27 Jan 2017 11:29:08 +0100 Subject: [PATCH 05/38] Changes for review. --- .../boost/graph/Connected_component_graph.h | 123 +++++++++--------- ...raph_concept_Connected_component_graph.cpp | 4 +- .../BGL/test_Connected_component_graph.cpp | 3 +- 3 files changed, 63 insertions(+), 67 deletions(-) diff --git a/BGL/include/CGAL/boost/graph/Connected_component_graph.h b/BGL/include/CGAL/boost/graph/Connected_component_graph.h index e0c94b6ac75..12e889c571f 100644 --- a/BGL/include/CGAL/boost/graph/Connected_component_graph.h +++ b/BGL/include/CGAL/boost/graph/Connected_component_graph.h @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -67,16 +66,18 @@ struct Connected_component_graph Connected_component_graph(const Graph& graph, FaceComponentMap fccmap, typename boost::property_traits::value_type pid) - : _graph(graph), property_map(fccmap), patch_index(pid) + : _graph(graph), _property_map(fccmap), _patch_index(pid) { } const Graph& graph()const{ return _graph; } - FaceComponentMap propertyMap()const{ return property_map; } + FaceComponentMap property_map()const{ return _property_map; } - typename boost::property_traits::value_type patchIndex()const{ return patch_index; } + typename boost::property_traits::value_type patch_index()const{ return _patch_index; } + + void change_patch_id(typename boost::property_traits::value_type pid) { _patch_index = pid;} struct Is_simplex_valid { @@ -91,15 +92,15 @@ struct Connected_component_graph bool operator()(Simplex s) { CGAL_assertion(adapter!=NULL); - return (is_valid(s, *adapter)); + return (in_CC(s, *adapter)); } const Self* adapter; }; private: const Graph& _graph; - FaceComponentMap property_map; - typename boost::property_traits::value_type patch_index; + FaceComponentMap _property_map; + typename boost::property_traits::value_type _patch_index; }; } // namespace CGAL @@ -136,12 +137,12 @@ struct graph_traits< CGAL::Connected_component_graph > static vertex_descriptor null_vertex() { - return vertex_descriptor(BGTG::null_vertex()); + return BGTG::null_vertex(); } static halfedge_descriptor null_halfedge() { - return halfedge_descriptor(BGTG::null_halfedge()); + return BGTG::null_halfedge(); } static edge_descriptor null_edge() @@ -151,7 +152,7 @@ struct graph_traits< CGAL::Connected_component_graph > static face_descriptor null_face() { - return face_descriptor(BGTG::null_face()); + return BGTG::null_face(); } }; @@ -167,39 +168,39 @@ struct graph_traits< const CGAL::Connected_component_graph bool -is_valid(const typename boost::graph_traits< Connected_component_graph >::face_descriptor f, +in_CC(const typename boost::graph_traits< Connected_component_graph >::face_descriptor f, const Connected_component_graph & w) { - return boost::get(w.propertyMap(), f) == w.patchIndex(); + return boost::get(w.property_map(), f) == w.patch_index(); } template bool -is_valid(const typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor h, +in_CC(const typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor h, const Connected_component_graph & w) { - return is_valid(face(h, w.graph()), w) || - is_valid(face(opposite(h, w.graph()), w.graph()), w); + return in_CC(face(h, w.graph()), w) || + in_CC(face(opposite(h, w.graph()), w.graph()), w); } template bool -is_valid(const typename boost::graph_traits< Connected_component_graph >::edge_descriptor e, +in_CC(const typename boost::graph_traits< Connected_component_graph >::edge_descriptor e, const Connected_component_graph & w) { - return is_valid(halfedge(e, w.graph()), w); + return in_CC(halfedge(e, w.graph()), w); } template bool -is_valid(const typename boost::graph_traits< Connected_component_graph >::vertex_descriptor v, +in_CC(const typename boost::graph_traits< Connected_component_graph >::vertex_descriptor v, const Connected_component_graph & w) { typename boost::graph_traits >::halfedge_descriptor h = halfedge(v, w.graph()); typename boost::graph_traits >::halfedge_descriptor hcirc = h; do { - if(is_valid(face(hcirc, w.graph()), w)) + if(in_CC(face(hcirc, w.graph()), w)) return true; hcirc = opposite(next(hcirc, w.graph()), w.graph()); }while(hcirc != h); @@ -226,13 +227,13 @@ typename boost::graph_traits::degree_size_type degree(typename boost::graph_traits >::vertex_descriptor v, const Connected_component_graph& w) { - CGAL_assertion(is_valid(v, w)); + CGAL_assertion(in_CC(v, w)); typename boost::graph_traits::degree_size_type v_deg = 0; typename boost::graph_traits >::halfedge_descriptor h = halfedge(v, w); typename boost::graph_traits >::halfedge_descriptor hcirc = h; do { - if(is_valid(hcirc, w)) + if(in_CC(hcirc, w)) ++v_deg; hcirc = opposite(next(hcirc, w.graph()), w.graph()); }while(hcirc != h); @@ -244,7 +245,7 @@ typename boost::graph_traits::degree_size_type out_degree(typename boost::graph_traits >::vertex_descriptor v, const Connected_component_graph& w) { - CGAL_assertion(is_valid(v, w)); + CGAL_assertion(in_CC(v, w)); return std::distance(out_edges(v, w).first ,out_edges(v, w).second); } @@ -253,7 +254,7 @@ typename boost::graph_traits::degree_size_type in_degree(typename boost::graph_traits >::vertex_descriptor v, const Connected_component_graph& w) { - CGAL_assertion(is_valid(v, w)); + CGAL_assertion(in_CC(v, w)); return std::distance(in_edges(v, w).first ,in_edges(v, w).second); } @@ -262,7 +263,7 @@ typename boost::graph_traits source(typename boost::graph_traits >::edge_descriptor e, const Connected_component_graph & w) { - CGAL_assertion(is_valid(e, w)); + CGAL_assertion(in_CC(e, w)); return source(e, w.graph()); } @@ -271,7 +272,7 @@ typename boost::graph_traits target(typename boost::graph_traits >::edge_descriptor e, const Connected_component_graph & w) { - CGAL_assertion(is_valid(e, w)); + CGAL_assertion(in_CC(e, w)); return target(e, w.graph()); } @@ -281,46 +282,43 @@ edge(typename boost::graph_traits >::vertex_descriptor v, const Connected_component_graph & w) { - CGAL_assertion(is_valid(u, w) && is_valid(v, w)); + CGAL_assertion(in_CC(u, w) && in_CC(v, w)); typename boost::graph_traits >::edge_descriptor e = edge(u, v, w.graph()).first; - bool res = is_valid(e, w); + bool res = in_CC(e, w); return std::make_pair(e, res); } template -std::pair >::vertex_iterator, -typename boost::graph_traits >::vertex_iterator> +CGAL::Iterator_range >::vertex_iterator> vertices(const Connected_component_graph & w) { typedef typename boost::graph_traits >::vertex_iterator vertex_iterator; typedef typename boost::graph_traits::vertex_iterator g_vertex_iterator; typename Connected_component_graph ::Is_simplex_valid predicate(&w); - std::pair original_vertices = vertices(w.graph()); - - return make_range(vertex_iterator(predicate, original_vertices.first, original_vertices.second), - vertex_iterator(predicate, original_vertices.second, original_vertices.second)); + g_vertex_iterator b,e; + boost::tie(b,e) = vertices(w.graph()); + return make_range(vertex_iterator(predicate, b, e), + vertex_iterator(predicate, e, e)); } template -std::pair >::edge_iterator, -typename boost::graph_traits >::edge_iterator> +CGAL::Iterator_range >::edge_iterator> edges(const Connected_component_graph & w) { typedef typename boost::graph_traits >::edge_iterator edge_iterator; typedef typename boost::graph_traits::edge_iterator g_edge_iterator; typename Connected_component_graph ::Is_simplex_valid predicate(&w); - std::pair original_edges = edges(w.graph()); - - return make_range(edge_iterator(predicate, original_edges.first, original_edges.second), - edge_iterator(predicate, original_edges.second, original_edges.second)); + g_edge_iterator b,e; + boost::tie(b,e) = edges(w.graph()); + return make_range(edge_iterator(predicate, b, e), + edge_iterator(predicate, e, e)); } template -std::pair >::out_edge_iterator, -typename boost::graph_traits >::out_edge_iterator> +CGAL::Iterator_range >::out_edge_iterator> out_edges(typename boost::graph_traits >::vertex_descriptor v, const Connected_component_graph & w) { @@ -336,8 +334,7 @@ out_edges(typename boost::graph_traits -std::pair >::in_edge_iterator, -typename boost::graph_traits >::in_edge_iterator> +CGAL::Iterator_range >::in_edge_iterator> in_edges(typename boost::graph_traits >::vertex_descriptor v, const Connected_component_graph & w) { @@ -360,7 +357,7 @@ typename boost::graph_traits< Connected_component_graph edge(typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor h, const Connected_component_graph & w) { - CGAL_assertion(CGAL::is_valid(h, w)); + CGAL_assertion(CGAL::in_CC(h, w)); return edge(h, w.graph()); } @@ -369,7 +366,7 @@ typename boost::graph_traits< Connected_component_graph halfedge(typename boost::graph_traits< Connected_component_graph >::edge_descriptor e, const Connected_component_graph & w) { - CGAL_assertion(CGAL::is_valid(e, w)); + CGAL_assertion(CGAL::in_CC(e, w)); return halfedge(e, w.graph()); } @@ -378,12 +375,12 @@ typename boost::graph_traits< Connected_component_graph halfedge(typename boost::graph_traits< Connected_component_graph >::vertex_descriptor v, const Connected_component_graph & w) { - CGAL_assertion(is_valid(v, w)); + CGAL_assertion(in_CC(v, w)); typename boost::graph_traits >::halfedge_descriptor h = halfedge(v, w.graph()); typename boost::graph_traits >::halfedge_descriptor hcirc = h; do { - if(is_valid(hcirc, w)) + if(in_CC(hcirc, w)) return hcirc; hcirc = opposite(next(hcirc, w.graph()), w.graph()); }while(hcirc != h); @@ -397,9 +394,9 @@ halfedge(typename boost::graph_traits< Connected_component_graph >::vertex_descriptor v, const Connected_component_graph & w) { - CGAL_assertion(is_valid(u, w) && is_valid(v, w)); + CGAL_assertion(in_CC(u, w) && in_CC(v, w)); typename boost::graph_traits >::halfedge_descriptor h = halfedge(u, v, w.graph()).first; - return std::make_pair(h, is_valid(h, w)); + return std::make_pair(h, in_CC(h, w)); } @@ -408,7 +405,7 @@ typename boost::graph_traits< Connected_component_graph opposite(typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor h, const Connected_component_graph & w) { - CGAL_assertion(is_valid(h, w) ); + CGAL_assertion(in_CC(h, w) ); return opposite(h, w.graph()); } @@ -417,7 +414,7 @@ typename boost::graph_traits< Connected_component_graph source(typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor h, const Connected_component_graph & w) { - CGAL_assertion(is_valid(h, w) ); + CGAL_assertion(in_CC(h, w) ); return source(h, w.graph()); } @@ -426,7 +423,7 @@ typename boost::graph_traits< Connected_component_graph target(typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor h, const Connected_component_graph & w) { - CGAL_assertion(is_valid(h, w) ); + CGAL_assertion(in_CC(h, w) ); return target(h, w.graph()); } @@ -435,15 +432,15 @@ typename boost::graph_traits< Connected_component_graph next(typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor h, const Connected_component_graph & w) { - CGAL_assertion(is_valid(h, w)); - if(is_valid(face(h, w.graph()), w)) + CGAL_assertion(in_CC(h, w)); + if(in_CC(face(h, w.graph()), w)) return next(h, w.graph()); //act as a border typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor hcirc = h; do { - if(is_valid(hcirc, w)) + if(in_CC(hcirc, w)) { return hcirc; } @@ -458,15 +455,15 @@ prev(typename boost::graph_traits< Connected_component_graph & w) { - CGAL_assertion(is_valid(h, w)); - if(is_valid(face(h, w.graph()), w)) + CGAL_assertion(in_CC(h, w)); + if(in_CC(face(h, w.graph()), w)) return prev(h, w.graph()); //act as a border typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor hcirc = h; do { - if(is_valid(hcirc, w)) + if(in_CC(hcirc, w)) { return hcirc; } @@ -508,8 +505,8 @@ typename boost::graph_traits< Connected_component_graph face(typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor h, const Connected_component_graph & w) { - CGAL_assertion(CGAL::is_valid(h, w)); - if(is_valid(face(h,w.graph()), w)) + CGAL_assertion(CGAL::in_CC(h, w)); + if(in_CC(face(h,w.graph()), w)) return face(h,w.graph()); else return boost::graph_traits< CGAL::Connected_component_graph >::null_face(); @@ -520,7 +517,7 @@ typename boost::graph_traits< Connected_component_graph halfedge(typename boost::graph_traits< Connected_component_graph >::face_descriptor f, const Connected_component_graph & w) { - CGAL_assertion(CGAL::is_valid(f, w)); + CGAL_assertion(CGAL::in_CC(f, w)); return halfedge(f,w.graph()); } @@ -552,9 +549,9 @@ num_faces(const Connected_component_graph & w) template bool -is_valid(const Connected_component_graph & w, bool verbose = false) +in_CC(const Connected_component_graph & w, bool verbose = false) { - return is_valid(w.graph(),verbose); + return in_CC(w.graph(),verbose); } template diff --git a/BGL/test/BGL/graph_concept_Connected_component_graph.cpp b/BGL/test/BGL/graph_concept_Connected_component_graph.cpp index b5194153d03..ce2e5d9eb18 100644 --- a/BGL/test/BGL/graph_concept_Connected_component_graph.cpp +++ b/BGL/test/BGL/graph_concept_Connected_component_graph.cpp @@ -1,5 +1,5 @@ -#include -#include + +#include #include #include diff --git a/BGL/test/BGL/test_Connected_component_graph.cpp b/BGL/test/BGL/test_Connected_component_graph.cpp index 8ee86e35392..fb8b0d7db11 100644 --- a/BGL/test/BGL/test_Connected_component_graph.cpp +++ b/BGL/test/BGL/test_Connected_component_graph.cpp @@ -1,5 +1,5 @@ #include - +#include #include "test_Prefix.h" #include #include @@ -401,7 +401,6 @@ main() CGAL_assertion( prev(prev(prev(h, fga), fga), fga) == h ); - //check degree CGAL_assertion(degree(v, fga) == 2); //check in_edges and out_edges From 513edafdb221eb3dc98a823669a9aa797dded1be Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 27 Jan 2017 11:32:13 +0100 Subject: [PATCH 06/38] use iterator_range instead of std::pair in Gwdwg --- .../graph/Graph_with_descriptor_with_graph.h | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/BGL/include/CGAL/boost/graph/Graph_with_descriptor_with_graph.h b/BGL/include/CGAL/boost/graph/Graph_with_descriptor_with_graph.h index 041d1ed67d7..c058efaa39f 100644 --- a/BGL/include/CGAL/boost/graph/Graph_with_descriptor_with_graph.h +++ b/BGL/include/CGAL/boost/graph/Graph_with_descriptor_with_graph.h @@ -23,6 +23,7 @@ #include #include #include +#include #include @@ -319,8 +320,7 @@ edge(typename boost::graph_traits >::ver template -std::pair >::vertex_iterator, - typename boost::graph_traits >::vertex_iterator> +CGAL::Iterator_range >::vertex_iterator> vertices(const Graph_with_descriptor_with_graph & w) { typename boost::graph_traits::vertex_iterator b,e; @@ -330,8 +330,7 @@ vertices(const Graph_with_descriptor_with_graph & w) } template -std::pair >::edge_iterator, - typename boost::graph_traits >::edge_iterator> +CGAL::Iterator_range >::edge_iterator> edges(const Graph_with_descriptor_with_graph & w) { typename boost::graph_traits::edge_iterator b,e; @@ -341,8 +340,7 @@ edges(const Graph_with_descriptor_with_graph & w) } template -std::pair >::out_edge_iterator, - typename boost::graph_traits >::out_edge_iterator> +CGAL::Iterator_range >::out_edge_iterator> out_edges(typename boost::graph_traits >::vertex_descriptor v, const Graph_with_descriptor_with_graph & w) { @@ -354,8 +352,7 @@ out_edges(typename boost::graph_traits > } template -std::pair >::in_edge_iterator, - typename boost::graph_traits >::in_edge_iterator> +CGAL::Iterator_range >::in_edge_iterator> in_edges(typename boost::graph_traits >::vertex_descriptor v, const Graph_with_descriptor_with_graph & w) { @@ -624,8 +621,7 @@ prev(typename boost::graph_traits< Graph_with_descriptor_with_graph >::ha // template -std::pair >::halfedge_iterator, - typename boost::graph_traits >::halfedge_iterator> +CGAL::Iterator_range >::halfedge_iterator> halfedges(const Graph_with_descriptor_with_graph & w) { typename boost::graph_traits::halfedge_iterator b,e; @@ -665,8 +661,7 @@ halfedge(typename boost::graph_traits< Graph_with_descriptor_with_graph > template -std::pair >::face_iterator, - typename boost::graph_traits >::face_iterator> +CGAL::Iterator_range >::face_iterator> faces(const Graph_with_descriptor_with_graph & w) { typename boost::graph_traits::face_iterator b,e; From afd44de2e62cdc78fbfe6cb2a85192ab5e6632f5 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 3 Feb 2017 10:24:28 +0100 Subject: [PATCH 07/38] Changes : - Remove copy_face_graph_patch - Use an unordered_set instead of a single patch_id. --- .../boost/graph/Connected_component_graph.h | 45 ++- .../CGAL/boost/graph/copy_face_graph_patch.h | 260 ------------------ .../BGL/test_Connected_component_graph.cpp | 40 ++- 3 files changed, 59 insertions(+), 286 deletions(-) delete mode 100644 BGL/include/CGAL/boost/graph/copy_face_graph_patch.h diff --git a/BGL/include/CGAL/boost/graph/Connected_component_graph.h b/BGL/include/CGAL/boost/graph/Connected_component_graph.h index 12e889c571f..9c4fd8aa77f 100644 --- a/BGL/include/CGAL/boost/graph/Connected_component_graph.h +++ b/BGL/include/CGAL/boost/graph/Connected_component_graph.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -35,9 +36,9 @@ namespace CGAL /*! \ingroup PkgBGLHelper -The class `Connected_component_graph` wraps a graph into another graph in such a way that only the specified connected component is seen from the outside. +The class `Connected_component_graph` wraps a graph into another graph in such a way that only the specified connected components are seen from the outside. -For example, calling `vertices(graph)` will return an iterator range of all but only the vertices that belong to the connected component whose id in `fccmap` is `pid`. +For example, calling `vertices(graph)` will return an iterator range of all but only the vertices that belong to the connected components whose ids in `fccmap` are contained in `pids`. \attention The functions `num_vertices()`, `num_edges()`, `num_halfedges()`, `num_faces()`, are forwarded from the underlying graph, which means that `num_vertices(graph)` is different from `std::distance(vertices(graph).first,vertices(graph).second)` @@ -62,22 +63,42 @@ struct Connected_component_graph typedef typename gt::face_descriptor face_descriptor; typedef Connected_component_graph Self; - + /*! + * \brief Creates a Connected_component_graph of the connected components of `graph` that are listed in `pids`. + * \param graph the graph containing the wanted patches. + * \param fccmap the property_map that assigns a patch to each face + * \param pids the indices of the patches of interest. + */ Connected_component_graph(const Graph& graph, FaceComponentMap fccmap, - typename boost::property_traits::value_type pid) - : _graph(graph), _property_map(fccmap), _patch_index(pid) + boost::unordered_set::value_type> pids) + : _graph(graph), _property_map(fccmap), _patch_indices(pids) { } - + /*! + * \brief Creates a Connected_component_graph of the connected component `pid` of `graph`. + * \param graph the graph containing the wanted patch. + * \param fccmap the property_map that assigns a patch to each face + * \param pid the index of the patch of interest. + */ + Connected_component_graph(const Graph& graph, + FaceComponentMap fccmap, + typename boost::property_traits::value_type pid) + : _graph(graph), _property_map(fccmap) + { + _patch_indices = boost::unordered_set::value_type>(); + _patch_indices.insert(pid); + } + ///returns the graph of the Connected_component_graph. const Graph& graph()const{ return _graph; } + ///returns the property map of the Connected_component_graph. FaceComponentMap property_map()const{ return _property_map; } - - typename boost::property_traits::value_type patch_index()const{ return _patch_index; } - - void change_patch_id(typename boost::property_traits::value_type pid) { _patch_index = pid;} + ///returns the unordered set of patch ids of the Connected_component_graph. + boost::unordered_set::value_type> patch_indices()const{ return _patch_indices; } + /// Replaces the current unordered set of patches by `pids` + void change_patch_id(boost::unordered_set::value_type> pids) { _patch_indices = pids;} struct Is_simplex_valid { @@ -100,7 +121,7 @@ struct Connected_component_graph private: const Graph& _graph; FaceComponentMap _property_map; - typename boost::property_traits::value_type _patch_index; + boost::unordered_set::value_type> _patch_indices; }; } // namespace CGAL @@ -171,7 +192,7 @@ bool in_CC(const typename boost::graph_traits< Connected_component_graph >::face_descriptor f, const Connected_component_graph & w) { - return boost::get(w.property_map(), f) == w.patch_index(); + return w.patch_indices().find(boost::get(w.property_map(), f)) != w.patch_indices().end(); } template diff --git a/BGL/include/CGAL/boost/graph/copy_face_graph_patch.h b/BGL/include/CGAL/boost/graph/copy_face_graph_patch.h deleted file mode 100644 index fe0c808d356..00000000000 --- a/BGL/include/CGAL/boost/graph/copy_face_graph_patch.h +++ /dev/null @@ -1,260 +0,0 @@ -// Copyright (c) 2017 GeometryFactory (France). All rights reserved. -// -// This file is part of CGAL (www.cgal.org); you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation; either version 3 of the License, -// or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// -// $URL$ -// $Id$ -// -// -// Author(s) : Maxime Gimeno - -#ifndef CGAL_BOOST_GRAPH_COPY_FACE_GRAPH_PATCH_H -#define CGAL_BOOST_GRAPH_COPY_FACE_GRAPH_PATCH_H - -#include -#include -#include -#include - -namespace CGAL { - -/*! - \ingroup PkgBGLHelperFct - - copies a connected component of a source model of `FaceListGraph` into a target model of a - `FaceListGraph`. `OutputIterators` can be provided to produce a - mapping between source and target elements. The target graph is not - cleared. - - \tparam SourceMesh a model of `FaceListGraph`. - The descriptor types `boost::graph_traits::%vertex_descriptor` - and `boost::graph_traits::%face_descriptor` must be - models of `Hashable`. - \tparam TargetMesh a model of `FaceListGraph` - \tparam FaceComponentMap a model of `WritablePropertyMap` with - `boost::graph_traits::%face_descriptor` as key type and - `graph_traits::faces_size_type` as value type. - \tparam V2V a model of `OutputIterator` accepting `std::pair` - \tparam H2H a model of `OutputIterator` accepting `std::pair` - \tparam F2F a model of `OutputIterator` accepting `std::pair` - \tparam Src_vpm a model of `ReadablePropertyMap` with `sm_vertex_descriptor` as key - \tparam Tgt_vpm a model of `WritablePropertyMap` with `tm_vertex_descriptor` as key - where the prefix `sm_` and `tm_` mean belonging to the source and - target mesh respectively. - - The types `sm_vertex_descriptor` and `sm_face_descriptor` must be models of the concept `Hashable`. - - \param sm the source mesh - \param fccmap the property map containing the faces of `sm` and the index of their connected component. - \param pid the index in `fccmap` of the connected component to copy - \param tm the target mesh - \param v2v pairs of `vertex_descriptors` from `sm` and corresponding `vertex_descriptors` in `tm` are added to `v2v` - \param h2h pairs of `halfedge_descriptors` from `sm` and corresponding `halfedge_descriptors` in `tm` are added to `h2h` - \param f2f pairs of `face_descriptors` from `sm` and corresponding `face_descriptors` in `tm` are added to `f2f` - \param sm_vpm vertex point map for `sm` - \param tm_vpm vertex point map for `tm` - - The points from `sm` to `tm` are converted using - `CGAL::Cartesian_converter`. - `SourceKernel` and `TargetKernel` are deduced using `CGAL::Kernel_traits` - from the value types of `Src_vpm` and `Tgt_vpm`. - - Other properties are not copied. -*/ - -#if defined(DOXYGEN_RUNNING) // Use template default arguments -template ::const_type, - typename Tgt_vpm = typename boost::property_map::type> -void copy_face_graph_patch(const SourceMesh& sm, - FaceComponentMap fccmap, - typename boost::graph_traits::faces_size_type pid, - TargetMesh& tm, - V2V v2v = V2V(), H2H h2h = H2H(), F2F f2f = F2F(), - Src_vpm sm_vpm = get(vertex_point, sm), - Tgt_vpm tm_vpm = get(vertex_point, tm) ) -#else // use the overloads -template -void copy_face_graph_patch(const SourceMesh& sm, FaceComponentMap fccmap, typename boost::graph_traits::faces_size_type pid, TargetMesh& tm, - V2V v2v, H2H h2h, F2F f2f, - Src_vpm sm_vpm, Tgt_vpm tm_vpm ) -#endif -{ - typedef CGAL::Connected_component_graph Adapter; - - copy_face_graph(Adapter(sm, fccmap, pid), tm, v2v, h2h, f2f, sm_vpm, tm_vpm); -} - - -/*! - \ingroup PkgBGLHelperFct - - copies the connected component containg `seed_face` of a source model of `FaceListGraph` into a target model of a - `FaceListGraph`. `OutputIterators` can be provided to produce a - mapping between source and target elements. The target graph is not - cleared. - - \tparam SourceMesh a model of `FaceListGraph`. - The descriptor types `boost::graph_traits::%vertex_descriptor` - and `boost::graph_traits::%face_descriptor` must be - models of `Hashable`. - \tparam TargetMesh a model of `FaceListGraph` - \tparam NamedParameters a sequence of \ref namedparameters - \tparam V2V a model of `OutputIterator` accepting `std::pair` - \tparam H2H a model of `OutputIterator` accepting `std::pair` - \tparam F2F a model of `OutputIterator` accepting `std::pair` - \tparam Src_vpm a model of `ReadablePropertyMap` with `sm_vertex_descriptor` as key - \tparam Tgt_vpm a model of `WritablePropertyMap` with `tm_vertex_descriptor` as key - where the prefix `sm_` and `tm_` mean belonging to the source and - target mesh respectively. - - The types `sm_vertex_descriptor` and `sm_face_descriptor` must be models of the concept `Hashable`. - - \param sm the source mesh - \param tm the target mesh - \param seed_face a face of `sm` belonging to the connected component to copy - \param np optional \ref namedparameters described below -* -* \cgalNamedParamsBegin -* \cgalParamBegin{edge_is_constrained_map} a property map containing the constrained-or-not status of each edge of `pmesh` \cgalParamEnd -* \cgalNamedParamsEnd - - \param v2v pairs of `vertex_descriptors` from `sm` and corresponding `vertex_descriptors` in `tm` are added to `v2v` - \param h2h pairs of `halfedge_descriptors` from `sm` and corresponding `halfedge_descriptors` in `tm` are added to `h2h` - \param f2f pairs of `face_descriptors` from `sm` and corresponding `face_descriptors` in `tm` are added to `f2f` - \param sm_vpm vertex point map for `sm` - \param tm_vpm vertex point map for `tm` - - The points from `sm` to `tm` are converted using - `CGAL::Cartesian_converter`. - `SourceKernel` and `TargetKernel` are deduced using `CGAL::Kernel_traits` - from the value types of `Src_vpm` and `Tgt_vpm`. - - Other properties are not copied. - -*/ -#if defined(DOXYGEN_RUNNING) // Use template default arguments -template ::const_type, - typename Tgt_vpm = typename boost::property_map::type> -void copy_face_graph_patch(const SourceMesh& sm, - const typename boost::graph_traits:: - face_descriptor& seed_face, - const NamedParameters& np = boost::parameter::all_default(), - TargetMesh& tm, - V2V v2v = V2V(), H2H h2h = H2H(), F2F f2f = F2F(), - Src_vpm sm_vpm = get(vertex_point, sm), - Tgt_vpm tm_vpm = get(vertex_point, tm) ) -#else // use the overloads - -template -void copy_face_graph_patch(const SourceMesh& sm, const typename boost::graph_traits:: - face_descriptor& seed_face, - const NamedParameters& np, TargetMesh& tm, V2V v2v, H2H h2h, F2F f2f, - Src_vpm sm_vpm, Tgt_vpm tm_vpm ) -#endif -{ - - typedef typename boost::graph_traits::face_descriptor g_face_descriptor; - typedef typename boost::graph_traits::faces_size_type faces_size_t; - typedef boost::associative_property_map< boost::unordered_map< g_face_descriptor, faces_size_t> >FCMap; - typedef CGAL::Connected_component_graph Adapter; - - boost::unordered_map map(CGAL::num_faces(sm)); - Polygon_mesh_processing::connected_components(sm, boost::make_assoc_property_map(map), np); - copy_face_graph(Adapter(sm, boost::make_assoc_property_map(map), map[seed_face]), tm, v2v, h2h, f2f, sm_vpm, tm_vpm); -} - -#if !defined(DOXYGEN_RUNNING) -template -void copy_face_graph_patch(const SourceMesh& sm, FaceComponentMap fccmap, typename boost::graph_traits::faces_size_type pid, TargetMesh& tm) -{ copy_face_graph_patch(sm, fccmap, pid, tm, Emptyset_iterator(), Emptyset_iterator(), Emptyset_iterator(), - get(vertex_point, sm), get(vertex_point, tm)); } - -template -void copy_face_graph_patch(const SourceMesh& sm, FaceComponentMap fccmap, typename boost::graph_traits::faces_size_type pid, TargetMesh& tm, V2V v2v) -{ copy_face_graph_patch(sm, fccmap, pid, tm, v2v, Emptyset_iterator(), Emptyset_iterator(), - get(vertex_point, sm), get(vertex_point, tm)); } - -template -void copy_face_graph_patch(const SourceMesh& sm, FaceComponentMap fccmap, typename boost::graph_traits::faces_size_type pid, TargetMesh& tm, V2V v2v, H2H h2h) -{ copy_face_graph_patch(sm, fccmap, pid, tm, v2v, h2h, Emptyset_iterator(), - get(vertex_point, sm), get(vertex_point, tm)); } - -template -void copy_face_graph_patch(const SourceMesh& sm, FaceComponentMap fccmap, typename boost::graph_traits::faces_size_type pid, TargetMesh& tm, V2V v2v, H2H h2h, F2F f2f) -{ copy_face_graph_patch(sm, fccmap, pid, tm, v2v, h2h, f2f, - get(vertex_point, sm), get(vertex_point, tm)); } - -template -void copy_face_graph_patch(const SourceMesh& sm, FaceComponentMap fccmap, typename boost::graph_traits::faces_size_type pid, TargetMesh& tm, V2V v2v, H2H h2h, F2F f2f, Src_vpm sm_vpm) -{ copy_face_graph_patch(sm, fccmap, pid, tm, v2v, h2h, f2f, - sm_vpm, get(vertex_point, tm)); } - - -template -void copy_face_graph_patch(const SourceMesh& sm, const typename boost::graph_traits:: - face_descriptor& seed_face, TargetMesh& tm) -{ copy_face_graph_patch(sm, seed_face, Polygon_mesh_processing::parameters::all_default(), tm, Emptyset_iterator(), Emptyset_iterator(), Emptyset_iterator(), - get(vertex_point, sm), get(vertex_point, tm)); } - -template -void copy_face_graph_patch(const SourceMesh& sm, const typename boost::graph_traits:: - face_descriptor& seed_face, - const NamedParameters& np, TargetMesh& tm) -{ copy_face_graph_patch(sm, seed_face, np, tm, Emptyset_iterator(), Emptyset_iterator(), Emptyset_iterator(), - get(vertex_point, sm), get(vertex_point, tm)); } - -template -void copy_face_graph_patch(const SourceMesh& sm, const typename boost::graph_traits:: - face_descriptor& seed_face, - const NamedParameters& np, TargetMesh& tm, V2V v2v) -{ copy_face_graph_patch(sm, seed_face, np, tm, v2v, Emptyset_iterator(), Emptyset_iterator(), - get(vertex_point, sm), get(vertex_point, tm)); } - -template -void copy_face_graph_patch(const SourceMesh& sm, const typename boost::graph_traits:: - face_descriptor& seed_face, - const NamedParameters& np, TargetMesh& tm, V2V v2v, H2H h2h) -{ copy_face_graph_patch(sm, seed_face, np, tm, v2v, h2h, Emptyset_iterator(), - get(vertex_point, sm), get(vertex_point, tm)); } - -template -void copy_face_graph_patch(const SourceMesh& sm, const typename boost::graph_traits:: - face_descriptor& seed_face, - const NamedParameters& np, TargetMesh& tm, V2V v2v, H2H h2h, F2F f2f) -{ copy_face_graph_patch(sm, seed_face, np, tm, v2v, h2h, f2f, - get(vertex_point, sm), get(vertex_point, tm)); } - -template -void copy_face_graph_patch(const SourceMesh& sm, const typename boost::graph_traits:: - face_descriptor& seed_face, - const NamedParameters& np, TargetMesh& tm, V2V v2v, H2H h2h, F2F f2f, Src_vpm sm_vpm) -{ copy_face_graph_patch(sm, seed_face, np, tm, v2v, h2h, f2f, - sm_vpm, get(vertex_point, tm)); } -#endif -}//end CGAL -#endif // CGAL_BOOST_GRAPH_COPY_FACE_GRAPH_PATCH_H diff --git a/BGL/test/BGL/test_Connected_component_graph.cpp b/BGL/test/BGL/test_Connected_component_graph.cpp index fb8b0d7db11..e69cfaaaff7 100644 --- a/BGL/test/BGL/test_Connected_component_graph.cpp +++ b/BGL/test/BGL/test_Connected_component_graph.cpp @@ -340,6 +340,16 @@ struct Constraint : public boost::put_get_helper::face_descriptor , std::size_t> > Adapter; - test(sm_data()); - //Make a tetrahedron and test the adapter for a patch that only contains the front face + // test(sm_data()); + //Make a tetrahedron and test the adapter for a patch that only contains 2 faces SM* sm = new SM(); CGAL::make_tetrahedron( Point_3(1,1,1), @@ -371,17 +381,19 @@ main() CGAL::Polygon_mesh_processing::connected_components(*sm, fccmap, CGAL::Polygon_mesh_processing::parameters:: edge_is_constrained_map(Constraint::vertex_descriptor, SM::Point> >(*sm, positions))); - - Adapter fga(*sm, fccmap, boost::get(fccmap, *faces(*sm).first)); + boost::unordered_set pids; + pids.insert(0); + pids.insert(2); + Adapter fga(*sm, fccmap, pids); CGAL_GRAPH_TRAITS_MEMBERS(Adapter); //check that there is the right number of simplices in fga CGAL_assertion(CGAL::is_valid(fga)); - CGAL_assertion(std::distance(faces(fga).first,faces(fga).second) == 1); - CGAL_assertion(std::distance(edges(fga).first,edges(fga).second) == 3); - CGAL_assertion(std::distance(halfedges(fga).first,halfedges(fga).second) == 6); - CGAL_assertion(std::distance(vertices(fga).first,vertices(fga).second) == 3); + CGAL_assertion(std::distance(faces(fga).first,faces(fga).second) == 2); + CGAL_assertion(std::distance(edges(fga).first,edges(fga).second) == 5); + CGAL_assertion(std::distance(halfedges(fga).first,halfedges(fga).second) == 10); + CGAL_assertion(std::distance(vertices(fga).first,vertices(fga).second) == 4); halfedge_descriptor h = halfedge(*faces(fga).first, fga); - vertex_descriptor v = target(h, fga); + vertex_descriptor v = source(h, fga); //check that next() works inside the patch CGAL_assertion( next(next(next(h, fga), fga), fga) == h @@ -389,7 +401,7 @@ main() //check that next() works on bordure of the patch h = opposite(h, fga); CGAL_assertion( - next(next(next(h, fga), fga), fga) == h + next(next(next(next(h, fga), fga), fga), fga) == h ); //check that prev() works inside the patch h = halfedge(*faces(fga).first, fga); @@ -399,13 +411,13 @@ main() //check that prev() works on bordure of the patch h = opposite(h, fga); CGAL_assertion( - prev(prev(prev(h, fga), fga), fga) == h + prev(prev(prev(prev(h, fga), fga), fga), fga) == h ); //check degree - CGAL_assertion(degree(v, fga) == 2); + CGAL_assertion(degree(v, fga) == 3); //check in_edges and out_edges - CGAL_assertion(std::distance(in_edges(v, fga).first ,in_edges(v, fga).second) == 2 ); - CGAL_assertion(std::distance(out_edges(v, fga).first ,out_edges(v, fga).second) == 2 ); + CGAL_assertion(std::distance(in_edges(v, fga).first ,in_edges(v, fga).second) == 3 ); + CGAL_assertion(std::distance(out_edges(v, fga).first ,out_edges(v, fga).second) == 3 ); return 0; } From 97ad4ba2b2c30de227a5215094cc06118da5c065 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 3 Feb 2017 11:26:45 +0100 Subject: [PATCH 08/38] Rename into Connected_components_graph --- BGL/doc/BGL/Doxyfile.in | 3 +- ...t_graph.h => Connected_components_graph.h} | 264 +++++++++--------- BGL/test/BGL/CMakeLists.txt | 4 +- ...ph_concept_Connected_components_graph.cpp} | 4 +- ...pp => test_Connected_components_graph.cpp} | 24 +- 5 files changed, 149 insertions(+), 150 deletions(-) rename BGL/include/CGAL/boost/graph/{Connected_component_graph.h => Connected_components_graph.h} (55%) rename BGL/test/BGL/{graph_concept_Connected_component_graph.cpp => graph_concept_Connected_components_graph.cpp} (91%) rename BGL/test/BGL/{test_Connected_component_graph.cpp => test_Connected_components_graph.cpp} (94%) diff --git a/BGL/doc/BGL/Doxyfile.in b/BGL/doc/BGL/Doxyfile.in index 94cc0d31684..b17cf50fe55 100644 --- a/BGL/doc/BGL/Doxyfile.in +++ b/BGL/doc/BGL/Doxyfile.in @@ -7,9 +7,8 @@ INPUT += ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/Euler_operations.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/selection.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/split_graph_into_polylines.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/copy_face_graph.h \ - ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/copy_face_graph_patch.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/Graph_with_descriptor_with_graph.h \ - ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/connected_component_graph.h \ + ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/Connected_components_graph.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/Dual.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/convert_nef_polyhedron_to_polygon_mesh.h EXAMPLE_PATH = ${CGAL_Surface_mesh_skeletonization_EXAMPLE_DIR} \ diff --git a/BGL/include/CGAL/boost/graph/Connected_component_graph.h b/BGL/include/CGAL/boost/graph/Connected_components_graph.h similarity index 55% rename from BGL/include/CGAL/boost/graph/Connected_component_graph.h rename to BGL/include/CGAL/boost/graph/Connected_components_graph.h index 9c4fd8aa77f..ee547fdd042 100644 --- a/BGL/include/CGAL/boost/graph/Connected_component_graph.h +++ b/BGL/include/CGAL/boost/graph/Connected_components_graph.h @@ -16,8 +16,8 @@ // // // Author(s) : Maxime Gimeno -#ifndef CGAL_BOOST_GRAPH_CONNECTED_COMPONENT_GRAPH_H -#define CGAL_BOOST_GRAPH_CONNECTED_COMPONENT_GRAPH_H +#ifndef CGAL_BOOST_GRAPH_Connected_components_graph_H +#define CGAL_BOOST_GRAPH_Connected_components_graph_H #include #include @@ -36,40 +36,40 @@ namespace CGAL /*! \ingroup PkgBGLHelper -The class `Connected_component_graph` wraps a graph into another graph in such a way that only the specified connected components are seen from the outside. +The class `Connected_components_graph` wraps a graph into another graph in such a way that only the specified connected components are seen from the outside. -For example, calling `vertices(graph)` will return an iterator range of all but only the vertices that belong to the connected components whose ids in `fccmap` are contained in `pids`. +For example, calling `vertices(graph)` will return an iterator range of all but only the vertices that belong to the connected components whose ids in the `FaceComponentMap` are contained in the given set. -\attention The functions `num_vertices()`, `num_edges()`, `num_halfedges()`, `num_faces()`, are forwarded from the underlying graph, +\attention The functions `%num_vertices()`, `%num_edges()`, `%num_halfedges()`, `%num_faces()`, are forwarded from the underlying graph, which means that `num_vertices(graph)` is different from `std::distance(vertices(graph).first,vertices(graph).second)` -Property maps can be wrapped with `Connected_component_graph_property_map`. +Property maps can be wrapped with `Connected_components_graph_property_map`. \tparam Graph must be a model of a `FaceListGraph` and `HalfedgeListGraph`. \tparam FaceComponentMap a model of `WritablePropertyMap` with - `boost::graph_traits::%face_descriptor` as key type and - `graph_traits::faces_size_type` as value type. + `boost::graph_traits::%face_descriptor` as key type and + `graph_traits::faces_size_type` as value type. \cgalModels `FaceListGraph` \cgalModels `HalfedgeListGraph` */ template -struct Connected_component_graph +struct Connected_components_graph { typedef boost::graph_traits gt; typedef typename gt::vertex_descriptor vertex_descriptor; typedef typename gt::halfedge_descriptor halfedge_descriptor; typedef typename gt::edge_descriptor edge_descriptor; typedef typename gt::face_descriptor face_descriptor; - typedef Connected_component_graph Self; + typedef Connected_components_graph Self; /*! - * \brief Creates a Connected_component_graph of the connected components of `graph` that are listed in `pids`. + * \brief Creates a Connected_components_graph of the connected components of `graph` that are listed in `pids`. * \param graph the graph containing the wanted patches. * \param fccmap the property_map that assigns a patch to each face * \param pids the indices of the patches of interest. */ - Connected_component_graph(const Graph& graph, + Connected_components_graph(const Graph& graph, FaceComponentMap fccmap, boost::unordered_set::value_type> pids) : _graph(graph), _property_map(fccmap), _patch_indices(pids) @@ -77,12 +77,12 @@ struct Connected_component_graph } /*! - * \brief Creates a Connected_component_graph of the connected component `pid` of `graph`. + * \brief Creates a Connected_components_graph of the connected component `pid` of `graph`. * \param graph the graph containing the wanted patch. * \param fccmap the property_map that assigns a patch to each face * \param pid the index of the patch of interest. */ - Connected_component_graph(const Graph& graph, + Connected_components_graph(const Graph& graph, FaceComponentMap fccmap, typename boost::property_traits::value_type pid) : _graph(graph), _property_map(fccmap) @@ -90,12 +90,12 @@ struct Connected_component_graph _patch_indices = boost::unordered_set::value_type>(); _patch_indices.insert(pid); } - ///returns the graph of the Connected_component_graph. + ///returns the graph of the Connected_components_graph. const Graph& graph()const{ return _graph; } - ///returns the property map of the Connected_component_graph. + ///returns the property map of the Connected_components_graph. FaceComponentMap property_map()const{ return _property_map; } - ///returns the unordered set of patch ids of the Connected_component_graph. + ///returns the unordered set of patch ids of the Connected_components_graph. boost::unordered_set::value_type> patch_indices()const{ return _patch_indices; } /// Replaces the current unordered set of patches by `pids` void change_patch_id(boost::unordered_set::value_type> pids) { _patch_indices = pids;} @@ -130,9 +130,9 @@ namespace boost { template -struct graph_traits< CGAL::Connected_component_graph > +struct graph_traits< CGAL::Connected_components_graph > { - typedef CGAL::Connected_component_graph G; + typedef CGAL::Connected_components_graph G; typedef boost::graph_traits BGTG; typedef typename BGTG::vertex_descriptor vertex_descriptor; typedef typename BGTG::halfedge_descriptor halfedge_descriptor; @@ -178,8 +178,8 @@ struct graph_traits< CGAL::Connected_component_graph > }; template -struct graph_traits< const CGAL::Connected_component_graph > - : public graph_traits< CGAL::Connected_component_graph > +struct graph_traits< const CGAL::Connected_components_graph > + : public graph_traits< CGAL::Connected_components_graph > {}; @@ -189,16 +189,16 @@ struct graph_traits< const CGAL::Connected_component_graph bool -in_CC(const typename boost::graph_traits< Connected_component_graph >::face_descriptor f, - const Connected_component_graph & w) +in_CC(const typename boost::graph_traits< Connected_components_graph >::face_descriptor f, + const Connected_components_graph & w) { return w.patch_indices().find(boost::get(w.property_map(), f)) != w.patch_indices().end(); } template bool -in_CC(const typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor h, - const Connected_component_graph & w) +in_CC(const typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, + const Connected_components_graph & w) { return in_CC(face(h, w.graph()), w) || in_CC(face(opposite(h, w.graph()), w.graph()), w); @@ -206,19 +206,19 @@ in_CC(const typename boost::graph_traits< Connected_component_graph bool -in_CC(const typename boost::graph_traits< Connected_component_graph >::edge_descriptor e, - const Connected_component_graph & w) +in_CC(const typename boost::graph_traits< Connected_components_graph >::edge_descriptor e, + const Connected_components_graph & w) { return in_CC(halfedge(e, w.graph()), w); } template bool -in_CC(const typename boost::graph_traits< Connected_component_graph >::vertex_descriptor v, - const Connected_component_graph & w) +in_CC(const typename boost::graph_traits< Connected_components_graph >::vertex_descriptor v, + const Connected_components_graph & w) { - typename boost::graph_traits >::halfedge_descriptor h = halfedge(v, w.graph()); - typename boost::graph_traits >::halfedge_descriptor hcirc = h; + typename boost::graph_traits >::halfedge_descriptor h = halfedge(v, w.graph()); + typename boost::graph_traits >::halfedge_descriptor hcirc = h; do { if(in_CC(face(hcirc, w.graph()), w)) @@ -231,27 +231,27 @@ in_CC(const typename boost::graph_traits< Connected_component_graph typename boost::graph_traits::vertices_size_type -num_vertices(const Connected_component_graph& w) +num_vertices(const Connected_components_graph& w) { return num_vertices(w.graph()); } template typename boost::graph_traits::edges_size_type -num_edges(const Connected_component_graph& w) +num_edges(const Connected_components_graph& w) { return num_edges(w.graph()); } template typename boost::graph_traits::degree_size_type -degree(typename boost::graph_traits >::vertex_descriptor v, - const Connected_component_graph& w) +degree(typename boost::graph_traits >::vertex_descriptor v, + const Connected_components_graph& w) { CGAL_assertion(in_CC(v, w)); typename boost::graph_traits::degree_size_type v_deg = 0; - typename boost::graph_traits >::halfedge_descriptor h = halfedge(v, w); - typename boost::graph_traits >::halfedge_descriptor hcirc = h; + typename boost::graph_traits >::halfedge_descriptor h = halfedge(v, w); + typename boost::graph_traits >::halfedge_descriptor hcirc = h; do { if(in_CC(hcirc, w)) @@ -263,8 +263,8 @@ degree(typename boost::graph_traits typename boost::graph_traits::degree_size_type -out_degree(typename boost::graph_traits >::vertex_descriptor v, - const Connected_component_graph& w) +out_degree(typename boost::graph_traits >::vertex_descriptor v, + const Connected_components_graph& w) { CGAL_assertion(in_CC(v, w)); return std::distance(out_edges(v, w).first ,out_edges(v, w).second); @@ -272,52 +272,52 @@ out_degree(typename boost::graph_traits typename boost::graph_traits::degree_size_type -in_degree(typename boost::graph_traits >::vertex_descriptor v, - const Connected_component_graph& w) +in_degree(typename boost::graph_traits >::vertex_descriptor v, + const Connected_components_graph& w) { CGAL_assertion(in_CC(v, w)); return std::distance(in_edges(v, w).first ,in_edges(v, w).second); } template -typename boost::graph_traits >::vertex_descriptor -source(typename boost::graph_traits >::edge_descriptor e, - const Connected_component_graph & w) +typename boost::graph_traits >::vertex_descriptor +source(typename boost::graph_traits >::edge_descriptor e, + const Connected_components_graph & w) { CGAL_assertion(in_CC(e, w)); return source(e, w.graph()); } template -typename boost::graph_traits >::vertex_descriptor -target(typename boost::graph_traits >::edge_descriptor e, - const Connected_component_graph & w) +typename boost::graph_traits >::vertex_descriptor +target(typename boost::graph_traits >::edge_descriptor e, + const Connected_components_graph & w) { CGAL_assertion(in_CC(e, w)); return target(e, w.graph()); } template -std::pair >::edge_descriptor, bool> -edge(typename boost::graph_traits >::vertex_descriptor u, - typename boost::graph_traits >::vertex_descriptor v, - const Connected_component_graph & w) +std::pair >::edge_descriptor, bool> +edge(typename boost::graph_traits >::vertex_descriptor u, + typename boost::graph_traits >::vertex_descriptor v, + const Connected_components_graph & w) { CGAL_assertion(in_CC(u, w) && in_CC(v, w)); - typename boost::graph_traits >::edge_descriptor e = edge(u, v, w.graph()).first; + typename boost::graph_traits >::edge_descriptor e = edge(u, v, w.graph()).first; bool res = in_CC(e, w); return std::make_pair(e, res); } template -CGAL::Iterator_range >::vertex_iterator> -vertices(const Connected_component_graph & w) +CGAL::Iterator_range >::vertex_iterator> +vertices(const Connected_components_graph & w) { - typedef typename boost::graph_traits >::vertex_iterator vertex_iterator; + typedef typename boost::graph_traits >::vertex_iterator vertex_iterator; typedef typename boost::graph_traits::vertex_iterator g_vertex_iterator; - typename Connected_component_graph ::Is_simplex_valid predicate(&w); + typename Connected_components_graph ::Is_simplex_valid predicate(&w); g_vertex_iterator b,e; boost::tie(b,e) = vertices(w.graph()); return make_range(vertex_iterator(predicate, b, e), @@ -325,13 +325,13 @@ vertices(const Connected_component_graph & w) } template -CGAL::Iterator_range >::edge_iterator> -edges(const Connected_component_graph & w) +CGAL::Iterator_range >::edge_iterator> +edges(const Connected_components_graph & w) { - typedef typename boost::graph_traits >::edge_iterator edge_iterator; + typedef typename boost::graph_traits >::edge_iterator edge_iterator; typedef typename boost::graph_traits::edge_iterator g_edge_iterator; - typename Connected_component_graph ::Is_simplex_valid predicate(&w); + typename Connected_components_graph ::Is_simplex_valid predicate(&w); g_edge_iterator b,e; boost::tie(b,e) = edges(w.graph()); return make_range(edge_iterator(predicate, b, e), @@ -339,15 +339,15 @@ edges(const Connected_component_graph & w) } template -CGAL::Iterator_range >::out_edge_iterator> -out_edges(typename boost::graph_traits >::vertex_descriptor v, - const Connected_component_graph & w) +CGAL::Iterator_range >::out_edge_iterator> +out_edges(typename boost::graph_traits >::vertex_descriptor v, + const Connected_components_graph & w) { - typedef typename boost::graph_traits >::out_edge_iterator out_edge_iterator; + typedef typename boost::graph_traits >::out_edge_iterator out_edge_iterator; typedef typename boost::graph_traits::out_edge_iterator g_out_edge_iterator; - typename Connected_component_graph ::Is_simplex_valid predicate(&w); + typename Connected_components_graph ::Is_simplex_valid predicate(&w); g_out_edge_iterator b,e; boost::tie(b,e) = out_edges(v, w.graph()); return make_range(out_edge_iterator(predicate, b, e), @@ -355,15 +355,15 @@ out_edges(typename boost::graph_traits -CGAL::Iterator_range >::in_edge_iterator> -in_edges(typename boost::graph_traits >::vertex_descriptor v, - const Connected_component_graph & w) +CGAL::Iterator_range >::in_edge_iterator> +in_edges(typename boost::graph_traits >::vertex_descriptor v, + const Connected_components_graph & w) { - typedef typename boost::graph_traits >::in_edge_iterator in_edge_iterator; + typedef typename boost::graph_traits >::in_edge_iterator in_edge_iterator; typedef typename boost::graph_traits::in_edge_iterator g_in_edge_iterator; - typename Connected_component_graph ::Is_simplex_valid predicate(&w); + typename Connected_components_graph ::Is_simplex_valid predicate(&w); g_in_edge_iterator b,e; boost::tie(b,e) = in_edges(v, w.graph()); return make_range(in_edge_iterator(predicate, b, e), @@ -374,91 +374,91 @@ in_edges(typename boost::graph_traits -typename boost::graph_traits< Connected_component_graph >::edge_descriptor -edge(typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor h, - const Connected_component_graph & w) +typename boost::graph_traits< Connected_components_graph >::edge_descriptor +edge(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, + const Connected_components_graph & w) { CGAL_assertion(CGAL::in_CC(h, w)); return edge(h, w.graph()); } template -typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor -halfedge(typename boost::graph_traits< Connected_component_graph >::edge_descriptor e, - const Connected_component_graph & w) +typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor +halfedge(typename boost::graph_traits< Connected_components_graph >::edge_descriptor e, + const Connected_components_graph & w) { CGAL_assertion(CGAL::in_CC(e, w)); return halfedge(e, w.graph()); } template -typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor -halfedge(typename boost::graph_traits< Connected_component_graph >::vertex_descriptor v, - const Connected_component_graph & w) +typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor +halfedge(typename boost::graph_traits< Connected_components_graph >::vertex_descriptor v, + const Connected_components_graph & w) { CGAL_assertion(in_CC(v, w)); - typename boost::graph_traits >::halfedge_descriptor h = halfedge(v, w.graph()); - typename boost::graph_traits >::halfedge_descriptor hcirc = h; + typename boost::graph_traits >::halfedge_descriptor h = halfedge(v, w.graph()); + typename boost::graph_traits >::halfedge_descriptor hcirc = h; do { if(in_CC(hcirc, w)) return hcirc; hcirc = opposite(next(hcirc, w.graph()), w.graph()); }while(hcirc != h); - return boost::graph_traits< CGAL::Connected_component_graph >::null_halfedge(); + return boost::graph_traits< CGAL::Connected_components_graph >::null_halfedge(); } template -std::pair >::halfedge_descriptor, bool> -halfedge(typename boost::graph_traits< Connected_component_graph >::vertex_descriptor u, - typename boost::graph_traits< Connected_component_graph >::vertex_descriptor v, - const Connected_component_graph & w) +std::pair >::halfedge_descriptor, bool> +halfedge(typename boost::graph_traits< Connected_components_graph >::vertex_descriptor u, + typename boost::graph_traits< Connected_components_graph >::vertex_descriptor v, + const Connected_components_graph & w) { CGAL_assertion(in_CC(u, w) && in_CC(v, w)); - typename boost::graph_traits >::halfedge_descriptor h = halfedge(u, v, w.graph()).first; + typename boost::graph_traits >::halfedge_descriptor h = halfedge(u, v, w.graph()).first; return std::make_pair(h, in_CC(h, w)); } template -typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor -opposite(typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor h, - const Connected_component_graph & w) +typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor +opposite(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, + const Connected_components_graph & w) { CGAL_assertion(in_CC(h, w) ); return opposite(h, w.graph()); } template -typename boost::graph_traits< Connected_component_graph >::vertex_descriptor -source(typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor h, - const Connected_component_graph & w) +typename boost::graph_traits< Connected_components_graph >::vertex_descriptor +source(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, + const Connected_components_graph & w) { CGAL_assertion(in_CC(h, w) ); return source(h, w.graph()); } template -typename boost::graph_traits< Connected_component_graph >::vertex_descriptor -target(typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor h, - const Connected_component_graph & w) +typename boost::graph_traits< Connected_components_graph >::vertex_descriptor +target(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, + const Connected_components_graph & w) { CGAL_assertion(in_CC(h, w) ); return target(h, w.graph()); } template -typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor -next(typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor h, - const Connected_component_graph & w) +typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor +next(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, + const Connected_components_graph & w) { CGAL_assertion(in_CC(h, w)); if(in_CC(face(h, w.graph()), w)) return next(h, w.graph()); //act as a border - typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor hcirc = h; + typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor hcirc = h; do { if(in_CC(hcirc, w)) @@ -467,13 +467,13 @@ next(typename boost::graph_traits< Connected_component_graph >::null_halfedge(); + return boost::graph_traits< CGAL::Connected_components_graph >::null_halfedge(); } template -typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor -prev(typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor h, - const Connected_component_graph & w) +typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor +prev(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, + const Connected_components_graph & w) { CGAL_assertion(in_CC(h, w)); @@ -481,7 +481,7 @@ prev(typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor hcirc = h; + typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor hcirc = h; do { if(in_CC(hcirc, w)) @@ -490,7 +490,7 @@ prev(typename boost::graph_traits< Connected_component_graph >::null_halfedge(); + return boost::graph_traits< CGAL::Connected_components_graph >::null_halfedge(); } // @@ -498,14 +498,14 @@ prev(typename boost::graph_traits< Connected_component_graph -std::pair >::halfedge_iterator, -typename boost::graph_traits >::halfedge_iterator> -halfedges(const Connected_component_graph & w) +std::pair >::halfedge_iterator, +typename boost::graph_traits >::halfedge_iterator> +halfedges(const Connected_components_graph & w) { - typedef typename boost::graph_traits >::halfedge_iterator halfedge_iterator; + typedef typename boost::graph_traits >::halfedge_iterator halfedge_iterator; typedef typename boost::graph_traits::halfedge_iterator g_halfedge_iterator; - typename Connected_component_graph ::Is_simplex_valid predicate(&w); + typename Connected_components_graph ::Is_simplex_valid predicate(&w); std::pair original_halfedges = halfedges(w.graph()); return make_range(halfedge_iterator(predicate, original_halfedges.first, original_halfedges.second), @@ -515,28 +515,28 @@ halfedges(const Connected_component_graph & w) template typename boost::graph_traits::halfedges_size_type -num_halfedges(const Connected_component_graph & w) +num_halfedges(const Connected_components_graph & w) { return num_halfedges(w.graph()); } // FaceGraph template -typename boost::graph_traits< Connected_component_graph >::face_descriptor -face(typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor h, - const Connected_component_graph & w) +typename boost::graph_traits< Connected_components_graph >::face_descriptor +face(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, + const Connected_components_graph & w) { CGAL_assertion(CGAL::in_CC(h, w)); if(in_CC(face(h,w.graph()), w)) return face(h,w.graph()); else - return boost::graph_traits< CGAL::Connected_component_graph >::null_face(); + return boost::graph_traits< CGAL::Connected_components_graph >::null_face(); } template -typename boost::graph_traits< Connected_component_graph >::halfedge_descriptor -halfedge(typename boost::graph_traits< Connected_component_graph >::face_descriptor f, - const Connected_component_graph & w) +typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor +halfedge(typename boost::graph_traits< Connected_components_graph >::face_descriptor f, + const Connected_components_graph & w) { CGAL_assertion(CGAL::in_CC(f, w)); return halfedge(f,w.graph()); @@ -544,14 +544,14 @@ halfedge(typename boost::graph_traits< Connected_component_graph -std::pair >::face_iterator, -typename boost::graph_traits >::face_iterator> -faces(const Connected_component_graph & w) +std::pair >::face_iterator, +typename boost::graph_traits >::face_iterator> +faces(const Connected_components_graph & w) { - typedef typename boost::graph_traits >::face_iterator face_iterator; + typedef typename boost::graph_traits >::face_iterator face_iterator; typedef typename boost::graph_traits::face_iterator g_face_iterator; - typename Connected_component_graph ::Is_simplex_valid predicate(&w); + typename Connected_components_graph ::Is_simplex_valid predicate(&w); std::pair original_faces = faces(w.graph()); return make_range(face_iterator(predicate, original_faces.first, original_faces.second), @@ -562,7 +562,7 @@ faces(const Connected_component_graph & w) template typename boost::graph_traits::vertices_size_type -num_faces(const Connected_component_graph & w) +num_faces(const Connected_components_graph & w) { return num_faces(w.graph()); } @@ -570,14 +570,14 @@ num_faces(const Connected_component_graph & w) template bool -in_CC(const Connected_component_graph & w, bool verbose = false) +in_CC(const Connected_components_graph & w, bool verbose = false) { return in_CC(w.graph(),verbose); } template typename boost::property_map::type -get(PropertyTag ptag, const Connected_component_graph& w) +get(PropertyTag ptag, const Connected_components_graph& w) { return get(ptag, w.graph()); } @@ -586,7 +586,7 @@ get(PropertyTag ptag, const Connected_component_graph& w template typename boost::property_traits::type>::value_type get(PropertyTag ptag, - const Connected_component_graph& w, + const Connected_components_graph& w, const typename boost::property_traits::type>::key_type& k) { return get(ptag, w.graph(), k); @@ -595,7 +595,7 @@ get(PropertyTag ptag, template void -put(PropertyTag ptag, const Connected_component_graph& w, +put(PropertyTag ptag, const Connected_components_graph& w, const typename boost::property_traits::type>::key_type& k, typename boost::property_traits::type>::value_type& v) { @@ -606,15 +606,15 @@ put(PropertyTag ptag, const Connected_component_graph& namespace boost { template - struct property_map,PropertyTag> { + struct property_map,PropertyTag> { typedef typename boost::property_map::type type; typedef typename boost::property_map::const_type const_type; }; template - struct graph_has_property, PropertyTag> + struct graph_has_property, PropertyTag> : graph_has_property {}; }// namespace boost -#endif // CGAL_BOOST_GRAPH_CONNECTED_COMPONENT_GRAPH_H +#endif // CGAL_BOOST_GRAPH_Connected_components_graph_H diff --git a/BGL/test/BGL/CMakeLists.txt b/BGL/test/BGL/CMakeLists.txt index 182e64ac01f..29beb28785f 100644 --- a/BGL/test/BGL/CMakeLists.txt +++ b/BGL/test/BGL/CMakeLists.txt @@ -87,9 +87,9 @@ create_single_source_cgal_program( "test_Has_member_id.cpp" ) create_single_source_cgal_program( "test_cgal_bgl_named_params.cpp" ) -create_single_source_cgal_program( "test_Connected_component_graph.cpp" ) +create_single_source_cgal_program( "test_Connected_components_graph.cpp" ) -create_single_source_cgal_program( "graph_concept_Connected_component_graph.cpp" ) +create_single_source_cgal_program( "graph_concept_Connected_components_graph.cpp" ) diff --git a/BGL/test/BGL/graph_concept_Connected_component_graph.cpp b/BGL/test/BGL/graph_concept_Connected_components_graph.cpp similarity index 91% rename from BGL/test/BGL/graph_concept_Connected_component_graph.cpp rename to BGL/test/BGL/graph_concept_Connected_components_graph.cpp index ce2e5d9eb18..5db6f9a4ab1 100644 --- a/BGL/test/BGL/graph_concept_Connected_component_graph.cpp +++ b/BGL/test/BGL/graph_concept_Connected_components_graph.cpp @@ -1,6 +1,6 @@ #include -#include +#include #include #include @@ -8,7 +8,7 @@ typedef CGAL::Simple_cartesian K; typedef CGAL::Surface_mesh SM; -typedef CGAL::Connected_component_graph::face_descriptor , std::size_t> > Adapter; +typedef CGAL::Connected_components_graph::face_descriptor , std::size_t> > Adapter; typedef boost::graph_traits< Adapter > Traits; typedef Traits::edge_descriptor edge_descriptor; typedef Traits::halfedge_descriptor halfedge_descriptor; diff --git a/BGL/test/BGL/test_Connected_component_graph.cpp b/BGL/test/BGL/test_Connected_components_graph.cpp similarity index 94% rename from BGL/test/BGL/test_Connected_component_graph.cpp rename to BGL/test/BGL/test_Connected_components_graph.cpp index e69cfaaaff7..380a3bb17fd 100644 --- a/BGL/test/BGL/test_Connected_component_graph.cpp +++ b/BGL/test/BGL/test_Connected_components_graph.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include "test_Prefix.h" #include @@ -14,7 +14,7 @@ void test_halfedge_around_vertex_iterator(const Graph& g) { typedef typename boost::graph_traits::face_descriptor g_face_descriptor; typedef boost::associative_property_map< boost::unordered_map< g_face_descriptor, std::size_t > >FCMap; - typedef CGAL::Connected_component_graph Adapter; + typedef CGAL::Connected_components_graph Adapter; CGAL_GRAPH_TRAITS_MEMBERS(Adapter); boost::unordered_map map(CGAL::num_faces(g)); CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); @@ -43,7 +43,7 @@ void test_halfedge_around_face_iterator(const Graph& g) { typedef typename boost::graph_traits::face_descriptor g_face_descriptor; typedef boost::associative_property_map< std::map< g_face_descriptor, std::size_t > >FCMap; - typedef CGAL::Connected_component_graph Adapter; + typedef CGAL::Connected_components_graph Adapter; CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); @@ -64,7 +64,7 @@ void test_edge_iterators(const Graph& g) { typedef typename boost::graph_traits::face_descriptor g_face_descriptor; typedef boost::associative_property_map< std::map< g_face_descriptor, std::size_t > >FCMap; - typedef CGAL::Connected_component_graph Adapter; + typedef CGAL::Connected_components_graph Adapter; CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); @@ -91,7 +91,7 @@ void test_vertex_iterators(Graph& g) { typedef typename boost::graph_traits::face_descriptor g_face_descriptor; typedef boost::associative_property_map< std::map< g_face_descriptor, std::size_t > >FCMap; - typedef CGAL::Connected_component_graph Adapter; + typedef CGAL::Connected_components_graph Adapter; CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); @@ -122,7 +122,7 @@ void test_out_edges(const Graph& g) { typedef typename boost::graph_traits::face_descriptor g_face_descriptor; typedef boost::associative_property_map< std::map< g_face_descriptor, std::size_t > >FCMap; - typedef CGAL::Connected_component_graph Adapter; + typedef CGAL::Connected_components_graph Adapter; CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); @@ -152,7 +152,7 @@ void test_in_edges(const Graph& g) { typedef typename boost::graph_traits::face_descriptor g_face_descriptor; typedef boost::associative_property_map< std::map< g_face_descriptor, std::size_t > >FCMap; - typedef CGAL::Connected_component_graph Adapter; + typedef CGAL::Connected_components_graph Adapter; CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); @@ -180,7 +180,7 @@ void test_in_out_edges(const Graph& g) { typedef typename boost::graph_traits::face_descriptor g_face_descriptor; typedef boost::associative_property_map< std::map< g_face_descriptor, std::size_t > >FCMap; - typedef CGAL::Connected_component_graph Adapter; + typedef CGAL::Connected_components_graph Adapter; CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); @@ -223,7 +223,7 @@ void test_edge_find(const Graph& g) { typedef typename boost::graph_traits::face_descriptor g_face_descriptor; typedef boost::associative_property_map< std::map< g_face_descriptor, std::size_t > >FCMap; - typedef CGAL::Connected_component_graph Adapter; + typedef CGAL::Connected_components_graph Adapter; CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); @@ -248,7 +248,7 @@ void test_faces(const Graph& g) { typedef typename boost::graph_traits::face_descriptor g_face_descriptor; typedef boost::associative_property_map< std::map< g_face_descriptor, std::size_t > >FCMap; - typedef CGAL::Connected_component_graph Adapter; + typedef CGAL::Connected_components_graph Adapter; CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); @@ -275,7 +275,7 @@ void test_read(const Graph& g) { typedef typename boost::graph_traits::face_descriptor g_face_descriptor; typedef boost::associative_property_map< std::map< g_face_descriptor, std::size_t > >FCMap; - typedef CGAL::Connected_component_graph Adapter; + typedef CGAL::Connected_components_graph Adapter; CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); @@ -364,7 +364,7 @@ struct Constraint : public boost::put_get_helper::face_descriptor , std::size_t> > Adapter; + typedef CGAL::Connected_components_graph::face_descriptor , std::size_t> > Adapter; // test(sm_data()); //Make a tetrahedron and test the adapter for a patch that only contains 2 faces SM* sm = new SM(); From 56616667822b1d04116bde5c53d5723e0fcc7f35 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 6 Feb 2017 09:32:49 +0100 Subject: [PATCH 09/38] Clean-up and add key and value types to fccmap. --- BGL/doc/BGL/PackageDescription.txt | 2 +- BGL/include/CGAL/boost/graph/Connected_components_graph.h | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/BGL/doc/BGL/PackageDescription.txt b/BGL/doc/BGL/PackageDescription.txt index 0c1a13847b5..b4cdfa3bde6 100644 --- a/BGL/doc/BGL/PackageDescription.txt +++ b/BGL/doc/BGL/PackageDescription.txt @@ -316,7 +316,7 @@ user might encounter. - `CGAL::Dual` - `CGAL::Graph_with_descriptor_with_graph` - `CGAL::Graph_with_descriptor_with_graph_property_map` -- `CGAL::Connected_component_graph` +- `CGAL::Connected_components_graph` ## Helper Functions ## - `CGAL::is_border()` diff --git a/BGL/include/CGAL/boost/graph/Connected_components_graph.h b/BGL/include/CGAL/boost/graph/Connected_components_graph.h index ee547fdd042..23365f73403 100644 --- a/BGL/include/CGAL/boost/graph/Connected_components_graph.h +++ b/BGL/include/CGAL/boost/graph/Connected_components_graph.h @@ -66,12 +66,14 @@ struct Connected_components_graph /*! * \brief Creates a Connected_components_graph of the connected components of `graph` that are listed in `pids`. * \param graph the graph containing the wanted patches. - * \param fccmap the property_map that assigns a patch to each face + * \param fccmap the property_map that assigns a patch to each face, with + `boost::graph_traits::%face_descriptor` as key type and + `graph_traits::faces_size_type` as value type. * \param pids the indices of the patches of interest. */ Connected_components_graph(const Graph& graph, FaceComponentMap fccmap, - boost::unordered_set::value_type> pids) + const boost::unordered_set::value_type>& pids) : _graph(graph), _property_map(fccmap), _patch_indices(pids) { } From 0707e06cee0ac51d07a46d8195f89482fc7f1344 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 7 Feb 2017 09:49:09 +0100 Subject: [PATCH 10/38] Changes after Andreas' review --- .../boost/graph/Connected_components_graph.h | 48 ++++++++------ .../Polygon_mesh_processing.txt | 8 ++- .../doc/Polygon_mesh_processing/examples.txt | 1 + .../Polygon_mesh_processing/CMakeLists.txt | 1 + .../connected_components_graph_example.cpp | 63 +++++++++++++++++++ 5 files changed, 102 insertions(+), 19 deletions(-) create mode 100644 Polygon_mesh_processing/examples/Polygon_mesh_processing/connected_components_graph_example.cpp diff --git a/BGL/include/CGAL/boost/graph/Connected_components_graph.h b/BGL/include/CGAL/boost/graph/Connected_components_graph.h index 23365f73403..5069c5870b3 100644 --- a/BGL/include/CGAL/boost/graph/Connected_components_graph.h +++ b/BGL/include/CGAL/boost/graph/Connected_components_graph.h @@ -65,31 +65,32 @@ struct Connected_components_graph /*! * \brief Creates a Connected_components_graph of the connected components of `graph` that are listed in `pids`. + typedef unspecified_type Indices; + * \param graph the graph containing the wanted patches. - * \param fccmap the property_map that assigns a patch to each face, with + * \param fccmap the property_map that assigns a connected component to each face, with `boost::graph_traits::%face_descriptor` as key type and `graph_traits::faces_size_type` as value type. - * \param pids the indices of the patches of interest. + * \param ir the indices of the connected components of interest. */ + template Connected_components_graph(const Graph& graph, - FaceComponentMap fccmap, - const boost::unordered_set::value_type>& pids) - : _graph(graph), _property_map(fccmap), _patch_indices(pids) - { - } + FaceComponentMap fccmap, + const IndexRange& ir) + : _graph(graph), _property_map(fccmap), _patch_indices(ir.begin(),ir.end()) + {} /*! - * \brief Creates a Connected_components_graph of the connected component `pid` of `graph`. + * \brief Creates a Connected_components_graph of the connected component `id` of `graph`. * \param graph the graph containing the wanted patch. * \param fccmap the property_map that assigns a patch to each face - * \param pid the index of the patch of interest. + * \param id the index of the connected component of interest. */ Connected_components_graph(const Graph& graph, - FaceComponentMap fccmap, - typename boost::property_traits::value_type pid) + FaceComponentMap fccmap, + typename boost::property_traits::value_type pid) : _graph(graph), _property_map(fccmap) { - _patch_indices = boost::unordered_set::value_type>(); _patch_indices.insert(pid); } ///returns the graph of the Connected_components_graph. @@ -98,10 +99,22 @@ struct Connected_components_graph ///returns the property map of the Connected_components_graph. FaceComponentMap property_map()const{ return _property_map; } ///returns the unordered set of patch ids of the Connected_components_graph. - boost::unordered_set::value_type> patch_indices()const{ return _patch_indices; } - /// Replaces the current unordered set of patches by `pids` - void change_patch_id(boost::unordered_set::value_type> pids) { _patch_indices = pids;} +#ifndef DOXYGEN_RUNNING + const boost::unordered_set::value_type>& +#else + Index_range +#endif + indices()const{ return _patch_indices; } + /// Replaces the current unordered set of patches by `pids` + template + void set_connected_components(const IndexRange& ir) { _patch_indices = boost::unordered_set::value_type>(ir.begin(), ir.end());} + + void set_connected_component(typename boost::property_traits::value_type pid) { + _patch_indices.clear(); + _patch_indices.insert(pid); + } + struct Is_simplex_valid { Is_simplex_valid(const Self* graph) @@ -194,7 +207,7 @@ bool in_CC(const typename boost::graph_traits< Connected_components_graph >::face_descriptor f, const Connected_components_graph & w) { - return w.patch_indices().find(boost::get(w.property_map(), f)) != w.patch_indices().end(); + return w.indices().find(boost::get(w.property_map(), f)) != w.indices().end(); } template @@ -546,8 +559,7 @@ halfedge(typename boost::graph_traits< Connected_components_graph -std::pair >::face_iterator, -typename boost::graph_traits >::face_iterator> +Iterator_range >::face_iterator> faces(const Connected_components_graph & w) { typedef typename boost::graph_traits >::face_iterator face_iterator; diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt index 4dfac665d86..07c73d381ad 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt @@ -598,7 +598,7 @@ should be discarded in favour of major connected components. \subsection CCExample Connected Components Example -The following example shows how to record the connected +The first example shows how to record the connected components of a polygon mesh. In particular, we provide an example for the optional parameter \c EdgeConstraintMap, a property map that returns information about an edge being a \e constraint or not. @@ -607,6 +607,12 @@ the propagation of a connected component index to cross it. \cgalExample{Polygon_mesh_processing/connected_components_example.cpp} +The second example shows how to use the class template `Connected_components_graph` +which enables to treat one or several connected components as a face graph. + +\cgalExample{Polygon_mesh_processing/connected_components_graph_example.cpp} + + \section PMPDistance Approximate Hausdorff Distance This package provides methods to compute (approximate) distances between meshes and point sets. diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt index f47ca95cac6..ce29168f6d2 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt @@ -7,6 +7,7 @@ \example Polygon_mesh_processing/point_inside_example.cpp \example Polygon_mesh_processing/triangulate_faces_example.cpp \example Polygon_mesh_processing/connected_components_example.cpp +\example Polygon_mesh_processing/connected_components_graph_example.cpp \example Polygon_mesh_processing/polygon_soup_example.cpp \example Polygon_mesh_processing/triangulate_polyline_example.cpp \example Polygon_mesh_processing/refine_fair_example.cpp diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt b/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt index 8560602f720..32d5286cd26 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt @@ -90,6 +90,7 @@ create_single_source_cgal_program( "compute_normals_example.cpp" CXX_FEATURES cx create_single_source_cgal_program( "point_inside_example.cpp") create_single_source_cgal_program( "triangulate_faces_example.cpp") create_single_source_cgal_program( "connected_components_example.cpp") +create_single_source_cgal_program( "connected_components_graph_example.cpp") create_single_source_cgal_program( "polygon_soup_example.cpp") create_single_source_cgal_program( "triangulate_polyline_example.cpp") create_single_source_cgal_program( "mesh_slicer_example.cpp") diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/connected_components_graph_example.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/connected_components_graph_example.cpp new file mode 100644 index 00000000000..81142ad9afc --- /dev/null +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/connected_components_graph_example.cpp @@ -0,0 +1,63 @@ +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; +typedef Kernel::Point_3 Point; + +typedef CGAL::Surface_mesh Mesh; +typedef boost::graph_traits::face_descriptor face_descriptor; +typedef boost::graph_traits::faces_size_type faces_size_type; + +typedef Mesh::Property_map FCCmap; + typedef CGAL::Connected_components_graph CCG; + +namespace PMP = CGAL::Polygon_mesh_processing; + + +int main(int argc, char* argv[]) +{ + std::ifstream input((argc > 1) ? argv[1] : "data/blobby_3cc.off"); + + Mesh mesh; + if (!input || !(input >> mesh) || mesh.is_empty()) { + std::cerr << "Not a valid off file." << std::endl; + return 1; + } + + FCCmap fccmap = mesh.add_property_map("f:CC").first; + + faces_size_type num = PMP::connected_components(mesh,fccmap); + + std::cerr << "- The graph has " << num << " connected components (face connectivity)" << std::endl; + + CCG ccg(mesh, fccmap, faces_size_type(0)); + + std::cout << "The faces in component 0 are:" << std::endl; + BOOST_FOREACH(boost::graph_traits::face_descriptor f, faces(ccg)){ + std::cout << f << std::endl; + } + + if(num>1){ + std::vector components; + components.push_back(0); + components.push_back(1); + + ccg.set_connected_components(components); + + std::cout << "The faces in components 0 and 1 are:" << std::endl; + BOOST_FOREACH(CCG::face_descriptor f, faces(ccg)){ + std::cout << f << std::endl; + } + } + return 0; +} + From 6e1199d56f0c43f7c2f5cd811497e11a3f71f937 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 27 Apr 2017 17:24:40 +0200 Subject: [PATCH 11/38] bitsets implementation, doc fix and tests fix. --- .../boost/graph/Connected_components_graph.h | 893 ++++++++++-------- .../BGL/test_Connected_components_graph.cpp | 66 +- 2 files changed, 508 insertions(+), 451 deletions(-) diff --git a/BGL/include/CGAL/boost/graph/Connected_components_graph.h b/BGL/include/CGAL/boost/graph/Connected_components_graph.h index 5069c5870b3..9f0942fb6c6 100644 --- a/BGL/include/CGAL/boost/graph/Connected_components_graph.h +++ b/BGL/include/CGAL/boost/graph/Connected_components_graph.h @@ -29,114 +29,193 @@ #include #include #include +#include namespace CGAL { -/*! -\ingroup PkgBGLHelper + /*! + * \ingroup PkgBGLHelper + * + * The class `Connected_components_graph` wraps a graph into another graph in such a way that only the specified connected components are seen from the outside. + * + * For example, calling `vertices(graph)` will return an iterator range of all but only the vertices that belong to the connected components whose ids in the + * `FaceComponentMap` are contained in the given set. + * + * \tparam Graph must be a model of a `FaceListGraph` and `HalfedgeListGraph`. + * + * \cgalModels `FaceListGraph` + * \cgalModels `HalfedgeListGraph` + */ -The class `Connected_components_graph` wraps a graph into another graph in such a way that only the specified connected components are seen from the outside. - -For example, calling `vertices(graph)` will return an iterator range of all but only the vertices that belong to the connected components whose ids in the `FaceComponentMap` are contained in the given set. - -\attention The functions `%num_vertices()`, `%num_edges()`, `%num_halfedges()`, `%num_faces()`, are forwarded from the underlying graph, -which means that `num_vertices(graph)` is different from `std::distance(vertices(graph).first,vertices(graph).second)` - -Property maps can be wrapped with `Connected_components_graph_property_map`. -\tparam Graph must be a model of a `FaceListGraph` and `HalfedgeListGraph`. -\tparam FaceComponentMap a model of `WritablePropertyMap` with - `boost::graph_traits::%face_descriptor` as key type and - `graph_traits::faces_size_type` as value type. - -\cgalModels `FaceListGraph` -\cgalModels `HalfedgeListGraph` -*/ - -template +template struct Connected_components_graph { - typedef boost::graph_traits gt; - typedef typename gt::vertex_descriptor vertex_descriptor; - typedef typename gt::halfedge_descriptor halfedge_descriptor; - typedef typename gt::edge_descriptor edge_descriptor; - typedef typename gt::face_descriptor face_descriptor; - typedef Connected_components_graph Self; + typedef boost::graph_traits gt; + typedef typename gt::vertex_descriptor vertex_descriptor; + typedef typename gt::halfedge_descriptor halfedge_descriptor; + typedef typename gt::edge_descriptor edge_descriptor; + typedef typename gt::face_descriptor face_descriptor; + typedef Connected_components_graph Self; + typedef typename boost::property_map::type FImap; + typedef typename boost::property_map::type VImap; + typedef typename boost::property_map::type HImap; - /*! - * \brief Creates a Connected_components_graph of the connected components of `graph` that are listed in `pids`. - typedef unspecified_type Indices; + /*! + * \brief Creates a Connected_components_graph of the connected components of `graph` specified in the range + * defined by `begin` and `end`. + * typedef unspecified_type Indices; - * \param graph the graph containing the wanted patches. - * \param fccmap the property_map that assigns a connected component to each face, with - `boost::graph_traits::%face_descriptor` as key type and - `graph_traits::faces_size_type` as value type. - * \param ir the indices of the connected components of interest. - */ - template - Connected_components_graph(const Graph& graph, - FaceComponentMap fccmap, - const IndexRange& ir) - : _graph(graph), _property_map(fccmap), _patch_indices(ir.begin(),ir.end()) + * \tparam FaceComponentMap a model of `ReadablePropertyMap` with + `boost::graph_traits::%face_descriptor` as key type and + `graph_traits::faces_size_type` as value type. + + * \param graph the graph containing the wanted patches. + * \param fccmap the property_map that assigns a connected component to each face, with + `boost::graph_traits::%face_descriptor` as key type and + `graph_traits::faces_size_type` as value type. + * \param begin an interator to the beginning of a range of connected components indices of interest. + * \param end an interator to the element past the end of a range of connected components indices of interest. + */ + + template + Connected_components_graph(const Graph& graph, + FaceComponentMap fccmap, + IndexRangeIterator begin, + IndexRangeIterator end) + : _graph(graph) + { + fimap = get(CGAL::face_index, graph); + vimap = get(boost::vertex_index, graph); + himap = get(CGAL::halfedge_index, graph); + face_patch.resize(num_faces(graph)); + vertex_patch.resize(num_vertices(graph)); + halfedge_patch.resize(num_halfedges(graph)); + boost::unordered_set::value_type> pids; + for(IndexRangeIterator it = begin; + it != end; + ++it) + { + pids.insert(*it); + } + + BOOST_FOREACH(face_descriptor fd, faces(graph) ) + { + if(pids.find(boost::get(fccmap, fd))!= pids.end() ) + { + face_patch.set(get(fimap, fd)); + BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_face(halfedge(fd, graph), graph)) + { + halfedge_patch.set(get(himap, hd)); + halfedge_patch.set(get(himap, opposite(hd, graph))); + vertex_patch.set(get(vimap, target(hd, graph))); + } + } + } + } + + /*! + * \brief Creates a Connected_components_graph of the connected component `pid` of `graph`. + * + * \tparam FaceComponentMap a model of `ReadablePropertyMap` with + `boost::graph_traits::%face_descriptor` as key type and + `graph_traits::faces_size_type` as value type. + * \param graph the graph containing the wanted patch. + * \param fccmap the property_map that assigns a connected component to each face, with + `boost::graph_traits::%face_descriptor` as key type and + `graph_traits::faces_size_type` as value type. + * \param pid the index of the connected component of interest. + */ + template + Connected_components_graph(const Graph& graph, + FaceComponentMap fccmap, + typename boost::property_traits::value_type pid) + : _graph(graph) + { + fimap = get(CGAL::face_index, graph); + vimap = get(boost::vertex_index, graph); + himap = get(CGAL::halfedge_index, graph); + face_patch.resize(num_faces(graph)); + vertex_patch.resize(num_vertices(graph)); + halfedge_patch.resize(num_halfedges(graph)); + BOOST_FOREACH(face_descriptor fd, faces(graph) ) + { + if(boost::get(fccmap, fd) == pid) + { + face_patch.set(get(fimap, fd)); + BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_face(halfedge(fd, graph), graph)) + { + halfedge_patch.set(get(himap, hd)); + halfedge_patch.set(get(himap, opposite(hd, graph))); + vertex_patch.set(get(vimap, target(hd, graph))); + } + } + } + } + ///returns the graph of the Connected_components_graph. + const Graph& graph()const{ return _graph; } + + + + struct Is_simplex_valid + { + Is_simplex_valid(const Self* graph) + :adapter(graph) {} - /*! - * \brief Creates a Connected_components_graph of the connected component `id` of `graph`. - * \param graph the graph containing the wanted patch. - * \param fccmap the property_map that assigns a patch to each face - * \param id the index of the connected component of interest. - */ - Connected_components_graph(const Graph& graph, - FaceComponentMap fccmap, - typename boost::property_traits::value_type pid) - : _graph(graph), _property_map(fccmap) + Is_simplex_valid() + :adapter(NULL) + {} + template + bool operator()(Simplex s) { - _patch_indices.insert(pid); + CGAL_assertion(adapter!=NULL); + return (in_CC(s, *adapter)); } - ///returns the graph of the Connected_components_graph. - const Graph& graph()const{ return _graph; } - - ///returns the property map of the Connected_components_graph. - FaceComponentMap property_map()const{ return _property_map; } - ///returns the unordered set of patch ids of the Connected_components_graph. -#ifndef DOXYGEN_RUNNING - const boost::unordered_set::value_type>& -#else - Index_range -#endif - indices()const{ return _patch_indices; } - - /// Replaces the current unordered set of patches by `pids` - template - void set_connected_components(const IndexRange& ir) { _patch_indices = boost::unordered_set::value_type>(ir.begin(), ir.end());} - - void set_connected_component(typename boost::property_traits::value_type pid) { - _patch_indices.clear(); - _patch_indices.insert(pid); - } - - struct Is_simplex_valid - { - Is_simplex_valid(const Self* graph) - :adapter(graph) - {} - - Is_simplex_valid() - :adapter(NULL) - {} - template - bool operator()(Simplex s) - { - CGAL_assertion(adapter!=NULL); - return (in_CC(s, *adapter)); - } - const Self* adapter; - }; + const Self* adapter; + }; + ///returns true if `f` is in the specified connected_components + bool is_in_cc(face_descriptor f) const + { + return face_patch[get(fimap, f)]; + } + ///returns true if `v` is in the specified connected_components + bool is_in_cc(vertex_descriptor v) const + { + return vertex_patch[get(vimap, v)]; + } + ///returns true if `h` is in the specified connected_components + bool is_in_cc(halfedge_descriptor h) const + { + return halfedge_patch[get(himap, h)]; + } + ///returns the number of faces contained in the specified connected_components + typename boost::graph_traits:: + vertices_size_type number_of_faces()const + { + return face_patch.count(); + } +///returns the number of vertices contained in the specified connected_components + typename boost::graph_traits:: + vertices_size_type number_of_vertices()const + { + return vertex_patch.count(); + } +///returns the number of halfedges contained in the specified connected_components + typename boost::graph_traits:: + vertices_size_type number_of_halfedges()const + { + return halfedge_patch.count(); + } private: - const Graph& _graph; - FaceComponentMap _property_map; - boost::unordered_set::value_type> _patch_indices; + FImap fimap; + VImap vimap; + HImap himap; + const Graph& _graph; + boost::dynamic_bitset<> face_patch; + boost::dynamic_bitset<> vertex_patch; + boost::dynamic_bitset<> halfedge_patch; }; } // namespace CGAL @@ -144,57 +223,57 @@ private: namespace boost { -template -struct graph_traits< CGAL::Connected_components_graph > +template +struct graph_traits< CGAL::Connected_components_graph > { - typedef CGAL::Connected_components_graph G; - typedef boost::graph_traits BGTG; - typedef typename BGTG::vertex_descriptor vertex_descriptor; - typedef typename BGTG::halfedge_descriptor halfedge_descriptor; - typedef typename BGTG::edge_descriptor edge_descriptor; - typedef typename BGTG::face_descriptor face_descriptor; + typedef CGAL::Connected_components_graph G; + typedef boost::graph_traits BGTG; + typedef typename BGTG::vertex_descriptor vertex_descriptor; + typedef typename BGTG::halfedge_descriptor halfedge_descriptor; + typedef typename BGTG::edge_descriptor edge_descriptor; + typedef typename BGTG::face_descriptor face_descriptor; - typedef boost::filter_iterator vertex_iterator; - typedef boost::filter_iterator halfedge_iterator; - typedef boost::filter_iterator edge_iterator; - typedef boost::filter_iterator face_iterator; + typedef boost::filter_iterator vertex_iterator; + typedef boost::filter_iterator halfedge_iterator; + typedef boost::filter_iterator edge_iterator; + typedef boost::filter_iterator face_iterator; - typedef boost::filter_iterator out_edge_iterator; - typedef boost::filter_iterator in_edge_iterator; + typedef boost::filter_iterator out_edge_iterator; + typedef boost::filter_iterator in_edge_iterator; - typedef typename BGTG::directed_category directed_category; - typedef typename BGTG::edge_parallel_category edge_parallel_category; - typedef typename BGTG::traversal_category traversal_category; - typedef typename BGTG::vertices_size_type vertices_size_type; - typedef typename BGTG::edges_size_type edges_size_type; - typedef typename BGTG::halfedges_size_type halfedges_size_type; - typedef typename BGTG::faces_size_type faces_size_type; - typedef typename BGTG::degree_size_type degree_size_type; + typedef typename BGTG::directed_category directed_category; + typedef typename BGTG::edge_parallel_category edge_parallel_category; + typedef typename BGTG::traversal_category traversal_category; + typedef typename BGTG::vertices_size_type vertices_size_type; + typedef typename BGTG::edges_size_type edges_size_type; + typedef typename BGTG::halfedges_size_type halfedges_size_type; + typedef typename BGTG::faces_size_type faces_size_type; + typedef typename BGTG::degree_size_type degree_size_type; - static vertex_descriptor null_vertex() - { - return BGTG::null_vertex(); - } + static vertex_descriptor null_vertex() + { + return BGTG::null_vertex(); + } - static halfedge_descriptor null_halfedge() - { - return BGTG::null_halfedge(); - } + static halfedge_descriptor null_halfedge() + { + return BGTG::null_halfedge(); + } - static edge_descriptor null_edge() - { - return edge_descriptor(BGTG::null_halfedge()); - } + static edge_descriptor null_edge() + { + return edge_descriptor(BGTG::null_halfedge()); + } - static face_descriptor null_face() - { - return BGTG::null_face(); - } + static face_descriptor null_face() + { + return BGTG::null_face(); + } }; -template -struct graph_traits< const CGAL::Connected_components_graph > - : public graph_traits< CGAL::Connected_components_graph > +template +struct graph_traits< const CGAL::Connected_components_graph > + : public graph_traits< CGAL::Connected_components_graph > {}; @@ -202,414 +281,403 @@ struct graph_traits< const CGAL::Connected_components_graph +template bool -in_CC(const typename boost::graph_traits< Connected_components_graph >::face_descriptor f, - const Connected_components_graph & w) +in_CC(const typename boost::graph_traits< Connected_components_graph >::face_descriptor f, + const Connected_components_graph & w) { - return w.indices().find(boost::get(w.property_map(), f)) != w.indices().end(); + return w.is_in_cc(f); } -template +template bool -in_CC(const typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, - const Connected_components_graph & w) +in_CC(const typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, + const Connected_components_graph & w) { - return in_CC(face(h, w.graph()), w) || - in_CC(face(opposite(h, w.graph()), w.graph()), w); + return w.is_in_cc(h); } -template +template bool -in_CC(const typename boost::graph_traits< Connected_components_graph >::edge_descriptor e, - const Connected_components_graph & w) +in_CC(const typename boost::graph_traits< Connected_components_graph >::edge_descriptor e, + const Connected_components_graph & w) { - return in_CC(halfedge(e, w.graph()), w); + return w.is_in_cc(halfedge(e, w.graph())); } -template +template bool -in_CC(const typename boost::graph_traits< Connected_components_graph >::vertex_descriptor v, - const Connected_components_graph & w) +in_CC(const typename boost::graph_traits< Connected_components_graph >::vertex_descriptor v, + const Connected_components_graph & w) { - typename boost::graph_traits >::halfedge_descriptor h = halfedge(v, w.graph()); - typename boost::graph_traits >::halfedge_descriptor hcirc = h; - do - { - if(in_CC(face(hcirc, w.graph()), w)) - return true; - hcirc = opposite(next(hcirc, w.graph()), w.graph()); - }while(hcirc != h); - return false; + return w.is_in_cc(v); } -template +template typename boost::graph_traits::vertices_size_type -num_vertices(const Connected_components_graph& w) +num_vertices(const Connected_components_graph& w) { - return num_vertices(w.graph()); + return w.number_of_vertices(); } -template +template typename boost::graph_traits::edges_size_type -num_edges(const Connected_components_graph& w) +num_edges(const Connected_components_graph& w) { - return num_edges(w.graph()); + return w.number_of_halfedges()/2; } -template +template typename boost::graph_traits::degree_size_type -degree(typename boost::graph_traits >::vertex_descriptor v, - const Connected_components_graph& w) +degree(typename boost::graph_traits >::vertex_descriptor v, + const Connected_components_graph& w) { - CGAL_assertion(in_CC(v, w)); - typename boost::graph_traits::degree_size_type v_deg = 0; - typename boost::graph_traits >::halfedge_descriptor h = halfedge(v, w); - typename boost::graph_traits >::halfedge_descriptor hcirc = h; - do - { - if(in_CC(hcirc, w)) - ++v_deg; - hcirc = opposite(next(hcirc, w.graph()), w.graph()); - }while(hcirc != h); - return v_deg; + CGAL_assertion(in_CC(v, w)); + typename boost::graph_traits::degree_size_type v_deg = 0; + typename boost::graph_traits >::halfedge_descriptor h = halfedge(v, w); + typename boost::graph_traits >::halfedge_descriptor hcirc = h; + do + { + if(in_CC(hcirc, w)) + ++v_deg; + hcirc = opposite(next(hcirc, w.graph()), w.graph()); + }while(hcirc != h); + return v_deg; } -template +template typename boost::graph_traits::degree_size_type -out_degree(typename boost::graph_traits >::vertex_descriptor v, - const Connected_components_graph& w) +out_degree(typename boost::graph_traits >::vertex_descriptor v, + const Connected_components_graph& w) { - CGAL_assertion(in_CC(v, w)); - return std::distance(out_edges(v, w).first ,out_edges(v, w).second); + CGAL_assertion(in_CC(v, w)); + return std::distance(out_edges(v, w).first ,out_edges(v, w).second); } -template +template typename boost::graph_traits::degree_size_type -in_degree(typename boost::graph_traits >::vertex_descriptor v, - const Connected_components_graph& w) +in_degree(typename boost::graph_traits >::vertex_descriptor v, + const Connected_components_graph& w) { - CGAL_assertion(in_CC(v, w)); - return std::distance(in_edges(v, w).first ,in_edges(v, w).second); + CGAL_assertion(in_CC(v, w)); + return std::distance(in_edges(v, w).first ,in_edges(v, w).second); } -template -typename boost::graph_traits >::vertex_descriptor -source(typename boost::graph_traits >::edge_descriptor e, - const Connected_components_graph & w) +template +typename boost::graph_traits >::vertex_descriptor +source(typename boost::graph_traits >::edge_descriptor e, + const Connected_components_graph & w) { - CGAL_assertion(in_CC(e, w)); - return source(e, w.graph()); + CGAL_assertion(in_CC(e, w)); + return source(e, w.graph()); } -template -typename boost::graph_traits >::vertex_descriptor -target(typename boost::graph_traits >::edge_descriptor e, - const Connected_components_graph & w) +template +typename boost::graph_traits >::vertex_descriptor +target(typename boost::graph_traits >::edge_descriptor e, + const Connected_components_graph & w) { - CGAL_assertion(in_CC(e, w)); - return target(e, w.graph()); + CGAL_assertion(in_CC(e, w)); + return target(e, w.graph()); } -template -std::pair >::edge_descriptor, bool> -edge(typename boost::graph_traits >::vertex_descriptor u, - typename boost::graph_traits >::vertex_descriptor v, - const Connected_components_graph & w) +template +std::pair >::edge_descriptor, bool> +edge(typename boost::graph_traits >::vertex_descriptor u, + typename boost::graph_traits >::vertex_descriptor v, + const Connected_components_graph & w) { - CGAL_assertion(in_CC(u, w) && in_CC(v, w)); - typename boost::graph_traits >::edge_descriptor e = edge(u, v, w.graph()).first; - bool res = in_CC(e, w); - return std::make_pair(e, res); + CGAL_assertion(in_CC(u, w) && in_CC(v, w)); + typename boost::graph_traits >::edge_descriptor e = edge(u, v, w.graph()).first; + bool res = in_CC(e, w); + return std::make_pair(e, res); } -template -CGAL::Iterator_range >::vertex_iterator> -vertices(const Connected_components_graph & w) +template +CGAL::Iterator_range >::vertex_iterator> +vertices(const Connected_components_graph & w) { - typedef typename boost::graph_traits >::vertex_iterator vertex_iterator; - typedef typename boost::graph_traits::vertex_iterator g_vertex_iterator; + typedef typename boost::graph_traits >::vertex_iterator vertex_iterator; + typedef typename boost::graph_traits::vertex_iterator g_vertex_iterator; - typename Connected_components_graph ::Is_simplex_valid predicate(&w); - g_vertex_iterator b,e; - boost::tie(b,e) = vertices(w.graph()); - return make_range(vertex_iterator(predicate, b, e), - vertex_iterator(predicate, e, e)); + typename Connected_components_graph ::Is_simplex_valid predicate(&w); + g_vertex_iterator b,e; + boost::tie(b,e) = vertices(w.graph()); + return make_range(vertex_iterator(predicate, b, e), + vertex_iterator(predicate, e, e)); } -template -CGAL::Iterator_range >::edge_iterator> -edges(const Connected_components_graph & w) +template +CGAL::Iterator_range >::edge_iterator> +edges(const Connected_components_graph & w) { - typedef typename boost::graph_traits >::edge_iterator edge_iterator; - typedef typename boost::graph_traits::edge_iterator g_edge_iterator; + typedef typename boost::graph_traits >::edge_iterator edge_iterator; + typedef typename boost::graph_traits::edge_iterator g_edge_iterator; - typename Connected_components_graph ::Is_simplex_valid predicate(&w); - g_edge_iterator b,e; - boost::tie(b,e) = edges(w.graph()); - return make_range(edge_iterator(predicate, b, e), - edge_iterator(predicate, e, e)); + typename Connected_components_graph ::Is_simplex_valid predicate(&w); + g_edge_iterator b,e; + boost::tie(b,e) = edges(w.graph()); + return make_range(edge_iterator(predicate, b, e), + edge_iterator(predicate, e, e)); } -template -CGAL::Iterator_range >::out_edge_iterator> -out_edges(typename boost::graph_traits >::vertex_descriptor v, - const Connected_components_graph & w) +template +CGAL::Iterator_range >::out_edge_iterator> +out_edges(typename boost::graph_traits >::vertex_descriptor v, + const Connected_components_graph & w) { - typedef typename boost::graph_traits >::out_edge_iterator out_edge_iterator; - typedef typename boost::graph_traits::out_edge_iterator g_out_edge_iterator; + typedef typename boost::graph_traits >::out_edge_iterator out_edge_iterator; + typedef typename boost::graph_traits::out_edge_iterator g_out_edge_iterator; - typename Connected_components_graph ::Is_simplex_valid predicate(&w); - g_out_edge_iterator b,e; - boost::tie(b,e) = out_edges(v, w.graph()); - return make_range(out_edge_iterator(predicate, b, e), - out_edge_iterator(predicate, e, e)); + typename Connected_components_graph ::Is_simplex_valid predicate(&w); + g_out_edge_iterator b,e; + boost::tie(b,e) = out_edges(v, w.graph()); + return make_range(out_edge_iterator(predicate, b, e), + out_edge_iterator(predicate, e, e)); } -template -CGAL::Iterator_range >::in_edge_iterator> -in_edges(typename boost::graph_traits >::vertex_descriptor v, - const Connected_components_graph & w) +template +CGAL::Iterator_range >::in_edge_iterator> +in_edges(typename boost::graph_traits >::vertex_descriptor v, + const Connected_components_graph & w) { - typedef typename boost::graph_traits >::in_edge_iterator in_edge_iterator; - typedef typename boost::graph_traits::in_edge_iterator g_in_edge_iterator; + typedef typename boost::graph_traits >::in_edge_iterator in_edge_iterator; + typedef typename boost::graph_traits::in_edge_iterator g_in_edge_iterator; - typename Connected_components_graph ::Is_simplex_valid predicate(&w); - g_in_edge_iterator b,e; - boost::tie(b,e) = in_edges(v, w.graph()); - return make_range(in_edge_iterator(predicate, b, e), - in_edge_iterator(predicate, e, e)); + typename Connected_components_graph ::Is_simplex_valid predicate(&w); + g_in_edge_iterator b,e; + boost::tie(b,e) = in_edges(v, w.graph()); + return make_range(in_edge_iterator(predicate, b, e), + in_edge_iterator(predicate, e, e)); } // // HalfedgeGraph // -template -typename boost::graph_traits< Connected_components_graph >::edge_descriptor -edge(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, - const Connected_components_graph & w) +template +typename boost::graph_traits< Connected_components_graph >::edge_descriptor +edge(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, + const Connected_components_graph & w) { - CGAL_assertion(CGAL::in_CC(h, w)); - return edge(h, w.graph()); + CGAL_assertion(CGAL::in_CC(h, w)); + return edge(h, w.graph()); } -template -typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor -halfedge(typename boost::graph_traits< Connected_components_graph >::edge_descriptor e, - const Connected_components_graph & w) +template +typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor +halfedge(typename boost::graph_traits< Connected_components_graph >::edge_descriptor e, + const Connected_components_graph & w) { - CGAL_assertion(CGAL::in_CC(e, w)); - return halfedge(e, w.graph()); + CGAL_assertion(CGAL::in_CC(e, w)); + return halfedge(e, w.graph()); } -template -typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor -halfedge(typename boost::graph_traits< Connected_components_graph >::vertex_descriptor v, - const Connected_components_graph & w) +template +typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor +halfedge(typename boost::graph_traits< Connected_components_graph >::vertex_descriptor v, + const Connected_components_graph & w) { - CGAL_assertion(in_CC(v, w)); - typename boost::graph_traits >::halfedge_descriptor h = halfedge(v, w.graph()); - typename boost::graph_traits >::halfedge_descriptor hcirc = h; - do + CGAL_assertion(in_CC(v, w)); + typename boost::graph_traits >::halfedge_descriptor h = halfedge(v, w.graph()); + typename boost::graph_traits >::halfedge_descriptor hcirc = h; + do + { + if(in_CC(hcirc, w)) + return hcirc; + hcirc = opposite(next(hcirc, w.graph()), w.graph()); + }while(hcirc != h); + return boost::graph_traits< CGAL::Connected_components_graph >::null_halfedge(); +} + + +template +std::pair >::halfedge_descriptor, bool> +halfedge(typename boost::graph_traits< Connected_components_graph >::vertex_descriptor u, + typename boost::graph_traits< Connected_components_graph >::vertex_descriptor v, + const Connected_components_graph & w) +{ + CGAL_assertion(in_CC(u, w) && in_CC(v, w)); + typename boost::graph_traits >::halfedge_descriptor h = halfedge(u, v, w.graph()).first; + return std::make_pair(h, in_CC(h, w)); +} + + +template +typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor +opposite(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, + const Connected_components_graph & w) +{ + CGAL_assertion(in_CC(h, w) ); + return opposite(h, w.graph()); +} + +template +typename boost::graph_traits< Connected_components_graph >::vertex_descriptor +source(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, + const Connected_components_graph & w) +{ + CGAL_assertion(in_CC(h, w) ); + return source(h, w.graph()); +} + +template +typename boost::graph_traits< Connected_components_graph >::vertex_descriptor +target(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, + const Connected_components_graph & w) +{ + CGAL_assertion(in_CC(h, w) ); + return target(h, w.graph()); +} + +template +typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor +next(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, + const Connected_components_graph & w) +{ + CGAL_assertion(in_CC(h, w)); + if(in_CC(next(h, w.graph()), w)) + return next(h, w.graph()); + + //act as a border + BOOST_FOREACH(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor hcirc + , CGAL::halfedges_around_target(target(h, w.graph()), w.graph())) + { + if(hcirc != h && in_CC(hcirc, w)) { - if(in_CC(hcirc, w)) - return hcirc; - hcirc = opposite(next(hcirc, w.graph()), w.graph()); - }while(hcirc != h); - return boost::graph_traits< CGAL::Connected_components_graph >::null_halfedge(); + return opposite(hcirc, w.graph()); + } + } + return boost::graph_traits< CGAL::Connected_components_graph >::null_halfedge(); } - -template -std::pair >::halfedge_descriptor, bool> -halfedge(typename boost::graph_traits< Connected_components_graph >::vertex_descriptor u, - typename boost::graph_traits< Connected_components_graph >::vertex_descriptor v, - const Connected_components_graph & w) +template +typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor +prev(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, + const Connected_components_graph & w) { - CGAL_assertion(in_CC(u, w) && in_CC(v, w)); - typename boost::graph_traits >::halfedge_descriptor h = halfedge(u, v, w.graph()).first; - return std::make_pair(h, in_CC(h, w)); -} + CGAL_assertion(in_CC(h, w)); + if(in_CC(prev(h, w.graph()), w)) + return prev(h, w.graph()); -template -typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor -opposite(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, - const Connected_components_graph & w) -{ - CGAL_assertion(in_CC(h, w) ); - return opposite(h, w.graph()); -} - -template -typename boost::graph_traits< Connected_components_graph >::vertex_descriptor -source(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, - const Connected_components_graph & w) -{ - CGAL_assertion(in_CC(h, w) ); - return source(h, w.graph()); -} - -template -typename boost::graph_traits< Connected_components_graph >::vertex_descriptor -target(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, - const Connected_components_graph & w) -{ - CGAL_assertion(in_CC(h, w) ); - return target(h, w.graph()); -} - -template -typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor -next(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, - const Connected_components_graph & w) -{ - CGAL_assertion(in_CC(h, w)); - if(in_CC(face(h, w.graph()), w)) - return next(h, w.graph()); - - //act as a border - typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor hcirc = h; - do + //act as a border + BOOST_FOREACH(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor hcirc + , CGAL::halfedges_around_source(source(h, w.graph()), w.graph())) + { + if(hcirc != h && in_CC(hcirc, w)) { - if(in_CC(hcirc, w)) - { - return hcirc; - } - hcirc = opposite(next(hcirc,w.graph()),w.graph()); - }while(hcirc != h); - return boost::graph_traits< CGAL::Connected_components_graph >::null_halfedge(); -} - -template -typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor -prev(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, - const Connected_components_graph & w) -{ - - CGAL_assertion(in_CC(h, w)); - if(in_CC(face(h, w.graph()), w)) - return prev(h, w.graph()); - - //act as a border - typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor hcirc = h; - do - { - if(in_CC(hcirc, w)) - { - return hcirc; - } - hcirc = opposite(prev(hcirc,w.graph()), w.graph()); - }while(hcirc != h); - return boost::graph_traits< CGAL::Connected_components_graph >::null_halfedge(); + return opposite(hcirc, w.graph()); + } + } + return boost::graph_traits< CGAL::Connected_components_graph >::null_halfedge(); } // // HalfedgeListGraph // -template -std::pair >::halfedge_iterator, -typename boost::graph_traits >::halfedge_iterator> -halfedges(const Connected_components_graph & w) +template +std::pair >::halfedge_iterator, +typename boost::graph_traits >::halfedge_iterator> +halfedges(const Connected_components_graph & w) { - typedef typename boost::graph_traits >::halfedge_iterator halfedge_iterator; - typedef typename boost::graph_traits::halfedge_iterator g_halfedge_iterator; + typedef typename boost::graph_traits >::halfedge_iterator halfedge_iterator; + typedef typename boost::graph_traits::halfedge_iterator g_halfedge_iterator; - typename Connected_components_graph ::Is_simplex_valid predicate(&w); - std::pair original_halfedges = halfedges(w.graph()); + typename Connected_components_graph ::Is_simplex_valid predicate(&w); + std::pair original_halfedges = halfedges(w.graph()); - return make_range(halfedge_iterator(predicate, original_halfedges.first, original_halfedges.second), - halfedge_iterator(predicate, original_halfedges.second, original_halfedges.second)); + return make_range(halfedge_iterator(predicate, original_halfedges.first, original_halfedges.second), + halfedge_iterator(predicate, original_halfedges.second, original_halfedges.second)); } -template +template typename boost::graph_traits::halfedges_size_type -num_halfedges(const Connected_components_graph & w) +num_halfedges(const Connected_components_graph & w) { - return num_halfedges(w.graph()); + return w.number_of_halfedges(); } // FaceGraph -template -typename boost::graph_traits< Connected_components_graph >::face_descriptor -face(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, - const Connected_components_graph & w) +template +typename boost::graph_traits< Connected_components_graph >::face_descriptor +face(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, + const Connected_components_graph & w) { - CGAL_assertion(CGAL::in_CC(h, w)); - if(in_CC(face(h,w.graph()), w)) - return face(h,w.graph()); - else - return boost::graph_traits< CGAL::Connected_components_graph >::null_face(); + CGAL_assertion(CGAL::in_CC(h, w)); + if(in_CC(h, w)) + return face(h,w.graph()); + else + return boost::graph_traits< CGAL::Connected_components_graph >::null_face(); } -template -typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor -halfedge(typename boost::graph_traits< Connected_components_graph >::face_descriptor f, - const Connected_components_graph & w) +template +typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor +halfedge(typename boost::graph_traits< Connected_components_graph >::face_descriptor f, + const Connected_components_graph & w) { - CGAL_assertion(CGAL::in_CC(f, w)); - return halfedge(f,w.graph()); + CGAL_assertion(CGAL::in_CC(f, w)); + return halfedge(f,w.graph()); } -template -Iterator_range >::face_iterator> -faces(const Connected_components_graph & w) +template +Iterator_range >::face_iterator> +faces(const Connected_components_graph & w) { - typedef typename boost::graph_traits >::face_iterator face_iterator; - typedef typename boost::graph_traits::face_iterator g_face_iterator; + typedef typename boost::graph_traits >::face_iterator face_iterator; + typedef typename boost::graph_traits::face_iterator g_face_iterator; - typename Connected_components_graph ::Is_simplex_valid predicate(&w); - std::pair original_faces = faces(w.graph()); + typename Connected_components_graph ::Is_simplex_valid predicate(&w); + std::pair original_faces = faces(w.graph()); - return make_range(face_iterator(predicate, original_faces.first, original_faces.second), - face_iterator(predicate, original_faces.second, original_faces.second)); + return make_range(face_iterator(predicate, original_faces.first, original_faces.second), + face_iterator(predicate, original_faces.second, original_faces.second)); } -template +template typename boost::graph_traits::vertices_size_type -num_faces(const Connected_components_graph & w) +num_faces(const Connected_components_graph & w) { - return num_faces(w.graph()); + return w.number_of_faces(); } -template +template bool -in_CC(const Connected_components_graph & w, bool verbose = false) +in_CC(const Connected_components_graph & w, bool verbose = false) { - return in_CC(w.graph(),verbose); + return in_CC(w.graph(),verbose); } -template +template typename boost::property_map::type -get(PropertyTag ptag, const Connected_components_graph& w) +get(PropertyTag ptag, const Connected_components_graph& w) { return get(ptag, w.graph()); } -template +template typename boost::property_traits::type>::value_type get(PropertyTag ptag, - const Connected_components_graph& w, + const Connected_components_graph& w, const typename boost::property_traits::type>::key_type& k) { return get(ptag, w.graph(), k); } -template +template void -put(PropertyTag ptag, const Connected_components_graph& w, +put(PropertyTag ptag, const Connected_components_graph& w, const typename boost::property_traits::type>::key_type& k, typename boost::property_traits::type>::value_type& v) { @@ -619,16 +687,15 @@ put(PropertyTag ptag, const Connected_components_graph& }//end namespace CGAL namespace boost { - template - struct property_map,PropertyTag> { - typedef typename boost::property_map::type type; - typedef typename boost::property_map::const_type const_type; - }; +template +struct property_map,PropertyTag> { + typedef typename boost::property_map::type type; + typedef typename boost::property_map::const_type const_type; +}; - template - struct graph_has_property, PropertyTag> +template +struct graph_has_property, PropertyTag> : graph_has_property {}; }// namespace boost - #endif // CGAL_BOOST_GRAPH_Connected_components_graph_H diff --git a/BGL/test/BGL/test_Connected_components_graph.cpp b/BGL/test/BGL/test_Connected_components_graph.cpp index 380a3bb17fd..9724343a838 100644 --- a/BGL/test/BGL/test_Connected_components_graph.cpp +++ b/BGL/test/BGL/test_Connected_components_graph.cpp @@ -13,8 +13,7 @@ template void test_halfedge_around_vertex_iterator(const Graph& g) { typedef typename boost::graph_traits::face_descriptor g_face_descriptor; - typedef boost::associative_property_map< boost::unordered_map< g_face_descriptor, std::size_t > >FCMap; - typedef CGAL::Connected_components_graph Adapter; + typedef CGAL::Connected_components_graph Adapter; CGAL_GRAPH_TRAITS_MEMBERS(Adapter); boost::unordered_map map(CGAL::num_faces(g)); CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); @@ -42,8 +41,7 @@ template void test_halfedge_around_face_iterator(const Graph& g) { typedef typename boost::graph_traits::face_descriptor g_face_descriptor; - typedef boost::associative_property_map< std::map< g_face_descriptor, std::size_t > >FCMap; - typedef CGAL::Connected_components_graph Adapter; + typedef CGAL::Connected_components_graph Adapter; CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); @@ -63,8 +61,7 @@ template void test_edge_iterators(const Graph& g) { typedef typename boost::graph_traits::face_descriptor g_face_descriptor; - typedef boost::associative_property_map< std::map< g_face_descriptor, std::size_t > >FCMap; - typedef CGAL::Connected_components_graph Adapter; + typedef CGAL::Connected_components_graph Adapter; CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); @@ -90,8 +87,7 @@ template void test_vertex_iterators(Graph& g) { typedef typename boost::graph_traits::face_descriptor g_face_descriptor; - typedef boost::associative_property_map< std::map< g_face_descriptor, std::size_t > >FCMap; - typedef CGAL::Connected_components_graph Adapter; + typedef CGAL::Connected_components_graph Adapter; CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); @@ -121,8 +117,7 @@ template void test_out_edges(const Graph& g) { typedef typename boost::graph_traits::face_descriptor g_face_descriptor; - typedef boost::associative_property_map< std::map< g_face_descriptor, std::size_t > >FCMap; - typedef CGAL::Connected_components_graph Adapter; + typedef CGAL::Connected_components_graph Adapter; CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); @@ -151,8 +146,7 @@ template void test_in_edges(const Graph& g) { typedef typename boost::graph_traits::face_descriptor g_face_descriptor; - typedef boost::associative_property_map< std::map< g_face_descriptor, std::size_t > >FCMap; - typedef CGAL::Connected_components_graph Adapter; + typedef CGAL::Connected_components_graph Adapter; CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); @@ -179,8 +173,7 @@ template void test_in_out_edges(const Graph& g) { typedef typename boost::graph_traits::face_descriptor g_face_descriptor; - typedef boost::associative_property_map< std::map< g_face_descriptor, std::size_t > >FCMap; - typedef CGAL::Connected_components_graph Adapter; + typedef CGAL::Connected_components_graph Adapter; CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); @@ -222,8 +215,7 @@ template void test_edge_find(const Graph& g) { typedef typename boost::graph_traits::face_descriptor g_face_descriptor; - typedef boost::associative_property_map< std::map< g_face_descriptor, std::size_t > >FCMap; - typedef CGAL::Connected_components_graph Adapter; + typedef CGAL::Connected_components_graph Adapter; CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); @@ -247,8 +239,7 @@ template void test_faces(const Graph& g) { typedef typename boost::graph_traits::face_descriptor g_face_descriptor; - typedef boost::associative_property_map< std::map< g_face_descriptor, std::size_t > >FCMap; - typedef CGAL::Connected_components_graph Adapter; + typedef CGAL::Connected_components_graph Adapter; CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); @@ -274,8 +265,7 @@ template void test_read(const Graph& g) { typedef typename boost::graph_traits::face_descriptor g_face_descriptor; - typedef boost::associative_property_map< std::map< g_face_descriptor, std::size_t > >FCMap; - typedef CGAL::Connected_components_graph Adapter; + typedef CGAL::Connected_components_graph Adapter; CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); @@ -326,30 +316,30 @@ struct Constraint : public boost::put_get_helper::face_descriptor , std::size_t> > Adapter; - // test(sm_data()); + + typedef CGAL::Connected_components_graph Adapter; + test(sm_data()); //Make a tetrahedron and test the adapter for a patch that only contains 2 faces SM* sm = new SM(); CGAL::make_tetrahedron( @@ -384,14 +374,14 @@ main() boost::unordered_set pids; pids.insert(0); pids.insert(2); - Adapter fga(*sm, fccmap, pids); + Adapter fga(*sm, fccmap, pids.begin(), pids.end()); CGAL_GRAPH_TRAITS_MEMBERS(Adapter); //check that there is the right number of simplices in fga CGAL_assertion(CGAL::is_valid(fga)); - CGAL_assertion(std::distance(faces(fga).first,faces(fga).second) == 2); - CGAL_assertion(std::distance(edges(fga).first,edges(fga).second) == 5); - CGAL_assertion(std::distance(halfedges(fga).first,halfedges(fga).second) == 10); - CGAL_assertion(std::distance(vertices(fga).first,vertices(fga).second) == 4); + CGAL_assertion(num_faces(fga) == 2); + CGAL_assertion(num_edges(fga) == 5); + CGAL_assertion(num_halfedges(fga) == 10); + CGAL_assertion(num_vertices(fga) == 4); halfedge_descriptor h = halfedge(*faces(fga).first, fga); vertex_descriptor v = source(h, fga); //check that next() works inside the patch From 793931be88b1e438cd7a079c8a20eaefcbe875b6 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Tue, 2 May 2017 14:21:45 +0200 Subject: [PATCH 12/38] Add templates for the index maps in the class type. --- .../boost/graph/Connected_components_graph.h | 442 +++++++++++------- 1 file changed, 282 insertions(+), 160 deletions(-) diff --git a/BGL/include/CGAL/boost/graph/Connected_components_graph.h b/BGL/include/CGAL/boost/graph/Connected_components_graph.h index 9f0942fb6c6..f37d4450ac2 100644 --- a/BGL/include/CGAL/boost/graph/Connected_components_graph.h +++ b/BGL/include/CGAL/boost/graph/Connected_components_graph.h @@ -39,8 +39,7 @@ namespace CGAL * * The class `Connected_components_graph` wraps a graph into another graph in such a way that only the specified connected components are seen from the outside. * - * For example, calling `vertices(graph)` will return an iterator range of all but only the vertices that belong to the connected components whose ids in the - * `FaceComponentMap` are contained in the given set. + * For example, calling `vertices(graph)` will return an iterator range of all but only the vertices that belong to the selected connected components. * * \tparam Graph must be a model of a `FaceListGraph` and `HalfedgeListGraph`. * @@ -48,7 +47,10 @@ namespace CGAL * \cgalModels `HalfedgeListGraph` */ -template +template::type, + typename VImap = typename boost::property_map::type, + typename HImap = typename boost::property_map::type> struct Connected_components_graph { typedef boost::graph_traits gt; @@ -56,10 +58,7 @@ struct Connected_components_graph typedef typename gt::halfedge_descriptor halfedge_descriptor; typedef typename gt::edge_descriptor edge_descriptor; typedef typename gt::face_descriptor face_descriptor; - typedef Connected_components_graph Self; - typedef typename boost::property_map::type FImap; - typedef typename boost::property_map::type VImap; - typedef typename boost::property_map::type HImap; + typedef Connected_components_graph Self; /*! * \brief Creates a Connected_components_graph of the connected components of `graph` specified in the range @@ -223,10 +222,13 @@ private: namespace boost { -template -struct graph_traits< CGAL::Connected_components_graph > +template +struct graph_traits< CGAL::Connected_components_graph > { - typedef CGAL::Connected_components_graph G; + typedef CGAL::Connected_components_graph G; typedef boost::graph_traits BGTG; typedef typename BGTG::vertex_descriptor vertex_descriptor; typedef typename BGTG::halfedge_descriptor halfedge_descriptor; @@ -271,9 +273,12 @@ struct graph_traits< CGAL::Connected_components_graph > } }; -template -struct graph_traits< const CGAL::Connected_components_graph > - : public graph_traits< CGAL::Connected_components_graph > +template +struct graph_traits< const CGAL::Connected_components_graph > + : public graph_traits< CGAL::Connected_components_graph > {}; @@ -281,62 +286,83 @@ struct graph_traits< const CGAL::Connected_components_graph > namespace CGAL { -template +template bool -in_CC(const typename boost::graph_traits< Connected_components_graph >::face_descriptor f, - const Connected_components_graph & w) +in_CC(const typename boost::graph_traits< Connected_components_graph >::face_descriptor f, + const Connected_components_graph & w) { return w.is_in_cc(f); } -template +template bool -in_CC(const typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, - const Connected_components_graph & w) +in_CC(const typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, + const Connected_components_graph & w) { return w.is_in_cc(h); } -template +template bool -in_CC(const typename boost::graph_traits< Connected_components_graph >::edge_descriptor e, - const Connected_components_graph & w) +in_CC(const typename boost::graph_traits< Connected_components_graph >::edge_descriptor e, + const Connected_components_graph & w) { return w.is_in_cc(halfedge(e, w.graph())); } -template +template bool -in_CC(const typename boost::graph_traits< Connected_components_graph >::vertex_descriptor v, - const Connected_components_graph & w) +in_CC(const typename boost::graph_traits< Connected_components_graph >::vertex_descriptor v, + const Connected_components_graph & w) { return w.is_in_cc(v); } -template +template typename boost::graph_traits::vertices_size_type -num_vertices(const Connected_components_graph& w) +num_vertices(const Connected_components_graph& w) { return w.number_of_vertices(); } -template +template typename boost::graph_traits::edges_size_type -num_edges(const Connected_components_graph& w) +num_edges(const Connected_components_graph& w) { return w.number_of_halfedges()/2; } -template +template typename boost::graph_traits::degree_size_type -degree(typename boost::graph_traits >::vertex_descriptor v, - const Connected_components_graph& w) +degree(typename boost::graph_traits >::vertex_descriptor v, + const Connected_components_graph& w) { CGAL_assertion(in_CC(v, w)); typename boost::graph_traits::degree_size_type v_deg = 0; - typename boost::graph_traits >::halfedge_descriptor h = halfedge(v, w); - typename boost::graph_traits >::halfedge_descriptor hcirc = h; + typename boost::graph_traits >::halfedge_descriptor h = halfedge(v, w); + typename boost::graph_traits >::halfedge_descriptor hcirc = h; do { if(in_CC(hcirc, w)) @@ -346,109 +372,136 @@ degree(typename boost::graph_traits >::vertex_ return v_deg; } -template +template typename boost::graph_traits::degree_size_type -out_degree(typename boost::graph_traits >::vertex_descriptor v, - const Connected_components_graph& w) +out_degree(typename boost::graph_traits >::vertex_descriptor v, + const Connected_components_graph& w) { CGAL_assertion(in_CC(v, w)); return std::distance(out_edges(v, w).first ,out_edges(v, w).second); } -template +template typename boost::graph_traits::degree_size_type -in_degree(typename boost::graph_traits >::vertex_descriptor v, - const Connected_components_graph& w) +in_degree(typename boost::graph_traits >::vertex_descriptor v, + const Connected_components_graph& w) { CGAL_assertion(in_CC(v, w)); return std::distance(in_edges(v, w).first ,in_edges(v, w).second); } -template -typename boost::graph_traits >::vertex_descriptor -source(typename boost::graph_traits >::edge_descriptor e, - const Connected_components_graph & w) +template +typename boost::graph_traits >::vertex_descriptor +source(typename boost::graph_traits >::edge_descriptor e, + const Connected_components_graph & w) { CGAL_assertion(in_CC(e, w)); return source(e, w.graph()); } -template -typename boost::graph_traits >::vertex_descriptor -target(typename boost::graph_traits >::edge_descriptor e, - const Connected_components_graph & w) +template +typename boost::graph_traits >::vertex_descriptor +target(typename boost::graph_traits >::edge_descriptor e, + const Connected_components_graph & w) { CGAL_assertion(in_CC(e, w)); return target(e, w.graph()); } -template -std::pair >::edge_descriptor, bool> -edge(typename boost::graph_traits >::vertex_descriptor u, - typename boost::graph_traits >::vertex_descriptor v, - const Connected_components_graph & w) +template +std::pair >::edge_descriptor, bool> +edge(typename boost::graph_traits >::vertex_descriptor u, + typename boost::graph_traits >::vertex_descriptor v, + const Connected_components_graph & w) { CGAL_assertion(in_CC(u, w) && in_CC(v, w)); - typename boost::graph_traits >::edge_descriptor e = edge(u, v, w.graph()).first; + typename boost::graph_traits >::edge_descriptor e = edge(u, v, w.graph()).first; bool res = in_CC(e, w); return std::make_pair(e, res); } -template -CGAL::Iterator_range >::vertex_iterator> -vertices(const Connected_components_graph & w) +template +CGAL::Iterator_range >::vertex_iterator> +vertices(const Connected_components_graph & w) { - typedef typename boost::graph_traits >::vertex_iterator vertex_iterator; + typedef typename boost::graph_traits >::vertex_iterator vertex_iterator; typedef typename boost::graph_traits::vertex_iterator g_vertex_iterator; - typename Connected_components_graph ::Is_simplex_valid predicate(&w); + typename Connected_components_graph ::Is_simplex_valid predicate(&w); g_vertex_iterator b,e; boost::tie(b,e) = vertices(w.graph()); return make_range(vertex_iterator(predicate, b, e), vertex_iterator(predicate, e, e)); } -template -CGAL::Iterator_range >::edge_iterator> -edges(const Connected_components_graph & w) +template +CGAL::Iterator_range >::edge_iterator> +edges(const Connected_components_graph & w) { - typedef typename boost::graph_traits >::edge_iterator edge_iterator; + typedef typename boost::graph_traits >::edge_iterator edge_iterator; typedef typename boost::graph_traits::edge_iterator g_edge_iterator; - typename Connected_components_graph ::Is_simplex_valid predicate(&w); + typename Connected_components_graph ::Is_simplex_valid predicate(&w); g_edge_iterator b,e; boost::tie(b,e) = edges(w.graph()); return make_range(edge_iterator(predicate, b, e), edge_iterator(predicate, e, e)); } -template -CGAL::Iterator_range >::out_edge_iterator> -out_edges(typename boost::graph_traits >::vertex_descriptor v, - const Connected_components_graph & w) +template +CGAL::Iterator_range >::out_edge_iterator> +out_edges(typename boost::graph_traits >::vertex_descriptor v, + const Connected_components_graph & w) { - typedef typename boost::graph_traits >::out_edge_iterator out_edge_iterator; + typedef typename boost::graph_traits >::out_edge_iterator out_edge_iterator; typedef typename boost::graph_traits::out_edge_iterator g_out_edge_iterator; - typename Connected_components_graph ::Is_simplex_valid predicate(&w); + typename Connected_components_graph ::Is_simplex_valid predicate(&w); g_out_edge_iterator b,e; boost::tie(b,e) = out_edges(v, w.graph()); return make_range(out_edge_iterator(predicate, b, e), out_edge_iterator(predicate, e, e)); } -template -CGAL::Iterator_range >::in_edge_iterator> -in_edges(typename boost::graph_traits >::vertex_descriptor v, - const Connected_components_graph & w) +template +CGAL::Iterator_range >::in_edge_iterator> +in_edges(typename boost::graph_traits >::vertex_descriptor v, + const Connected_components_graph & w) { - typedef typename boost::graph_traits >::in_edge_iterator in_edge_iterator; + typedef typename boost::graph_traits >::in_edge_iterator in_edge_iterator; typedef typename boost::graph_traits::in_edge_iterator g_in_edge_iterator; - typename Connected_components_graph ::Is_simplex_valid predicate(&w); + typename Connected_components_graph ::Is_simplex_valid predicate(&w); g_in_edge_iterator b,e; boost::tie(b,e) = in_edges(v, w.graph()); return make_range(in_edge_iterator(predicate, b, e), @@ -458,106 +511,133 @@ in_edges(typename boost::graph_traits >::verte // // HalfedgeGraph // -template -typename boost::graph_traits< Connected_components_graph >::edge_descriptor -edge(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, - const Connected_components_graph & w) +template +typename boost::graph_traits< Connected_components_graph >::edge_descriptor +edge(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, + const Connected_components_graph & w) { CGAL_assertion(CGAL::in_CC(h, w)); return edge(h, w.graph()); } -template -typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor -halfedge(typename boost::graph_traits< Connected_components_graph >::edge_descriptor e, - const Connected_components_graph & w) +template +typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor +halfedge(typename boost::graph_traits< Connected_components_graph >::edge_descriptor e, + const Connected_components_graph & w) { CGAL_assertion(CGAL::in_CC(e, w)); return halfedge(e, w.graph()); } -template -typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor -halfedge(typename boost::graph_traits< Connected_components_graph >::vertex_descriptor v, - const Connected_components_graph & w) +template +typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor +halfedge(typename boost::graph_traits< Connected_components_graph >::vertex_descriptor v, + const Connected_components_graph & w) { CGAL_assertion(in_CC(v, w)); - typename boost::graph_traits >::halfedge_descriptor h = halfedge(v, w.graph()); - typename boost::graph_traits >::halfedge_descriptor hcirc = h; + typename boost::graph_traits >::halfedge_descriptor h = halfedge(v, w.graph()); + typename boost::graph_traits >::halfedge_descriptor hcirc = h; do { if(in_CC(hcirc, w)) return hcirc; hcirc = opposite(next(hcirc, w.graph()), w.graph()); }while(hcirc != h); - return boost::graph_traits< CGAL::Connected_components_graph >::null_halfedge(); + return boost::graph_traits< CGAL::Connected_components_graph >::null_halfedge(); } -template -std::pair >::halfedge_descriptor, bool> -halfedge(typename boost::graph_traits< Connected_components_graph >::vertex_descriptor u, - typename boost::graph_traits< Connected_components_graph >::vertex_descriptor v, - const Connected_components_graph & w) +template +std::pair >::halfedge_descriptor, bool> +halfedge(typename boost::graph_traits< Connected_components_graph >::vertex_descriptor u, + typename boost::graph_traits< Connected_components_graph >::vertex_descriptor v, + const Connected_components_graph & w) { CGAL_assertion(in_CC(u, w) && in_CC(v, w)); - typename boost::graph_traits >::halfedge_descriptor h = halfedge(u, v, w.graph()).first; + typename boost::graph_traits >::halfedge_descriptor h = halfedge(u, v, w.graph()).first; return std::make_pair(h, in_CC(h, w)); } -template -typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor -opposite(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, - const Connected_components_graph & w) +template +typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor +opposite(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, + const Connected_components_graph & w) { CGAL_assertion(in_CC(h, w) ); return opposite(h, w.graph()); } -template -typename boost::graph_traits< Connected_components_graph >::vertex_descriptor -source(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, - const Connected_components_graph & w) +template +typename boost::graph_traits< Connected_components_graph >::vertex_descriptor +source(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, + const Connected_components_graph & w) { CGAL_assertion(in_CC(h, w) ); return source(h, w.graph()); } -template -typename boost::graph_traits< Connected_components_graph >::vertex_descriptor -target(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, - const Connected_components_graph & w) +template +typename boost::graph_traits< Connected_components_graph >::vertex_descriptor +target(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, + const Connected_components_graph & w) { CGAL_assertion(in_CC(h, w) ); return target(h, w.graph()); } -template -typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor -next(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, - const Connected_components_graph & w) +template +typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor +next(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, + const Connected_components_graph & w) { CGAL_assertion(in_CC(h, w)); if(in_CC(next(h, w.graph()), w)) return next(h, w.graph()); - //act as a border - BOOST_FOREACH(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor hcirc - , CGAL::halfedges_around_target(target(h, w.graph()), w.graph())) + typedef typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h_d; + BOOST_FOREACH( h_d hcirc, + CGAL::halfedges_around_target(target(h, w.graph()), w.graph())) { if(hcirc != h && in_CC(hcirc, w)) { return opposite(hcirc, w.graph()); } } - return boost::graph_traits< CGAL::Connected_components_graph >::null_halfedge(); + return boost::graph_traits< CGAL::Connected_components_graph >::null_halfedge(); } -template -typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor -prev(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, - const Connected_components_graph & w) +template +typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor +prev(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, + const Connected_components_graph & w) { CGAL_assertion(in_CC(h, w)); @@ -565,30 +645,34 @@ prev(typename boost::graph_traits< Connected_components_graph >::halfedge return prev(h, w.graph()); //act as a border - BOOST_FOREACH(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor hcirc - , CGAL::halfedges_around_source(source(h, w.graph()), w.graph())) + typedef typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h_d; + BOOST_FOREACH(h_d hcirc, + CGAL::halfedges_around_source(source(h, w.graph()), w.graph())) { if(hcirc != h && in_CC(hcirc, w)) { return opposite(hcirc, w.graph()); } } - return boost::graph_traits< CGAL::Connected_components_graph >::null_halfedge(); + return boost::graph_traits< CGAL::Connected_components_graph >::null_halfedge(); } // // HalfedgeListGraph // -template -std::pair >::halfedge_iterator, -typename boost::graph_traits >::halfedge_iterator> -halfedges(const Connected_components_graph & w) +template +std::pair >::halfedge_iterator, +typename boost::graph_traits >::halfedge_iterator> +halfedges(const Connected_components_graph & w) { - typedef typename boost::graph_traits >::halfedge_iterator halfedge_iterator; + typedef typename boost::graph_traits >::halfedge_iterator halfedge_iterator; typedef typename boost::graph_traits::halfedge_iterator g_halfedge_iterator; - typename Connected_components_graph ::Is_simplex_valid predicate(&w); + typename Connected_components_graph ::Is_simplex_valid predicate(&w); std::pair original_halfedges = halfedges(w.graph()); return make_range(halfedge_iterator(predicate, original_halfedges.first, original_halfedges.second), @@ -596,44 +680,56 @@ halfedges(const Connected_components_graph & w) } -template +template typename boost::graph_traits::halfedges_size_type -num_halfedges(const Connected_components_graph & w) +num_halfedges(const Connected_components_graph & w) { return w.number_of_halfedges(); } // FaceGraph -template -typename boost::graph_traits< Connected_components_graph >::face_descriptor -face(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, - const Connected_components_graph & w) +template +typename boost::graph_traits< Connected_components_graph >::face_descriptor +face(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, + const Connected_components_graph & w) { CGAL_assertion(CGAL::in_CC(h, w)); if(in_CC(h, w)) return face(h,w.graph()); else - return boost::graph_traits< CGAL::Connected_components_graph >::null_face(); + return boost::graph_traits< CGAL::Connected_components_graph >::null_face(); } -template -typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor -halfedge(typename boost::graph_traits< Connected_components_graph >::face_descriptor f, - const Connected_components_graph & w) +template +typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor +halfedge(typename boost::graph_traits< Connected_components_graph >::face_descriptor f, + const Connected_components_graph & w) { CGAL_assertion(CGAL::in_CC(f, w)); return halfedge(f,w.graph()); } -template -Iterator_range >::face_iterator> -faces(const Connected_components_graph & w) +template +Iterator_range >::face_iterator> +faces(const Connected_components_graph & w) { - typedef typename boost::graph_traits >::face_iterator face_iterator; + typedef typename boost::graph_traits >::face_iterator face_iterator; typedef typename boost::graph_traits::face_iterator g_face_iterator; - typename Connected_components_graph ::Is_simplex_valid predicate(&w); + typename Connected_components_graph ::Is_simplex_valid predicate(&w); std::pair original_faces = faces(w.graph()); return make_range(face_iterator(predicate, original_faces.first, original_faces.second), @@ -642,42 +738,60 @@ faces(const Connected_components_graph & w) -template +template typename boost::graph_traits::vertices_size_type -num_faces(const Connected_components_graph & w) +num_faces(const Connected_components_graph & w) { return w.number_of_faces(); } -template +template bool -in_CC(const Connected_components_graph & w, bool verbose = false) +in_CC(const Connected_components_graph & w, bool verbose = false) { return in_CC(w.graph(),verbose); } -template +template typename boost::property_map::type -get(PropertyTag ptag, const Connected_components_graph& w) +get(PropertyTag ptag, const Connected_components_graph& w) { return get(ptag, w.graph()); } -template +template typename boost::property_traits::type>::value_type get(PropertyTag ptag, - const Connected_components_graph& w, + const Connected_components_graph& w, const typename boost::property_traits::type>::key_type& k) { return get(ptag, w.graph(), k); } -template +template void -put(PropertyTag ptag, const Connected_components_graph& w, +put(PropertyTag ptag, const Connected_components_graph& w, const typename boost::property_traits::type>::key_type& k, typename boost::property_traits::type>::value_type& v) { @@ -687,14 +801,22 @@ put(PropertyTag ptag, const Connected_components_graph& w, }//end namespace CGAL namespace boost { -template -struct property_map,PropertyTag> { +template +struct property_map,PropertyTag> { typedef typename boost::property_map::type type; typedef typename boost::property_map::const_type const_type; }; -template -struct graph_has_property, PropertyTag> +template +struct graph_has_property, PropertyTag> : graph_has_property {}; }// namespace boost From 4e0bdba9314952be30e518d6e330add80899cb6f Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Tue, 2 May 2017 14:50:01 +0200 Subject: [PATCH 13/38] update changes.html and add tparams for the index maps. --- .../CGAL/boost/graph/Connected_components_graph.h | 9 ++++++--- Installation/changes.html | 8 ++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/BGL/include/CGAL/boost/graph/Connected_components_graph.h b/BGL/include/CGAL/boost/graph/Connected_components_graph.h index f37d4450ac2..2f9d83c8dcb 100644 --- a/BGL/include/CGAL/boost/graph/Connected_components_graph.h +++ b/BGL/include/CGAL/boost/graph/Connected_components_graph.h @@ -16,8 +16,8 @@ // // // Author(s) : Maxime Gimeno -#ifndef CGAL_BOOST_GRAPH_Connected_components_graph_H -#define CGAL_BOOST_GRAPH_Connected_components_graph_H +#ifndef CGAL_BOOST_GRAPH_CONNECTED_COMPONENTS_GRAPH_H +#define CGAL_BOOST_GRAPH_CONNECTED_COMPONENTS_GRAPH_H #include #include @@ -42,6 +42,9 @@ namespace CGAL * For example, calling `vertices(graph)` will return an iterator range of all but only the vertices that belong to the selected connected components. * * \tparam Graph must be a model of a `FaceListGraph` and `HalfedgeListGraph`. + * \tparam FImap a model of `ReadablePropertyMap` with `boost::graph_traits::%face_descriptor` as key and `size_type` as value. + * \tparam VImap a model of `ReadablePropertyMap` with `boost::graph_traits::%vertex_descriptor` as key and `size_type` as value. + * \tparam HImap a model of `ReadablePropertyMap` with `boost::graph_traits::%halfedge_descriptor` as key and `size_type` as value. * * \cgalModels `FaceListGraph` * \cgalModels `HalfedgeListGraph` @@ -820,4 +823,4 @@ struct graph_has_property {}; }// namespace boost -#endif // CGAL_BOOST_GRAPH_Connected_components_graph_H +#endif // CGAL_BOOST_GRAPH_CONNECTED_COMPONENTS_GRAPH_H diff --git a/Installation/changes.html b/Installation/changes.html index 55f6a05be02..90a702237ad 100644 --- a/Installation/changes.html +++ b/Installation/changes.html @@ -178,6 +178,14 @@ and src/ directories). +

CGAL and the Boost Graph Library (BGL)

+
    +
  • + Add class CGAL::Connected_components_graph that + wraps an existing graph and hide all simplices that are not + in the selected connected components. +
  • +
From 0ab9cf974c1b26dfa039d7e5b5edb42495b8f569 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 3 May 2017 10:16:35 +0200 Subject: [PATCH 14/38] Add property maps binders for the indices and fix remaining bugs in graph_traits. copy_face_graph doesn't crash anymore. --- .../boost/graph/Connected_components_graph.h | 624 +++++++++++------- .../BGL/test_Connected_components_graph.cpp | 11 +- 2 files changed, 378 insertions(+), 257 deletions(-) diff --git a/BGL/include/CGAL/boost/graph/Connected_components_graph.h b/BGL/include/CGAL/boost/graph/Connected_components_graph.h index 2f9d83c8dcb..f9e9f435ef6 100644 --- a/BGL/include/CGAL/boost/graph/Connected_components_graph.h +++ b/BGL/include/CGAL/boost/graph/Connected_components_graph.h @@ -42,18 +42,18 @@ namespace CGAL * For example, calling `vertices(graph)` will return an iterator range of all but only the vertices that belong to the selected connected components. * * \tparam Graph must be a model of a `FaceListGraph` and `HalfedgeListGraph`. - * \tparam FImap a model of `ReadablePropertyMap` with `boost::graph_traits::%face_descriptor` as key and `size_type` as value. - * \tparam VImap a model of `ReadablePropertyMap` with `boost::graph_traits::%vertex_descriptor` as key and `size_type` as value. - * \tparam HImap a model of `ReadablePropertyMap` with `boost::graph_traits::%halfedge_descriptor` as key and `size_type` as value. + * \tparam FIMap a model of `ReadablePropertyMap` with `boost::graph_traits::%face_descriptor` as key and `graph_traits::faces_size_type` + * \tparam VIMap a model of `ReadablePropertyMap` with `boost::graph_traits::%vertex_descriptor` as key and `graph_traits::vertices_size_type` + * \tparam HIMap a model of `ReadablePropertyMap` with `boost::graph_traits::%halfedge_descriptor` as key and `graph_traits::halfedges_size_type` * * \cgalModels `FaceListGraph` * \cgalModels `HalfedgeListGraph` */ template::type, - typename VImap = typename boost::property_map::type, - typename HImap = typename boost::property_map::type> + typename FIMap = typename boost::property_map::type, + typename VIMap = typename boost::property_map::type, + typename HIMap = typename boost::property_map::type> struct Connected_components_graph { typedef boost::graph_traits gt; @@ -61,19 +61,22 @@ struct Connected_components_graph typedef typename gt::halfedge_descriptor halfedge_descriptor; typedef typename gt::edge_descriptor edge_descriptor; typedef typename gt::face_descriptor face_descriptor; - typedef Connected_components_graph Self; + typedef typename boost::property_traits< FIMap >::value_type face_index_type; + typedef typename boost::property_traits< VIMap >::value_type vertex_index_type; + typedef typename boost::property_traits< HIMap >::value_type halfedge_index_type; + typedef Connected_components_graph Self; /*! * \brief Creates a Connected_components_graph of the connected components of `graph` specified in the range * defined by `begin` and `end`. - * typedef unspecified_type Indices; + * typedef unspecified_type IndexRangeIterator; * \tparam FaceComponentMap a model of `ReadablePropertyMap` with `boost::graph_traits::%face_descriptor` as key type and `graph_traits::faces_size_type` as value type. * \param graph the graph containing the wanted patches. - * \param fccmap the property_map that assigns a connected component to each face, with + * \param fcmap the property_map that assigns a connected component to each face, with `boost::graph_traits::%face_descriptor` as key type and `graph_traits::faces_size_type` as value type. * \param begin an interator to the beginning of a range of connected components indices of interest. @@ -82,7 +85,7 @@ struct Connected_components_graph template Connected_components_graph(const Graph& graph, - FaceComponentMap fccmap, + FaceComponentMap fcmap, IndexRangeIterator begin, IndexRangeIterator end) : _graph(graph) @@ -103,7 +106,7 @@ struct Connected_components_graph BOOST_FOREACH(face_descriptor fd, faces(graph) ) { - if(pids.find(boost::get(fccmap, fd))!= pids.end() ) + if(pids.find(boost::get(fcmap, fd))!= pids.end() ) { face_patch.set(get(fimap, fd)); BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_face(halfedge(fd, graph), graph)) @@ -123,14 +126,14 @@ struct Connected_components_graph `boost::graph_traits::%face_descriptor` as key type and `graph_traits::faces_size_type` as value type. * \param graph the graph containing the wanted patch. - * \param fccmap the property_map that assigns a connected component to each face, with + * \param fcmap the property_map that assigns a connected component's index to each face, with `boost::graph_traits::%face_descriptor` as key type and `graph_traits::faces_size_type` as value type. * \param pid the index of the connected component of interest. */ template Connected_components_graph(const Graph& graph, - FaceComponentMap fccmap, + FaceComponentMap fcmap, typename boost::property_traits::value_type pid) : _graph(graph) { @@ -142,7 +145,7 @@ struct Connected_components_graph halfedge_patch.resize(num_halfedges(graph)); BOOST_FOREACH(face_descriptor fd, faces(graph) ) { - if(boost::get(fccmap, fd) == pid) + if(boost::get(fcmap, fd) == pid) { face_patch.set(get(fimap, fd)); BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_face(halfedge(fd, graph), graph)) @@ -177,47 +180,95 @@ struct Connected_components_graph const Self* adapter; }; - ///returns true if `f` is in the specified connected_components bool is_in_cc(face_descriptor f) const { return face_patch[get(fimap, f)]; } - ///returns true if `v` is in the specified connected_components + bool is_in_cc(vertex_descriptor v) const { return vertex_patch[get(vimap, v)]; } - ///returns true if `h` is in the specified connected_components + bool is_in_cc(halfedge_descriptor h) const { return halfedge_patch[get(himap, h)]; } - ///returns the number of faces contained in the specified connected_components + ///returns the number of faces contained in the specified connected components typename boost::graph_traits:: - vertices_size_type number_of_faces()const + faces_size_type number_of_faces()const { return face_patch.count(); } -///returns the number of vertices contained in the specified connected_components +///returns the number of vertices contained in the specified connected components typename boost::graph_traits:: vertices_size_type number_of_vertices()const { return vertex_patch.count(); } -///returns the number of halfedges contained in the specified connected_components +///returns the number of halfedges contained in the specified connected components typename boost::graph_traits:: - vertices_size_type number_of_halfedges()const + halfedges_size_type number_of_halfedges()const { return halfedge_patch.count(); } + + Property_map_binder< FIMap, typename Pointer_property_map< typename boost::property_traits< FIMap >::value_type >::type > + get_face_index_map() const + { + if (face_indices.empty()) + { + face_index_type index = 0; + face_indices.resize(num_faces(_graph)); + for (std::size_t i=face_patch.find_first(); i < face_patch.npos; i = face_patch.find_next(i)) + { + face_indices[i] = index++; + } + } + return bind_property_maps(fimap, make_property_map(face_indices) ); + } + + Property_map_binder< VIMap, typename Pointer_property_map< typename boost::property_traits< VIMap >::value_type >::type > + get_vertex_index_map() const + { + if (vertex_indices.empty()) + { + vertex_index_type index = 0; + vertex_indices.resize(num_vertices(_graph)); + for (std::size_t i=vertex_patch.find_first(); i < vertex_patch.npos; i = vertex_patch.find_next(i)) + { + vertex_indices[i] = index++; + } + } + return bind_property_maps(vimap, make_property_map(vertex_indices) ); + } + + Property_map_binder< HIMap, typename Pointer_property_map< typename boost::property_traits< HIMap >::value_type >::type > + get_halfedge_index_map() const + { + if (halfedge_indices.empty()) + { + halfedge_index_type index = 0; + halfedge_indices.resize(num_halfedges(_graph)); + for (std::size_t i=halfedge_patch.find_first(); i < halfedge_patch.npos; i = halfedge_patch.find_next(i)) + { + halfedge_indices[i] = index++; + } + } + return bind_property_maps(himap, make_property_map(halfedge_indices) ); + } + private: - FImap fimap; - VImap vimap; - HImap himap; + FIMap fimap; + VIMap vimap; + HIMap himap; const Graph& _graph; boost::dynamic_bitset<> face_patch; boost::dynamic_bitset<> vertex_patch; boost::dynamic_bitset<> halfedge_patch; + mutable std::vector face_indices; + mutable std::vector vertex_indices; + mutable std::vector halfedge_indices; }; } // namespace CGAL @@ -226,12 +277,12 @@ namespace boost { template -struct graph_traits< CGAL::Connected_components_graph > + typename FIMap, + typename VIMap, + typename HIMap> +struct graph_traits< CGAL::Connected_components_graph > { - typedef CGAL::Connected_components_graph G; + typedef CGAL::Connected_components_graph G; typedef boost::graph_traits BGTG; typedef typename BGTG::vertex_descriptor vertex_descriptor; typedef typename BGTG::halfedge_descriptor halfedge_descriptor; @@ -277,11 +328,11 @@ struct graph_traits< CGAL::Connected_components_graph -struct graph_traits< const CGAL::Connected_components_graph > - : public graph_traits< CGAL::Connected_components_graph > + typename FIMap, + typename VIMap, + typename HIMap> +struct graph_traits< const CGAL::Connected_components_graph > + : public graph_traits< CGAL::Connected_components_graph > {}; @@ -290,82 +341,82 @@ struct graph_traits< const CGAL::Connected_components_graph + typename FIMap, + typename VIMap, + typename HIMap> bool -in_CC(const typename boost::graph_traits< Connected_components_graph >::face_descriptor f, - const Connected_components_graph & w) +in_CC(const typename boost::graph_traits< Connected_components_graph >::face_descriptor f, + const Connected_components_graph & w) { return w.is_in_cc(f); } template + typename FIMap, + typename VIMap, + typename HIMap> bool -in_CC(const typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, - const Connected_components_graph & w) +in_CC(const typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, + const Connected_components_graph & w) { return w.is_in_cc(h); } template + typename FIMap, + typename VIMap, + typename HIMap> bool -in_CC(const typename boost::graph_traits< Connected_components_graph >::edge_descriptor e, - const Connected_components_graph & w) +in_CC(const typename boost::graph_traits< Connected_components_graph >::edge_descriptor e, + const Connected_components_graph & w) { return w.is_in_cc(halfedge(e, w.graph())); } template + typename FIMap, + typename VIMap, + typename HIMap> bool -in_CC(const typename boost::graph_traits< Connected_components_graph >::vertex_descriptor v, - const Connected_components_graph & w) +in_CC(const typename boost::graph_traits< Connected_components_graph >::vertex_descriptor v, + const Connected_components_graph & w) { return w.is_in_cc(v); } template + typename FIMap, + typename VIMap, + typename HIMap> typename boost::graph_traits::vertices_size_type -num_vertices(const Connected_components_graph& w) +num_vertices(const Connected_components_graph& w) { return w.number_of_vertices(); } template + typename FIMap, + typename VIMap, + typename HIMap> typename boost::graph_traits::edges_size_type -num_edges(const Connected_components_graph& w) +num_edges(const Connected_components_graph& w) { return w.number_of_halfedges()/2; } template + typename FIMap, + typename VIMap, + typename HIMap> typename boost::graph_traits::degree_size_type -degree(typename boost::graph_traits >::vertex_descriptor v, - const Connected_components_graph& w) +degree(typename boost::graph_traits >::vertex_descriptor v, + const Connected_components_graph& w) { CGAL_assertion(in_CC(v, w)); typename boost::graph_traits::degree_size_type v_deg = 0; - typename boost::graph_traits >::halfedge_descriptor h = halfedge(v, w); - typename boost::graph_traits >::halfedge_descriptor hcirc = h; + typename boost::graph_traits >::halfedge_descriptor h = halfedge(v, w); + typename boost::graph_traits >::halfedge_descriptor hcirc = h; do { if(in_CC(hcirc, w)) @@ -376,80 +427,80 @@ degree(typename boost::graph_traits + typename FIMap, + typename VIMap, + typename HIMap> typename boost::graph_traits::degree_size_type -out_degree(typename boost::graph_traits >::vertex_descriptor v, - const Connected_components_graph& w) +out_degree(typename boost::graph_traits >::vertex_descriptor v, + const Connected_components_graph& w) { CGAL_assertion(in_CC(v, w)); return std::distance(out_edges(v, w).first ,out_edges(v, w).second); } template + typename FIMap, + typename VIMap, + typename HIMap> typename boost::graph_traits::degree_size_type -in_degree(typename boost::graph_traits >::vertex_descriptor v, - const Connected_components_graph& w) +in_degree(typename boost::graph_traits >::vertex_descriptor v, + const Connected_components_graph& w) { CGAL_assertion(in_CC(v, w)); return std::distance(in_edges(v, w).first ,in_edges(v, w).second); } template -typename boost::graph_traits >::vertex_descriptor -source(typename boost::graph_traits >::edge_descriptor e, - const Connected_components_graph & w) + typename FIMap, + typename VIMap, + typename HIMap> +typename boost::graph_traits >::vertex_descriptor +source(typename boost::graph_traits >::edge_descriptor e, + const Connected_components_graph & w) { CGAL_assertion(in_CC(e, w)); return source(e, w.graph()); } template -typename boost::graph_traits >::vertex_descriptor -target(typename boost::graph_traits >::edge_descriptor e, - const Connected_components_graph & w) + typename FIMap, + typename VIMap, + typename HIMap> +typename boost::graph_traits >::vertex_descriptor +target(typename boost::graph_traits >::edge_descriptor e, + const Connected_components_graph & w) { CGAL_assertion(in_CC(e, w)); return target(e, w.graph()); } template -std::pair >::edge_descriptor, bool> -edge(typename boost::graph_traits >::vertex_descriptor u, - typename boost::graph_traits >::vertex_descriptor v, - const Connected_components_graph & w) + typename FIMap, + typename VIMap, + typename HIMap> +std::pair >::edge_descriptor, bool> +edge(typename boost::graph_traits >::vertex_descriptor u, + typename boost::graph_traits >::vertex_descriptor v, + const Connected_components_graph & w) { CGAL_assertion(in_CC(u, w) && in_CC(v, w)); - typename boost::graph_traits >::edge_descriptor e = edge(u, v, w.graph()).first; + typename boost::graph_traits >::edge_descriptor e = edge(u, v, w.graph()).first; bool res = in_CC(e, w); return std::make_pair(e, res); } template -CGAL::Iterator_range >::vertex_iterator> -vertices(const Connected_components_graph & w) + typename FIMap, + typename VIMap, + typename HIMap> +CGAL::Iterator_range >::vertex_iterator> +vertices(const Connected_components_graph & w) { - typedef typename boost::graph_traits >::vertex_iterator vertex_iterator; + typedef typename boost::graph_traits >::vertex_iterator vertex_iterator; typedef typename boost::graph_traits::vertex_iterator g_vertex_iterator; - typename Connected_components_graph ::Is_simplex_valid predicate(&w); + typename Connected_components_graph ::Is_simplex_valid predicate(&w); g_vertex_iterator b,e; boost::tie(b,e) = vertices(w.graph()); return make_range(vertex_iterator(predicate, b, e), @@ -457,16 +508,16 @@ vertices(const Connected_components_graph & w) } template -CGAL::Iterator_range >::edge_iterator> -edges(const Connected_components_graph & w) + typename FIMap, + typename VIMap, + typename HIMap> +CGAL::Iterator_range >::edge_iterator> +edges(const Connected_components_graph & w) { - typedef typename boost::graph_traits >::edge_iterator edge_iterator; + typedef typename boost::graph_traits >::edge_iterator edge_iterator; typedef typename boost::graph_traits::edge_iterator g_edge_iterator; - typename Connected_components_graph ::Is_simplex_valid predicate(&w); + typename Connected_components_graph ::Is_simplex_valid predicate(&w); g_edge_iterator b,e; boost::tie(b,e) = edges(w.graph()); return make_range(edge_iterator(predicate, b, e), @@ -474,18 +525,18 @@ edges(const Connected_components_graph & w) } template -CGAL::Iterator_range >::out_edge_iterator> -out_edges(typename boost::graph_traits >::vertex_descriptor v, - const Connected_components_graph & w) + typename FIMap, + typename VIMap, + typename HIMap> +CGAL::Iterator_range >::out_edge_iterator> +out_edges(typename boost::graph_traits >::vertex_descriptor v, + const Connected_components_graph & w) { - typedef typename boost::graph_traits >::out_edge_iterator out_edge_iterator; + typedef typename boost::graph_traits >::out_edge_iterator out_edge_iterator; typedef typename boost::graph_traits::out_edge_iterator g_out_edge_iterator; - typename Connected_components_graph ::Is_simplex_valid predicate(&w); + typename Connected_components_graph ::Is_simplex_valid predicate(&w); g_out_edge_iterator b,e; boost::tie(b,e) = out_edges(v, w.graph()); return make_range(out_edge_iterator(predicate, b, e), @@ -493,18 +544,18 @@ out_edges(typename boost::graph_traits -CGAL::Iterator_range >::in_edge_iterator> -in_edges(typename boost::graph_traits >::vertex_descriptor v, - const Connected_components_graph & w) + typename FIMap, + typename VIMap, + typename HIMap> +CGAL::Iterator_range >::in_edge_iterator> +in_edges(typename boost::graph_traits >::vertex_descriptor v, + const Connected_components_graph & w) { - typedef typename boost::graph_traits >::in_edge_iterator in_edge_iterator; + typedef typename boost::graph_traits >::in_edge_iterator in_edge_iterator; typedef typename boost::graph_traits::in_edge_iterator g_in_edge_iterator; - typename Connected_components_graph ::Is_simplex_valid predicate(&w); + typename Connected_components_graph ::Is_simplex_valid predicate(&w); g_in_edge_iterator b,e; boost::tie(b,e) = in_edges(v, w.graph()); return make_range(in_edge_iterator(predicate, b, e), @@ -515,114 +566,114 @@ in_edges(typename boost::graph_traits -typename boost::graph_traits< Connected_components_graph >::edge_descriptor -edge(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, - const Connected_components_graph & w) + typename FIMap, + typename VIMap, + typename HIMap> +typename boost::graph_traits< Connected_components_graph >::edge_descriptor +edge(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, + const Connected_components_graph & w) { CGAL_assertion(CGAL::in_CC(h, w)); return edge(h, w.graph()); } template -typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor -halfedge(typename boost::graph_traits< Connected_components_graph >::edge_descriptor e, - const Connected_components_graph & w) + typename FIMap, + typename VIMap, + typename HIMap> +typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor +halfedge(typename boost::graph_traits< Connected_components_graph >::edge_descriptor e, + const Connected_components_graph & w) { CGAL_assertion(CGAL::in_CC(e, w)); return halfedge(e, w.graph()); } template -typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor -halfedge(typename boost::graph_traits< Connected_components_graph >::vertex_descriptor v, - const Connected_components_graph & w) + typename FIMap, + typename VIMap, + typename HIMap> +typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor +halfedge(typename boost::graph_traits< Connected_components_graph >::vertex_descriptor v, + const Connected_components_graph & w) { CGAL_assertion(in_CC(v, w)); - typename boost::graph_traits >::halfedge_descriptor h = halfedge(v, w.graph()); - typename boost::graph_traits >::halfedge_descriptor hcirc = h; + typename boost::graph_traits >::halfedge_descriptor h = halfedge(v, w.graph()); + typename boost::graph_traits >::halfedge_descriptor hcirc = h; do { if(in_CC(hcirc, w)) return hcirc; hcirc = opposite(next(hcirc, w.graph()), w.graph()); }while(hcirc != h); - return boost::graph_traits< CGAL::Connected_components_graph >::null_halfedge(); + return boost::graph_traits< CGAL::Connected_components_graph >::null_halfedge(); } template -std::pair >::halfedge_descriptor, bool> -halfedge(typename boost::graph_traits< Connected_components_graph >::vertex_descriptor u, - typename boost::graph_traits< Connected_components_graph >::vertex_descriptor v, - const Connected_components_graph & w) + typename FIMap, + typename VIMap, + typename HIMap> +std::pair >::halfedge_descriptor, bool> +halfedge(typename boost::graph_traits< Connected_components_graph >::vertex_descriptor u, + typename boost::graph_traits< Connected_components_graph >::vertex_descriptor v, + const Connected_components_graph & w) { CGAL_assertion(in_CC(u, w) && in_CC(v, w)); - typename boost::graph_traits >::halfedge_descriptor h = halfedge(u, v, w.graph()).first; + typename boost::graph_traits >::halfedge_descriptor h = halfedge(u, v, w.graph()).first; return std::make_pair(h, in_CC(h, w)); } template -typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor -opposite(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, - const Connected_components_graph & w) + typename FIMap, + typename VIMap, + typename HIMap> +typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor +opposite(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, + const Connected_components_graph & w) { CGAL_assertion(in_CC(h, w) ); return opposite(h, w.graph()); } template -typename boost::graph_traits< Connected_components_graph >::vertex_descriptor -source(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, - const Connected_components_graph & w) + typename FIMap, + typename VIMap, + typename HIMap> +typename boost::graph_traits< Connected_components_graph >::vertex_descriptor +source(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, + const Connected_components_graph & w) { CGAL_assertion(in_CC(h, w) ); return source(h, w.graph()); } template -typename boost::graph_traits< Connected_components_graph >::vertex_descriptor -target(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, - const Connected_components_graph & w) + typename FIMap, + typename VIMap, + typename HIMap> +typename boost::graph_traits< Connected_components_graph >::vertex_descriptor +target(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, + const Connected_components_graph & w) { CGAL_assertion(in_CC(h, w) ); return target(h, w.graph()); } template -typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor -next(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, - const Connected_components_graph & w) + typename FIMap, + typename VIMap, + typename HIMap> +typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor +next(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, + const Connected_components_graph & w) { CGAL_assertion(in_CC(h, w)); if(in_CC(next(h, w.graph()), w)) return next(h, w.graph()); //act as a border - typedef typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h_d; + typedef typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h_d; BOOST_FOREACH( h_d hcirc, CGAL::halfedges_around_target(target(h, w.graph()), w.graph())) { @@ -631,16 +682,16 @@ next(typename boost::graph_traits< Connected_components_graph >::null_halfedge(); + return boost::graph_traits< CGAL::Connected_components_graph >::null_halfedge(); } template -typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor -prev(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, - const Connected_components_graph & w) + typename FIMap, + typename VIMap, + typename HIMap> +typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor +prev(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, + const Connected_components_graph & w) { CGAL_assertion(in_CC(h, w)); @@ -648,7 +699,7 @@ prev(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h_d; + typedef typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h_d; BOOST_FOREACH(h_d hcirc, CGAL::halfedges_around_source(source(h, w.graph()), w.graph())) { @@ -657,7 +708,7 @@ prev(typename boost::graph_traits< Connected_components_graph >::null_halfedge(); + return boost::graph_traits< CGAL::Connected_components_graph >::null_halfedge(); } // @@ -665,17 +716,17 @@ prev(typename boost::graph_traits< Connected_components_graph -std::pair >::halfedge_iterator, -typename boost::graph_traits >::halfedge_iterator> -halfedges(const Connected_components_graph & w) + typename FIMap, + typename VIMap, + typename HIMap> +std::pair >::halfedge_iterator, +typename boost::graph_traits >::halfedge_iterator> +halfedges(const Connected_components_graph & w) { - typedef typename boost::graph_traits >::halfedge_iterator halfedge_iterator; + typedef typename boost::graph_traits >::halfedge_iterator halfedge_iterator; typedef typename boost::graph_traits::halfedge_iterator g_halfedge_iterator; - typename Connected_components_graph ::Is_simplex_valid predicate(&w); + typename Connected_components_graph ::Is_simplex_valid predicate(&w); std::pair original_halfedges = halfedges(w.graph()); return make_range(halfedge_iterator(predicate, original_halfedges.first, original_halfedges.second), @@ -684,38 +735,38 @@ halfedges(const Connected_components_graph & w) template + typename FIMap, + typename VIMap, + typename HIMap> typename boost::graph_traits::halfedges_size_type -num_halfedges(const Connected_components_graph & w) +num_halfedges(const Connected_components_graph & w) { return w.number_of_halfedges(); } // FaceGraph template -typename boost::graph_traits< Connected_components_graph >::face_descriptor -face(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, - const Connected_components_graph & w) + typename FIMap, + typename VIMap, + typename HIMap> +typename boost::graph_traits< Connected_components_graph >::face_descriptor +face(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, + const Connected_components_graph & w) { CGAL_assertion(CGAL::in_CC(h, w)); - if(in_CC(h, w)) + if(in_CC(face(h,w.graph()), w)) return face(h,w.graph()); else - return boost::graph_traits< CGAL::Connected_components_graph >::null_face(); + return boost::graph_traits< CGAL::Connected_components_graph >::null_face(); } template -typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor -halfedge(typename boost::graph_traits< Connected_components_graph >::face_descriptor f, - const Connected_components_graph & w) + typename FIMap, + typename VIMap, + typename HIMap> +typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor +halfedge(typename boost::graph_traits< Connected_components_graph >::face_descriptor f, + const Connected_components_graph & w) { CGAL_assertion(CGAL::in_CC(f, w)); return halfedge(f,w.graph()); @@ -723,16 +774,16 @@ halfedge(typename boost::graph_traits< Connected_components_graph -Iterator_range >::face_iterator> -faces(const Connected_components_graph & w) + typename FIMap, + typename VIMap, + typename HIMap> +Iterator_range >::face_iterator> +faces(const Connected_components_graph & w) { - typedef typename boost::graph_traits >::face_iterator face_iterator; + typedef typename boost::graph_traits >::face_iterator face_iterator; typedef typename boost::graph_traits::face_iterator g_face_iterator; - typename Connected_components_graph ::Is_simplex_valid predicate(&w); + typename Connected_components_graph ::Is_simplex_valid predicate(&w); std::pair original_faces = faces(w.graph()); return make_range(face_iterator(predicate, original_faces.first, original_faces.second), @@ -742,46 +793,79 @@ faces(const Connected_components_graph & w) template + typename FIMap, + typename VIMap, + typename HIMap> typename boost::graph_traits::vertices_size_type -num_faces(const Connected_components_graph & w) +num_faces(const Connected_components_graph & w) { return w.number_of_faces(); } template + typename FIMap, + typename VIMap, + typename HIMap> bool -in_CC(const Connected_components_graph & w, bool verbose = false) +in_CC(const Connected_components_graph & w, bool verbose = false) { return in_CC(w.graph(),verbose); } template typename boost::property_map::type -get(PropertyTag ptag, const Connected_components_graph& w) +get(PropertyTag ptag, const Connected_components_graph& w) { return get(ptag, w.graph()); } +//specializations for indices +template +typename boost::property_map, CGAL::face_index_t >::type +get(CGAL::face_index_t, const Connected_components_graph& w) +{ + return w.get_face_index_map(); +} + template +typename boost::property_map, boost::vertex_index_t >::type +get(boost::vertex_index_t, const Connected_components_graph& w) +{ + return w.get_vertex_index_map(); +} + + +template +typename boost::property_map, CGAL::halfedge_index_t >::type +get(CGAL::halfedge_index_t, const Connected_components_graph& w) +{ + return w.get_halfedge_index_map(); +} + + +template typename boost::property_traits::type>::value_type get(PropertyTag ptag, - const Connected_components_graph& w, + const Connected_components_graph& w, const typename boost::property_traits::type>::key_type& k) { return get(ptag, w.graph(), k); @@ -789,12 +873,12 @@ get(PropertyTag ptag, template void -put(PropertyTag ptag, const Connected_components_graph& w, +put(PropertyTag ptag, const Connected_components_graph& w, const typename boost::property_traits::type>::key_type& k, typename boost::property_traits::type>::value_type& v) { @@ -805,22 +889,54 @@ put(PropertyTag ptag, const Connected_components_graph -struct property_map,PropertyTag> { +struct property_map,PropertyTag> { typedef typename boost::property_map::type type; typedef typename boost::property_map::const_type const_type; }; template -struct graph_has_property, PropertyTag> +struct graph_has_property, PropertyTag> : graph_has_property {}; + +//specializations for indices +template +struct property_map, CGAL::face_index_t>{ + typedef typename CGAL::Property_map_binder< FIMap, + typename CGAL::Pointer_property_map< typename boost::property_traits< FIMap >::value_type >::type > type; + typedef type const_type; +}; + +template +struct property_map, boost::vertex_index_t>{ + typedef typename CGAL::Property_map_binder< VIMap, + typename CGAL::Pointer_property_map< typename boost::property_traits< VIMap >::value_type >::type > type; + typedef type const_type; +}; + +template + +struct property_map, CGAL::halfedge_index_t>{ + typedef typename CGAL::Property_map_binder< HIMap, + typename CGAL::Pointer_property_map< typename boost::property_traits< HIMap >::value_type >::type > type; + typedef type const_type; +}; }// namespace boost #endif // CGAL_BOOST_GRAPH_CONNECTED_COMPONENTS_GRAPH_H diff --git a/BGL/test/BGL/test_Connected_components_graph.cpp b/BGL/test/BGL/test_Connected_components_graph.cpp index 9724343a838..8ca1cd2a1cd 100644 --- a/BGL/test/BGL/test_Connected_components_graph.cpp +++ b/BGL/test/BGL/test_Connected_components_graph.cpp @@ -1,11 +1,13 @@ #include #include +#include #include "test_Prefix.h" #include #include #include #include #include +#include typedef boost::unordered_set id_map; @@ -355,7 +357,7 @@ main() { typedef CGAL::Connected_components_graph Adapter; - test(sm_data()); + //test(sm_data()); //Make a tetrahedron and test the adapter for a patch that only contains 2 faces SM* sm = new SM(); CGAL::make_tetrahedron( @@ -366,10 +368,10 @@ main() *sm); SM::Property_map::face_descriptor , std::size_t> fccmap = sm->add_property_map::face_descriptor, std::size_t>("f:CC").first; - CGAL::Properties::Property_map::vertex_descriptor, SM::Point> positions = + SM::Property_map::vertex_descriptor, SM::Point> positions = sm->points(); CGAL::Polygon_mesh_processing::connected_components(*sm, fccmap, CGAL::Polygon_mesh_processing::parameters:: - edge_is_constrained_map(Constraint::vertex_descriptor, + edge_is_constrained_map(Constraint::vertex_descriptor, SM::Point> >(*sm, positions))); boost::unordered_set pids; pids.insert(0); @@ -409,5 +411,8 @@ main() CGAL_assertion(std::distance(in_edges(v, fga).first ,in_edges(v, fga).second) == 3 ); CGAL_assertion(std::distance(out_edges(v, fga).first ,out_edges(v, fga).second) == 3 ); + SM copy; + CGAL::copy_face_graph(fga, copy); + return 0; } From 557e1a78c1aa10a0740f23c1fdc9220a6c62565f Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 3 May 2017 12:49:45 +0200 Subject: [PATCH 15/38] Add tests for Polyhedron and fix Property forwarding --- .../boost/graph/Connected_components_graph.h | 141 +++++++++----- .../BGL/test_Connected_components_graph.cpp | 179 ++++++++++++------ 2 files changed, 221 insertions(+), 99 deletions(-) diff --git a/BGL/include/CGAL/boost/graph/Connected_components_graph.h b/BGL/include/CGAL/boost/graph/Connected_components_graph.h index f9e9f435ef6..f4b44d128ca 100644 --- a/BGL/include/CGAL/boost/graph/Connected_components_graph.h +++ b/BGL/include/CGAL/boost/graph/Connected_components_graph.h @@ -66,6 +66,58 @@ struct Connected_components_graph typedef typename boost::property_traits< HIMap >::value_type halfedge_index_type; typedef Connected_components_graph Self; + template + void base_iterator_constructor(IndexRangeIterator begin, + IndexRangeIterator end, + FaceComponentMap fcmap) + { + face_patch.resize(num_faces(_graph)); + vertex_patch.resize(num_vertices(_graph)); + halfedge_patch.resize(num_halfedges(_graph)); + boost::unordered_set::value_type> pids; + for(IndexRangeIterator it = begin; + it != end; + ++it) + { + pids.insert(*it); + } + + BOOST_FOREACH(face_descriptor fd, faces(_graph) ) + { + if(pids.find(boost::get(fcmap, fd))!= pids.end() ) + { + face_patch.set(get(fimap, fd)); + BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_face(halfedge(fd, _graph), _graph)) + { + halfedge_patch.set(get(himap, hd)); + halfedge_patch.set(get(himap, opposite(hd, _graph))); + vertex_patch.set(get(vimap, target(hd, _graph))); + } + } + } + } + + template + void base_constructor(FaceComponentMap fcmap, + typename boost::property_traits::value_type pid) + { + face_patch.resize(num_faces(_graph)); + vertex_patch.resize(num_vertices(_graph)); + halfedge_patch.resize(num_halfedges(_graph)); + BOOST_FOREACH(face_descriptor fd, faces(_graph) ) + { + if(boost::get(fcmap, fd) == pid) + { + face_patch.set(get(fimap, fd)); + BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_face(halfedge(fd, _graph), _graph)) + { + halfedge_patch.set(get(himap, hd)); + halfedge_patch.set(get(himap, opposite(hd, _graph))); + vertex_patch.set(get(vimap, target(hd, _graph))); + } + } + } + } /*! * \brief Creates a Connected_components_graph of the connected components of `graph` specified in the range * defined by `begin` and `end`. @@ -83,42 +135,31 @@ struct Connected_components_graph * \param end an interator to the element past the end of a range of connected components indices of interest. */ + template + Connected_components_graph(const Graph& graph, + FaceComponentMap fcmap, + IndexRangeIterator begin, + IndexRangeIterator end, + FIMap fimap, + VIMap vimap, + HIMap himap) + : _graph(const_cast(graph)), fimap(fimap), vimap(vimap), himap(himap) + { + base_iterator_constructor(begin, end, fcmap); + } + template Connected_components_graph(const Graph& graph, FaceComponentMap fcmap, IndexRangeIterator begin, IndexRangeIterator end) - : _graph(graph) + : _graph(const_cast(graph)) { fimap = get(CGAL::face_index, graph); vimap = get(boost::vertex_index, graph); himap = get(CGAL::halfedge_index, graph); - face_patch.resize(num_faces(graph)); - vertex_patch.resize(num_vertices(graph)); - halfedge_patch.resize(num_halfedges(graph)); - boost::unordered_set::value_type> pids; - for(IndexRangeIterator it = begin; - it != end; - ++it) - { - pids.insert(*it); - } - - BOOST_FOREACH(face_descriptor fd, faces(graph) ) - { - if(pids.find(boost::get(fcmap, fd))!= pids.end() ) - { - face_patch.set(get(fimap, fd)); - BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_face(halfedge(fd, graph), graph)) - { - halfedge_patch.set(get(himap, hd)); - halfedge_patch.set(get(himap, opposite(hd, graph))); - vertex_patch.set(get(vimap, target(hd, graph))); - } - } - } + base_iterator_constructor(begin, end, fcmap); } - /*! * \brief Creates a Connected_components_graph of the connected component `pid` of `graph`. * @@ -131,36 +172,33 @@ struct Connected_components_graph `graph_traits::faces_size_type` as value type. * \param pid the index of the connected component of interest. */ + template + Connected_components_graph(const Graph& graph, + FaceComponentMap fcmap, + typename boost::property_traits::value_type pid, + FIMap fimap, + VIMap vimap, + HIMap himap) + : _graph(const_cast(graph)), fimap(fimap), vimap(vimap), himap(himap) + { + base_constructor(fcmap, pid); + } + template Connected_components_graph(const Graph& graph, FaceComponentMap fcmap, typename boost::property_traits::value_type pid) - : _graph(graph) + : _graph(const_cast(graph)) { fimap = get(CGAL::face_index, graph); vimap = get(boost::vertex_index, graph); himap = get(CGAL::halfedge_index, graph); - face_patch.resize(num_faces(graph)); - vertex_patch.resize(num_vertices(graph)); - halfedge_patch.resize(num_halfedges(graph)); - BOOST_FOREACH(face_descriptor fd, faces(graph) ) - { - if(boost::get(fcmap, fd) == pid) - { - face_patch.set(get(fimap, fd)); - BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_face(halfedge(fd, graph), graph)) - { - halfedge_patch.set(get(himap, hd)); - halfedge_patch.set(get(himap, opposite(hd, graph))); - vertex_patch.set(get(vimap, target(hd, graph))); - } - } - } + base_constructor(fcmap, pid); } ///returns the graph of the Connected_components_graph. const Graph& graph()const{ return _graph; } - + Graph& graph(){ return _graph; } struct Is_simplex_valid { @@ -259,10 +297,10 @@ struct Connected_components_graph } private: + Graph& _graph; FIMap fimap; VIMap vimap; HIMap himap; - const Graph& _graph; boost::dynamic_bitset<> face_patch; boost::dynamic_bitset<> vertex_patch; boost::dynamic_bitset<> halfedge_patch; @@ -818,12 +856,23 @@ template -typename boost::property_map::type +typename boost::property_map::const_type get(PropertyTag ptag, const Connected_components_graph& w) { return get(ptag, w.graph()); } +template +typename boost::property_map::type +get(PropertyTag ptag, Connected_components_graph& w) +{ + return get(ptag, w.graph()); +} + //specializations for indices template & graphs) typedef SM::Point Point_3; -template -struct Constraint : public boost::put_get_helper > +template +struct Constraint : public boost::put_get_helper > { - typedef typename boost::graph_traits::edge_descriptor edge_descriptor; + typedef typename boost::graph_traits::edge_descriptor edge_descriptor; typedef boost::readable_property_map_tag category; typedef bool value_type; typedef bool reference; @@ -310,73 +310,51 @@ struct Constraint : public boost::put_get_helper +void test_mesh(Adapter fga) { - typedef CGAL::Connected_components_graph Adapter; - //test(sm_data()); - //Make a tetrahedron and test the adapter for a patch that only contains 2 faces - SM* sm = new SM(); - CGAL::make_tetrahedron( - Point_3(1,1,1), - Point_3(0,0,0), - Point_3(0,0,1), - Point_3(1,0,1), - *sm); - SM::Property_map::face_descriptor , std::size_t> fccmap = - sm->add_property_map::face_descriptor, std::size_t>("f:CC").first; - SM::Property_map::vertex_descriptor, SM::Point> positions = - sm->points(); - CGAL::Polygon_mesh_processing::connected_components(*sm, fccmap, CGAL::Polygon_mesh_processing::parameters:: - edge_is_constrained_map(Constraint::vertex_descriptor, - SM::Point> >(*sm, positions))); - boost::unordered_set pids; - pids.insert(0); - pids.insert(2); - Adapter fga(*sm, fccmap, pids.begin(), pids.end()); CGAL_GRAPH_TRAITS_MEMBERS(Adapter); //check that there is the right number of simplices in fga CGAL_assertion(CGAL::is_valid(fga)); @@ -396,7 +374,7 @@ main() next(next(next(next(h, fga), fga), fga), fga) == h ); //check that prev() works inside the patch - h = halfedge(*faces(fga).first, fga); + h = halfedge(*faces(fga).first, fga); CGAL_assertion( prev(prev(prev(h, fga), fga), fga) == h ); @@ -411,8 +389,103 @@ main() CGAL_assertion(std::distance(in_edges(v, fga).first ,in_edges(v, fga).second) == 3 ); CGAL_assertion(std::distance(out_edges(v, fga).first ,out_edges(v, fga).second) == 3 ); - SM copy; + Mesh copy; CGAL::copy_face_graph(fga, copy); - - return 0; +} + + +int +main() +{ + + test(sm_data()); + //Make a tetrahedron and test the adapter for a patch that only contains 2 faces + typedef typename CGAL::Connected_components_graph SM_Adapter; + typedef SM::Property_map::face_descriptor , std::size_t> SM_FCCMap; + SM* sm = new SM(); + CGAL::make_tetrahedron( + Point_3(1,1,1), + Point_3(0,0,0), + Point_3(0,0,1), + Point_3(1,0,1), + *sm); + SM_FCCMap fccmap = + sm->add_property_map::face_descriptor, std::size_t>("f:CC").first; + SM::Property_map::vertex_descriptor, SM::Point> positions = + sm->points(); + CGAL::Polygon_mesh_processing::connected_components(*sm, fccmap, CGAL::Polygon_mesh_processing::parameters:: + edge_is_constrained_map(Constraint::vertex_descriptor, + SM::Point> >(*sm, positions))); + boost::unordered_set pids; + pids.insert(0); + pids.insert(2); + SM_Adapter sm_adapter(*sm, fccmap, pids.begin(), pids.end()); + test_mesh(sm_adapter); + + + + + typedef boost::graph_traits PolyTraits; + typedef boost::property_map::type VPMap; + typedef PolyTraits::face_descriptor poly_face_descriptor; + typedef PolyTraits::vertex_descriptor poly_vertex_descriptor; + typedef PolyTraits::halfedge_descriptor poly_halfedge_descriptor; + typedef boost::associative_property_map< std::map > FIMap; + typedef boost::associative_property_map< std::map > VIMap; + typedef boost::associative_property_map< std::map > HIMap; + typedef typename CGAL::Connected_components_graph Poly_Adapter; + Polyhedron *poly = new Polyhedron(); + CGAL::make_tetrahedron( + Point_3(1,1,1), + Point_3(0,0,0), + Point_3(0,0,1), + Point_3(1,0,1), + *poly); + + std::map fimap; + + std::map vimap; + + std::map himap; + int i = 0; + BOOST_FOREACH(poly_face_descriptor f, faces(*poly)) + { + fimap[f]=i++; + } + i = 0; + BOOST_FOREACH(poly_vertex_descriptor v, vertices(*poly)) + { + vimap[v]=i++; + } + i = 0; + BOOST_FOREACH(poly_halfedge_descriptor h, halfedges(*poly)) + { + himap[h]=i++; + } + + FIMap poly_fimap(fimap); + VIMap poly_vimap(vimap); + HIMap poly_himap(himap); + std::map fc_map; + FIMap poly_fccmap(fc_map); + + VPMap vpmap = get(boost::vertex_point, *poly); + CGAL::Polygon_mesh_processing::connected_components(*poly, poly_fccmap, CGAL::Polygon_mesh_processing::parameters:: + edge_is_constrained_map(Constraint(*poly, vpmap)). + face_index_map(poly_fimap)); + Poly_Adapter poly_adapter(*poly, + poly_fccmap, + pids.begin(), + pids.end(), + poly_fimap, + poly_vimap, + poly_himap); + test_mesh(poly_adapter); } From 64eb2d09c698a6e2602bc0c77811d2cda1308cae Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 3 May 2017 14:38:41 +0200 Subject: [PATCH 16/38] Change doc for default index maps and add an example to Surface_mesh_segmentation using area() and Connected_components_graphs. --- .../boost/graph/Connected_components_graph.h | 49 ++++++++++++----- .../Surface_Mesh_Segmentation.txt | 6 +++ .../Surface_mesh_segmentation/examples.txt | 1 + .../Surface_mesh_segmentation/CMakeLists.txt | 3 ++ ...extract_segmentation_into_mesh_example.cpp | 54 +++++++++++++++++++ 5 files changed, 101 insertions(+), 12 deletions(-) create mode 100644 Surface_mesh_segmentation/examples/Surface_mesh_segmentation/extract_segmentation_into_mesh_example.cpp diff --git a/BGL/include/CGAL/boost/graph/Connected_components_graph.h b/BGL/include/CGAL/boost/graph/Connected_components_graph.h index f4b44d128ca..0f31b4a796f 100644 --- a/BGL/include/CGAL/boost/graph/Connected_components_graph.h +++ b/BGL/include/CGAL/boost/graph/Connected_components_graph.h @@ -42,14 +42,13 @@ namespace CGAL * For example, calling `vertices(graph)` will return an iterator range of all but only the vertices that belong to the selected connected components. * * \tparam Graph must be a model of a `FaceListGraph` and `HalfedgeListGraph`. - * \tparam FIMap a model of `ReadablePropertyMap` with `boost::graph_traits::%face_descriptor` as key and `graph_traits::faces_size_type` - * \tparam VIMap a model of `ReadablePropertyMap` with `boost::graph_traits::%vertex_descriptor` as key and `graph_traits::vertices_size_type` - * \tparam HIMap a model of `ReadablePropertyMap` with `boost::graph_traits::%halfedge_descriptor` as key and `graph_traits::halfedges_size_type` + * \tparam FIMap a model of `ReadablePropertyMap` with `boost::graph_traits::%face_descriptor` as key and `graph_traits::%faces_size_type` as value + * \tparam VIMap a model of `ReadablePropertyMap` with `boost::graph_traits::%vertex_descriptor` as key and `graph_traits::%vertices_size_type` as value + * \tparam HIMap a model of `ReadablePropertyMap` with `boost::graph_traits::%halfedge_descriptor` as key and `graph_traits::%halfedges_size_type` as value * * \cgalModels `FaceListGraph` * \cgalModels `HalfedgeListGraph` */ - template::type, typename VIMap = typename boost::property_map::type, @@ -125,14 +124,20 @@ struct Connected_components_graph * \tparam FaceComponentMap a model of `ReadablePropertyMap` with `boost::graph_traits::%face_descriptor` as key type and - `graph_traits::faces_size_type` as value type. + `graph_traits::%faces_size_type` as value type. * \param graph the graph containing the wanted patches. * \param fcmap the property_map that assigns a connected component to each face, with `boost::graph_traits::%face_descriptor` as key type and - `graph_traits::faces_size_type` as value type. + `graph_traits::%faces_size_type` as value type. * \param begin an interator to the beginning of a range of connected components indices of interest. * \param end an interator to the element past the end of a range of connected components indices of interest. + * \param fimap the property map that assigns an index to each face, + * with boost::graph_traits::%face_descriptor as key type and boost::graph_traits::%faces_size_type as value type + * \param vimap the property map that assigns an index to each vertex, + * with boost::graph_traits::%vertex_descriptor as key type and boost::graph_traits::%vertices_size_type as value type + * \param himap the property map that assigns an index to each halfedge, + * with boost::graph_traits::%halfedge_descriptor as key type and boost::graph_traits::%halfedges_size_type as value type */ template @@ -140,9 +145,16 @@ struct Connected_components_graph FaceComponentMap fcmap, IndexRangeIterator begin, IndexRangeIterator end, + #ifdef DOXYGEN_RUNNING + FIMap fimap = get(CGAL::face_index, graph), + VIMap vimap = get(boost::vertex_index, graph), + HIMap himap = get(CGAL::halfedge_index, graph) + #else FIMap fimap, VIMap vimap, - HIMap himap) + HIMap himap + #endif + ) : _graph(const_cast(graph)), fimap(fimap), vimap(vimap), himap(himap) { base_iterator_constructor(begin, end, fcmap); @@ -165,20 +177,33 @@ struct Connected_components_graph * * \tparam FaceComponentMap a model of `ReadablePropertyMap` with `boost::graph_traits::%face_descriptor` as key type and - `graph_traits::faces_size_type` as value type. + `graph_traits::%faces_size_type` as value type. * \param graph the graph containing the wanted patch. * \param fcmap the property_map that assigns a connected component's index to each face, with `boost::graph_traits::%face_descriptor` as key type and - `graph_traits::faces_size_type` as value type. + `graph_traits::%faces_size_type` as value type. * \param pid the index of the connected component of interest. + * \param fimap the property map that assigns an index to each face, + * with boost::graph_traits::%face_descriptor as key type and boost::graph_traits::%faces_size_type as value type + * \param vimap the property map that assigns an index to each vertex, + * with boost::graph_traits::%vertex_descriptor as key type and boost::graph_traits::%vertices_size_type as value type + * \param himap the property map that assigns an index to each halfedge, + * with boost::graph_traits::%halfedge_descriptor as key type and boost::graph_traits::%halfedges_size_type as value type */ template Connected_components_graph(const Graph& graph, FaceComponentMap fcmap, typename boost::property_traits::value_type pid, + #ifdef DOXYGEN_RUNNING + FIMap fimap = get(CGAL::face_index, graph), + VIMap vimap = get(boost::vertex_index, graph), + HIMap himap = get(CGAL::halfedge_index, graph) + #else FIMap fimap, VIMap vimap, - HIMap himap) + HIMap himap + #endif + ) : _graph(const_cast(graph)), fimap(fimap), vimap(vimap), himap(himap) { base_constructor(fcmap, pid); @@ -195,9 +220,9 @@ struct Connected_components_graph himap = get(CGAL::halfedge_index, graph); base_constructor(fcmap, pid); } - ///returns the graph of the Connected_components_graph. + ///returns a const reference to the graph of the Connected_components_graph. const Graph& graph()const{ return _graph; } - + ///returns a reference to the graph of the Connected_components_graph. Graph& graph(){ return _graph; } struct Is_simplex_valid diff --git a/Surface_mesh_segmentation/doc/Surface_mesh_segmentation/Surface_Mesh_Segmentation.txt b/Surface_mesh_segmentation/doc/Surface_mesh_segmentation/Surface_Mesh_Segmentation.txt index 506ec1a5dfb..3646fc34818 100644 --- a/Surface_mesh_segmentation/doc/Surface_mesh_segmentation/Surface_Mesh_Segmentation.txt +++ b/Surface_mesh_segmentation/doc/Surface_mesh_segmentation/Surface_Mesh_Segmentation.txt @@ -200,11 +200,17 @@ The main advantage is to decrease from log to constant the complexity for access \cgalExample{Surface_mesh_segmentation/segmentation_with_facet_ids_example.cpp} + \subsection Surface_mesh_segmentationUsingapolyhedron Using a Surface_mesh When using a `Surface_mesh`, you can use the built-in property mechanism. \cgalExample{Surface_mesh_segmentation/segmentation_from_sdf_values_SM_example.cpp} +\subsection Surface_mesh_segmentationIndependantmeshpersegment Independant TriangleMesh per Segment + It is possible to consider each segment as an independant triangle mesh, like in the following example, where the area of each segment is computed. + +\cgalExample{Surface_mesh_segmentation/extract_segmentation_into_mesh_example.cpp} +
\section Performances Performances diff --git a/Surface_mesh_segmentation/doc/Surface_mesh_segmentation/examples.txt b/Surface_mesh_segmentation/doc/Surface_mesh_segmentation/examples.txt index 20ebc1fe599..4dca4c1a63a 100644 --- a/Surface_mesh_segmentation/doc/Surface_mesh_segmentation/examples.txt +++ b/Surface_mesh_segmentation/doc/Surface_mesh_segmentation/examples.txt @@ -3,3 +3,4 @@ /// \example Surface_mesh_segmentation/segmentation_from_sdf_values_SM_example.cpp /// \example Surface_mesh_segmentation/segmentation_via_sdf_values_example.cpp /// \example Surface_mesh_segmentation/segmentation_with_facet_ids_example.cpp +/// \example Surface_mesh_segmentation/extract_segmentation_into_mesh_example.cpp diff --git a/Surface_mesh_segmentation/examples/Surface_mesh_segmentation/CMakeLists.txt b/Surface_mesh_segmentation/examples/Surface_mesh_segmentation/CMakeLists.txt index 95d98601c9b..581a03e756b 100644 --- a/Surface_mesh_segmentation/examples/Surface_mesh_segmentation/CMakeLists.txt +++ b/Surface_mesh_segmentation/examples/Surface_mesh_segmentation/CMakeLists.txt @@ -64,8 +64,11 @@ create_single_source_cgal_program( "segmentation_from_sdf_values_example.cpp" ) create_single_source_cgal_program( "segmentation_via_sdf_values_example.cpp" ) create_single_source_cgal_program( "segmentation_with_facet_ids_example.cpp" ) + create_single_source_cgal_program( "segmentation_from_sdf_values_SM_example.cpp") +create_single_source_cgal_program( "extract_segmentation_into_mesh_example.cpp") + if(OpenMesh_FOUND) create_single_source_cgal_program( "segmentation_from_sdf_values_OpenMesh_example.cpp" ) target_link_libraries( segmentation_from_sdf_values_OpenMesh_example ${OPENMESH_LIBRARIES} ) diff --git a/Surface_mesh_segmentation/examples/Surface_mesh_segmentation/extract_segmentation_into_mesh_example.cpp b/Surface_mesh_segmentation/examples/Surface_mesh_segmentation/extract_segmentation_into_mesh_example.cpp new file mode 100644 index 00000000000..699cf816331 --- /dev/null +++ b/Surface_mesh_segmentation/examples/Surface_mesh_segmentation/extract_segmentation_into_mesh_example.cpp @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; +typedef CGAL::Surface_mesh SM; +typedef boost::graph_traits::face_descriptor face_descriptor; + +int main(int argc, char** argv ) +{ + SM mesh; + if (argc==2){ + std::ifstream input(argv[1]); + input >> mesh; + } else { + std::ifstream cactus("data/cactus.off"); + cactus >> mesh; + } + typedef SM::Property_map Facet_double_map; + Facet_double_map sdf_property_map; + + sdf_property_map = mesh.add_property_map("f:sdf").first; + + CGAL::sdf_values(mesh, sdf_property_map); + + // create a property-map for segment-ids + typedef SM::Property_map Facet_int_map; + Facet_int_map segment_property_map = mesh.add_property_map("f:sid").first;; + + // segment the mesh using default parameters for number of levels, and smoothing lambda + // Any other scalar values can be used instead of using SDF values computed using the CGAL function + std::size_t number_of_segments = CGAL::segmentation_from_sdf_values(mesh, sdf_property_map, segment_property_map); + + typedef CGAL::Connected_components_graph Cc_graph; + //print area of each segment and then put it in a Mesh and print it in an OFF file + for(std::size_t id = 0; id < number_of_segments; ++id) + { + Cc_graph segment_mesh(mesh, segment_property_map, id); + std::cout << "Segment "< Date: Wed, 3 May 2017 15:59:29 +0200 Subject: [PATCH 17/38] Simplify Polyhedron test. --- .../BGL/test_Connected_components_graph.cpp | 44 ++++--------------- 1 file changed, 9 insertions(+), 35 deletions(-) diff --git a/BGL/test/BGL/test_Connected_components_graph.cpp b/BGL/test/BGL/test_Connected_components_graph.cpp index d8123161212..eb558dce7ca 100644 --- a/BGL/test/BGL/test_Connected_components_graph.cpp +++ b/BGL/test/BGL/test_Connected_components_graph.cpp @@ -428,14 +428,11 @@ main() typedef boost::graph_traits PolyTraits; typedef boost::property_map::type VPMap; typedef PolyTraits::face_descriptor poly_face_descriptor; - typedef PolyTraits::vertex_descriptor poly_vertex_descriptor; - typedef PolyTraits::halfedge_descriptor poly_halfedge_descriptor; typedef boost::associative_property_map< std::map > FIMap; - typedef boost::associative_property_map< std::map > VIMap; - typedef boost::associative_property_map< std::map > HIMap; + PolyTraits::faces_size_type> > FCMap; + typedef boost::property_map::type FIMap; + typedef boost::property_map::type VIMap; + typedef boost::property_map::type HIMap; typedef typename CGAL::Connected_components_graph Poly_Adapter; Polyhedron *poly = new Polyhedron(); CGAL::make_tetrahedron( @@ -445,36 +442,13 @@ main() Point_3(1,0,1), *poly); - std::map fimap; - std::map vimap; - - std::map himap; - int i = 0; - BOOST_FOREACH(poly_face_descriptor f, faces(*poly)) - { - fimap[f]=i++; - } - i = 0; - BOOST_FOREACH(poly_vertex_descriptor v, vertices(*poly)) - { - vimap[v]=i++; - } - i = 0; - BOOST_FOREACH(poly_halfedge_descriptor h, halfedges(*poly)) - { - himap[h]=i++; - } - - FIMap poly_fimap(fimap); - VIMap poly_vimap(vimap); - HIMap poly_himap(himap); + FIMap poly_fimap = get(CGAL::face_external_index, *poly); + VIMap poly_vimap = get(CGAL::vertex_external_index, *poly); + HIMap poly_himap = get(CGAL::halfedge_external_index, *poly); std::map fc_map; - FIMap poly_fccmap(fc_map); + FCMap poly_fccmap(fc_map); VPMap vpmap = get(boost::vertex_point, *poly); CGAL::Polygon_mesh_processing::connected_components(*poly, poly_fccmap, CGAL::Polygon_mesh_processing::parameters:: @@ -487,5 +461,5 @@ main() poly_fimap, poly_vimap, poly_himap); - test_mesh(poly_adapter); + test_mesh(poly_adapter); } From 1caba594049d69189c7378a7cd6a04b0d90fe7f9 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 3 May 2017 16:14:25 +0200 Subject: [PATCH 18/38] add a function to change the current connected component ids to the cc_graph and update Segmentation example. --- .../boost/graph/Connected_components_graph.h | 21 +++++++++++++++++++ ...extract_segmentation_into_mesh_example.cpp | 4 +++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/BGL/include/CGAL/boost/graph/Connected_components_graph.h b/BGL/include/CGAL/boost/graph/Connected_components_graph.h index 0f31b4a796f..44f565ad313 100644 --- a/BGL/include/CGAL/boost/graph/Connected_components_graph.h +++ b/BGL/include/CGAL/boost/graph/Connected_components_graph.h @@ -225,6 +225,27 @@ struct Connected_components_graph ///returns a reference to the graph of the Connected_components_graph. Graph& graph(){ return _graph; } + ///change the selected component's id + template + void set_selected_component(FaceComponentMap fcmap, + typename boost::property_traits::value_type pid) + { + face_indices.clear(); + vertex_indices.clear(); + halfedge_indices.clear(); + base_constructor(fcmap, pid); + } + /// change the selected components ids + template + void set_selected_components(FaceComponentMap fcmap, + IndexRangeIterator begin, + IndexRangeIterator end) + { + face_indices.clear(); + vertex_indices.clear(); + halfedge_indices.clear(); + base_iterator_constructor(begin, end, fcmap); + } struct Is_simplex_valid { Is_simplex_valid(const Self* graph) diff --git a/Surface_mesh_segmentation/examples/Surface_mesh_segmentation/extract_segmentation_into_mesh_example.cpp b/Surface_mesh_segmentation/examples/Surface_mesh_segmentation/extract_segmentation_into_mesh_example.cpp index 699cf816331..37ab72c7b97 100644 --- a/Surface_mesh_segmentation/examples/Surface_mesh_segmentation/extract_segmentation_into_mesh_example.cpp +++ b/Surface_mesh_segmentation/examples/Surface_mesh_segmentation/extract_segmentation_into_mesh_example.cpp @@ -40,9 +40,11 @@ int main(int argc, char** argv ) typedef CGAL::Connected_components_graph Cc_graph; //print area of each segment and then put it in a Mesh and print it in an OFF file + Cc_graph segment_mesh(mesh, segment_property_map, 0); for(std::size_t id = 0; id < number_of_segments; ++id) { - Cc_graph segment_mesh(mesh, segment_property_map, id); + if(id > 0) + segment_mesh.set_selected_component(segment_property_map, id); std::cout << "Segment "< Date: Tue, 9 May 2017 12:50:40 +0200 Subject: [PATCH 19/38] Fix PMP example --- .../connected_components_graph_example.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/connected_components_graph_example.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/connected_components_graph_example.cpp index 81142ad9afc..b26bd1aaf90 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/connected_components_graph_example.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/connected_components_graph_example.cpp @@ -18,7 +18,7 @@ typedef boost::graph_traits::face_descriptor face_descriptor; typedef boost::graph_traits::faces_size_type faces_size_type; typedef Mesh::Property_map FCCmap; - typedef CGAL::Connected_components_graph CCG; + typedef CGAL::Connected_components_graph CCG; namespace PMP = CGAL::Polygon_mesh_processing; @@ -39,7 +39,7 @@ int main(int argc, char* argv[]) std::cerr << "- The graph has " << num << " connected components (face connectivity)" << std::endl; - CCG ccg(mesh, fccmap, faces_size_type(0)); + CCG ccg(mesh, fccmap, 0); std::cout << "The faces in component 0 are:" << std::endl; BOOST_FOREACH(boost::graph_traits::face_descriptor f, faces(ccg)){ @@ -51,7 +51,7 @@ int main(int argc, char* argv[]) components.push_back(0); components.push_back(1); - ccg.set_connected_components(components); + ccg.set_selected_components(fccmap,components.begin(), components.end()); std::cout << "The faces in components 0 and 1 are:" << std::endl; BOOST_FOREACH(CCG::face_descriptor f, faces(ccg)){ From 185ac3bbd0dc870ab56c66b9846fe943fd6f19b2 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 11 May 2017 14:21:30 +0200 Subject: [PATCH 20/38] clean-up the doc --- .../CGAL/boost/graph/Connected_components_graph.h | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/BGL/include/CGAL/boost/graph/Connected_components_graph.h b/BGL/include/CGAL/boost/graph/Connected_components_graph.h index 44f565ad313..4ffc7f618a6 100644 --- a/BGL/include/CGAL/boost/graph/Connected_components_graph.h +++ b/BGL/include/CGAL/boost/graph/Connected_components_graph.h @@ -39,7 +39,7 @@ namespace CGAL * * The class `Connected_components_graph` wraps a graph into another graph in such a way that only the specified connected components are seen from the outside. * - * For example, calling `vertices(graph)` will return an iterator range of all but only the vertices that belong to the selected connected components. + * For example, calling `vertices(graph)` will provide the range of vertices belonging to the selected components. * * \tparam Graph must be a model of a `FaceListGraph` and `HalfedgeListGraph`. * \tparam FIMap a model of `ReadablePropertyMap` with `boost::graph_traits::%face_descriptor` as key and `graph_traits::%faces_size_type` as value @@ -120,11 +120,10 @@ struct Connected_components_graph /*! * \brief Creates a Connected_components_graph of the connected components of `graph` specified in the range * defined by `begin` and `end`. - * typedef unspecified_type IndexRangeIterator; - * \tparam FaceComponentMap a model of `ReadablePropertyMap` with `boost::graph_traits::%face_descriptor` as key type and `graph_traits::%faces_size_type` as value type. + * \tparam IndexRangeIterator an iterator of a range of `boost::property_traits::%value_type`. * \param graph the graph containing the wanted patches. * \param fcmap the property_map that assigns a connected component to each face, with @@ -225,7 +224,7 @@ struct Connected_components_graph ///returns a reference to the graph of the Connected_components_graph. Graph& graph(){ return _graph; } - ///change the selected component's id + ///change the selected component template void set_selected_component(FaceComponentMap fcmap, typename boost::property_traits::value_type pid) @@ -235,7 +234,7 @@ struct Connected_components_graph halfedge_indices.clear(); base_constructor(fcmap, pid); } - /// change the selected components ids + /// change the selected components template void set_selected_components(FaceComponentMap fcmap, IndexRangeIterator begin, From 1f96262d3d7931c4462aa93a672f12d6599cc9ab Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 12 May 2017 11:52:07 +0200 Subject: [PATCH 21/38] Rename the graph into Face_filtered_graph and add a function to check its validity. --- BGL/doc/BGL/Doxyfile.in | 2 +- BGL/doc/BGL/PackageDescription.txt | 2 +- ...mponents_graph.h => Face_filtered_graph.h} | 358 +++++++++++------- BGL/test/BGL/CMakeLists.txt | 4 +- ... => graph_concept_Face_filtered_graph.cpp} | 4 +- ...graph.cpp => test_Face_filtered_graph.cpp} | 27 +- Installation/changes.html | 2 +- .../Polygon_mesh_processing.txt | 4 +- .../doc/Polygon_mesh_processing/examples.txt | 2 +- .../Polygon_mesh_processing/CMakeLists.txt | 2 +- ...le.cpp => face_filtered_graph_example.cpp} | 4 +- ...extract_segmentation_into_mesh_example.cpp | 4 +- 12 files changed, 243 insertions(+), 172 deletions(-) rename BGL/include/CGAL/boost/graph/{Connected_components_graph.h => Face_filtered_graph.h} (63%) rename BGL/test/BGL/{graph_concept_Connected_components_graph.cpp => graph_concept_Face_filtered_graph.cpp} (91%) rename BGL/test/BGL/{test_Connected_components_graph.cpp => test_Face_filtered_graph.cpp} (95%) rename Polygon_mesh_processing/examples/Polygon_mesh_processing/{connected_components_graph_example.cpp => face_filtered_graph_example.cpp} (94%) diff --git a/BGL/doc/BGL/Doxyfile.in b/BGL/doc/BGL/Doxyfile.in index b17cf50fe55..95aa22e39c6 100644 --- a/BGL/doc/BGL/Doxyfile.in +++ b/BGL/doc/BGL/Doxyfile.in @@ -8,7 +8,7 @@ INPUT += ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/Euler_operations.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/split_graph_into_polylines.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/copy_face_graph.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/Graph_with_descriptor_with_graph.h \ - ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/Connected_components_graph.h \ + ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/Face_filtered_graph.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/Dual.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/convert_nef_polyhedron_to_polygon_mesh.h EXAMPLE_PATH = ${CGAL_Surface_mesh_skeletonization_EXAMPLE_DIR} \ diff --git a/BGL/doc/BGL/PackageDescription.txt b/BGL/doc/BGL/PackageDescription.txt index b4cdfa3bde6..3120cb99902 100644 --- a/BGL/doc/BGL/PackageDescription.txt +++ b/BGL/doc/BGL/PackageDescription.txt @@ -316,7 +316,7 @@ user might encounter. - `CGAL::Dual` - `CGAL::Graph_with_descriptor_with_graph` - `CGAL::Graph_with_descriptor_with_graph_property_map` -- `CGAL::Connected_components_graph` +- `CGAL::Face_filtered_graph` ## Helper Functions ## - `CGAL::is_border()` diff --git a/BGL/include/CGAL/boost/graph/Connected_components_graph.h b/BGL/include/CGAL/boost/graph/Face_filtered_graph.h similarity index 63% rename from BGL/include/CGAL/boost/graph/Connected_components_graph.h rename to BGL/include/CGAL/boost/graph/Face_filtered_graph.h index 4ffc7f618a6..53e38049f28 100644 --- a/BGL/include/CGAL/boost/graph/Connected_components_graph.h +++ b/BGL/include/CGAL/boost/graph/Face_filtered_graph.h @@ -16,8 +16,8 @@ // // // Author(s) : Maxime Gimeno -#ifndef CGAL_BOOST_GRAPH_CONNECTED_COMPONENTS_GRAPH_H -#define CGAL_BOOST_GRAPH_CONNECTED_COMPONENTS_GRAPH_H +#ifndef CGAL_BOOST_GRAPH_FACE_FILTERED_GRAPH_H +#define CGAL_BOOST_GRAPH_FACE_FILTERED_GRAPH_H #include #include @@ -37,10 +37,14 @@ namespace CGAL /*! * \ingroup PkgBGLHelper * - * The class `Connected_components_graph` wraps a graph into another graph in such a way that only the specified connected components are seen from the outside. + * The class `Face_filtered_graph` wraps a graph into another graph and act like a mask. It assigns a patch id to each face + * and acts in such a way that only the specified patches are seen from the outside. * * For example, calling `vertices(graph)` will provide the range of vertices belonging to the selected components. * + * The `Face_filtered_graph` enables to either consider each patch independently or a union of some of these patches. + * Such a union of patches must define a manifold mesh. + * * \tparam Graph must be a model of a `FaceListGraph` and `HalfedgeListGraph`. * \tparam FIMap a model of `ReadablePropertyMap` with `boost::graph_traits::%face_descriptor` as key and `graph_traits::%faces_size_type` as value * \tparam VIMap a model of `ReadablePropertyMap` with `boost::graph_traits::%vertex_descriptor` as key and `graph_traits::%vertices_size_type` as value @@ -53,7 +57,7 @@ template::type, typename VIMap = typename boost::property_map::type, typename HIMap = typename boost::property_map::type> -struct Connected_components_graph +struct Face_filtered_graph { typedef boost::graph_traits gt; typedef typename gt::vertex_descriptor vertex_descriptor; @@ -63,7 +67,7 @@ struct Connected_components_graph typedef typename boost::property_traits< FIMap >::value_type face_index_type; typedef typename boost::property_traits< VIMap >::value_type vertex_index_type; typedef typename boost::property_traits< HIMap >::value_type halfedge_index_type; - typedef Connected_components_graph Self; + typedef Face_filtered_graph Self; template void base_iterator_constructor(IndexRangeIterator begin, @@ -94,6 +98,7 @@ struct Connected_components_graph } } } + CGAL_assertion(is_selection_valid()); } template @@ -116,9 +121,10 @@ struct Connected_components_graph } } } + CGAL_assertion(is_selection_valid()); } /*! - * \brief Creates a Connected_components_graph of the connected components of `graph` specified in the range + * \brief Creates a Face_filtered_graph of the patches of `graph` specified in the range * defined by `begin` and `end`. * \tparam FaceComponentMap a model of `ReadablePropertyMap` with `boost::graph_traits::%face_descriptor` as key type and @@ -126,11 +132,11 @@ struct Connected_components_graph * \tparam IndexRangeIterator an iterator of a range of `boost::property_traits::%value_type`. * \param graph the graph containing the wanted patches. - * \param fcmap the property_map that assigns a connected component to each face, with + * \param fcmap the property_map that assigns a patch to each face, with `boost::graph_traits::%face_descriptor` as key type and `graph_traits::%faces_size_type` as value type. - * \param begin an interator to the beginning of a range of connected components indices of interest. - * \param end an interator to the element past the end of a range of connected components indices of interest. + * \param begin an interator to the beginning of a range of patches indices of interest. + * \param end an interator to the element past the end of a range of patches indices of interest. * \param fimap the property map that assigns an index to each face, * with boost::graph_traits::%face_descriptor as key type and boost::graph_traits::%faces_size_type as value type * \param vimap the property map that assigns an index to each vertex, @@ -140,7 +146,7 @@ struct Connected_components_graph */ template - Connected_components_graph(const Graph& graph, + Face_filtered_graph(const Graph& graph, FaceComponentMap fcmap, IndexRangeIterator begin, IndexRangeIterator end, @@ -160,7 +166,7 @@ struct Connected_components_graph } template - Connected_components_graph(const Graph& graph, + Face_filtered_graph(const Graph& graph, FaceComponentMap fcmap, IndexRangeIterator begin, IndexRangeIterator end) @@ -172,16 +178,16 @@ struct Connected_components_graph base_iterator_constructor(begin, end, fcmap); } /*! - * \brief Creates a Connected_components_graph of the connected component `pid` of `graph`. + * \brief Creates a Face_filtered_graph of the patch `pid` of `graph`. * * \tparam FaceComponentMap a model of `ReadablePropertyMap` with `boost::graph_traits::%face_descriptor` as key type and `graph_traits::%faces_size_type` as value type. * \param graph the graph containing the wanted patch. - * \param fcmap the property_map that assigns a connected component's index to each face, with + * \param fcmap the property_map that assigns a patch's index to each face, with `boost::graph_traits::%face_descriptor` as key type and `graph_traits::%faces_size_type` as value type. - * \param pid the index of the connected component of interest. + * \param pid the index of the patch of interest. * \param fimap the property map that assigns an index to each face, * with boost::graph_traits::%face_descriptor as key type and boost::graph_traits::%faces_size_type as value type * \param vimap the property map that assigns an index to each vertex, @@ -190,7 +196,7 @@ struct Connected_components_graph * with boost::graph_traits::%halfedge_descriptor as key type and boost::graph_traits::%halfedges_size_type as value type */ template - Connected_components_graph(const Graph& graph, + Face_filtered_graph(const Graph& graph, FaceComponentMap fcmap, typename boost::property_traits::value_type pid, #ifdef DOXYGEN_RUNNING @@ -209,7 +215,7 @@ struct Connected_components_graph } template - Connected_components_graph(const Graph& graph, + Face_filtered_graph(const Graph& graph, FaceComponentMap fcmap, typename boost::property_traits::value_type pid) : _graph(const_cast(graph)) @@ -219,9 +225,9 @@ struct Connected_components_graph himap = get(CGAL::halfedge_index, graph); base_constructor(fcmap, pid); } - ///returns a const reference to the graph of the Connected_components_graph. + ///returns a const reference to the graph of the Face_filtered_graph. const Graph& graph()const{ return _graph; } - ///returns a reference to the graph of the Connected_components_graph. + ///returns a reference to the graph of the Face_filtered_graph. Graph& graph(){ return _graph; } ///change the selected component @@ -233,6 +239,7 @@ struct Connected_components_graph vertex_indices.clear(); halfedge_indices.clear(); base_constructor(fcmap, pid); + CGAL_assertion(is_selection_valid()); } /// change the selected components template @@ -244,6 +251,7 @@ struct Connected_components_graph vertex_indices.clear(); halfedge_indices.clear(); base_iterator_constructor(begin, end, fcmap); + CGAL_assertion(is_selection_valid()); } struct Is_simplex_valid { @@ -277,19 +285,19 @@ struct Connected_components_graph { return halfedge_patch[get(himap, h)]; } - ///returns the number of faces contained in the specified connected components + ///returns the number of faces contained in the specified patches typename boost::graph_traits:: faces_size_type number_of_faces()const { return face_patch.count(); } -///returns the number of vertices contained in the specified connected components +///returns the number of vertices contained in the specified patches typename boost::graph_traits:: vertices_size_type number_of_vertices()const { return vertex_patch.count(); } -///returns the number of halfedges contained in the specified connected components +///returns the number of halfedges contained in the specified patches typename boost::graph_traits:: halfedges_size_type number_of_halfedges()const { @@ -341,6 +349,70 @@ struct Connected_components_graph return bind_property_maps(himap, make_property_map(halfedge_indices) ); } + ///returns true if around each vertex of the `Face_filtered_graph`, + /// there is only one set of selected faces. In other words, returns true + /// if all the selected faces around a vertex are consecutive. + bool is_selection_valid() + { + BOOST_FOREACH(vertex_descriptor vd, vertices(*this) ) + { + face_descriptor first_selected = boost::graph_traits::null_face(); + bool first_unselected_found(false), + second_unselected_found(false); + + //find an unselected face, then find the first selected face. + //Find another unselected face, the next selected face must be the first; + //else this is not valid. + halfedge_descriptor hd = halfedge(vd, _graph); + face_descriptor first_tested = boost::graph_traits::null_face(); + while(1) //will break if valid, return false if not valid + { + face_descriptor fd = face(hd, _graph); + + if(first_tested == boost::graph_traits::null_face()) + first_tested = fd; + else if(fd == first_tested ) + { + //if there is no unselected face, break + if(face_patch[get(fimap, fd)] && !first_unselected_found) + break; + //if there is no selected face, break + else if(!face_patch[get(fimap, fd)] && + first_selected == boost::graph_traits::null_face()) + break; + } + + if(fd != boost::graph_traits::null_face()) + { + if(face_patch[get(fimap, fd)]) + { + if(first_unselected_found && + first_selected == boost::graph_traits::null_face()) + { + first_selected = fd; + } + else if(second_unselected_found) + { + if(fd == first_selected) + break; + else + return false; + } + } + else + { + if(first_selected == boost::graph_traits::null_face()) + first_unselected_found = true; + else + second_unselected_found = true; + } + } + hd = next(opposite(hd, _graph), _graph); + } + } + return true; + } + private: Graph& _graph; FIMap fimap; @@ -363,9 +435,9 @@ template -struct graph_traits< CGAL::Connected_components_graph > +struct graph_traits< CGAL::Face_filtered_graph > { - typedef CGAL::Connected_components_graph G; + typedef CGAL::Face_filtered_graph G; typedef boost::graph_traits BGTG; typedef typename BGTG::vertex_descriptor vertex_descriptor; typedef typename BGTG::halfedge_descriptor halfedge_descriptor; @@ -414,8 +486,8 @@ template -struct graph_traits< const CGAL::Connected_components_graph > - : public graph_traits< CGAL::Connected_components_graph > +struct graph_traits< const CGAL::Face_filtered_graph > + : public graph_traits< CGAL::Face_filtered_graph > {}; @@ -428,8 +500,8 @@ template bool -in_CC(const typename boost::graph_traits< Connected_components_graph >::face_descriptor f, - const Connected_components_graph & w) +in_CC(const typename boost::graph_traits< Face_filtered_graph >::face_descriptor f, + const Face_filtered_graph & w) { return w.is_in_cc(f); } @@ -439,8 +511,8 @@ template bool -in_CC(const typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, - const Connected_components_graph & w) +in_CC(const typename boost::graph_traits< Face_filtered_graph >::halfedge_descriptor h, + const Face_filtered_graph & w) { return w.is_in_cc(h); } @@ -450,8 +522,8 @@ template bool -in_CC(const typename boost::graph_traits< Connected_components_graph >::edge_descriptor e, - const Connected_components_graph & w) +in_CC(const typename boost::graph_traits< Face_filtered_graph >::edge_descriptor e, + const Face_filtered_graph & w) { return w.is_in_cc(halfedge(e, w.graph())); } @@ -461,8 +533,8 @@ template bool -in_CC(const typename boost::graph_traits< Connected_components_graph >::vertex_descriptor v, - const Connected_components_graph & w) +in_CC(const typename boost::graph_traits< Face_filtered_graph >::vertex_descriptor v, + const Face_filtered_graph & w) { return w.is_in_cc(v); } @@ -473,7 +545,7 @@ template typename boost::graph_traits::vertices_size_type -num_vertices(const Connected_components_graph& w) +num_vertices(const Face_filtered_graph& w) { return w.number_of_vertices(); } @@ -483,7 +555,7 @@ template typename boost::graph_traits::edges_size_type -num_edges(const Connected_components_graph& w) +num_edges(const Face_filtered_graph& w) { return w.number_of_halfedges()/2; } @@ -493,13 +565,13 @@ template typename boost::graph_traits::degree_size_type -degree(typename boost::graph_traits >::vertex_descriptor v, - const Connected_components_graph& w) +degree(typename boost::graph_traits >::vertex_descriptor v, + const Face_filtered_graph& w) { CGAL_assertion(in_CC(v, w)); typename boost::graph_traits::degree_size_type v_deg = 0; - typename boost::graph_traits >::halfedge_descriptor h = halfedge(v, w); - typename boost::graph_traits >::halfedge_descriptor hcirc = h; + typename boost::graph_traits >::halfedge_descriptor h = halfedge(v, w); + typename boost::graph_traits >::halfedge_descriptor hcirc = h; do { if(in_CC(hcirc, w)) @@ -514,8 +586,8 @@ template typename boost::graph_traits::degree_size_type -out_degree(typename boost::graph_traits >::vertex_descriptor v, - const Connected_components_graph& w) +out_degree(typename boost::graph_traits >::vertex_descriptor v, + const Face_filtered_graph& w) { CGAL_assertion(in_CC(v, w)); return std::distance(out_edges(v, w).first ,out_edges(v, w).second); @@ -526,8 +598,8 @@ template typename boost::graph_traits::degree_size_type -in_degree(typename boost::graph_traits >::vertex_descriptor v, - const Connected_components_graph& w) +in_degree(typename boost::graph_traits >::vertex_descriptor v, + const Face_filtered_graph& w) { CGAL_assertion(in_CC(v, w)); return std::distance(in_edges(v, w).first ,in_edges(v, w).second); @@ -537,9 +609,9 @@ template -typename boost::graph_traits >::vertex_descriptor -source(typename boost::graph_traits >::edge_descriptor e, - const Connected_components_graph & w) +typename boost::graph_traits >::vertex_descriptor +source(typename boost::graph_traits >::edge_descriptor e, + const Face_filtered_graph & w) { CGAL_assertion(in_CC(e, w)); return source(e, w.graph()); @@ -549,9 +621,9 @@ template -typename boost::graph_traits >::vertex_descriptor -target(typename boost::graph_traits >::edge_descriptor e, - const Connected_components_graph & w) +typename boost::graph_traits >::vertex_descriptor +target(typename boost::graph_traits >::edge_descriptor e, + const Face_filtered_graph & w) { CGAL_assertion(in_CC(e, w)); return target(e, w.graph()); @@ -561,13 +633,13 @@ template -std::pair >::edge_descriptor, bool> -edge(typename boost::graph_traits >::vertex_descriptor u, - typename boost::graph_traits >::vertex_descriptor v, - const Connected_components_graph & w) +std::pair >::edge_descriptor, bool> +edge(typename boost::graph_traits >::vertex_descriptor u, + typename boost::graph_traits >::vertex_descriptor v, + const Face_filtered_graph & w) { CGAL_assertion(in_CC(u, w) && in_CC(v, w)); - typename boost::graph_traits >::edge_descriptor e = edge(u, v, w.graph()).first; + typename boost::graph_traits >::edge_descriptor e = edge(u, v, w.graph()).first; bool res = in_CC(e, w); return std::make_pair(e, res); } @@ -577,13 +649,13 @@ template -CGAL::Iterator_range >::vertex_iterator> -vertices(const Connected_components_graph & w) +CGAL::Iterator_range >::vertex_iterator> +vertices(const Face_filtered_graph & w) { - typedef typename boost::graph_traits >::vertex_iterator vertex_iterator; + typedef typename boost::graph_traits >::vertex_iterator vertex_iterator; typedef typename boost::graph_traits::vertex_iterator g_vertex_iterator; - typename Connected_components_graph ::Is_simplex_valid predicate(&w); + typename Face_filtered_graph ::Is_simplex_valid predicate(&w); g_vertex_iterator b,e; boost::tie(b,e) = vertices(w.graph()); return make_range(vertex_iterator(predicate, b, e), @@ -594,13 +666,13 @@ template -CGAL::Iterator_range >::edge_iterator> -edges(const Connected_components_graph & w) +CGAL::Iterator_range >::edge_iterator> +edges(const Face_filtered_graph & w) { - typedef typename boost::graph_traits >::edge_iterator edge_iterator; + typedef typename boost::graph_traits >::edge_iterator edge_iterator; typedef typename boost::graph_traits::edge_iterator g_edge_iterator; - typename Connected_components_graph ::Is_simplex_valid predicate(&w); + typename Face_filtered_graph ::Is_simplex_valid predicate(&w); g_edge_iterator b,e; boost::tie(b,e) = edges(w.graph()); return make_range(edge_iterator(predicate, b, e), @@ -611,15 +683,15 @@ template -CGAL::Iterator_range >::out_edge_iterator> -out_edges(typename boost::graph_traits >::vertex_descriptor v, - const Connected_components_graph & w) +CGAL::Iterator_range >::out_edge_iterator> +out_edges(typename boost::graph_traits >::vertex_descriptor v, + const Face_filtered_graph & w) { - typedef typename boost::graph_traits >::out_edge_iterator out_edge_iterator; + typedef typename boost::graph_traits >::out_edge_iterator out_edge_iterator; typedef typename boost::graph_traits::out_edge_iterator g_out_edge_iterator; - typename Connected_components_graph ::Is_simplex_valid predicate(&w); + typename Face_filtered_graph ::Is_simplex_valid predicate(&w); g_out_edge_iterator b,e; boost::tie(b,e) = out_edges(v, w.graph()); return make_range(out_edge_iterator(predicate, b, e), @@ -630,15 +702,15 @@ template -CGAL::Iterator_range >::in_edge_iterator> -in_edges(typename boost::graph_traits >::vertex_descriptor v, - const Connected_components_graph & w) +CGAL::Iterator_range >::in_edge_iterator> +in_edges(typename boost::graph_traits >::vertex_descriptor v, + const Face_filtered_graph & w) { - typedef typename boost::graph_traits >::in_edge_iterator in_edge_iterator; + typedef typename boost::graph_traits >::in_edge_iterator in_edge_iterator; typedef typename boost::graph_traits::in_edge_iterator g_in_edge_iterator; - typename Connected_components_graph ::Is_simplex_valid predicate(&w); + typename Face_filtered_graph ::Is_simplex_valid predicate(&w); g_in_edge_iterator b,e; boost::tie(b,e) = in_edges(v, w.graph()); return make_range(in_edge_iterator(predicate, b, e), @@ -652,9 +724,9 @@ template -typename boost::graph_traits< Connected_components_graph >::edge_descriptor -edge(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, - const Connected_components_graph & w) +typename boost::graph_traits< Face_filtered_graph >::edge_descriptor +edge(typename boost::graph_traits< Face_filtered_graph >::halfedge_descriptor h, + const Face_filtered_graph & w) { CGAL_assertion(CGAL::in_CC(h, w)); return edge(h, w.graph()); @@ -664,9 +736,9 @@ template -typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor -halfedge(typename boost::graph_traits< Connected_components_graph >::edge_descriptor e, - const Connected_components_graph & w) +typename boost::graph_traits< Face_filtered_graph >::halfedge_descriptor +halfedge(typename boost::graph_traits< Face_filtered_graph >::edge_descriptor e, + const Face_filtered_graph & w) { CGAL_assertion(CGAL::in_CC(e, w)); return halfedge(e, w.graph()); @@ -676,20 +748,20 @@ template -typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor -halfedge(typename boost::graph_traits< Connected_components_graph >::vertex_descriptor v, - const Connected_components_graph & w) +typename boost::graph_traits< Face_filtered_graph >::halfedge_descriptor +halfedge(typename boost::graph_traits< Face_filtered_graph >::vertex_descriptor v, + const Face_filtered_graph & w) { CGAL_assertion(in_CC(v, w)); - typename boost::graph_traits >::halfedge_descriptor h = halfedge(v, w.graph()); - typename boost::graph_traits >::halfedge_descriptor hcirc = h; + typename boost::graph_traits >::halfedge_descriptor h = halfedge(v, w.graph()); + typename boost::graph_traits >::halfedge_descriptor hcirc = h; do { if(in_CC(hcirc, w)) return hcirc; hcirc = opposite(next(hcirc, w.graph()), w.graph()); }while(hcirc != h); - return boost::graph_traits< CGAL::Connected_components_graph >::null_halfedge(); + return boost::graph_traits< CGAL::Face_filtered_graph >::null_halfedge(); } @@ -697,13 +769,13 @@ template -std::pair >::halfedge_descriptor, bool> -halfedge(typename boost::graph_traits< Connected_components_graph >::vertex_descriptor u, - typename boost::graph_traits< Connected_components_graph >::vertex_descriptor v, - const Connected_components_graph & w) +std::pair >::halfedge_descriptor, bool> +halfedge(typename boost::graph_traits< Face_filtered_graph >::vertex_descriptor u, + typename boost::graph_traits< Face_filtered_graph >::vertex_descriptor v, + const Face_filtered_graph & w) { CGAL_assertion(in_CC(u, w) && in_CC(v, w)); - typename boost::graph_traits >::halfedge_descriptor h = halfedge(u, v, w.graph()).first; + typename boost::graph_traits >::halfedge_descriptor h = halfedge(u, v, w.graph()).first; return std::make_pair(h, in_CC(h, w)); } @@ -712,9 +784,9 @@ template -typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor -opposite(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, - const Connected_components_graph & w) +typename boost::graph_traits< Face_filtered_graph >::halfedge_descriptor +opposite(typename boost::graph_traits< Face_filtered_graph >::halfedge_descriptor h, + const Face_filtered_graph & w) { CGAL_assertion(in_CC(h, w) ); return opposite(h, w.graph()); @@ -724,9 +796,9 @@ template -typename boost::graph_traits< Connected_components_graph >::vertex_descriptor -source(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, - const Connected_components_graph & w) +typename boost::graph_traits< Face_filtered_graph >::vertex_descriptor +source(typename boost::graph_traits< Face_filtered_graph >::halfedge_descriptor h, + const Face_filtered_graph & w) { CGAL_assertion(in_CC(h, w) ); return source(h, w.graph()); @@ -736,9 +808,9 @@ template -typename boost::graph_traits< Connected_components_graph >::vertex_descriptor -target(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, - const Connected_components_graph & w) +typename boost::graph_traits< Face_filtered_graph >::vertex_descriptor +target(typename boost::graph_traits< Face_filtered_graph >::halfedge_descriptor h, + const Face_filtered_graph & w) { CGAL_assertion(in_CC(h, w) ); return target(h, w.graph()); @@ -748,15 +820,15 @@ template -typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor -next(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, - const Connected_components_graph & w) +typename boost::graph_traits< Face_filtered_graph >::halfedge_descriptor +next(typename boost::graph_traits< Face_filtered_graph >::halfedge_descriptor h, + const Face_filtered_graph & w) { CGAL_assertion(in_CC(h, w)); if(in_CC(next(h, w.graph()), w)) return next(h, w.graph()); //act as a border - typedef typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h_d; + typedef typename boost::graph_traits< Face_filtered_graph >::halfedge_descriptor h_d; BOOST_FOREACH( h_d hcirc, CGAL::halfedges_around_target(target(h, w.graph()), w.graph())) { @@ -765,16 +837,16 @@ next(typename boost::graph_traits< Connected_components_graph >::null_halfedge(); + return boost::graph_traits< CGAL::Face_filtered_graph >::null_halfedge(); } template -typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor -prev(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, - const Connected_components_graph & w) +typename boost::graph_traits< Face_filtered_graph >::halfedge_descriptor +prev(typename boost::graph_traits< Face_filtered_graph >::halfedge_descriptor h, + const Face_filtered_graph & w) { CGAL_assertion(in_CC(h, w)); @@ -782,7 +854,7 @@ prev(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h_d; + typedef typename boost::graph_traits< Face_filtered_graph >::halfedge_descriptor h_d; BOOST_FOREACH(h_d hcirc, CGAL::halfedges_around_source(source(h, w.graph()), w.graph())) { @@ -791,7 +863,7 @@ prev(typename boost::graph_traits< Connected_components_graph >::null_halfedge(); + return boost::graph_traits< CGAL::Face_filtered_graph >::null_halfedge(); } // @@ -802,14 +874,14 @@ template -std::pair >::halfedge_iterator, -typename boost::graph_traits >::halfedge_iterator> -halfedges(const Connected_components_graph & w) +std::pair >::halfedge_iterator, +typename boost::graph_traits >::halfedge_iterator> +halfedges(const Face_filtered_graph & w) { - typedef typename boost::graph_traits >::halfedge_iterator halfedge_iterator; + typedef typename boost::graph_traits >::halfedge_iterator halfedge_iterator; typedef typename boost::graph_traits::halfedge_iterator g_halfedge_iterator; - typename Connected_components_graph ::Is_simplex_valid predicate(&w); + typename Face_filtered_graph ::Is_simplex_valid predicate(&w); std::pair original_halfedges = halfedges(w.graph()); return make_range(halfedge_iterator(predicate, original_halfedges.first, original_halfedges.second), @@ -822,7 +894,7 @@ template typename boost::graph_traits::halfedges_size_type -num_halfedges(const Connected_components_graph & w) +num_halfedges(const Face_filtered_graph & w) { return w.number_of_halfedges(); } @@ -832,24 +904,24 @@ template -typename boost::graph_traits< Connected_components_graph >::face_descriptor -face(typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor h, - const Connected_components_graph & w) +typename boost::graph_traits< Face_filtered_graph >::face_descriptor +face(typename boost::graph_traits< Face_filtered_graph >::halfedge_descriptor h, + const Face_filtered_graph & w) { CGAL_assertion(CGAL::in_CC(h, w)); if(in_CC(face(h,w.graph()), w)) return face(h,w.graph()); else - return boost::graph_traits< CGAL::Connected_components_graph >::null_face(); + return boost::graph_traits< CGAL::Face_filtered_graph >::null_face(); } template -typename boost::graph_traits< Connected_components_graph >::halfedge_descriptor -halfedge(typename boost::graph_traits< Connected_components_graph >::face_descriptor f, - const Connected_components_graph & w) +typename boost::graph_traits< Face_filtered_graph >::halfedge_descriptor +halfedge(typename boost::graph_traits< Face_filtered_graph >::face_descriptor f, + const Face_filtered_graph & w) { CGAL_assertion(CGAL::in_CC(f, w)); return halfedge(f,w.graph()); @@ -860,13 +932,13 @@ template -Iterator_range >::face_iterator> -faces(const Connected_components_graph & w) +Iterator_range >::face_iterator> +faces(const Face_filtered_graph & w) { - typedef typename boost::graph_traits >::face_iterator face_iterator; + typedef typename boost::graph_traits >::face_iterator face_iterator; typedef typename boost::graph_traits::face_iterator g_face_iterator; - typename Connected_components_graph ::Is_simplex_valid predicate(&w); + typename Face_filtered_graph ::Is_simplex_valid predicate(&w); std::pair original_faces = faces(w.graph()); return make_range(face_iterator(predicate, original_faces.first, original_faces.second), @@ -880,7 +952,7 @@ template typename boost::graph_traits::vertices_size_type -num_faces(const Connected_components_graph & w) +num_faces(const Face_filtered_graph & w) { return w.number_of_faces(); } @@ -891,7 +963,7 @@ template bool -in_CC(const Connected_components_graph & w, bool verbose = false) +in_CC(const Face_filtered_graph & w, bool verbose = false) { return in_CC(w.graph(),verbose); } @@ -902,7 +974,7 @@ template typename boost::property_map::const_type -get(PropertyTag ptag, const Connected_components_graph& w) +get(PropertyTag ptag, const Face_filtered_graph& w) { return get(ptag, w.graph()); } @@ -913,7 +985,7 @@ template typename boost::property_map::type -get(PropertyTag ptag, Connected_components_graph& w) +get(PropertyTag ptag, Face_filtered_graph& w) { return get(ptag, w.graph()); } @@ -923,8 +995,8 @@ template -typename boost::property_map, CGAL::face_index_t >::type -get(CGAL::face_index_t, const Connected_components_graph& w) +typename boost::property_map, CGAL::face_index_t >::type +get(CGAL::face_index_t, const Face_filtered_graph& w) { return w.get_face_index_map(); } @@ -934,8 +1006,8 @@ template -typename boost::property_map, boost::vertex_index_t >::type -get(boost::vertex_index_t, const Connected_components_graph& w) +typename boost::property_map, boost::vertex_index_t >::type +get(boost::vertex_index_t, const Face_filtered_graph& w) { return w.get_vertex_index_map(); } @@ -945,8 +1017,8 @@ template -typename boost::property_map, CGAL::halfedge_index_t >::type -get(CGAL::halfedge_index_t, const Connected_components_graph& w) +typename boost::property_map, CGAL::halfedge_index_t >::type +get(CGAL::halfedge_index_t, const Face_filtered_graph& w) { return w.get_halfedge_index_map(); } @@ -959,7 +1031,7 @@ template typename boost::property_traits::type>::value_type get(PropertyTag ptag, - const Connected_components_graph& w, + const Face_filtered_graph& w, const typename boost::property_traits::type>::key_type& k) { return get(ptag, w.graph(), k); @@ -972,7 +1044,7 @@ template void -put(PropertyTag ptag, const Connected_components_graph& w, +put(PropertyTag ptag, const Face_filtered_graph& w, const typename boost::property_traits::type>::key_type& k, typename boost::property_traits::type>::value_type& v) { @@ -987,7 +1059,7 @@ template -struct property_map,PropertyTag> { +struct property_map,PropertyTag> { typedef typename boost::property_map::type type; typedef typename boost::property_map::const_type const_type; }; @@ -997,7 +1069,7 @@ template -struct graph_has_property, PropertyTag> +struct graph_has_property, PropertyTag> : graph_has_property {}; @@ -1006,7 +1078,7 @@ template -struct property_map, CGAL::face_index_t>{ +struct property_map, CGAL::face_index_t>{ typedef typename CGAL::Property_map_binder< FIMap, typename CGAL::Pointer_property_map< typename boost::property_traits< FIMap >::value_type >::type > type; typedef type const_type; @@ -1016,7 +1088,7 @@ template -struct property_map, boost::vertex_index_t>{ +struct property_map, boost::vertex_index_t>{ typedef typename CGAL::Property_map_binder< VIMap, typename CGAL::Pointer_property_map< typename boost::property_traits< VIMap >::value_type >::type > type; typedef type const_type; @@ -1027,10 +1099,10 @@ template -struct property_map, CGAL::halfedge_index_t>{ +struct property_map, CGAL::halfedge_index_t>{ typedef typename CGAL::Property_map_binder< HIMap, typename CGAL::Pointer_property_map< typename boost::property_traits< HIMap >::value_type >::type > type; typedef type const_type; }; }// namespace boost -#endif // CGAL_BOOST_GRAPH_CONNECTED_COMPONENTS_GRAPH_H +#endif // CGAL_BOOST_GRAPH_FACE_FILTERED_GRAPH_H diff --git a/BGL/test/BGL/CMakeLists.txt b/BGL/test/BGL/CMakeLists.txt index 29beb28785f..8f68e5469d1 100644 --- a/BGL/test/BGL/CMakeLists.txt +++ b/BGL/test/BGL/CMakeLists.txt @@ -87,9 +87,9 @@ create_single_source_cgal_program( "test_Has_member_id.cpp" ) create_single_source_cgal_program( "test_cgal_bgl_named_params.cpp" ) -create_single_source_cgal_program( "test_Connected_components_graph.cpp" ) +create_single_source_cgal_program( "test_Face_filtered_graph.cpp" ) -create_single_source_cgal_program( "graph_concept_Connected_components_graph.cpp" ) +create_single_source_cgal_program( "graph_concept_Face_filtered_graph.cpp" ) diff --git a/BGL/test/BGL/graph_concept_Connected_components_graph.cpp b/BGL/test/BGL/graph_concept_Face_filtered_graph.cpp similarity index 91% rename from BGL/test/BGL/graph_concept_Connected_components_graph.cpp rename to BGL/test/BGL/graph_concept_Face_filtered_graph.cpp index 5db6f9a4ab1..ab8957bfb60 100644 --- a/BGL/test/BGL/graph_concept_Connected_components_graph.cpp +++ b/BGL/test/BGL/graph_concept_Face_filtered_graph.cpp @@ -1,6 +1,6 @@ #include -#include +#include #include #include @@ -8,7 +8,7 @@ typedef CGAL::Simple_cartesian K; typedef CGAL::Surface_mesh SM; -typedef CGAL::Connected_components_graph::face_descriptor , std::size_t> > Adapter; +typedef CGAL::Face_filtered_graph::face_descriptor , std::size_t> > Adapter; typedef boost::graph_traits< Adapter > Traits; typedef Traits::edge_descriptor edge_descriptor; typedef Traits::halfedge_descriptor halfedge_descriptor; diff --git a/BGL/test/BGL/test_Connected_components_graph.cpp b/BGL/test/BGL/test_Face_filtered_graph.cpp similarity index 95% rename from BGL/test/BGL/test_Connected_components_graph.cpp rename to BGL/test/BGL/test_Face_filtered_graph.cpp index eb558dce7ca..9bc178a70a7 100644 --- a/BGL/test/BGL/test_Connected_components_graph.cpp +++ b/BGL/test/BGL/test_Face_filtered_graph.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include #include "test_Prefix.h" @@ -15,7 +15,7 @@ template void test_halfedge_around_vertex_iterator(const Graph& g) { typedef typename boost::graph_traits::face_descriptor g_face_descriptor; - typedef CGAL::Connected_components_graph Adapter; + typedef CGAL::Face_filtered_graph Adapter; CGAL_GRAPH_TRAITS_MEMBERS(Adapter); boost::unordered_map map(CGAL::num_faces(g)); CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); @@ -43,7 +43,7 @@ template void test_halfedge_around_face_iterator(const Graph& g) { typedef typename boost::graph_traits::face_descriptor g_face_descriptor; - typedef CGAL::Connected_components_graph Adapter; + typedef CGAL::Face_filtered_graph Adapter; CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); @@ -63,7 +63,7 @@ template void test_edge_iterators(const Graph& g) { typedef typename boost::graph_traits::face_descriptor g_face_descriptor; - typedef CGAL::Connected_components_graph Adapter; + typedef CGAL::Face_filtered_graph Adapter; CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); @@ -89,7 +89,7 @@ template void test_vertex_iterators(Graph& g) { typedef typename boost::graph_traits::face_descriptor g_face_descriptor; - typedef CGAL::Connected_components_graph Adapter; + typedef CGAL::Face_filtered_graph Adapter; CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); @@ -119,7 +119,7 @@ template void test_out_edges(const Graph& g) { typedef typename boost::graph_traits::face_descriptor g_face_descriptor; - typedef CGAL::Connected_components_graph Adapter; + typedef CGAL::Face_filtered_graph Adapter; CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); @@ -148,7 +148,7 @@ template void test_in_edges(const Graph& g) { typedef typename boost::graph_traits::face_descriptor g_face_descriptor; - typedef CGAL::Connected_components_graph Adapter; + typedef CGAL::Face_filtered_graph Adapter; CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); @@ -175,7 +175,7 @@ template void test_in_out_edges(const Graph& g) { typedef typename boost::graph_traits::face_descriptor g_face_descriptor; - typedef CGAL::Connected_components_graph Adapter; + typedef CGAL::Face_filtered_graph Adapter; CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); @@ -217,7 +217,7 @@ template void test_edge_find(const Graph& g) { typedef typename boost::graph_traits::face_descriptor g_face_descriptor; - typedef CGAL::Connected_components_graph Adapter; + typedef CGAL::Face_filtered_graph Adapter; CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); @@ -241,7 +241,7 @@ template void test_faces(const Graph& g) { typedef typename boost::graph_traits::face_descriptor g_face_descriptor; - typedef CGAL::Connected_components_graph Adapter; + typedef CGAL::Face_filtered_graph Adapter; CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); @@ -267,7 +267,7 @@ template void test_read(const Graph& g) { typedef typename boost::graph_traits::face_descriptor g_face_descriptor; - typedef CGAL::Connected_components_graph Adapter; + typedef CGAL::Face_filtered_graph Adapter; CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); @@ -397,10 +397,9 @@ void test_mesh(Adapter fga) int main() { - test(sm_data()); //Make a tetrahedron and test the adapter for a patch that only contains 2 faces - typedef typename CGAL::Connected_components_graph SM_Adapter; + typedef typename CGAL::Face_filtered_graph SM_Adapter; typedef SM::Property_map::face_descriptor , std::size_t> SM_FCCMap; SM* sm = new SM(); CGAL::make_tetrahedron( @@ -433,7 +432,7 @@ main() typedef boost::property_map::type FIMap; typedef boost::property_map::type VIMap; typedef boost::property_map::type HIMap; - typedef typename CGAL::Connected_components_graph Poly_Adapter; + typedef typename CGAL::Face_filtered_graph Poly_Adapter; Polyhedron *poly = new Polyhedron(); CGAL::make_tetrahedron( Point_3(1,1,1), diff --git a/Installation/changes.html b/Installation/changes.html index 90a702237ad..f333407b38d 100644 --- a/Installation/changes.html +++ b/Installation/changes.html @@ -181,7 +181,7 @@ and src/ directories).

CGAL and the Boost Graph Library (BGL)

  • - Add class CGAL::Connected_components_graph that + Add class CGAL::Face_filtered_graph that wraps an existing graph and hide all simplices that are not in the selected connected components.
  • diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt index 07c73d381ad..c87dd1a0a3e 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt @@ -607,10 +607,10 @@ the propagation of a connected component index to cross it. \cgalExample{Polygon_mesh_processing/connected_components_example.cpp} -The second example shows how to use the class template `Connected_components_graph` +The second example shows how to use the class template `Face_filtered_graph` which enables to treat one or several connected components as a face graph. -\cgalExample{Polygon_mesh_processing/connected_components_graph_example.cpp} +\cgalExample{Polygon_mesh_processing/face_filtered_graph_example.cpp} \section PMPDistance Approximate Hausdorff Distance diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt index ce29168f6d2..3c535ae0ccf 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt @@ -7,7 +7,7 @@ \example Polygon_mesh_processing/point_inside_example.cpp \example Polygon_mesh_processing/triangulate_faces_example.cpp \example Polygon_mesh_processing/connected_components_example.cpp -\example Polygon_mesh_processing/connected_components_graph_example.cpp +\example Polygon_mesh_processing/filtered_face_graph_example.cpp \example Polygon_mesh_processing/polygon_soup_example.cpp \example Polygon_mesh_processing/triangulate_polyline_example.cpp \example Polygon_mesh_processing/refine_fair_example.cpp diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt b/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt index 32d5286cd26..f45f1a02ba4 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt @@ -90,7 +90,7 @@ create_single_source_cgal_program( "compute_normals_example.cpp" CXX_FEATURES cx create_single_source_cgal_program( "point_inside_example.cpp") create_single_source_cgal_program( "triangulate_faces_example.cpp") create_single_source_cgal_program( "connected_components_example.cpp") -create_single_source_cgal_program( "connected_components_graph_example.cpp") +create_single_source_cgal_program( "face_filtered_graph_example.cpp") create_single_source_cgal_program( "polygon_soup_example.cpp") create_single_source_cgal_program( "triangulate_polyline_example.cpp") create_single_source_cgal_program( "mesh_slicer_example.cpp") diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/connected_components_graph_example.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/face_filtered_graph_example.cpp similarity index 94% rename from Polygon_mesh_processing/examples/Polygon_mesh_processing/connected_components_graph_example.cpp rename to Polygon_mesh_processing/examples/Polygon_mesh_processing/face_filtered_graph_example.cpp index b26bd1aaf90..62ee6c33d28 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/connected_components_graph_example.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/face_filtered_graph_example.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include @@ -18,7 +18,7 @@ typedef boost::graph_traits::face_descriptor face_descriptor; typedef boost::graph_traits::faces_size_type faces_size_type; typedef Mesh::Property_map FCCmap; - typedef CGAL::Connected_components_graph CCG; + typedef CGAL::Face_filtered_graph CCG; namespace PMP = CGAL::Polygon_mesh_processing; diff --git a/Surface_mesh_segmentation/examples/Surface_mesh_segmentation/extract_segmentation_into_mesh_example.cpp b/Surface_mesh_segmentation/examples/Surface_mesh_segmentation/extract_segmentation_into_mesh_example.cpp index 37ab72c7b97..806f3bb3c71 100644 --- a/Surface_mesh_segmentation/examples/Surface_mesh_segmentation/extract_segmentation_into_mesh_example.cpp +++ b/Surface_mesh_segmentation/examples/Surface_mesh_segmentation/extract_segmentation_into_mesh_example.cpp @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include #include #include @@ -38,7 +38,7 @@ int main(int argc, char** argv ) // Any other scalar values can be used instead of using SDF values computed using the CGAL function std::size_t number_of_segments = CGAL::segmentation_from_sdf_values(mesh, sdf_property_map, segment_property_map); - typedef CGAL::Connected_components_graph Cc_graph; + typedef CGAL::Face_filtered_graph Cc_graph; //print area of each segment and then put it in a Mesh and print it in an OFF file Cc_graph segment_mesh(mesh, segment_property_map, 0); for(std::size_t id = 0; id < number_of_segments; ++id) From 3ab2f10997fadb58050472436c1de703bc222b0e Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 12 May 2017 14:04:19 +0200 Subject: [PATCH 22/38] replace remaining 'componant' by 'patch' --- .../CGAL/boost/graph/Face_filtered_graph.h | 54 +++++++++---------- .../face_filtered_graph_example.cpp | 2 +- ...extract_segmentation_into_mesh_example.cpp | 2 +- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/BGL/include/CGAL/boost/graph/Face_filtered_graph.h b/BGL/include/CGAL/boost/graph/Face_filtered_graph.h index 53e38049f28..e703ca9dda0 100644 --- a/BGL/include/CGAL/boost/graph/Face_filtered_graph.h +++ b/BGL/include/CGAL/boost/graph/Face_filtered_graph.h @@ -40,7 +40,7 @@ namespace CGAL * The class `Face_filtered_graph` wraps a graph into another graph and act like a mask. It assigns a patch id to each face * and acts in such a way that only the specified patches are seen from the outside. * - * For example, calling `vertices(graph)` will provide the range of vertices belonging to the selected components. + * For example, calling `vertices(graph)` will provide the range of vertices belonging to the selected patches. * * The `Face_filtered_graph` enables to either consider each patch independently or a union of some of these patches. * Such a union of patches must define a manifold mesh. @@ -69,15 +69,15 @@ struct Face_filtered_graph typedef typename boost::property_traits< HIMap >::value_type halfedge_index_type; typedef Face_filtered_graph Self; - template + template void base_iterator_constructor(IndexRangeIterator begin, IndexRangeIterator end, - FaceComponentMap fcmap) + FacePatchMap fcmap) { face_patch.resize(num_faces(_graph)); vertex_patch.resize(num_vertices(_graph)); halfedge_patch.resize(num_halfedges(_graph)); - boost::unordered_set::value_type> pids; + boost::unordered_set::value_type> pids; for(IndexRangeIterator it = begin; it != end; ++it) @@ -101,9 +101,9 @@ struct Face_filtered_graph CGAL_assertion(is_selection_valid()); } - template - void base_constructor(FaceComponentMap fcmap, - typename boost::property_traits::value_type pid) + template + void base_constructor(FacePatchMap fcmap, + typename boost::property_traits::value_type pid) { face_patch.resize(num_faces(_graph)); vertex_patch.resize(num_vertices(_graph)); @@ -126,10 +126,10 @@ struct Face_filtered_graph /*! * \brief Creates a Face_filtered_graph of the patches of `graph` specified in the range * defined by `begin` and `end`. - * \tparam FaceComponentMap a model of `ReadablePropertyMap` with + * \tparam FacePatchMap a model of `ReadablePropertyMap` with `boost::graph_traits::%face_descriptor` as key type and `graph_traits::%faces_size_type` as value type. - * \tparam IndexRangeIterator an iterator of a range of `boost::property_traits::%value_type`. + * \tparam IndexRangeIterator an iterator of a range of `boost::property_traits::%value_type`. * \param graph the graph containing the wanted patches. * \param fcmap the property_map that assigns a patch to each face, with @@ -145,9 +145,9 @@ struct Face_filtered_graph * with boost::graph_traits::%halfedge_descriptor as key type and boost::graph_traits::%halfedges_size_type as value type */ - template + template Face_filtered_graph(const Graph& graph, - FaceComponentMap fcmap, + FacePatchMap fcmap, IndexRangeIterator begin, IndexRangeIterator end, #ifdef DOXYGEN_RUNNING @@ -165,9 +165,9 @@ struct Face_filtered_graph base_iterator_constructor(begin, end, fcmap); } - template + template Face_filtered_graph(const Graph& graph, - FaceComponentMap fcmap, + FacePatchMap fcmap, IndexRangeIterator begin, IndexRangeIterator end) : _graph(const_cast(graph)) @@ -180,7 +180,7 @@ struct Face_filtered_graph /*! * \brief Creates a Face_filtered_graph of the patch `pid` of `graph`. * - * \tparam FaceComponentMap a model of `ReadablePropertyMap` with + * \tparam FacePatchMap a model of `ReadablePropertyMap` with `boost::graph_traits::%face_descriptor` as key type and `graph_traits::%faces_size_type` as value type. * \param graph the graph containing the wanted patch. @@ -195,10 +195,10 @@ struct Face_filtered_graph * \param himap the property map that assigns an index to each halfedge, * with boost::graph_traits::%halfedge_descriptor as key type and boost::graph_traits::%halfedges_size_type as value type */ - template + template Face_filtered_graph(const Graph& graph, - FaceComponentMap fcmap, - typename boost::property_traits::value_type pid, + FacePatchMap fcmap, + typename boost::property_traits::value_type pid, #ifdef DOXYGEN_RUNNING FIMap fimap = get(CGAL::face_index, graph), VIMap vimap = get(boost::vertex_index, graph), @@ -214,10 +214,10 @@ struct Face_filtered_graph base_constructor(fcmap, pid); } - template + template Face_filtered_graph(const Graph& graph, - FaceComponentMap fcmap, - typename boost::property_traits::value_type pid) + FacePatchMap fcmap, + typename boost::property_traits::value_type pid) : _graph(const_cast(graph)) { fimap = get(CGAL::face_index, graph); @@ -230,10 +230,10 @@ struct Face_filtered_graph ///returns a reference to the graph of the Face_filtered_graph. Graph& graph(){ return _graph; } - ///change the selected component - template - void set_selected_component(FaceComponentMap fcmap, - typename boost::property_traits::value_type pid) + ///change the selected patch + template + void set_selected_patch(FacePatchMap fcmap, + typename boost::property_traits::value_type pid) { face_indices.clear(); vertex_indices.clear(); @@ -241,9 +241,9 @@ struct Face_filtered_graph base_constructor(fcmap, pid); CGAL_assertion(is_selection_valid()); } - /// change the selected components - template - void set_selected_components(FaceComponentMap fcmap, + /// change the selected patches + template + void set_selected_patches(FacePatchMap fcmap, IndexRangeIterator begin, IndexRangeIterator end) { diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/face_filtered_graph_example.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/face_filtered_graph_example.cpp index 62ee6c33d28..5cb2adc4909 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/face_filtered_graph_example.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/face_filtered_graph_example.cpp @@ -51,7 +51,7 @@ int main(int argc, char* argv[]) components.push_back(0); components.push_back(1); - ccg.set_selected_components(fccmap,components.begin(), components.end()); + ccg.set_selected_patches(fccmap,components.begin(), components.end()); std::cout << "The faces in components 0 and 1 are:" << std::endl; BOOST_FOREACH(CCG::face_descriptor f, faces(ccg)){ diff --git a/Surface_mesh_segmentation/examples/Surface_mesh_segmentation/extract_segmentation_into_mesh_example.cpp b/Surface_mesh_segmentation/examples/Surface_mesh_segmentation/extract_segmentation_into_mesh_example.cpp index 806f3bb3c71..ffaf7da11be 100644 --- a/Surface_mesh_segmentation/examples/Surface_mesh_segmentation/extract_segmentation_into_mesh_example.cpp +++ b/Surface_mesh_segmentation/examples/Surface_mesh_segmentation/extract_segmentation_into_mesh_example.cpp @@ -44,7 +44,7 @@ int main(int argc, char** argv ) for(std::size_t id = 0; id < number_of_segments; ++id) { if(id > 0) - segment_mesh.set_selected_component(segment_property_map, id); + segment_mesh.set_selected_patch(segment_property_map, id); std::cout << "Segment "< Date: Wed, 17 May 2017 10:51:28 +0200 Subject: [PATCH 23/38] import API and documentation --- .../CGAL/boost/graph/Face_filtered_graph.h | 159 ++++++++++++------ .../face_filtered_graph_example.cpp | 2 +- ...extract_segmentation_into_mesh_example.cpp | 2 +- 3 files changed, 113 insertions(+), 50 deletions(-) diff --git a/BGL/include/CGAL/boost/graph/Face_filtered_graph.h b/BGL/include/CGAL/boost/graph/Face_filtered_graph.h index e703ca9dda0..9ecfb545f59 100644 --- a/BGL/include/CGAL/boost/graph/Face_filtered_graph.h +++ b/BGL/include/CGAL/boost/graph/Face_filtered_graph.h @@ -16,6 +16,7 @@ // // // Author(s) : Maxime Gimeno + #ifndef CGAL_BOOST_GRAPH_FACE_FILTERED_GRAPH_H #define CGAL_BOOST_GRAPH_FACE_FILTERED_GRAPH_H @@ -37,21 +38,33 @@ namespace CGAL /*! * \ingroup PkgBGLHelper * - * The class `Face_filtered_graph` wraps a graph into another graph and act like a mask. It assigns a patch id to each face - * and acts in such a way that only the specified patches are seen from the outside. + * The class `Face_filtered_graph` is an adaptor that creates a filtered view of a graph + * by restricting it to a subset of faces. Contrary to + * boost::filtered_graph, + * this class only requires a way to access the selected faces and will automatically select the + * edges/halfedges and vertices present in the adapted graph. A vertex is selected if it is incident to at least one + * selected face. A edge is selected if it is incident to at least a selected face. A halfedge is selected if its edge + * is selected. * - * For example, calling `vertices(graph)` will provide the range of vertices belonging to the selected patches. + * Since this class is a model of the `FaceGraph` concept, there is a restriction on the set of selected faces: + * the adapted graph must define a manifold mesh. In order to check that this condition is verified, you can + * use the function `is_selection_valid()`. * - * The `Face_filtered_graph` enables to either consider each patch independently or a union of some of these patches. - * Such a union of patches must define a manifold mesh. + * There are two different ways to initialize this class. You can directly provide the set of faces selected, or + * if you have a face patch map, select the patches of faces. The latter option is convenient if you want to access + * some connected components of a graph after having called `CGAL::Polygon_mesh_processing::connected_components()`. * - * \tparam Graph must be a model of a `FaceListGraph` and `HalfedgeListGraph`. - * \tparam FIMap a model of `ReadablePropertyMap` with `boost::graph_traits::%face_descriptor` as key and `graph_traits::%faces_size_type` as value - * \tparam VIMap a model of `ReadablePropertyMap` with `boost::graph_traits::%vertex_descriptor` as key and `graph_traits::%vertices_size_type` as value - * \tparam HIMap a model of `ReadablePropertyMap` with `boost::graph_traits::%halfedge_descriptor` as key and `graph_traits::%halfedges_size_type` as value + * The documented interface of this class is limited on purpose and free functions of the concept + * this class is a model of must be used to manipulate it. + * + * \tparam Graph must be a model of a `FaceListGraph`, `HalfedgeListGraph`, and VertexListGraph. + * \tparam FIMap a model of `ReadablePropertyMap` with `face_descriptor` as key and `graph_traits::%faces_size_type` as value + * \tparam VIMap a model of `ReadablePropertyMap` with `vertex_descriptor` as key and `graph_traits::%vertices_size_type` as value + * \tparam HIMap a model of `ReadablePropertyMap` with `halfedge_descriptor` as key and `graph_traits::%halfedges_size_type` as value * * \cgalModels `FaceListGraph` * \cgalModels `HalfedgeListGraph` + * \cgalModels VertexListGraph */ template::type, @@ -60,15 +73,22 @@ template gt; - typedef typename gt::vertex_descriptor vertex_descriptor; - typedef typename gt::halfedge_descriptor halfedge_descriptor; - typedef typename gt::edge_descriptor edge_descriptor; - typedef typename gt::face_descriptor face_descriptor; + /// Vertex descriptor type + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + /// Halfedge descriptor type + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + /// Edge descriptor type + typedef typename boost::graph_traits::edge_descriptor edge_descriptor; + /// Face descriptor type + typedef typename boost::graph_traits::face_descriptor face_descriptor; + + // non documented types typedef typename boost::property_traits< FIMap >::value_type face_index_type; typedef typename boost::property_traits< VIMap >::value_type vertex_index_type; typedef typename boost::property_traits< HIMap >::value_type halfedge_index_type; typedef Face_filtered_graph Self; +private: template void base_iterator_constructor(IndexRangeIterator begin, IndexRangeIterator end, @@ -123,28 +143,29 @@ struct Face_filtered_graph } CGAL_assertion(is_selection_valid()); } + +public: /*! - * \brief Creates a Face_filtered_graph of the patches of `graph` specified in the range - * defined by `begin` and `end`. + * \brief Constructor where the set of selected faces is specified as a range of patch ids. + * * \tparam FacePatchMap a model of `ReadablePropertyMap` with - `boost::graph_traits::%face_descriptor` as key type and + `face_descriptor` as key type and `graph_traits::%faces_size_type` as value type. * \tparam IndexRangeIterator an iterator of a range of `boost::property_traits::%value_type`. - - * \param graph the graph containing the wanted patches. - * \param fcmap the property_map that assigns a patch to each face, with - `boost::graph_traits::%face_descriptor` as key type and - `graph_traits::%faces_size_type` as value type. + * \note the index maps must be initialized from `0` to the number of simplices. + * + * \param graph the underlying graph. + * \param fcmap the property_map that assigns a patch index to each face, with + `face_descriptor` as key type and `boost::graph_traits::%faces_size_type` as value type. * \param begin an interator to the beginning of a range of patches indices of interest. * \param end an interator to the element past the end of a range of patches indices of interest. * \param fimap the property map that assigns an index to each face, - * with boost::graph_traits::%face_descriptor as key type and boost::graph_traits::%faces_size_type as value type + * with `face_descriptor` as key type and `boost::graph_traits::%faces_size_type` as value type * \param vimap the property map that assigns an index to each vertex, - * with boost::graph_traits::%vertex_descriptor as key type and boost::graph_traits::%vertices_size_type as value type + * with `vertex_descriptor` as key type and `boost::graph_traits::%vertices_size_type` as value type * \param himap the property map that assigns an index to each halfedge, - * with boost::graph_traits::%halfedge_descriptor as key type and boost::graph_traits::%halfedges_size_type as value type + * with `halfedge_descriptor` as key type and `boost::graph_traits::%halfedges_size_type` as value type */ - template Face_filtered_graph(const Graph& graph, FacePatchMap fcmap, @@ -178,22 +199,23 @@ struct Face_filtered_graph base_iterator_constructor(begin, end, fcmap); } /*! - * \brief Creates a Face_filtered_graph of the patch `pid` of `graph`. + * \brief Constructor where the set of selected faces is specified as a patch id. * * \tparam FacePatchMap a model of `ReadablePropertyMap` with - `boost::graph_traits::%face_descriptor` as key type and + `face_descriptor` as key type and `graph_traits::%faces_size_type` as value type. - * \param graph the graph containing the wanted patch. - * \param fcmap the property_map that assigns a patch's index to each face, with - `boost::graph_traits::%face_descriptor` as key type and + * \note the index maps must be initialized from `0` to the number of simplices. + * \param graph the underlying graph. + * \param fcmap the property_map that assigns a patch index to each face, with + `face_descriptor` as key type and `graph_traits::%faces_size_type` as value type. * \param pid the index of the patch of interest. * \param fimap the property map that assigns an index to each face, - * with boost::graph_traits::%face_descriptor as key type and boost::graph_traits::%faces_size_type as value type + * with `face_descriptor` as key type and `boost::graph_traits::%faces_size_type` as value type * \param vimap the property map that assigns an index to each vertex, - * with boost::graph_traits::%vertex_descriptor as key type and boost::graph_traits::%vertices_size_type as value type + * with `vertex_descriptor` as key type and `boost::graph_traits::%vertices_size_type` as value type * \param himap the property map that assigns an index to each halfedge, - * with boost::graph_traits::%halfedge_descriptor as key type and boost::graph_traits::%halfedges_size_type as value type + * with `halfedge_descriptor` as key type and `boost::graph_traits::%halfedges_size_type` as value type */ template Face_filtered_graph(const Graph& graph, @@ -225,15 +247,52 @@ struct Face_filtered_graph himap = get(CGAL::halfedge_index, graph); base_constructor(fcmap, pid); } - ///returns a const reference to the graph of the Face_filtered_graph. + + /*! + * \brief Constructor where the set of selected faces is specified as a range of face descriptors. + * + * \tparam FaceRange a model of `ConstRange` with `face_descriptor` as value type. + * \note the index maps must be initialized from `0` to the number of simplices. + * \param graph the graph containing the wanted patch. + * \param selected_face_range the set of selected faces. + * \param fimap the property map that assigns an index to each face, + * with `face_descriptor` as key type and `boost::graph_traits::%faces_size_type` as value type + * \param vimap the property map that assigns an index to each vertex, + * with `vertex_descriptor` as key type and `boost::graph_traits::%vertices_size_type` as value type + * \param himap the property map that assigns an index to each halfedge, + * with `halfedge_descriptor` as key type and `boost::graph_traits::%halfedges_size_type` as value type + */ + template + Face_filtered_graph(const Graph& graph, + const FaceRange& selected_face_range, + #ifdef DOXYGEN_RUNNING + FIMap fimap = get(CGAL::face_index, graph), + VIMap vimap = get(boost::vertex_index, graph), + HIMap himap = get(CGAL::halfedge_index, graph) + #else + FIMap fimap, + VIMap vimap, + HIMap himap + #endif + ) : _graph(const_cast(graph)), fimap(fimap), vimap(vimap), himap(himap) + { + set_selected_faces(selected_face_range); + } + + template + Face_filtered_graph(const Graph& graph, + const FaceRange& face_range); + + + ///returns a const reference to the underlying graph. const Graph& graph()const{ return _graph; } - ///returns a reference to the graph of the Face_filtered_graph. + ///returns a reference to the underlying graph. Graph& graph(){ return _graph; } - ///change the selected patch + ///change the set of selected faces using a patch id template - void set_selected_patch(FacePatchMap fcmap, - typename boost::property_traits::value_type pid) + void set_selected_faces(FacePatchMap fcmap, + typename boost::property_traits::value_type pid) { face_indices.clear(); vertex_indices.clear(); @@ -241,11 +300,11 @@ struct Face_filtered_graph base_constructor(fcmap, pid); CGAL_assertion(is_selection_valid()); } - /// change the selected patches + /// change the set of selected faces using a range of patch ids template - void set_selected_patches(FacePatchMap fcmap, - IndexRangeIterator begin, - IndexRangeIterator end) + void set_selected_faces(FacePatchMap fcmap, + IndexRangeIterator begin, + IndexRangeIterator end) { face_indices.clear(); vertex_indices.clear(); @@ -253,6 +312,11 @@ struct Face_filtered_graph base_iterator_constructor(begin, end, fcmap); CGAL_assertion(is_selection_valid()); } + /// change the set of selected faces using a range of face descriptors + /// \todo implement me + template + void set_selected_faces(FaceRange selected_face_range); + struct Is_simplex_valid { Is_simplex_valid(const Self* graph) @@ -285,19 +349,19 @@ struct Face_filtered_graph { return halfedge_patch[get(himap, h)]; } - ///returns the number of faces contained in the specified patches + ///returns the number of selected faces typename boost::graph_traits:: faces_size_type number_of_faces()const { return face_patch.count(); } -///returns the number of vertices contained in the specified patches +///returns the number of selected vertices. typename boost::graph_traits:: vertices_size_type number_of_vertices()const { return vertex_patch.count(); } -///returns the number of halfedges contained in the specified patches +///returns the number of selected halfedges. typename boost::graph_traits:: halfedges_size_type number_of_halfedges()const { @@ -349,9 +413,8 @@ struct Face_filtered_graph return bind_property_maps(himap, make_property_map(halfedge_indices) ); } - ///returns true if around each vertex of the `Face_filtered_graph`, - /// there is only one set of selected faces. In other words, returns true - /// if all the selected faces around a vertex are consecutive. + /// returns `true` if around any vertex of a selected face, + /// there is at most one connected set of selected faces. bool is_selection_valid() { BOOST_FOREACH(vertex_descriptor vd, vertices(*this) ) diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/face_filtered_graph_example.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/face_filtered_graph_example.cpp index 5cb2adc4909..4d2baf09517 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/face_filtered_graph_example.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/face_filtered_graph_example.cpp @@ -51,7 +51,7 @@ int main(int argc, char* argv[]) components.push_back(0); components.push_back(1); - ccg.set_selected_patches(fccmap,components.begin(), components.end()); + ccg.set_selected_faces(fccmap,components.begin(), components.end()); std::cout << "The faces in components 0 and 1 are:" << std::endl; BOOST_FOREACH(CCG::face_descriptor f, faces(ccg)){ diff --git a/Surface_mesh_segmentation/examples/Surface_mesh_segmentation/extract_segmentation_into_mesh_example.cpp b/Surface_mesh_segmentation/examples/Surface_mesh_segmentation/extract_segmentation_into_mesh_example.cpp index ffaf7da11be..c8194e60ea7 100644 --- a/Surface_mesh_segmentation/examples/Surface_mesh_segmentation/extract_segmentation_into_mesh_example.cpp +++ b/Surface_mesh_segmentation/examples/Surface_mesh_segmentation/extract_segmentation_into_mesh_example.cpp @@ -44,7 +44,7 @@ int main(int argc, char** argv ) for(std::size_t id = 0; id < number_of_segments; ++id) { if(id > 0) - segment_mesh.set_selected_patch(segment_property_map, id); + segment_mesh.set_selected_faces(segment_property_map, id); std::cout << "Segment "< Date: Wed, 17 May 2017 11:10:31 +0200 Subject: [PATCH 24/38] use set_selected_faces in the constructor and add the missing implementation --- .../CGAL/boost/graph/Face_filtered_graph.h | 134 +++++++++--------- 1 file changed, 67 insertions(+), 67 deletions(-) diff --git a/BGL/include/CGAL/boost/graph/Face_filtered_graph.h b/BGL/include/CGAL/boost/graph/Face_filtered_graph.h index 9ecfb545f59..53c4731c9cd 100644 --- a/BGL/include/CGAL/boost/graph/Face_filtered_graph.h +++ b/BGL/include/CGAL/boost/graph/Face_filtered_graph.h @@ -88,63 +88,6 @@ struct Face_filtered_graph typedef typename boost::property_traits< HIMap >::value_type halfedge_index_type; typedef Face_filtered_graph Self; -private: - template - void base_iterator_constructor(IndexRangeIterator begin, - IndexRangeIterator end, - FacePatchMap fcmap) - { - face_patch.resize(num_faces(_graph)); - vertex_patch.resize(num_vertices(_graph)); - halfedge_patch.resize(num_halfedges(_graph)); - boost::unordered_set::value_type> pids; - for(IndexRangeIterator it = begin; - it != end; - ++it) - { - pids.insert(*it); - } - - BOOST_FOREACH(face_descriptor fd, faces(_graph) ) - { - if(pids.find(boost::get(fcmap, fd))!= pids.end() ) - { - face_patch.set(get(fimap, fd)); - BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_face(halfedge(fd, _graph), _graph)) - { - halfedge_patch.set(get(himap, hd)); - halfedge_patch.set(get(himap, opposite(hd, _graph))); - vertex_patch.set(get(vimap, target(hd, _graph))); - } - } - } - CGAL_assertion(is_selection_valid()); - } - - template - void base_constructor(FacePatchMap fcmap, - typename boost::property_traits::value_type pid) - { - face_patch.resize(num_faces(_graph)); - vertex_patch.resize(num_vertices(_graph)); - halfedge_patch.resize(num_halfedges(_graph)); - BOOST_FOREACH(face_descriptor fd, faces(_graph) ) - { - if(boost::get(fcmap, fd) == pid) - { - face_patch.set(get(fimap, fd)); - BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_face(halfedge(fd, _graph), _graph)) - { - halfedge_patch.set(get(himap, hd)); - halfedge_patch.set(get(himap, opposite(hd, _graph))); - vertex_patch.set(get(vimap, target(hd, _graph))); - } - } - } - CGAL_assertion(is_selection_valid()); - } - -public: /*! * \brief Constructor where the set of selected faces is specified as a range of patch ids. * @@ -183,7 +126,7 @@ public: ) : _graph(const_cast(graph)), fimap(fimap), vimap(vimap), himap(himap) { - base_iterator_constructor(begin, end, fcmap); + set_selected_faces(begin, end, fcmap); } template @@ -196,7 +139,7 @@ public: fimap = get(CGAL::face_index, graph); vimap = get(boost::vertex_index, graph); himap = get(CGAL::halfedge_index, graph); - base_iterator_constructor(begin, end, fcmap); + set_selected_faces(begin, end, fcmap); } /*! * \brief Constructor where the set of selected faces is specified as a patch id. @@ -233,7 +176,7 @@ public: ) : _graph(const_cast(graph)), fimap(fimap), vimap(vimap), himap(himap) { - base_constructor(fcmap, pid); + set_selected_faces(fcmap, pid); } template @@ -245,7 +188,7 @@ public: fimap = get(CGAL::face_index, graph); vimap = get(boost::vertex_index, graph); himap = get(CGAL::halfedge_index, graph); - base_constructor(fcmap, pid); + set_selected_faces(fcmap, pid); } /*! @@ -297,8 +240,23 @@ public: face_indices.clear(); vertex_indices.clear(); halfedge_indices.clear(); - base_constructor(fcmap, pid); - CGAL_assertion(is_selection_valid()); + + face_patch.resize(num_faces(_graph)); + vertex_patch.resize(num_vertices(_graph)); + halfedge_patch.resize(num_halfedges(_graph)); + BOOST_FOREACH(face_descriptor fd, faces(_graph) ) + { + if(get(fcmap, fd) == pid) + { + face_patch.set(get(fimap, fd)); + BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_face(halfedge(fd, _graph), _graph)) + { + halfedge_patch.set(get(himap, hd)); + halfedge_patch.set(get(himap, opposite(hd, _graph))); + vertex_patch.set(get(vimap, target(hd, _graph))); + } + } + } } /// change the set of selected faces using a range of patch ids template @@ -309,13 +267,55 @@ public: face_indices.clear(); vertex_indices.clear(); halfedge_indices.clear(); - base_iterator_constructor(begin, end, fcmap); - CGAL_assertion(is_selection_valid()); + + face_patch.resize(num_faces(_graph)); + vertex_patch.resize(num_vertices(_graph)); + halfedge_patch.resize(num_halfedges(_graph)); + + boost::unordered_set::value_type> pids; + for(IndexRangeIterator it = begin; + it != end; + ++it) + { + pids.insert(*it); + } + + BOOST_FOREACH(face_descriptor fd, faces(_graph) ) + { + if(pids.count(get(fcmap, fd)) != 0) + { + face_patch.set(get(fimap, fd)); + BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_face(halfedge(fd, _graph), _graph)) + { + halfedge_patch.set(get(himap, hd)); + halfedge_patch.set(get(himap, opposite(hd, _graph))); + vertex_patch.set(get(vimap, target(hd, _graph))); + } + } + } } /// change the set of selected faces using a range of face descriptors - /// \todo implement me template - void set_selected_faces(FaceRange selected_face_range); + void set_selected_faces(FaceRange selected_face_range) + { + face_indices.clear(); + vertex_indices.clear(); + halfedge_indices.clear(); + + face_patch.resize(num_faces(_graph)); + vertex_patch.resize(num_vertices(_graph)); + halfedge_patch.resize(num_halfedges(_graph)); + BOOST_FOREACH(face_descriptor fd, selected_face_range) + { + face_patch.set(get(fimap, fd)); + BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_face(halfedge(fd, _graph), _graph)) + { + halfedge_patch.set(get(himap, hd)); + halfedge_patch.set(get(himap, opposite(hd, _graph))); + vertex_patch.set(get(vimap, target(hd, _graph))); + } + } + } struct Is_simplex_valid { From a0f149961426dc853f1190431c29730307ee4e6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 17 May 2017 11:12:31 +0200 Subject: [PATCH 25/38] rename bitsets of selected simplices --- .../CGAL/boost/graph/Face_filtered_graph.h | 72 +++++++++---------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/BGL/include/CGAL/boost/graph/Face_filtered_graph.h b/BGL/include/CGAL/boost/graph/Face_filtered_graph.h index 53c4731c9cd..34b9e748604 100644 --- a/BGL/include/CGAL/boost/graph/Face_filtered_graph.h +++ b/BGL/include/CGAL/boost/graph/Face_filtered_graph.h @@ -241,19 +241,19 @@ struct Face_filtered_graph vertex_indices.clear(); halfedge_indices.clear(); - face_patch.resize(num_faces(_graph)); - vertex_patch.resize(num_vertices(_graph)); - halfedge_patch.resize(num_halfedges(_graph)); + selected_faces.resize(num_faces(_graph)); + selected_vertices.resize(num_vertices(_graph)); + selected_halfedges.resize(num_halfedges(_graph)); BOOST_FOREACH(face_descriptor fd, faces(_graph) ) { if(get(fcmap, fd) == pid) { - face_patch.set(get(fimap, fd)); + selected_faces.set(get(fimap, fd)); BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_face(halfedge(fd, _graph), _graph)) { - halfedge_patch.set(get(himap, hd)); - halfedge_patch.set(get(himap, opposite(hd, _graph))); - vertex_patch.set(get(vimap, target(hd, _graph))); + selected_halfedges.set(get(himap, hd)); + selected_halfedges.set(get(himap, opposite(hd, _graph))); + selected_vertices.set(get(vimap, target(hd, _graph))); } } } @@ -268,9 +268,9 @@ struct Face_filtered_graph vertex_indices.clear(); halfedge_indices.clear(); - face_patch.resize(num_faces(_graph)); - vertex_patch.resize(num_vertices(_graph)); - halfedge_patch.resize(num_halfedges(_graph)); + selected_faces.resize(num_faces(_graph)); + selected_vertices.resize(num_vertices(_graph)); + selected_halfedges.resize(num_halfedges(_graph)); boost::unordered_set::value_type> pids; for(IndexRangeIterator it = begin; @@ -284,12 +284,12 @@ struct Face_filtered_graph { if(pids.count(get(fcmap, fd)) != 0) { - face_patch.set(get(fimap, fd)); + selected_faces.set(get(fimap, fd)); BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_face(halfedge(fd, _graph), _graph)) { - halfedge_patch.set(get(himap, hd)); - halfedge_patch.set(get(himap, opposite(hd, _graph))); - vertex_patch.set(get(vimap, target(hd, _graph))); + selected_halfedges.set(get(himap, hd)); + selected_halfedges.set(get(himap, opposite(hd, _graph))); + selected_vertices.set(get(vimap, target(hd, _graph))); } } } @@ -302,17 +302,17 @@ struct Face_filtered_graph vertex_indices.clear(); halfedge_indices.clear(); - face_patch.resize(num_faces(_graph)); - vertex_patch.resize(num_vertices(_graph)); - halfedge_patch.resize(num_halfedges(_graph)); + selected_faces.resize(num_faces(_graph)); + selected_vertices.resize(num_vertices(_graph)); + selected_halfedges.resize(num_halfedges(_graph)); BOOST_FOREACH(face_descriptor fd, selected_face_range) { - face_patch.set(get(fimap, fd)); + selected_faces.set(get(fimap, fd)); BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_face(halfedge(fd, _graph), _graph)) { - halfedge_patch.set(get(himap, hd)); - halfedge_patch.set(get(himap, opposite(hd, _graph))); - vertex_patch.set(get(vimap, target(hd, _graph))); + selected_halfedges.set(get(himap, hd)); + selected_halfedges.set(get(himap, opposite(hd, _graph))); + selected_vertices.set(get(vimap, target(hd, _graph))); } } } @@ -337,35 +337,35 @@ struct Face_filtered_graph bool is_in_cc(face_descriptor f) const { - return face_patch[get(fimap, f)]; + return selected_faces[get(fimap, f)]; } bool is_in_cc(vertex_descriptor v) const { - return vertex_patch[get(vimap, v)]; + return selected_vertices[get(vimap, v)]; } bool is_in_cc(halfedge_descriptor h) const { - return halfedge_patch[get(himap, h)]; + return selected_halfedges[get(himap, h)]; } ///returns the number of selected faces typename boost::graph_traits:: faces_size_type number_of_faces()const { - return face_patch.count(); + return selected_faces.count(); } ///returns the number of selected vertices. typename boost::graph_traits:: vertices_size_type number_of_vertices()const { - return vertex_patch.count(); + return selected_vertices.count(); } ///returns the number of selected halfedges. typename boost::graph_traits:: halfedges_size_type number_of_halfedges()const { - return halfedge_patch.count(); + return selected_halfedges.count(); } Property_map_binder< FIMap, typename Pointer_property_map< typename boost::property_traits< FIMap >::value_type >::type > @@ -375,7 +375,7 @@ struct Face_filtered_graph { face_index_type index = 0; face_indices.resize(num_faces(_graph)); - for (std::size_t i=face_patch.find_first(); i < face_patch.npos; i = face_patch.find_next(i)) + for (std::size_t i=selected_faces.find_first(); i < selected_faces.npos; i = selected_faces.find_next(i)) { face_indices[i] = index++; } @@ -390,7 +390,7 @@ struct Face_filtered_graph { vertex_index_type index = 0; vertex_indices.resize(num_vertices(_graph)); - for (std::size_t i=vertex_patch.find_first(); i < vertex_patch.npos; i = vertex_patch.find_next(i)) + for (std::size_t i=selected_vertices.find_first(); i < selected_vertices.npos; i = selected_vertices.find_next(i)) { vertex_indices[i] = index++; } @@ -405,7 +405,7 @@ struct Face_filtered_graph { halfedge_index_type index = 0; halfedge_indices.resize(num_halfedges(_graph)); - for (std::size_t i=halfedge_patch.find_first(); i < halfedge_patch.npos; i = halfedge_patch.find_next(i)) + for (std::size_t i=selected_halfedges.find_first(); i < selected_halfedges.npos; i = selected_halfedges.find_next(i)) { halfedge_indices[i] = index++; } @@ -437,17 +437,17 @@ struct Face_filtered_graph else if(fd == first_tested ) { //if there is no unselected face, break - if(face_patch[get(fimap, fd)] && !first_unselected_found) + if(selected_faces[get(fimap, fd)] && !first_unselected_found) break; //if there is no selected face, break - else if(!face_patch[get(fimap, fd)] && + else if(!selected_faces[get(fimap, fd)] && first_selected == boost::graph_traits::null_face()) break; } if(fd != boost::graph_traits::null_face()) { - if(face_patch[get(fimap, fd)]) + if(selected_faces[get(fimap, fd)]) { if(first_unselected_found && first_selected == boost::graph_traits::null_face()) @@ -481,9 +481,9 @@ private: FIMap fimap; VIMap vimap; HIMap himap; - boost::dynamic_bitset<> face_patch; - boost::dynamic_bitset<> vertex_patch; - boost::dynamic_bitset<> halfedge_patch; + boost::dynamic_bitset<> selected_faces; + boost::dynamic_bitset<> selected_vertices; + boost::dynamic_bitset<> selected_halfedges; mutable std::vector face_indices; mutable std::vector vertex_indices; mutable std::vector halfedge_indices; From b453991a4419ff2a22a504ceab7547265245a43c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 17 May 2017 13:00:59 +0200 Subject: [PATCH 26/38] rename face patch index map --- .../CGAL/boost/graph/Face_filtered_graph.h | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/BGL/include/CGAL/boost/graph/Face_filtered_graph.h b/BGL/include/CGAL/boost/graph/Face_filtered_graph.h index 34b9e748604..ac5cb36c4dc 100644 --- a/BGL/include/CGAL/boost/graph/Face_filtered_graph.h +++ b/BGL/include/CGAL/boost/graph/Face_filtered_graph.h @@ -91,14 +91,14 @@ struct Face_filtered_graph /*! * \brief Constructor where the set of selected faces is specified as a range of patch ids. * - * \tparam FacePatchMap a model of `ReadablePropertyMap` with + * \tparam FacePatchIndexMap a model of `ReadablePropertyMap` with `face_descriptor` as key type and `graph_traits::%faces_size_type` as value type. - * \tparam IndexRangeIterator an iterator of a range of `boost::property_traits::%value_type`. + * \tparam IndexRangeIterator an iterator of a range of `boost::property_traits::%value_type`. * \note the index maps must be initialized from `0` to the number of simplices. * * \param graph the underlying graph. - * \param fcmap the property_map that assigns a patch index to each face, with + * \param face_patch_index_map the property_map that assigns a patch index to each face, with `face_descriptor` as key type and `boost::graph_traits::%faces_size_type` as value type. * \param begin an interator to the beginning of a range of patches indices of interest. * \param end an interator to the element past the end of a range of patches indices of interest. @@ -109,9 +109,9 @@ struct Face_filtered_graph * \param himap the property map that assigns an index to each halfedge, * with `halfedge_descriptor` as key type and `boost::graph_traits::%halfedges_size_type` as value type */ - template + template Face_filtered_graph(const Graph& graph, - FacePatchMap fcmap, + FacePatchIndexMap face_patch_index_map, IndexRangeIterator begin, IndexRangeIterator end, #ifdef DOXYGEN_RUNNING @@ -126,12 +126,12 @@ struct Face_filtered_graph ) : _graph(const_cast(graph)), fimap(fimap), vimap(vimap), himap(himap) { - set_selected_faces(begin, end, fcmap); + set_selected_faces(begin, end, face_patch_index_map); } - template + template Face_filtered_graph(const Graph& graph, - FacePatchMap fcmap, + FacePatchIndexMap face_patch_index_map, IndexRangeIterator begin, IndexRangeIterator end) : _graph(const_cast(graph)) @@ -139,17 +139,17 @@ struct Face_filtered_graph fimap = get(CGAL::face_index, graph); vimap = get(boost::vertex_index, graph); himap = get(CGAL::halfedge_index, graph); - set_selected_faces(begin, end, fcmap); + set_selected_faces(begin, end, face_patch_index_map); } /*! * \brief Constructor where the set of selected faces is specified as a patch id. * - * \tparam FacePatchMap a model of `ReadablePropertyMap` with + * \tparam FacePatchIndexMap a model of `ReadablePropertyMap` with `face_descriptor` as key type and `graph_traits::%faces_size_type` as value type. * \note the index maps must be initialized from `0` to the number of simplices. * \param graph the underlying graph. - * \param fcmap the property_map that assigns a patch index to each face, with + * \param face_patch_index_map the property_map that assigns a patch index to each face, with `face_descriptor` as key type and `graph_traits::%faces_size_type` as value type. * \param pid the index of the patch of interest. @@ -160,10 +160,10 @@ struct Face_filtered_graph * \param himap the property map that assigns an index to each halfedge, * with `halfedge_descriptor` as key type and `boost::graph_traits::%halfedges_size_type` as value type */ - template + template Face_filtered_graph(const Graph& graph, - FacePatchMap fcmap, - typename boost::property_traits::value_type pid, + FacePatchIndexMap face_patch_index_map, + typename boost::property_traits::value_type pid, #ifdef DOXYGEN_RUNNING FIMap fimap = get(CGAL::face_index, graph), VIMap vimap = get(boost::vertex_index, graph), @@ -176,19 +176,19 @@ struct Face_filtered_graph ) : _graph(const_cast(graph)), fimap(fimap), vimap(vimap), himap(himap) { - set_selected_faces(fcmap, pid); + set_selected_faces(face_patch_index_map, pid); } - template + template Face_filtered_graph(const Graph& graph, - FacePatchMap fcmap, - typename boost::property_traits::value_type pid) + FacePatchIndexMap face_patch_index_map, + typename boost::property_traits::value_type pid) : _graph(const_cast(graph)) { fimap = get(CGAL::face_index, graph); vimap = get(boost::vertex_index, graph); himap = get(CGAL::halfedge_index, graph); - set_selected_faces(fcmap, pid); + set_selected_faces(face_patch_index_map, pid); } /*! @@ -233,9 +233,9 @@ struct Face_filtered_graph Graph& graph(){ return _graph; } ///change the set of selected faces using a patch id - template - void set_selected_faces(FacePatchMap fcmap, - typename boost::property_traits::value_type pid) + template + void set_selected_faces(FacePatchIndexMap face_patch_index_map, + typename boost::property_traits::value_type pid) { face_indices.clear(); vertex_indices.clear(); @@ -246,7 +246,7 @@ struct Face_filtered_graph selected_halfedges.resize(num_halfedges(_graph)); BOOST_FOREACH(face_descriptor fd, faces(_graph) ) { - if(get(fcmap, fd) == pid) + if(get(face_patch_index_map, fd) == pid) { selected_faces.set(get(fimap, fd)); BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_face(halfedge(fd, _graph), _graph)) @@ -259,8 +259,8 @@ struct Face_filtered_graph } } /// change the set of selected faces using a range of patch ids - template - void set_selected_faces(FacePatchMap fcmap, + template + void set_selected_faces(FacePatchIndexMap face_patch_index_map, IndexRangeIterator begin, IndexRangeIterator end) { @@ -272,7 +272,7 @@ struct Face_filtered_graph selected_vertices.resize(num_vertices(_graph)); selected_halfedges.resize(num_halfedges(_graph)); - boost::unordered_set::value_type> pids; + boost::unordered_set::value_type> pids; for(IndexRangeIterator it = begin; it != end; ++it) @@ -282,7 +282,7 @@ struct Face_filtered_graph BOOST_FOREACH(face_descriptor fd, faces(_graph) ) { - if(pids.count(get(fcmap, fd)) != 0) + if(pids.count(get(face_patch_index_map, fd)) != 0) { selected_faces.set(get(fimap, fd)); BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_face(halfedge(fd, _graph), _graph)) From 6d2526499e3ebd2a4761c3dfc6cdc1e3e44fd9d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 17 May 2017 14:00:44 +0200 Subject: [PATCH 27/38] replace iterators of face patch indices by a range --- .../CGAL/boost/graph/Face_filtered_graph.h | 116 +++++++++--------- BGL/test/BGL/test_Face_filtered_graph.cpp | 25 ++-- .../face_filtered_graph_example.cpp | 10 +- ...extract_segmentation_into_mesh_example.cpp | 6 +- 4 files changed, 78 insertions(+), 79 deletions(-) diff --git a/BGL/include/CGAL/boost/graph/Face_filtered_graph.h b/BGL/include/CGAL/boost/graph/Face_filtered_graph.h index ac5cb36c4dc..e914f2c3c5d 100644 --- a/BGL/include/CGAL/boost/graph/Face_filtered_graph.h +++ b/BGL/include/CGAL/boost/graph/Face_filtered_graph.h @@ -31,7 +31,7 @@ #include #include #include - +#include namespace CGAL { @@ -94,14 +94,13 @@ struct Face_filtered_graph * \tparam FacePatchIndexMap a model of `ReadablePropertyMap` with `face_descriptor` as key type and `graph_traits::%faces_size_type` as value type. - * \tparam IndexRangeIterator an iterator of a range of `boost::property_traits::%value_type`. + * \tparam FacePatchIndexRange a model of `ConstRange` with `boost::property_traits::%value_type` as value type. * \note the index maps must be initialized from `0` to the number of simplices. * * \param graph the underlying graph. * \param face_patch_index_map the property_map that assigns a patch index to each face, with `face_descriptor` as key type and `boost::graph_traits::%faces_size_type` as value type. - * \param begin an interator to the beginning of a range of patches indices of interest. - * \param end an interator to the element past the end of a range of patches indices of interest. + * \param selected_face_patch_indices a range of the face patch indices to select. * \param fimap the property map that assigns an index to each face, * with `face_descriptor` as key type and `boost::graph_traits::%faces_size_type` as value type * \param vimap the property map that assigns an index to each vertex, @@ -109,37 +108,38 @@ struct Face_filtered_graph * \param himap the property map that assigns an index to each halfedge, * with `halfedge_descriptor` as key type and `boost::graph_traits::%halfedges_size_type` as value type */ - template + template Face_filtered_graph(const Graph& graph, - FacePatchIndexMap face_patch_index_map, - IndexRangeIterator begin, - IndexRangeIterator end, + const FacePatchIndexRange& selected_face_patch_indices, + FacePatchIndexMap face_patch_index_map, #ifdef DOXYGEN_RUNNING - FIMap fimap = get(CGAL::face_index, graph), - VIMap vimap = get(boost::vertex_index, graph), - HIMap himap = get(CGAL::halfedge_index, graph) + FIMap fimap = get(CGAL::face_index, graph), + VIMap vimap = get(boost::vertex_index, graph), + HIMap himap = get(CGAL::halfedge_index, graph) #else - FIMap fimap, - VIMap vimap, - HIMap himap + FIMap fimap, + VIMap vimap, + HIMap himap, + typename boost::enable_if< + typename boost::has_range_const_iterator::type + >::type* = 0 #endif ) : _graph(const_cast(graph)), fimap(fimap), vimap(vimap), himap(himap) { - set_selected_faces(begin, end, face_patch_index_map); + set_selected_faces(selected_face_patch_indices, face_patch_index_map); } - template + template Face_filtered_graph(const Graph& graph, - FacePatchIndexMap face_patch_index_map, - IndexRangeIterator begin, - IndexRangeIterator end) + const FacePatchIndexRange& selected_face_patch_indices, + FacePatchIndexMap face_patch_index_map) : _graph(const_cast(graph)) { fimap = get(CGAL::face_index, graph); vimap = get(boost::vertex_index, graph); himap = get(CGAL::halfedge_index, graph); - set_selected_faces(begin, end, face_patch_index_map); + set_selected_faces(selected_face_patch_indices, face_patch_index_map); } /*! * \brief Constructor where the set of selected faces is specified as a patch id. @@ -152,7 +152,7 @@ struct Face_filtered_graph * \param face_patch_index_map the property_map that assigns a patch index to each face, with `face_descriptor` as key type and `graph_traits::%faces_size_type` as value type. - * \param pid the index of the patch of interest. + * \param selected_face_patch_index the index of the face patch selected. * \param fimap the property map that assigns an index to each face, * with `face_descriptor` as key type and `boost::graph_traits::%faces_size_type` as value type * \param vimap the property map that assigns an index to each vertex, @@ -162,27 +162,27 @@ struct Face_filtered_graph */ template Face_filtered_graph(const Graph& graph, - FacePatchIndexMap face_patch_index_map, - typename boost::property_traits::value_type pid, + typename boost::property_traits::value_type selected_face_patch_index, + FacePatchIndexMap face_patch_index_map, #ifdef DOXYGEN_RUNNING - FIMap fimap = get(CGAL::face_index, graph), - VIMap vimap = get(boost::vertex_index, graph), - HIMap himap = get(CGAL::halfedge_index, graph) + FIMap fimap = get(CGAL::face_index, graph), + VIMap vimap = get(boost::vertex_index, graph), + HIMap himap = get(CGAL::halfedge_index, graph) #else - FIMap fimap, - VIMap vimap, - HIMap himap + FIMap fimap, + VIMap vimap, + HIMap himap #endif ) : _graph(const_cast(graph)), fimap(fimap), vimap(vimap), himap(himap) { - set_selected_faces(face_patch_index_map, pid); + set_selected_faces(selected_face_patch_index, face_patch_index_map); } template Face_filtered_graph(const Graph& graph, - FacePatchIndexMap face_patch_index_map, - typename boost::property_traits::value_type pid) + typename boost::property_traits::value_type pid, + FacePatchIndexMap face_patch_index_map) : _graph(const_cast(graph)) { fimap = get(CGAL::face_index, graph); @@ -197,7 +197,7 @@ struct Face_filtered_graph * \tparam FaceRange a model of `ConstRange` with `face_descriptor` as value type. * \note the index maps must be initialized from `0` to the number of simplices. * \param graph the graph containing the wanted patch. - * \param selected_face_range the set of selected faces. + * \param selected_faces the set of selected faces. * \param fimap the property map that assigns an index to each face, * with `face_descriptor` as key type and `boost::graph_traits::%faces_size_type` as value type * \param vimap the property map that assigns an index to each vertex, @@ -207,19 +207,19 @@ struct Face_filtered_graph */ template Face_filtered_graph(const Graph& graph, - const FaceRange& selected_face_range, + const FaceRange& selected_faces, #ifdef DOXYGEN_RUNNING - FIMap fimap = get(CGAL::face_index, graph), - VIMap vimap = get(boost::vertex_index, graph), - HIMap himap = get(CGAL::halfedge_index, graph) + FIMap fimap = get(CGAL::face_index, graph), + VIMap vimap = get(boost::vertex_index, graph), + HIMap himap = get(CGAL::halfedge_index, graph) #else - FIMap fimap, - VIMap vimap, - HIMap himap + FIMap fimap, + VIMap vimap, + HIMap himap #endif ) : _graph(const_cast(graph)), fimap(fimap), vimap(vimap), himap(himap) { - set_selected_faces(selected_face_range); + set_selected_faces(selected_faces); } template @@ -234,8 +234,8 @@ struct Face_filtered_graph ///change the set of selected faces using a patch id template - void set_selected_faces(FacePatchIndexMap face_patch_index_map, - typename boost::property_traits::value_type pid) + void set_selected_faces(typename boost::property_traits::value_type face_patch_id, + FacePatchIndexMap face_patch_index_map) { face_indices.clear(); vertex_indices.clear(); @@ -246,7 +246,7 @@ struct Face_filtered_graph selected_halfedges.resize(num_halfedges(_graph)); BOOST_FOREACH(face_descriptor fd, faces(_graph) ) { - if(get(face_patch_index_map, fd) == pid) + if(get(face_patch_index_map, fd) == face_patch_id) { selected_faces.set(get(fimap, fd)); BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_face(halfedge(fd, _graph), _graph)) @@ -259,10 +259,15 @@ struct Face_filtered_graph } } /// change the set of selected faces using a range of patch ids - template - void set_selected_faces(FacePatchIndexMap face_patch_index_map, - IndexRangeIterator begin, - IndexRangeIterator end) + template + void set_selected_faces(const FacePatchIndexRange& selected_face_patch_indices, + FacePatchIndexMap face_patch_index_map + #ifndef DOXYGEN_RUNNING + , typename boost::enable_if< + typename boost::has_range_const_iterator::type + >::type* = 0 + #endif + ) { face_indices.clear(); vertex_indices.clear(); @@ -271,14 +276,9 @@ struct Face_filtered_graph selected_faces.resize(num_faces(_graph)); selected_vertices.resize(num_vertices(_graph)); selected_halfedges.resize(num_halfedges(_graph)); - - boost::unordered_set::value_type> pids; - for(IndexRangeIterator it = begin; - it != end; - ++it) - { - pids.insert(*it); - } + typedef typename boost::property_traits::value_type Patch_index; + boost::unordered_set pids(boost::begin(selected_face_patch_indices), + boost::end(selected_face_patch_indices)); BOOST_FOREACH(face_descriptor fd, faces(_graph) ) { @@ -296,7 +296,7 @@ struct Face_filtered_graph } /// change the set of selected faces using a range of face descriptors template - void set_selected_faces(FaceRange selected_face_range) + void set_selected_faces(const FaceRange& selected_faces) { face_indices.clear(); vertex_indices.clear(); @@ -305,7 +305,7 @@ struct Face_filtered_graph selected_faces.resize(num_faces(_graph)); selected_vertices.resize(num_vertices(_graph)); selected_halfedges.resize(num_halfedges(_graph)); - BOOST_FOREACH(face_descriptor fd, selected_face_range) + BOOST_FOREACH(face_descriptor fd, selected_faces) { selected_faces.set(get(fimap, fd)); BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_face(halfedge(fd, _graph), _graph)) diff --git a/BGL/test/BGL/test_Face_filtered_graph.cpp b/BGL/test/BGL/test_Face_filtered_graph.cpp index 9bc178a70a7..decf294fc92 100644 --- a/BGL/test/BGL/test_Face_filtered_graph.cpp +++ b/BGL/test/BGL/test_Face_filtered_graph.cpp @@ -21,7 +21,7 @@ void test_halfedge_around_vertex_iterator(const Graph& g) CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); - Adapter fg(g, boost::make_assoc_property_map(map), 0); + Adapter fg(g, 0, boost::make_assoc_property_map(map)); typename boost::graph_traits::vertex_iterator vit, vend; for(boost::tie(vit, vend) = vertices(fg); vit != vend; ++vit) { halfedge_around_target_iterator havit, havend; @@ -47,7 +47,7 @@ void test_halfedge_around_face_iterator(const Graph& g) CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); - Adapter fg(g, boost::make_assoc_property_map(map), 0); + Adapter fg(g, 0, boost::make_assoc_property_map(map)); face_iterator fit, fend; for(boost::tie(fit, fend) = faces(fg); fit != fend; ++fit) { halfedge_around_face_iterator hafit, hafend; @@ -67,7 +67,7 @@ void test_edge_iterators(const Graph& g) CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); - Adapter fg(g, boost::make_assoc_property_map(map), 0); + Adapter fg(g, 0, boost::make_assoc_property_map(map)); // do we iterate as many as that? edge_iterator eb, ee; @@ -93,7 +93,7 @@ void test_vertex_iterators(Graph& g) CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); - Adapter fg(g, boost::make_assoc_property_map(map), 0); + Adapter fg(g, 0, boost::make_assoc_property_map(map)); vertex_iterator vb, ve; std::size_t count = 0; for(boost::tie(vb, ve) = vertices(fg); vb != ve; ++vb){ @@ -123,7 +123,7 @@ void test_out_edges(const Graph& g) CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); - Adapter fg(g, boost::make_assoc_property_map(map), 0); + Adapter fg(g, 0, boost::make_assoc_property_map(map)); vertex_iterator vb, ve; for(boost::tie(vb, ve) = vertices(fg); vb != ve; ++vb) { @@ -152,7 +152,7 @@ void test_in_edges(const Graph& g) CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); - Adapter fg(g, boost::make_assoc_property_map(map), 0); + Adapter fg(g, 0, boost::make_assoc_property_map(map)); vertex_iterator vb, ve; for(boost::tie(vb, ve) = vertices(fg); vb != ve; ++vb) { @@ -179,7 +179,7 @@ void test_in_out_edges(const Graph& g) CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); - Adapter fg(g, boost::make_assoc_property_map(map), 0); + Adapter fg(g, 0, boost::make_assoc_property_map(map)); // check that the sets of in out edges are the same vertex_iterator vb, ve; @@ -221,7 +221,7 @@ void test_edge_find(const Graph& g) CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); - Adapter fg(g, boost::make_assoc_property_map(map), 0); + Adapter fg(g, 0, boost::make_assoc_property_map(map)); typedef std::pair ret; edge_iterator eb, ee; @@ -245,7 +245,7 @@ void test_faces(const Graph& g) CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); - Adapter fg(g, boost::make_assoc_property_map(map), 0); + Adapter fg(g, 0, boost::make_assoc_property_map(map)); unsigned int count = 0; face_iterator fb, fe; @@ -271,7 +271,7 @@ void test_read(const Graph& g) CGAL_GRAPH_TRAITS_MEMBERS(Adapter); std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); - Adapter fg(g, boost::make_assoc_property_map(map), 0); + Adapter fg(g, 0, boost::make_assoc_property_map(map)); assert(CGAL::is_valid(fg)); } @@ -418,7 +418,7 @@ main() boost::unordered_set pids; pids.insert(0); pids.insert(2); - SM_Adapter sm_adapter(*sm, fccmap, pids.begin(), pids.end()); + SM_Adapter sm_adapter(*sm, pids, fccmap); test_mesh(sm_adapter); @@ -454,9 +454,8 @@ main() edge_is_constrained_map(Constraint(*poly, vpmap)). face_index_map(poly_fimap)); Poly_Adapter poly_adapter(*poly, + pids, poly_fccmap, - pids.begin(), - pids.end(), poly_fimap, poly_vimap, poly_himap); diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/face_filtered_graph_example.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/face_filtered_graph_example.cpp index 4d2baf09517..f9b4b46c932 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/face_filtered_graph_example.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/face_filtered_graph_example.cpp @@ -18,7 +18,7 @@ typedef boost::graph_traits::face_descriptor face_descriptor; typedef boost::graph_traits::faces_size_type faces_size_type; typedef Mesh::Property_map FCCmap; - typedef CGAL::Face_filtered_graph CCG; + typedef CGAL::Face_filtered_graph Filtered_graph; namespace PMP = CGAL::Polygon_mesh_processing; @@ -39,10 +39,10 @@ int main(int argc, char* argv[]) std::cerr << "- The graph has " << num << " connected components (face connectivity)" << std::endl; - CCG ccg(mesh, fccmap, 0); + Filtered_graph ffg(mesh, 0, fccmap); std::cout << "The faces in component 0 are:" << std::endl; - BOOST_FOREACH(boost::graph_traits::face_descriptor f, faces(ccg)){ + BOOST_FOREACH(boost::graph_traits::face_descriptor f, faces(ffg)){ std::cout << f << std::endl; } @@ -51,10 +51,10 @@ int main(int argc, char* argv[]) components.push_back(0); components.push_back(1); - ccg.set_selected_faces(fccmap,components.begin(), components.end()); + ffg.set_selected_faces(components, fccmap); std::cout << "The faces in components 0 and 1 are:" << std::endl; - BOOST_FOREACH(CCG::face_descriptor f, faces(ccg)){ + BOOST_FOREACH(Filtered_graph::face_descriptor f, faces(ffg)){ std::cout << f << std::endl; } } diff --git a/Surface_mesh_segmentation/examples/Surface_mesh_segmentation/extract_segmentation_into_mesh_example.cpp b/Surface_mesh_segmentation/examples/Surface_mesh_segmentation/extract_segmentation_into_mesh_example.cpp index c8194e60ea7..c226c867b5a 100644 --- a/Surface_mesh_segmentation/examples/Surface_mesh_segmentation/extract_segmentation_into_mesh_example.cpp +++ b/Surface_mesh_segmentation/examples/Surface_mesh_segmentation/extract_segmentation_into_mesh_example.cpp @@ -38,13 +38,13 @@ int main(int argc, char** argv ) // Any other scalar values can be used instead of using SDF values computed using the CGAL function std::size_t number_of_segments = CGAL::segmentation_from_sdf_values(mesh, sdf_property_map, segment_property_map); - typedef CGAL::Face_filtered_graph Cc_graph; + typedef CGAL::Face_filtered_graph Filtered_graph; //print area of each segment and then put it in a Mesh and print it in an OFF file - Cc_graph segment_mesh(mesh, segment_property_map, 0); + Filtered_graph segment_mesh(mesh, 0, segment_property_map); for(std::size_t id = 0; id < number_of_segments; ++id) { if(id > 0) - segment_mesh.set_selected_faces(segment_property_map, id); + segment_mesh.set_selected_faces(id, segment_property_map); std::cout << "Segment "< Date: Wed, 17 May 2017 15:35:20 +0200 Subject: [PATCH 28/38] move helper functions in the BGL package so that they can be used there too --- .../CGAL/boost/graph/named_function_params.h | 64 +++++++++++++++++++ .../internal/named_params_helper.h | 62 ------------------ 2 files changed, 64 insertions(+), 62 deletions(-) diff --git a/BGL/include/CGAL/boost/graph/named_function_params.h b/BGL/include/CGAL/boost/graph/named_function_params.h index e54eefb81a8..eaab2e76b2c 100644 --- a/BGL/include/CGAL/boost/graph/named_function_params.h +++ b/BGL/include/CGAL/boost/graph/named_function_params.h @@ -101,6 +101,8 @@ namespace boost{ } //end of namespace boost #endif +#define CGAL_BGL_NP_TEMPLATE_PARAMETERS T, typename Tag, typename Base +#define CGAL_BGL_NP_CLASS CGAL::cgal_bgl_named_params namespace CGAL { namespace internal_np{ @@ -162,6 +164,68 @@ using boost::visitor; } // namespace parameters + //helper classes + template + class property_map_selector + { + public: + typedef typename boost::graph_has_property::type Has_internal_pmap; + typedef typename boost::mpl::if_c< Has_internal_pmap::value + , typename boost::property_map::type + , typename boost::cgal_no_property::type + >::type type; + typedef typename boost::mpl::if_c< Has_internal_pmap::value + , typename boost::property_map::const_type + , typename boost::cgal_no_property::const_type + >::type const_type; + + type get_pmap(const PropertyTag& p, PolygonMesh& pmesh) + { + return get_impl(p, pmesh, Has_internal_pmap()); + } + + const_type get_const_pmap(const PropertyTag& p, const PolygonMesh& pmesh) + { + return get_const_pmap_impl(p, pmesh, Has_internal_pmap()); + } + + private: + type get_impl(const PropertyTag&, PolygonMesh&, CGAL::Tag_false) + { + return type(); //boost::cgal_no_property::type + } + type get_impl(const PropertyTag& p, PolygonMesh& pmesh, CGAL::Tag_true) + { + return get(p, pmesh); + } + + const_type get_const_pmap_impl(const PropertyTag& + , const PolygonMesh&, CGAL::Tag_false) + { + return const_type(); //boost::cgal_no_property::type + } + const_type get_const_pmap_impl(const PropertyTag& p + , const PolygonMesh& pmesh, CGAL::Tag_true) + { + return get(p, pmesh); + } + }; + + template + typename property_map_selector::type + get_property_map(const PropertyTag& p, PolygonMesh& pmesh) + { + property_map_selector pms; + return pms.get_pmap(p, pmesh); + } + + template + typename property_map_selector::const_type + get_const_property_map(const PropertyTag& p, const PolygonMesh& pmesh) + { + property_map_selector pms; + return pms.get_const_pmap(p, pmesh); + } } //namespace CGAL // partial specializations hate inheritance and we need to repeat diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/named_params_helper.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/named_params_helper.h index 50daf1c47a7..30cc2b5e7df 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/named_params_helper.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/named_params_helper.h @@ -42,52 +42,6 @@ public: typedef typename boost::property_traits::value_type type; }; -template -class property_map_selector -{ -public: - typedef typename boost::graph_has_property::type Has_internal_pmap; - typedef typename boost::mpl::if_c< Has_internal_pmap::value - , typename boost::property_map::type - , typename boost::cgal_no_property::type - >::type type; - typedef typename boost::mpl::if_c< Has_internal_pmap::value - , typename boost::property_map::const_type - , typename boost::cgal_no_property::const_type - >::type const_type; - - type get_pmap(const PropertyTag& p, PolygonMesh& pmesh) - { - return get_impl(p, pmesh, Has_internal_pmap()); - } - - const_type get_const_pmap(const PropertyTag& p, const PolygonMesh& pmesh) - { - return get_const_pmap_impl(p, pmesh, Has_internal_pmap()); - } - -private: - type get_impl(const PropertyTag&, PolygonMesh&, CGAL::Tag_false) - { - return type(); //boost::cgal_no_property::type - } - type get_impl(const PropertyTag& p, PolygonMesh& pmesh, CGAL::Tag_true) - { - return get(p, pmesh); - } - - const_type get_const_pmap_impl(const PropertyTag& - , const PolygonMesh&, CGAL::Tag_false) - { - return const_type(); //boost::cgal_no_property::type - } - const_type get_const_pmap_impl(const PropertyTag& p - , const PolygonMesh& pmesh, CGAL::Tag_true) - { - return get(p, pmesh); - } -}; - template class GetVertexPointMap { @@ -138,22 +92,6 @@ public: > ::type type; }; -template -typename property_map_selector::type -get_property_map(const PropertyTag& p, PolygonMesh& pmesh) -{ - property_map_selector pms; - return pms.get_pmap(p, pmesh); -} - -template -typename property_map_selector::const_type -get_const_property_map(const PropertyTag& p, const PolygonMesh& pmesh) -{ - property_map_selector pms; - return pms.get_const_pmap(p, pmesh); -} - template class GetFaceIndexMap { From ad87028699eb457fa5b77cf7c7393eea6d94a23a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 17 May 2017 15:36:01 +0200 Subject: [PATCH 29/38] use named parameters for index maps --- BGL/doc/BGL/Doxyfile.in | 12 ++ .../CGAL/boost/graph/Face_filtered_graph.h | 153 ++++++++++-------- BGL/test/BGL/test_Face_filtered_graph.cpp | 6 +- 3 files changed, 105 insertions(+), 66 deletions(-) diff --git a/BGL/doc/BGL/Doxyfile.in b/BGL/doc/BGL/Doxyfile.in index 95aa22e39c6..9796b38035d 100644 --- a/BGL/doc/BGL/Doxyfile.in +++ b/BGL/doc/BGL/Doxyfile.in @@ -16,6 +16,18 @@ EXAMPLE_PATH = ${CGAL_Surface_mesh_skeletonization_EXAMPLE_DIR} \ ALIASES += "bgllink{1}=\1" ALIASES += "cgalNamedParamsBegin=
    Named Parameters
" +# macros to be used inside the code +ALIASES += "cgalNamedParamsBegin=
Named Parameters
" +ALIASES += "cgalNamedParamsEnd=
" +ALIASES += "cgalParamBegin{1}=\1" +ALIASES += "cgalParamEnd=" + + EXTRACT_ALL=NO HIDE_UNDOC_MEMBERS = YES HIDE_UNDOC_CLASSES = YES + +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = YES +EXPAND_AS_DEFINED = CGAL_BGL_NP_TEMPLATE_PARAMETERS \ + CGAL_BGL_NP_CLASS diff --git a/BGL/include/CGAL/boost/graph/Face_filtered_graph.h b/BGL/include/CGAL/boost/graph/Face_filtered_graph.h index e914f2c3c5d..3de8bfaf276 100644 --- a/BGL/include/CGAL/boost/graph/Face_filtered_graph.h +++ b/BGL/include/CGAL/boost/graph/Face_filtered_graph.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -32,6 +33,12 @@ #include #include #include + +#ifdef DOXYGEN_RUNNING +#define CGAL_BGL_NP_TEMPLATE_PARAMETERS NamedParameters +#define CGAL_BGL_NP_CLASS NamedParameters +#endif + namespace CGAL { @@ -57,6 +64,11 @@ namespace CGAL * The documented interface of this class is limited on purpose and free functions of the concept * this class is a model of must be used to manipulate it. * + * A BGL-like named parameter mechanism is used in the constructors of this class. %Default values are available but if you need + * to set them, you can pass for `np` `CGAL::parameters::face_index_map(fim).halfedge_index_map(him).vertex_index_map(vim)` + * where `fim`, `him`, and `vim` are the respective index maps. The order of the arguments is not important and any of them can be + * missing if the default is fine. + * * \tparam Graph must be a model of a `FaceListGraph`, `HalfedgeListGraph`, and VertexListGraph. * \tparam FIMap a model of `ReadablePropertyMap` with `face_descriptor` as key and `graph_traits::%faces_size_type` as value * \tparam VIMap a model of `ReadablePropertyMap` with `vertex_descriptor` as key and `graph_traits::%vertices_size_type` as value @@ -95,37 +107,41 @@ struct Face_filtered_graph `face_descriptor` as key type and `graph_traits::%faces_size_type` as value type. * \tparam FacePatchIndexRange a model of `ConstRange` with `boost::property_traits::%value_type` as value type. - * \note the index maps must be initialized from `0` to the number of simplices. + * \tparam NamedParameters a sequence of named parameters * * \param graph the underlying graph. * \param face_patch_index_map the property_map that assigns a patch index to each face, with `face_descriptor` as key type and `boost::graph_traits::%faces_size_type` as value type. * \param selected_face_patch_indices a range of the face patch indices to select. - * \param fimap the property map that assigns an index to each face, - * with `face_descriptor` as key type and `boost::graph_traits::%faces_size_type` as value type - * \param vimap the property map that assigns an index to each vertex, - * with `vertex_descriptor` as key type and `boost::graph_traits::%vertices_size_type` as value type - * \param himap the property map that assigns an index to each halfedge, - * with `halfedge_descriptor` as key type and `boost::graph_traits::%halfedges_size_type` as value type + * \param np optional sequence of named parameters among the ones listed below + * + * \cgalNamedParamsBegin + * \cgalParamBegin{face_index_map} + * a property map containing an index for each face initialized from 0 to `num_vertices(graph)` + * \cgalParamEnd + * \cgalParamBegin{vertex_index_map} + * a property map containing an index for each vertex initialized 0 to `num_vertices(vertex)` + * \cgalParamEnd + * \cgalParamBegin{halfedge_index_map} + * a property map containing an index for each halfedge initialized 0 to `num_halfedges(graph)` + * \cgalParamEnd + * \cgalNamedParamsEnd */ - template + template Face_filtered_graph(const Graph& graph, const FacePatchIndexRange& selected_face_patch_indices, FacePatchIndexMap face_patch_index_map, - #ifdef DOXYGEN_RUNNING - FIMap fimap = get(CGAL::face_index, graph), - VIMap vimap = get(boost::vertex_index, graph), - HIMap himap = get(CGAL::halfedge_index, graph) - #else - FIMap fimap, - VIMap vimap, - HIMap himap, - typename boost::enable_if< - typename boost::has_range_const_iterator::type - >::type* = 0 + const CGAL_BGL_NP_CLASS& np + #ifndef DOXYGEN_RUNNING + , typename boost::enable_if< + typename boost::has_range_const_iterator::type + >::type* = 0 #endif ) - : _graph(const_cast(graph)), fimap(fimap), vimap(vimap), himap(himap) + : _graph(const_cast(graph)) + , fimap(boost::choose_param(get_param(np, internal_np::face_index), get_const_property_map(face_index, graph))) + , vimap(boost::choose_param(get_param(np, boost::vertex_index), get_const_property_map(boost::vertex_index, graph))) + , himap(boost::choose_param(get_param(np, internal_np::halfedge_index), get_const_property_map(halfedge_index, graph))) { set_selected_faces(selected_face_patch_indices, face_patch_index_map); } @@ -135,10 +151,10 @@ struct Face_filtered_graph const FacePatchIndexRange& selected_face_patch_indices, FacePatchIndexMap face_patch_index_map) : _graph(const_cast(graph)) + , fimap(get(CGAL::face_index, graph)) + , vimap(get(boost::vertex_index, graph)) + , himap(get(CGAL::halfedge_index, graph)) { - fimap = get(CGAL::face_index, graph); - vimap = get(boost::vertex_index, graph); - himap = get(CGAL::halfedge_index, graph); set_selected_faces(selected_face_patch_indices, face_patch_index_map); } /*! @@ -147,34 +163,36 @@ struct Face_filtered_graph * \tparam FacePatchIndexMap a model of `ReadablePropertyMap` with `face_descriptor` as key type and `graph_traits::%faces_size_type` as value type. - * \note the index maps must be initialized from `0` to the number of simplices. + * \tparam NamedParameters a sequence of named parameters * \param graph the underlying graph. * \param face_patch_index_map the property_map that assigns a patch index to each face, with `face_descriptor` as key type and `graph_traits::%faces_size_type` as value type. * \param selected_face_patch_index the index of the face patch selected. - * \param fimap the property map that assigns an index to each face, - * with `face_descriptor` as key type and `boost::graph_traits::%faces_size_type` as value type - * \param vimap the property map that assigns an index to each vertex, - * with `vertex_descriptor` as key type and `boost::graph_traits::%vertices_size_type` as value type - * \param himap the property map that assigns an index to each halfedge, - * with `halfedge_descriptor` as key type and `boost::graph_traits::%halfedges_size_type` as value type + * \param np optional sequence of named parameters among the ones listed below + * + * \cgalNamedParamsBegin + * \cgalParamBegin{face_index_map} + * a property map containing an index for each face initialized from 0 to `num_vertices(graph)` + * \cgalParamEnd + * \cgalParamBegin{vertex_index_map} + * a property map containing an index for each vertex initialized 0 to `num_vertices(vertex)` + * \cgalParamEnd + * \cgalParamBegin{halfedge_index_map} + * a property map containing an index for each halfedge initialized 0 to `num_halfedges(graph)` + * \cgalParamEnd + * \cgalNamedParamsEnd */ - template + template Face_filtered_graph(const Graph& graph, typename boost::property_traits::value_type selected_face_patch_index, FacePatchIndexMap face_patch_index_map, - #ifdef DOXYGEN_RUNNING - FIMap fimap = get(CGAL::face_index, graph), - VIMap vimap = get(boost::vertex_index, graph), - HIMap himap = get(CGAL::halfedge_index, graph) - #else - FIMap fimap, - VIMap vimap, - HIMap himap - #endif + const CGAL_BGL_NP_CLASS& np ) - : _graph(const_cast(graph)), fimap(fimap), vimap(vimap), himap(himap) + : _graph(const_cast(graph)) + , fimap(boost::choose_param(get_param(np, internal_np::face_index), get_const_property_map(face_index, graph))) + , vimap(boost::choose_param(get_param(np, boost::vertex_index), get_const_property_map(boost::vertex_index, graph))) + , himap(boost::choose_param(get_param(np, internal_np::halfedge_index), get_const_property_map(halfedge_index, graph))) { set_selected_faces(selected_face_patch_index, face_patch_index_map); } @@ -184,10 +202,10 @@ struct Face_filtered_graph typename boost::property_traits::value_type pid, FacePatchIndexMap face_patch_index_map) : _graph(const_cast(graph)) + , fimap(get(CGAL::face_index, graph)) + , vimap(get(boost::vertex_index, graph)) + , himap(get(CGAL::halfedge_index, graph)) { - fimap = get(CGAL::face_index, graph); - vimap = get(boost::vertex_index, graph); - himap = get(CGAL::halfedge_index, graph); set_selected_faces(face_patch_index_map, pid); } @@ -195,37 +213,46 @@ struct Face_filtered_graph * \brief Constructor where the set of selected faces is specified as a range of face descriptors. * * \tparam FaceRange a model of `ConstRange` with `face_descriptor` as value type. + * \tparam NamedParameters a sequence of named parameters * \note the index maps must be initialized from `0` to the number of simplices. * \param graph the graph containing the wanted patch. * \param selected_faces the set of selected faces. - * \param fimap the property map that assigns an index to each face, - * with `face_descriptor` as key type and `boost::graph_traits::%faces_size_type` as value type - * \param vimap the property map that assigns an index to each vertex, - * with `vertex_descriptor` as key type and `boost::graph_traits::%vertices_size_type` as value type - * \param himap the property map that assigns an index to each halfedge, - * with `halfedge_descriptor` as key type and `boost::graph_traits::%halfedges_size_type` as value type + * \param np optional sequence of named parameters among the ones listed below + * + * \cgalNamedParamsBegin + * \cgalParamBegin{face_index_map} + * a property map containing an index for each face initialized from 0 to `num_vertices(graph)` + * \cgalParamEnd + * \cgalParamBegin{vertex_index_map} + * a property map containing an index for each vertex initialized 0 to `num_vertices(vertex)` + * \cgalParamEnd + * \cgalParamBegin{halfedge_index_map} + * a property map containing an index for each halfedge initialized 0 to `num_halfedges(graph)` + * \cgalParamEnd + * \cgalNamedParamsEnd */ - template + template Face_filtered_graph(const Graph& graph, const FaceRange& selected_faces, - #ifdef DOXYGEN_RUNNING - FIMap fimap = get(CGAL::face_index, graph), - VIMap vimap = get(boost::vertex_index, graph), - HIMap himap = get(CGAL::halfedge_index, graph) - #else - FIMap fimap, - VIMap vimap, - HIMap himap - #endif - ) : _graph(const_cast(graph)), fimap(fimap), vimap(vimap), himap(himap) + const CGAL_BGL_NP_CLASS& np) + : _graph(const_cast(graph)) + , fimap(boost::choose_param(get_param(np, internal_np::face_index), get_const_property_map(face_index, graph))) + , vimap(boost::choose_param(get_param(np, boost::vertex_index), get_const_property_map(boost::vertex_index, graph))) + , himap(boost::choose_param(get_param(np, internal_np::halfedge_index), get_const_property_map(halfedge_index, graph))) { set_selected_faces(selected_faces); } template Face_filtered_graph(const Graph& graph, - const FaceRange& face_range); - + const FaceRange& selected_faces) + : _graph(const_cast(graph)) + , fimap(get(CGAL::face_index, graph)) + , vimap(get(boost::vertex_index, graph)) + , himap(get(CGAL::halfedge_index, graph)) + { + set_selected_faces(selected_faces); + } ///returns a const reference to the underlying graph. const Graph& graph()const{ return _graph; } diff --git a/BGL/test/BGL/test_Face_filtered_graph.cpp b/BGL/test/BGL/test_Face_filtered_graph.cpp index decf294fc92..132c9018a1e 100644 --- a/BGL/test/BGL/test_Face_filtered_graph.cpp +++ b/BGL/test/BGL/test_Face_filtered_graph.cpp @@ -456,8 +456,8 @@ main() Poly_Adapter poly_adapter(*poly, pids, poly_fccmap, - poly_fimap, - poly_vimap, - poly_himap); + CGAL::parameters::face_index_map(poly_fimap). + vertex_index_map(poly_vimap). + halfedge_index_map(poly_himap)); test_mesh(poly_adapter); } From 5c1ace5124ee043bf4f856681e6928dadad2f2fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 17 May 2017 15:56:12 +0200 Subject: [PATCH 30/38] add example and use bgllink macro --- BGL/doc/BGL/Doxyfile.in | 2 ++ BGL/doc/BGL/examples.txt | 2 ++ BGL/include/CGAL/boost/graph/Face_filtered_graph.h | 4 ++-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/BGL/doc/BGL/Doxyfile.in b/BGL/doc/BGL/Doxyfile.in index 9796b38035d..d70296e8886 100644 --- a/BGL/doc/BGL/Doxyfile.in +++ b/BGL/doc/BGL/Doxyfile.in @@ -12,6 +12,8 @@ INPUT += ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/Euler_operations.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/Dual.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/convert_nef_polyhedron_to_polygon_mesh.h EXAMPLE_PATH = ${CGAL_Surface_mesh_skeletonization_EXAMPLE_DIR} \ + ${CGAL_Surface_mesh_segmentation_EXAMPLE_DIR} \ + ${CGAL_Polygon_mesh_processing_EXAMPLE_DIR} \ ${CGAL_BGL_EXAMPLE_DIR} ALIASES += "bgllink{1}=\1" diff --git a/BGL/doc/BGL/examples.txt b/BGL/doc/BGL/examples.txt index c84dda9d44c..a700c3cf217 100644 --- a/BGL/doc/BGL/examples.txt +++ b/BGL/doc/BGL/examples.txt @@ -17,4 +17,6 @@ \example BGL_surface_mesh/prim.cpp \example BGL_surface_mesh/surface_mesh_dual.cpp \example Surface_mesh_skeletonization/simple_mcfskel_example.cpp +\example Surface_mesh_segmentation/extract_segmentation_into_mesh_example.cpp +\example Polygon_mesh_processing/face_filtered_graph_example.cpp */ diff --git a/BGL/include/CGAL/boost/graph/Face_filtered_graph.h b/BGL/include/CGAL/boost/graph/Face_filtered_graph.h index 3de8bfaf276..43b243bf66a 100644 --- a/BGL/include/CGAL/boost/graph/Face_filtered_graph.h +++ b/BGL/include/CGAL/boost/graph/Face_filtered_graph.h @@ -69,14 +69,14 @@ namespace CGAL * where `fim`, `him`, and `vim` are the respective index maps. The order of the arguments is not important and any of them can be * missing if the default is fine. * - * \tparam Graph must be a model of a `FaceListGraph`, `HalfedgeListGraph`, and VertexListGraph. + * \tparam Graph must be a model of a `FaceListGraph`, `HalfedgeListGraph`, and \bgllink{VertexListGraph}. * \tparam FIMap a model of `ReadablePropertyMap` with `face_descriptor` as key and `graph_traits::%faces_size_type` as value * \tparam VIMap a model of `ReadablePropertyMap` with `vertex_descriptor` as key and `graph_traits::%vertices_size_type` as value * \tparam HIMap a model of `ReadablePropertyMap` with `halfedge_descriptor` as key and `graph_traits::%halfedges_size_type` as value * * \cgalModels `FaceListGraph` * \cgalModels `HalfedgeListGraph` - * \cgalModels VertexListGraph + * \cgalModels \bgllink{VertexListGraph} */ template::type, From f457b0340d003b8277b498fd6abc2fe0301fcaf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 17 May 2017 15:58:53 +0200 Subject: [PATCH 31/38] remove extra note --- BGL/include/CGAL/boost/graph/Face_filtered_graph.h | 1 - 1 file changed, 1 deletion(-) diff --git a/BGL/include/CGAL/boost/graph/Face_filtered_graph.h b/BGL/include/CGAL/boost/graph/Face_filtered_graph.h index 43b243bf66a..a05f3c968c1 100644 --- a/BGL/include/CGAL/boost/graph/Face_filtered_graph.h +++ b/BGL/include/CGAL/boost/graph/Face_filtered_graph.h @@ -214,7 +214,6 @@ struct Face_filtered_graph * * \tparam FaceRange a model of `ConstRange` with `face_descriptor` as value type. * \tparam NamedParameters a sequence of named parameters - * \note the index maps must be initialized from `0` to the number of simplices. * \param graph the graph containing the wanted patch. * \param selected_faces the set of selected faces. * \param np optional sequence of named parameters among the ones listed below From 3de923a32c7d25889ac7e5d50701cecbb51c79d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 17 May 2017 16:19:48 +0200 Subject: [PATCH 32/38] remove functions from the classified reference manual copy_face_graph_patch does not exist and reserve is part of a concept --- BGL/doc/BGL/PackageDescription.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/BGL/doc/BGL/PackageDescription.txt b/BGL/doc/BGL/PackageDescription.txt index 3120cb99902..42397587333 100644 --- a/BGL/doc/BGL/PackageDescription.txt +++ b/BGL/doc/BGL/PackageDescription.txt @@ -343,8 +343,6 @@ user might encounter. - `CGAL::clear()` - `CGAL::copy_face_graph()` -- `CGAL::reserve()` -- `CGAL::copy_face_graph_patch()` ## Iterators ## - `CGAL::Halfedge_around_source_iterator` From c81e4444bf9d7b5ed847b8cc6a98c54e0f54d407 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 2 Jun 2017 10:26:14 +0200 Subject: [PATCH 33/38] Fix OpenMesh link errors and add a test for OpenMesh data. --- BGL/test/BGL/CMakeLists.txt | 6 ++++-- BGL/test/BGL/test_Face_filtered_graph.cpp | 9 ++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/BGL/test/BGL/CMakeLists.txt b/BGL/test/BGL/CMakeLists.txt index 8f68e5469d1..551b40ec2ca 100644 --- a/BGL/test/BGL/CMakeLists.txt +++ b/BGL/test/BGL/CMakeLists.txt @@ -87,12 +87,14 @@ create_single_source_cgal_program( "test_Has_member_id.cpp" ) create_single_source_cgal_program( "test_cgal_bgl_named_params.cpp" ) -create_single_source_cgal_program( "test_Face_filtered_graph.cpp" ) create_single_source_cgal_program( "graph_concept_Face_filtered_graph.cpp" ) - +create_single_source_cgal_program( "test_Face_filtered_graph.cpp" ) +if(OpenMesh_FOUND) + target_link_libraries( test_Face_filtered_graph ${OPENMESH_LIBRARIES}) +endif() if(OpenMesh_FOUND) target_link_libraries( test_clear ${OPENMESH_LIBRARIES}) diff --git a/BGL/test/BGL/test_Face_filtered_graph.cpp b/BGL/test/BGL/test_Face_filtered_graph.cpp index 132c9018a1e..7d3f9f1d94d 100644 --- a/BGL/test/BGL/test_Face_filtered_graph.cpp +++ b/BGL/test/BGL/test_Face_filtered_graph.cpp @@ -17,7 +17,7 @@ void test_halfedge_around_vertex_iterator(const Graph& g) typedef typename boost::graph_traits::face_descriptor g_face_descriptor; typedef CGAL::Face_filtered_graph Adapter; CGAL_GRAPH_TRAITS_MEMBERS(Adapter); - boost::unordered_map map(CGAL::num_faces(g)); + boost::unordered_map map(num_faces(g)); CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); @@ -398,8 +398,11 @@ int main() { test(sm_data()); +#ifdef CGAL_USE_OPENMESH + test(omesh_data()); +#endif //Make a tetrahedron and test the adapter for a patch that only contains 2 faces - typedef typename CGAL::Face_filtered_graph SM_Adapter; + typedef CGAL::Face_filtered_graph SM_Adapter; typedef SM::Property_map::face_descriptor , std::size_t> SM_FCCMap; SM* sm = new SM(); CGAL::make_tetrahedron( @@ -432,7 +435,7 @@ main() typedef boost::property_map::type FIMap; typedef boost::property_map::type VIMap; typedef boost::property_map::type HIMap; - typedef typename CGAL::Face_filtered_graph Poly_Adapter; + typedef CGAL::Face_filtered_graph Poly_Adapter; Polyhedron *poly = new Polyhedron(); CGAL::make_tetrahedron( Point_3(1,1,1), From c3eac61ace78173abe47ebaad33ed8c5d060b69e Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Tue, 6 Jun 2017 09:31:41 +0200 Subject: [PATCH 34/38] Fix path to example --- .../doc/Polygon_mesh_processing/examples.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt index 3c535ae0ccf..c48fdb07ad1 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt @@ -7,7 +7,7 @@ \example Polygon_mesh_processing/point_inside_example.cpp \example Polygon_mesh_processing/triangulate_faces_example.cpp \example Polygon_mesh_processing/connected_components_example.cpp -\example Polygon_mesh_processing/filtered_face_graph_example.cpp +\example Polygon_mesh_processing/face_filtered_graph_example.cpp \example Polygon_mesh_processing/polygon_soup_example.cpp \example Polygon_mesh_processing/triangulate_polyline_example.cpp \example Polygon_mesh_processing/refine_fair_example.cpp From f9df1e23570996e9eb87366d2015e2deebfebd69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 7 Jun 2017 16:22:33 +0200 Subject: [PATCH 35/38] fix conversion warnings --- .../CGAL/boost/graph/Face_filtered_graph.h | 37 +++++++++++-------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/BGL/include/CGAL/boost/graph/Face_filtered_graph.h b/BGL/include/CGAL/boost/graph/Face_filtered_graph.h index a05f3c968c1..34ac67e2edf 100644 --- a/BGL/include/CGAL/boost/graph/Face_filtered_graph.h +++ b/BGL/include/CGAL/boost/graph/Face_filtered_graph.h @@ -93,6 +93,12 @@ struct Face_filtered_graph typedef typename boost::graph_traits::edge_descriptor edge_descriptor; /// Face descriptor type typedef typename boost::graph_traits::face_descriptor face_descriptor; + /// Size type + #ifndef DOXYGEN_RUNNING + typedef boost::dynamic_bitset<>::size_type size_type; + #else + typedef unspecified_type size_type; + #endif // non documented types typedef typename boost::property_traits< FIMap >::value_type face_index_type; @@ -376,20 +382,17 @@ struct Face_filtered_graph return selected_halfedges[get(himap, h)]; } ///returns the number of selected faces - typename boost::graph_traits:: - faces_size_type number_of_faces()const + size_type number_of_faces()const { return selected_faces.count(); } ///returns the number of selected vertices. - typename boost::graph_traits:: - vertices_size_type number_of_vertices()const + size_type number_of_vertices()const { return selected_vertices.count(); } ///returns the number of selected halfedges. - typename boost::graph_traits:: - halfedges_size_type number_of_halfedges()const + size_type number_of_halfedges()const { return selected_halfedges.count(); } @@ -544,10 +547,10 @@ struct graph_traits< CGAL::Face_filtered_graph > typedef typename BGTG::directed_category directed_category; typedef typename BGTG::edge_parallel_category edge_parallel_category; typedef typename BGTG::traversal_category traversal_category; - typedef typename BGTG::vertices_size_type vertices_size_type; - typedef typename BGTG::edges_size_type edges_size_type; - typedef typename BGTG::halfedges_size_type halfedges_size_type; - typedef typename BGTG::faces_size_type faces_size_type; + typedef typename boost::dynamic_bitset<>::size_type vertices_size_type; + typedef typename boost::dynamic_bitset<>::size_type edges_size_type; + typedef typename boost::dynamic_bitset<>::size_type halfedges_size_type; + typedef typename boost::dynamic_bitset<>::size_type faces_size_type; typedef typename BGTG::degree_size_type degree_size_type; static vertex_descriptor null_vertex() @@ -633,7 +636,7 @@ template -typename boost::graph_traits::vertices_size_type +typename Face_filtered_graph::size_type num_vertices(const Face_filtered_graph& w) { return w.number_of_vertices(); @@ -643,7 +646,7 @@ template -typename boost::graph_traits::edges_size_type +typename Face_filtered_graph::size_type num_edges(const Face_filtered_graph& w) { return w.number_of_halfedges()/2; @@ -679,7 +682,8 @@ out_degree(typename boost::graph_traits& w) { CGAL_assertion(in_CC(v, w)); - return std::distance(out_edges(v, w).first ,out_edges(v, w).second); + return static_cast::degree_size_type>( + std::distance(out_edges(v, w).first ,out_edges(v, w).second) ); } template& w) { CGAL_assertion(in_CC(v, w)); - return std::distance(in_edges(v, w).first ,in_edges(v, w).second); + return static_cast::degree_size_type>( + std::distance(in_edges(v, w).first ,in_edges(v, w).second) ); } template -typename boost::graph_traits::halfedges_size_type +typename Face_filtered_graph::size_type num_halfedges(const Face_filtered_graph & w) { return w.number_of_halfedges(); @@ -1040,7 +1045,7 @@ template -typename boost::graph_traits::vertices_size_type +typename Face_filtered_graph::size_type num_faces(const Face_filtered_graph & w) { return w.number_of_faces(); From 1c07419cc5c74955b119f171c276c81d30d5eec9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 8 Jun 2017 10:15:30 +0200 Subject: [PATCH 36/38] fix unused variable warning --- BGL/test/BGL/test_Face_filtered_graph.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BGL/test/BGL/test_Face_filtered_graph.cpp b/BGL/test/BGL/test_Face_filtered_graph.cpp index 7d3f9f1d94d..75427a24292 100644 --- a/BGL/test/BGL/test_Face_filtered_graph.cpp +++ b/BGL/test/BGL/test_Face_filtered_graph.cpp @@ -363,7 +363,7 @@ void test_mesh(Adapter fga) CGAL_assertion(num_halfedges(fga) == 10); CGAL_assertion(num_vertices(fga) == 4); halfedge_descriptor h = halfedge(*faces(fga).first, fga); - vertex_descriptor v = source(h, fga); + CGAL_assertion_code( vertex_descriptor v = source(h, fga) ); //check that next() works inside the patch CGAL_assertion( next(next(next(h, fga), fga), fga) == h From a570495a0fd30084ff57cceb5e7acd703bb09814 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 15 Jun 2017 16:03:59 +0200 Subject: [PATCH 37/38] Fix face() for border halfedges. --- BGL/include/CGAL/boost/graph/Face_filtered_graph.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/BGL/include/CGAL/boost/graph/Face_filtered_graph.h b/BGL/include/CGAL/boost/graph/Face_filtered_graph.h index 34ac67e2edf..5e375a9fe80 100644 --- a/BGL/include/CGAL/boost/graph/Face_filtered_graph.h +++ b/BGL/include/CGAL/boost/graph/Face_filtered_graph.h @@ -1003,7 +1003,9 @@ face(typename boost::graph_traits< Face_filtered_graph & w) { CGAL_assertion(CGAL::in_CC(h, w)); - if(in_CC(face(h,w.graph()), w)) + if(face(h, w.graph()) == boost::graph_traits::null_face()) // h is a border hafedge + return boost::graph_traits< CGAL::Face_filtered_graph >::null_face(); + else if(in_CC(face(h,w.graph()), w)) return face(h,w.graph()); else return boost::graph_traits< CGAL::Face_filtered_graph >::null_face(); From 9c828b4d32d1921f3b4c6cf62fc547f4b4cb0270 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 16 Jun 2017 14:26:52 +0200 Subject: [PATCH 38/38] Use version 2.6.3 of qglviewer instead of master --- .travis/build_package.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis/build_package.sh b/.travis/build_package.sh index 4db46faba23..2bb583ef54d 100755 --- a/.travis/build_package.sh +++ b/.travis/build_package.sh @@ -19,7 +19,7 @@ function build_demo { cd build-travis if [ $NEED_3D = 1 ]; then #install libqglviewer - git clone --depth=1 https://github.com/GillesDebunne/libQGLViewer.git ./qglviewer + git clone --depth=4 -b v2.6.3 --single-branch https://github.com/GillesDebunne/libQGLViewer.git ./qglviewer pushd ./qglviewer/QGLViewer #use qt5 instead of qt4 export QT_SELECT=5