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; +} +