diff --git a/BGL/doc/BGL/CGAL/HalfedgeDS_face_max_base_with_id.h b/BGL/doc/BGL/CGAL/HalfedgeDS_face_max_base_with_id.h index 446481b9fc4..0006a4332e8 100644 --- a/BGL/doc/BGL/CGAL/HalfedgeDS_face_max_base_with_id.h +++ b/BGL/doc/BGL/CGAL/HalfedgeDS_face_max_base_with_id.h @@ -2,7 +2,7 @@ namespace CGAL { /*! -\ingroup PkgBGLHelper +\ingroup BGLGraphExternalIndices The class `HalfedgeDS_face_max_base_with_id` is a model of the `HalfedgeDSFace` concept. diff --git a/BGL/doc/BGL/CGAL/HalfedgeDS_halfedge_max_base_with_id.h b/BGL/doc/BGL/CGAL/HalfedgeDS_halfedge_max_base_with_id.h index 6e597c7d346..b9d7f4142eb 100644 --- a/BGL/doc/BGL/CGAL/HalfedgeDS_halfedge_max_base_with_id.h +++ b/BGL/doc/BGL/CGAL/HalfedgeDS_halfedge_max_base_with_id.h @@ -2,7 +2,7 @@ namespace CGAL { /*! -\ingroup PkgBGLHelper +\ingroup BGLGraphExternalIndices The class `HalfedgeDS_halfedge_max_base_with_id` is a model of the `HalfedgeDSHalfedge` concept. diff --git a/BGL/doc/BGL/CGAL/HalfedgeDS_vertex_max_base_with_id.h b/BGL/doc/BGL/CGAL/HalfedgeDS_vertex_max_base_with_id.h index 0839d254c8f..565236d880e 100644 --- a/BGL/doc/BGL/CGAL/HalfedgeDS_vertex_max_base_with_id.h +++ b/BGL/doc/BGL/CGAL/HalfedgeDS_vertex_max_base_with_id.h @@ -2,7 +2,7 @@ namespace CGAL { /*! -\ingroup PkgBGLHelper +\ingroup BGLGraphExternalIndices The class `HalfedgeDS_vertex_max_base_with_id` is a model of the `HalfedgeDSVertex` concept. It is diff --git a/BGL/doc/BGL/CGAL/Linear_cell_complex_bgl_min_items.h b/BGL/doc/BGL/CGAL/Linear_cell_complex_bgl_min_items.h index 0c9ab30a613..611ff3cd88b 100644 --- a/BGL/doc/BGL/CGAL/Linear_cell_complex_bgl_min_items.h +++ b/BGL/doc/BGL/CGAL/Linear_cell_complex_bgl_min_items.h @@ -2,7 +2,7 @@ namespace CGAL { /*! -\ingroup PkgBGLHelper +\ingroup BGLGraphExternalIndices The class `Linear_cell_complex_bgl_min_items` defines `void` as the information associated with darts, darts have ids and 0- and 2-attributes are enabled and have ids. diff --git a/BGL/doc/BGL/CGAL/Linear_cell_complex_for_bgl_combinatorial_map_helper.h b/BGL/doc/BGL/CGAL/Linear_cell_complex_for_bgl_combinatorial_map_helper.h index 72ba704077c..8bebd8f9e53 100644 --- a/BGL/doc/BGL/CGAL/Linear_cell_complex_for_bgl_combinatorial_map_helper.h +++ b/BGL/doc/BGL/CGAL/Linear_cell_complex_for_bgl_combinatorial_map_helper.h @@ -2,7 +2,7 @@ namespace CGAL { /*! -\ingroup PkgBGLHelper +\ingroup BGLGraphExternalIndices The class `Linear_cell_complex_for_bgl_combinatorial_map_helper` defines a `CGAL::Linear_cell_complex_for_combinatorial_map` as inner type, named `type`, having `CGAL::Linear_cell_complex_bgl_min_items` as items class. With this item class, no information are associated with darts, darts have ids and 0- and 2-attributes are enabled and have ids. diff --git a/BGL/doc/BGL/CGAL/Polyhedron_items_with_id_3.h b/BGL/doc/BGL/CGAL/Polyhedron_items_with_id_3.h index fdfee46c400..a64795aaa74 100644 --- a/BGL/doc/BGL/CGAL/Polyhedron_items_with_id_3.h +++ b/BGL/doc/BGL/CGAL/Polyhedron_items_with_id_3.h @@ -2,7 +2,7 @@ namespace CGAL { /*! -\ingroup PkgBGLHelper +\ingroup BGLGraphExternalIndices The class `Polyhedron_items_with_id_3` is a model of the `PolyhedronItems_3` concept. It provides definitions for vertices with points, halfedges, @@ -63,7 +63,7 @@ public: /*! -\ingroup PkgBGLHelper +\ingroup BGLGraphExternalIndices Given a `CGAL::Polyhedron_3`, for each simplex type (vertex, halfedge, facet) associates an index from diff --git a/BGL/doc/BGL/CGAL/Triangulation_face_base_with_id_2.h b/BGL/doc/BGL/CGAL/Triangulation_face_base_with_id_2.h index 83e14e58af7..15827d6758b 100644 --- a/BGL/doc/BGL/CGAL/Triangulation_face_base_with_id_2.h +++ b/BGL/doc/BGL/CGAL/Triangulation_face_base_with_id_2.h @@ -1,15 +1,16 @@ namespace CGAL { /*! -\ingroup PkgBGLHelper +\ingroup BGLGraphExternalIndices The class `Triangulation_face_base_with_id_2` is a model of the concept `TriangulationFaceBase_2`, the base face of a -2D-triangulation. It provides an integer field that can be used to +2D-triangulation. It provides an integer field that can be used to index faces for \sc{Bgl} algorithms. Note that the user is in charge of setting indices correctly before -running a graph algorithm. +running a graph algorithm, by calling the function +`CGAL::set_triangulation_ids(Triangulation&)`. \tparam TriangulationTraits_2 is the geometric traits class and must be a model of `TriangulationTraits_2`. @@ -42,4 +43,19 @@ int& id(); /// @} }; /* end Triangulation_face_base_with_id_2 */ + +/// \ingroup BGLGraphExternalIndices +/// +/// This function initializes vertex, edge, and face indices of the triangulation `tr` and must +/// be called prior to using `tr` as a BGL graph in an algorithm that requires +/// vertex, halfedge, edge, or face indices. +/// +/// \tparam Triangulation a 2D triangulation of \cgal, whose combinatorial data structure +/// has been initialized with the vertex and face classes `Triangulation_vertex_base_with_id_2` +/// and `Triangulation_face_base_with_id_2`. +/// +/// \sa the \ref PkgTriangulation2 package +template +void set_triangulation_ids(Triangulation& tr); + } /* end namespace CGAL */ diff --git a/BGL/doc/BGL/CGAL/Triangulation_vertex_base_with_id_2.h b/BGL/doc/BGL/CGAL/Triangulation_vertex_base_with_id_2.h index a93691aa0b4..bc156657b30 100644 --- a/BGL/doc/BGL/CGAL/Triangulation_vertex_base_with_id_2.h +++ b/BGL/doc/BGL/CGAL/Triangulation_vertex_base_with_id_2.h @@ -1,7 +1,7 @@ namespace CGAL { /*! -\ingroup PkgBGLHelper +\ingroup BGLGraphExternalIndices The class `Triangulation_vertex_base_with_id_2` is a model of the concept `TriangulationVertexBase_2`, the base vertex of a @@ -9,7 +9,8 @@ concept `TriangulationVertexBase_2`, the base vertex of a index vertices for \sc{Bgl} algorithms. Note that the user is in charge of setting indices correctly before -running a graph algorithm. +running a graph algorithm, by calling the function +`CGAL::set_triangulation_ids(Triangulation&)`. \tparam TriangulationTraits_2 is the geometric traits class and must be a model of `TriangulationTraits_2`. diff --git a/BGL/doc/BGL/CGAL/boost/graph/properties.h b/BGL/doc/BGL/CGAL/boost/graph/properties.h index cf6c46860b5..a7416d53eae 100644 --- a/BGL/doc/BGL/CGAL/boost/graph/properties.h +++ b/BGL/doc/BGL/CGAL/boost/graph/properties.h @@ -1,5 +1,5 @@ -/// Boost Namespace -namespace boost { +/// CGAL Namespace +namespace CGAL { /// \ingroup PkgBGLProperties /// @{ @@ -34,9 +34,6 @@ enum face_index_t { face_index }; enum vertex_point_t { vertex_point }; /// @} -} // namespace boost - -namespace CGAL { /// \ingroup PkgBGLProperties /// diff --git a/BGL/doc/BGL/NamedParameters.txt b/BGL/doc/BGL/NamedParameters.txt index ce3be60f8f4..47c1d3f866a 100644 --- a/BGL/doc/BGL/NamedParameters.txt +++ b/BGL/doc/BGL/NamedParameters.txt @@ -38,38 +38,51 @@ a \cgal point type as value type. \n \cgalNPEnd \cgalNPBegin{vertex_index_map} \anchor BGL_vertex_index_map -is the property map containing the index of each vertex of the input polygon mesh.\n +is the property map associating a unique index to each vertex of a polygon mesh `g`, +between `0` and `num_vertices(g)-1`. +If this parameter is not passed, internal machinery will create and initialize a vertex index +property map, either using the internal property map if it exists or using an external map. The latter +might result in - slightly - worsened performance in case of non-constant complexity for index access.\n Type: a class model of `ReadablePropertyMap` with `boost::graph_traits::%vertex_descriptor` as key type and the value type \code typename boost::property_traits::type>::value_type \endcode -Default: \code boost::get(CGAL::vertex_index, pmesh)\endcode +Default: an initialized vertex index property map \cgalNPEnd \cgalNPBegin{halfedge_index_map} \anchor BGL_halfedge_index_map -is the property map containing the index of each halfedge of the input polygon mesh.\n +is the property map associating a unique index to each halfedge of a polygon mesh, +between `0` and `num_halfedges(g)-1`. +If this parameter is not passed, internal machinery will create and initialize a halfedge index +property map, either using the internal property map if it exists or using an external map. The latter +might result in - slightly - worsened performance in case of non-constant complexity for index access.\n Type: a class model of `ReadablePropertyMap` with `boost::graph_traits::%halfedge_descriptor` as key type and the value type: \code typename boost::property_traits::type>::value_type \endcode -Default: \code boost::get(CGAL::halfedge_index, pmesh)\endcode -If this internal property map exists, its values should be initialized. +Default: an initialized halfedge index property map \cgalNPEnd \cgalNPBegin{edge_index_map} \anchor BGL_edge_index_map -is the property map containing the index of each edge of the input polygon mesh.\n +is the property map associating a unique index to each edge of a polygon mesh, +between `0` and `num_edges(g)-1`. +If this parameter is not passed, internal machinery will create and initialize a edge index +property map, either using the internal property map if it exists or using an external map. The latter +might result in - slightly - worsened performance in case of non-constant complexity for index access.\n Type: a class model of `ReadablePropertyMap` with `boost::graph_traits::%edge_descriptor` as key type and the value type: \code typename boost::property_traits::type>::value_type \endcode -Default: \code boost::get(CGAL::edge_index, pmesh)\endcode -If this internal property map exists, its values should be initialized. +Default: an initialized edge index property map \cgalNPEnd \cgalNPBegin{face_index_map} \anchor BGL_face_index_map -is the property map containing the index of each face of the input polygon mesh.\n +is the property map associating a unique index to each face of a polygon mesh, +between `0` and `num_faces(g)-1`. +If this parameter is not passed, internal machinery will create and initialize a face index +property map, either using the internal property map if it exists or using an external map. The latter +might result in - slightly - worsened performance in case of non-constant complexity for index access.\n Type: a class model of `ReadablePropertyMap` with `boost::graph_traits::%face_descriptor` as key type and the value type: \code typename boost::property_traits::type>::value_type \endcode -Default: \code boost::get(CGAL::face_index, pmesh)\endcode -If this internal property map exists, its values should be initialized. +Default: an initialized face index property map \cgalNPEnd \cgalNPBegin{edge_is_constrained_map} \anchor BGL_edge_is_constrained_map diff --git a/BGL/doc/BGL/PackageDescription.txt b/BGL/doc/BGL/PackageDescription.txt index 7f6e70bfa86..9c512e780ce 100644 --- a/BGL/doc/BGL/PackageDescription.txt +++ b/BGL/doc/BGL/PackageDescription.txt @@ -443,7 +443,7 @@ the requirement for traversal of all faces in a graph. /// \defgroup PkgBGLPropertiesDynamic Dynamic Properties /// \ingroup PkgBGLRef -/// \defgroup PkgBGLHelper Helper Classes +/// \defgroup PkgBGLGraphExternalIndices External Indices /// \ingroup PkgBGLRef /// \defgroup PkgBGLHelperFct Helper Functions @@ -473,8 +473,11 @@ The dynamic property tags enable to associate information to simplices of a `Fac */ /*! -\addtogroup PkgBGLHelper -Several classes that enable to store ids in vertices/halfedges/faces of a `CGAL::Polyhedron_3`, as well as adapters such as `CGAL::Dual`. +\addtogroup BGLGraphExternalIndices +A number of BGL and \cgal algorithms require the graph to have (initialized) integer-like indices +for its vertices, edges, or faces. However, not all graphs intrinsically offer a natural way +to attach a unique ID to each element. The following classes and functions paliate this +by attaching and initializing external IDs to the elements of the graph. */ /*! @@ -574,25 +577,25 @@ Methods to read and write graphs. - `MutableFaceGraph` \cgalCRPSection{Properties} -- `boost::vertex_index_t` -- `boost::halfedge_index_t` -- `boost::edge_index_t` -- `boost::face_index_t` -- `boost::vertex_point_t` +- `CGAL::vertex_index_t` +- `CGAL::halfedge_index_t` +- `CGAL::edge_index_t` +- `CGAL::face_index_t` +- `CGAL::vertex_point_t` \cgalCRPSection{%CGAL Classes Adapted for the Graph API} -Different \cgal types have been adapted as graphs for the \sc{Bgl}. All +A number of \cgal structures have been adapted as graphs for the \sc{Bgl}. All adapted types are listed here. The pages document which concepts they model, the properties they support, and any possible caveats that a user might encounter. -- \link BGLSMGT `boost::graph_traits< CGAL::Surface_mesh

>` \endlink +- \link BGLSMGT `boost::graph_traits >` \endlink - \link BGLPolyGT `boost::graph_traits< CGAL::Polyhedron_3 >` \endlink -- \link BGLLCCGT `boost::graph_traits< CGAL::Linear_cell_complex_for_combinatorial_map<...> >` \endlink +- \link BGLLCCGT `boost::graph_traits >` \endlink - \link BGLSeam_meshGT `boost::graph_traits< CGAL::Seam_mesh >` \endlink -- \link BGLT2GT `boost::graph_traits< CGAL::Triangulation_2 >` \endlink -- \link BGLArgtGT `boost::graph_traits< CGAL::Arrangement_2 >` \endlink +- \link BGLT2GT `boost::graph_traits >` \endlink and other 2D triangulations +- \link BGLArgtGT `boost::graph_traits >` \endlink - \link BGLOMPAK `boost::graph_traits >` \endlink - \link BGLOMTMAK `boost::graph_traits >` \endlink @@ -642,6 +645,8 @@ user might encounter. - `CGAL::clear()` - `CGAL::copy_face_graph()` +- `CGAL::set_triangulation_ids()` + \cgalCRPSection{Iterators} - `CGAL::Halfedge_around_source_iterator` - `CGAL::Halfedge_around_target_iterator` diff --git a/BGL/include/CGAL/boost/graph/Face_filtered_graph.h b/BGL/include/CGAL/boost/graph/Face_filtered_graph.h index ffd943fb9c4..875eb7f3e73 100644 --- a/BGL/include/CGAL/boost/graph/Face_filtered_graph.h +++ b/BGL/include/CGAL/boost/graph/Face_filtered_graph.h @@ -16,23 +16,24 @@ #include #include #include +#include #include -#include -#include -#include -#include #include -#include +#include +#include + #include +#include +#include #include +#include #ifdef DOXYGEN_RUNNING #define CGAL_BGL_NP_TEMPLATE_PARAMETERS NamedParameters #define CGAL_BGL_NP_CLASS NamedParameters #endif -namespace CGAL -{ +namespace CGAL { /*! * \ingroup PkgBGLAdaptors @@ -62,18 +63,18 @@ namespace CGAL * missing if the default is fine. * * \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 + * \tparam FIMap a model of `ReadablePropertyMap` with `graph_traits::%face_descriptor` as key and `graph_traits::%faces_size_type` as value + * \tparam VIMap a model of `ReadablePropertyMap` with `graph_traits::%vertex_descriptor` as key and `graph_traits::%vertices_size_type` as value + * \tparam HIMap a model of `ReadablePropertyMap` with `graph_traits::%halfedge_descriptor` as key and `graph_traits::%halfedges_size_type` as value * * \cgalModels `FaceListGraph` * \cgalModels `HalfedgeListGraph` * \cgalModels \bgllink{VertexListGraph} */ template::type, - typename VIMap = typename boost::property_map::type, - typename HIMap = typename boost::property_map::type> + typename FIMap = Default, + typename VIMap = Default, + typename HIMap = Default> struct Face_filtered_graph { typedef boost::graph_traits gt; @@ -93,10 +94,15 @@ struct Face_filtered_graph #endif // 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; + typedef typename Default::Get::const_type>::type FIM; + typedef typename Default::Get::const_type>::type VIM; + typedef typename Default::Get::const_type>::type HIM; + + typedef typename boost::property_traits::value_type face_index_type; + typedef typename boost::property_traits::value_type vertex_index_type; + typedef typename boost::property_traits::value_type halfedge_index_type; + + typedef Face_filtered_graph Self; /*! * \brief Constructor where the set of selected faces is specified as a range of patch ids. @@ -115,31 +121,31 @@ struct Face_filtered_graph * * \cgalNamedParamsBegin * \cgalParamBegin{face_index_map} - * a property map containing an index for each face initialized from 0 to `num_vertices(graph)` + * a property map containing for each face of `graph` a unique index between `0` and `num_faces(graph)-1` * \cgalParamEnd * \cgalParamBegin{vertex_index_map} - * a property map containing an index for each vertex initialized 0 to `num_vertices(graph)` + * a property map containing for each vertex of `graph` a unique index between `0` and `num_vertices(graph)-1` * \cgalParamEnd * \cgalParamBegin{halfedge_index_map} - * a property map containing an index for each halfedge initialized 0 to `num_halfedges(graph)` + * a property map containing for each halfedge of `graph` a unique index between `0` and `num_halfedges(graph)-1` * \cgalParamEnd * \cgalNamedParamsEnd */ template Face_filtered_graph(const Graph& graph, const FacePatchIndexRange& selected_face_patch_indices, - FacePatchIndexMap face_patch_index_map, - 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(parameters::choose_parameter(parameters::get_parameter(np, internal_np::face_index), get_const_property_map(face_index, graph))) - , vimap(parameters::choose_parameter(parameters::get_parameter(np, internal_np::vertex_index), get_const_property_map(boost::vertex_index, graph))) - , himap(parameters::choose_parameter(parameters::get_parameter(np, internal_np::halfedge_index), get_const_property_map(halfedge_index, graph))) + FacePatchIndexMap face_patch_index_map, + 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(CGAL::get_initialized_face_index_map(graph, np)), + vimap(CGAL::get_initialized_vertex_index_map(graph, np)), + himap(CGAL::get_initialized_halfedge_index_map(graph, np)) { set_selected_faces(selected_face_patch_indices, face_patch_index_map); } @@ -152,10 +158,10 @@ struct Face_filtered_graph typename boost::has_range_const_iterator::type >::type* = 0 ) - : _graph(const_cast(graph)) - , fimap(get(CGAL::face_index, graph)) - , vimap(get(boost::vertex_index, graph)) - , himap(get(CGAL::halfedge_index, graph)) + : _graph(const_cast(graph)), + fimap(CGAL::get_initialized_face_index_map(graph)), + vimap(CGAL::get_initialized_vertex_index_map(graph)), + himap(CGAL::get_initialized_halfedge_index_map(graph)) { set_selected_faces(selected_face_patch_indices, face_patch_index_map); } @@ -175,38 +181,37 @@ struct Face_filtered_graph * * \cgalNamedParamsBegin * \cgalParamBegin{face_index_map} - * a property map containing an index for each face initialized from 0 to `num_vertices(graph)` + * a property map containing for each face of `graph` a unique index between `0` and `num_faces(graph)-1` * \cgalParamEnd * \cgalParamBegin{vertex_index_map} - * a property map containing an index for each vertex initialized 0 to `num_vertices(graph)` + * a property map containing for each vertex of `graph` a unique index between `0` and `num_vertices(graph)-1` * \cgalParamEnd * \cgalParamBegin{halfedge_index_map} - * a property map containing an index for each halfedge initialized 0 to `num_halfedges(graph)` + * a property map containing for each halfedge of `graph` a unique index between `0` and `num_halfedges(graph)-1` * \cgalParamEnd * \cgalNamedParamsEnd */ template Face_filtered_graph(const Graph& graph, - typename boost::property_traits::value_type selected_face_patch_index, - FacePatchIndexMap face_patch_index_map, - const CGAL_BGL_NP_CLASS& np - ) - : _graph(const_cast(graph)) - , fimap(parameters::choose_parameter(parameters::get_parameter(np, internal_np::face_index), get_const_property_map(face_index, graph))) - , vimap(parameters::choose_parameter(parameters::get_parameter(np, internal_np::vertex_index), get_const_property_map(boost::vertex_index, graph))) - , himap(parameters::choose_parameter(parameters::get_parameter(np, internal_np::halfedge_index), get_const_property_map(halfedge_index, graph))) + typename boost::property_traits::value_type selected_face_patch_index, + FacePatchIndexMap face_patch_index_map, + const CGAL_BGL_NP_CLASS& np) + : _graph(const_cast(graph)), + fimap(CGAL::get_initialized_face_index_map(graph, np)), + vimap(CGAL::get_initialized_vertex_index_map(graph, np)), + himap(CGAL::get_initialized_halfedge_index_map(graph, np)) { set_selected_faces(selected_face_patch_index, face_patch_index_map); } template Face_filtered_graph(const Graph& 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)) + typename boost::property_traits::value_type pid, + FacePatchIndexMap face_patch_index_map) + : _graph(const_cast(graph)), + fimap(CGAL::get_initialized_face_index_map(graph)), + vimap(CGAL::get_initialized_vertex_index_map(graph)), + himap(CGAL::get_initialized_halfedge_index_map(graph)) { set_selected_faces(pid, face_patch_index_map); } @@ -236,10 +241,10 @@ struct Face_filtered_graph Face_filtered_graph(const Graph& graph, const FaceRange& selected_faces, const CGAL_BGL_NP_CLASS& np) - : _graph(const_cast(graph)) - , fimap(parameters::choose_parameter(parameters::get_parameter(np, internal_np::face_index), get_const_property_map(face_index, graph))) - , vimap(parameters::choose_parameter(parameters::get_parameter(np, internal_np::vertex_index), get_const_property_map(boost::vertex_index, graph))) - , himap(parameters::choose_parameter(parameters::get_parameter(np, internal_np::halfedge_index), get_const_property_map(halfedge_index, graph))) + : _graph(const_cast(graph)), + fimap(CGAL::get_initialized_face_index_map(graph, np)), + vimap(CGAL::get_initialized_vertex_index_map(graph, np)), + himap(CGAL::get_initialized_halfedge_index_map(graph, np)) { set_selected_faces(selected_faces); } @@ -247,10 +252,10 @@ struct Face_filtered_graph template Face_filtered_graph(const Graph& graph, 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)) + : _graph(const_cast(graph)), + fimap(CGAL::get_initialized_face_index_map(graph)), + vimap(CGAL::get_initialized_vertex_index_map(graph)), + himap(CGAL::get_initialized_halfedge_index_map(graph)) { set_selected_faces(selected_faces); } @@ -293,12 +298,12 @@ struct Face_filtered_graph template void set_selected_faces(const FacePatchIndexRange& selected_face_patch_indices, FacePatchIndexMap face_patch_index_map - #ifndef DOXYGEN_RUNNING +#ifndef DOXYGEN_RUNNING , typename boost::enable_if< typename boost::has_range_const_iterator::type >::type* = 0 - #endif - ) +#endif + ) { face_indices.clear(); vertex_indices.clear(); @@ -407,7 +412,7 @@ struct Face_filtered_graph return selected_halfedges.count(); } - Property_map_binder< FIMap, typename Pointer_property_map< typename boost::property_traits< FIMap >::value_type >::type > + Property_map_binder::value_type>::type> get_face_index_map() const { if (face_indices.empty()) @@ -422,7 +427,7 @@ struct Face_filtered_graph 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 > + Property_map_binder::value_type>::type> get_vertex_index_map() const { if (vertex_indices.empty()) @@ -437,7 +442,7 @@ struct Face_filtered_graph 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 > + Property_map_binder::value_type >::type> get_halfedge_index_map() const { if (halfedge_indices.empty()) @@ -510,9 +515,9 @@ struct Face_filtered_graph private: Graph& _graph; - FIMap fimap; - VIMap vimap; - HIMap himap; + FIM fimap; + VIM vimap; + HIM himap; boost::dynamic_bitset<> selected_faces; boost::dynamic_bitset<> selected_vertices; boost::dynamic_bitset<> selected_halfedges; @@ -1142,38 +1147,40 @@ CGAL_FILTERED_FACE_GRAPH_DYNAMIC_PMAP_SPECIALIZATION(dynamic_face_property_t) #undef CGAL_FILTERED_FACE_GRAPH_DYNAMIC_PMAP_SPECIALIZATION - - //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, CGAL::face_index_t> +{ + typedef typename CGAL::Face_filtered_graph::FIM FIM; + typedef typename CGAL::Property_map_binder::value_type>::type> type; + typedef type const_type; +}; + +template +struct property_map, boost::vertex_index_t> +{ + typedef typename CGAL::Face_filtered_graph::VIM VIM; + typedef typename CGAL::Property_map_binder::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; +struct property_map, CGAL::halfedge_index_t> +{ + typedef typename CGAL::Face_filtered_graph::HIM HIM; + typedef typename CGAL::Property_map_binder::value_type>::type> type; + typedef type const_type; }; -template +} // namespace boost -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_FACE_FILTERED_GRAPH_H diff --git a/BGL/include/CGAL/boost/graph/IO/VTK.h b/BGL/include/CGAL/boost/graph/IO/VTK.h index 618942eaefe..5771ee19cb4 100644 --- a/BGL/include/CGAL/boost/graph/IO/VTK.h +++ b/BGL/include/CGAL/boost/graph/IO/VTK.h @@ -148,13 +148,8 @@ void write_polys(std::ostream& os, typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; typedef typename boost::graph_traits::face_descriptor face_descriptor; - typedef typename CGAL::GetVertexIndexMap::type VIM; - - using parameters::get_parameter; - using parameters::choose_parameter; - - VIM V = choose_parameter(get_parameter(np, internal_np::vertex_index), - get_const_property_map(boost::vertex_index, g)); + typedef typename CGAL::GetInitializedVertexIndexMap::const_type Vimap; + Vimap V = CGAL::get_initialized_vertex_index_map(mesh, np); std::vector connectivity_table; std::vector offsets; @@ -186,13 +181,8 @@ void write_polys_tag(std::ostream& os, typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; typedef typename boost::graph_traits::face_descriptor face_descriptor; - typedef typename CGAL::GetVertexIndexMap::type VIM; - - using parameters::get_parameter; - using parameters::choose_parameter; - - VIM V = choose_parameter(get_parameter(np, internal_np::vertex_index), - get_const_property_map(boost::vertex_index, g)); + typedef typename CGAL::GetInitializedVertexIndexMap::const_type Vimap; + Vimap V = CGAL::get_initialized_vertex_index_map(mesh, np); std::string formatattribute = binary ? " format=\"appended\"" : " format=\"ascii\""; @@ -370,8 +360,7 @@ void write_polys_points(std::ostream& os, * `CGAL::vertex_Point` must be available in `FaceGraph`. * \cgalParamEnd * \cgalParamBegin{vertex_index_map} the property map with the indices associated to - * the vertices of `g`. If this parameter is omitted, an internal property map for - * `CGAL::vertex_index_t` must be available in `FaceGraph`. + * the vertices of `g`. * \cgalParamEnd * \cgalNamedParamsEnd * \see \ref IOStreamVTK diff --git a/BGL/include/CGAL/boost/graph/METIS/partition_dual_graph.h b/BGL/include/CGAL/boost/graph/METIS/partition_dual_graph.h index 50c0bcf7e37..d11a426b5e1 100644 --- a/BGL/include/CGAL/boost/graph/METIS/partition_dual_graph.h +++ b/BGL/include/CGAL/boost/graph/METIS/partition_dual_graph.h @@ -42,17 +42,14 @@ void partition_dual_graph(const TriangleMesh& tm, CGAL_precondition(CGAL::is_triangle_mesh(tm)); CGAL_precondition_msg(nparts > 1, ("Partitioning requires a number of parts > 1")); - using parameters::choose_parameter; using parameters::get_parameter; typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::face_iterator face_iterator; - // vertex index map - typedef typename CGAL::GetVertexIndexMap::type Indices; - Indices indices = choose_parameter(get_parameter(np, internal_np::vertex_index), - get_const_property_map(boost::vertex_index, tm)); + typedef typename CGAL::GetInitializedVertexIndexMap::type Indices; + Indices indices = CGAL::get_initialized_vertex_index_map(tm, np); idx_t nn = static_cast(num_vertices(tm)); idx_t ne = static_cast(num_faces(tm)); @@ -136,9 +133,6 @@ void partition_dual_graph(const TriangleMesh& tm, int nparts, /// based on the mesh's dual graph. The resulting partition is stored in the vertex and/or face /// property maps that are passed as parameters using \ref bgl_namedparameters "Named Parameters". /// -/// Property map for `CGAL::vertex_index_t` should be either available -/// as an internal property map to `tm` or provided as \ref bgl_namedparameters "Named Parameters". -/// /// \param tm a triangle mesh /// \param nparts the number of parts in the final partition /// \param np optional \ref bgl_namedparameters "Named Parameters" described below @@ -148,7 +142,7 @@ void partition_dual_graph(const TriangleMesh& tm, int nparts, /// /// \cgalNamedParamsBegin /// \cgalParamBegin{vertex_index_map} -/// is a property map containing the index of each vertex of `tm` intialized from `0` to `num_vertices(tm)-1`. +/// is a property map containing for each vertex of `tm` a unique index between `0` and `num_vertices(tm)-1`. /// \cgalParamEnd /// \cgalParamBegin{METIS_options} /// is a parameter used in to pass options to the METIS mesh diff --git a/BGL/include/CGAL/boost/graph/METIS/partition_graph.h b/BGL/include/CGAL/boost/graph/METIS/partition_graph.h index ec60ecbc11a..4ef813efcc6 100644 --- a/BGL/include/CGAL/boost/graph/METIS/partition_graph.h +++ b/BGL/include/CGAL/boost/graph/METIS/partition_graph.h @@ -77,17 +77,14 @@ void partition_graph(const TriangleMesh& tm, CGAL_precondition(CGAL::is_triangle_mesh(tm)); CGAL_precondition_msg(nparts > 1, ("Partitioning requires a number of parts > 1")); - using parameters::choose_parameter; using parameters::get_parameter; typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::face_iterator face_iterator; - //Vertex index map - typedef typename CGAL::GetVertexIndexMap::type Indices; - Indices indices = choose_parameter(get_parameter(np, internal_np::vertex_index), - get_const_property_map(boost::vertex_index, tm)); + typedef typename CGAL::GetInitializedVertexIndexMap::type Indices; + Indices indices = CGAL::get_initialized_vertex_index_map(tm, np); idx_t nn = static_cast(num_vertices(tm)); idx_t ne = static_cast(num_faces(tm)); @@ -168,9 +165,6 @@ void partition_graph(const TriangleMesh& tm, int nparts, /// mesh's nodal graph. The resulting partition is stored in the vertex and/or face /// property maps that are passed as parameters using \ref bgl_namedparameters "Named Parameters". /// -/// Property map for `CGAL::vertex_index_t` should be either available -/// as an internal property map to `tm` or provided as \ref bgl_namedparameters "Named Parameters". -/// /// \param tm a triangle mesh /// \param nparts the number of parts in the final partition /// \param np optional \ref bgl_namedparameters "Named Parameters" described below @@ -180,7 +174,7 @@ void partition_graph(const TriangleMesh& tm, int nparts, /// /// \cgalNamedParamsBegin /// \cgalParamBegin{vertex_index_map} -/// is a property map containing the index of each vertex of `tm` intialized from `0` to `num_vertices(tm)-1`. +/// is a property map containing for each vertex of `tm` a unique index between `0` and `num_vertices(tm)-1`. /// \cgalParamEnd /// \cgalParamBegin{METIS_options} /// is a parameter used in to pass options to the METIS mesh diff --git a/BGL/include/CGAL/boost/graph/Seam_mesh.h b/BGL/include/CGAL/boost/graph/Seam_mesh.h index 33a995dba43..07ed312307f 100644 --- a/BGL/include/CGAL/boost/graph/Seam_mesh.h +++ b/BGL/include/CGAL/boost/graph/Seam_mesh.h @@ -124,8 +124,8 @@ public: /// The type for the objects used to identify halfedges in the underlying mesh. typedef typename boost::graph_traits::halfedge_descriptor TM_halfedge_descriptor; - /// The type for the iterators that traverse through the complete halfedge set of the underlying mesh. - typedef typename boost::graph_traits::halfedge_iterator TM_halfedge_iterator; + /// The type for the iterators that traverse through the complete halfedge set of the underlying mesh. + typedef typename boost::graph_traits::halfedge_iterator TM_halfedge_iterator; /// The type for the objects used to identify edges in the underlying mesh. typedef typename boost::graph_traits::edge_descriptor TM_edge_descriptor; @@ -439,6 +439,11 @@ public: { return ! (e1 == e2); } + + friend std::size_t hash_value(const edge_descriptor& ed) + { + return hash_value((std::min)(ed.hd, ed.mesh_->opposite(ed.hd))); + } }; #ifndef DOXYGEN_RUNNING diff --git a/BGL/include/CGAL/boost/graph/copy_face_graph.h b/BGL/include/CGAL/boost/graph/copy_face_graph.h index 5eafa161533..4e0dc04cd93 100644 --- a/BGL/include/CGAL/boost/graph/copy_face_graph.h +++ b/BGL/include/CGAL/boost/graph/copy_face_graph.h @@ -199,13 +199,8 @@ void copy_face_graph(const SourceMesh& sm, TargetMesh& tm, typedef typename boost::graph_traits::halfedge_descriptor tm_halfedge_descriptor; std::vector hedges(num_halfedges(sm)); - // init halfedge index map - /// \TODO shall we keep that? - helpers::init_halfedge_indices(const_cast(sm), - get(boost::halfedge_index, sm)); - copy_face_graph_impl(sm, tm, - bind_property_maps(get(boost::halfedge_index, sm), + bind_property_maps(get_initialized_halfedge_index_map(sm), make_property_map(hedges)), v2v, h2h, f2f, sm_vpm, tm_vpm); diff --git a/BGL/include/CGAL/boost/graph/internal/initialized_index_maps_helpers.h b/BGL/include/CGAL/boost/graph/internal/initialized_index_maps_helpers.h new file mode 100644 index 00000000000..e392ff064a0 --- /dev/null +++ b/BGL/include/CGAL/boost/graph/internal/initialized_index_maps_helpers.h @@ -0,0 +1,307 @@ +// Copyright (c) 2020 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// Author(s) : Mael Rouxel-Labbé +// Maxime Gimeno + +#ifndef CGAL_BOOST_GRAPH_INITIALIZED_INTERNAL_INDEX_MAPS_HELPERS +#define CGAL_BOOST_GRAPH_INITIALIZED_INTERNAL_INDEX_MAPS_HELPERS + +#include +#include +#include +#include +#include + +#include +#include + +namespace CGAL { +namespace BGL { +namespace internal { + +// Check that an index map has been correctly initialized +template +bool is_index_map_valid(IndexMap idmap, + const std::size_t num_simplices, + const DescriptorRange& range) +{ + typedef typename boost::property_traits::value_type Id_type; + + Id_type max_id = static_cast(num_simplices); + std::vector indices(max_id); + for(const auto& d : range) + { + const Id_type id = get(idmap, d); + if(id >= 0 && id < max_id && !indices[id]) + { + indices[id] = true; + } + else + { +#ifdef CGAL_BGL_INDEX_MAP_DEBUG + std::cerr << "Invalid ID: " << id << " num_simplices: " << num_simplices << std::endl; +#endif + return false; + } + } + + return true; +} + +template +bool is_index_map_valid(const CGAL::internal_np::vertex_index_t, VertexIndexPropertyMap vertex_index_map, const Graph& g) +{ + return is_index_map_valid(vertex_index_map, num_vertices(g), vertices(g)); +} + +template +bool is_index_map_valid(const CGAL::internal_np::halfedge_index_t, HalfedgeIndexPropertyMap halfedge_index_map, const Graph& g) +{ + return is_index_map_valid(halfedge_index_map, num_halfedges(g), halfedges(g)); +} + +template +bool is_index_map_valid(const CGAL::internal_np::edge_index_t, EdgeIndexPropertyMap edge_index_map, const Graph& g) +{ + return is_index_map_valid(edge_index_map, num_edges(g), edges(g)); +} + +template +bool is_index_map_valid(const CGAL::internal_np::face_index_t, FaceIndexPropertyMap face_index_map, const Graph& g) +{ + return is_index_map_valid(face_index_map, num_faces(g), faces(g)); +} + +template +void initialize_index_map(const PropertyTag, IndexPropertyMap, const Graph&) +{ + // Unknown parameter; should never be here. + CGAL_assertion(false); +} + +template ::value> +struct Index_map_initializer +{ + void operator()(const CGAL::internal_np::vertex_index_t, IndexPropertyMap vertex_index_map, const Graph& g) + { + typename boost::property_traits::value_type i = 0; + for(typename boost::graph_traits::vertex_descriptor vd : vertices(g)) + put(vertex_index_map, vd, i++); + } + + void operator()(const CGAL::internal_np::halfedge_index_t, IndexPropertyMap halfedge_index_map, const Graph& g) + { + typename boost::property_traits::value_type i = 0; + for(typename boost::graph_traits::halfedge_descriptor hd : halfedges(g)) + put(halfedge_index_map, hd, i++); + } + + void operator()(const CGAL::internal_np::edge_index_t, IndexPropertyMap edge_index_map, const Graph& g) + { + typename boost::property_traits::value_type i = 0; + for(typename boost::graph_traits::edge_descriptor ed : edges(g)) + put(edge_index_map, ed, i++); + } + + void operator()(const CGAL::internal_np::face_index_t, IndexPropertyMap face_index_map, const Graph& g) + { + typename boost::property_traits::value_type i = 0; + for(typename boost::graph_traits::face_descriptor fd : faces(g)) + put(face_index_map, fd, i++); + } + + template + void operator()(const PropertyTag, IndexPropertyMap, const Graph&) + { + // Unknown parameter; should never be here. + CGAL_assertion(false); + } +}; + +template +struct Index_map_initializer +{ + template + void operator()(const PropertyTag, IndexPropertyMap, const Graph&) + { + // The property map is not writable; should never be here. + CGAL_assertion_msg(false, "You are trying to initialize a non-writable property map"); + } +}; + +// Just for convenience, define the following functions: +// +// BGL::internal::initialize_vertex_index_map() +// BGL::internal::initialize_halfedge_index_map() +// BGL::internal::initialize_edge_index_map() +// BGL::internal::initialize_face_index_map() + +#define CGAL_DEF_INITIALIZE_ID_MAP_FUNCTION(TYPE) \ +template \ +void initialize_##TYPE##_index_map(WritableIndexPropertyMap index_map, \ + const Graph& g) \ +{ \ + Index_map_initializer initializer; \ + initializer(CGAL::internal_np::TYPE##_index_t{}, index_map, g); \ +} + +CGAL_DEF_INITIALIZE_ID_MAP_FUNCTION(vertex) +CGAL_DEF_INITIALIZE_ID_MAP_FUNCTION(halfedge) +CGAL_DEF_INITIALIZE_ID_MAP_FUNCTION(edge) +CGAL_DEF_INITIALIZE_ID_MAP_FUNCTION(face) + +#undef CGAL_DEF_INITIALIZE_ID_FUCNTION + +// Using the pmap passed in named parameters ------------------------------------------------------- +template +IndexMap get_initialized_index_map_const(const IndexMap index_map, + const PropertyTag p, Tag, DynamicTag, + const Graph& g) +{ + CGAL_USE(g); + CGAL_USE(p); + + // If you are passing a pmap via NPs, it must be initialized + CGAL_assertion(is_index_map_valid(p, index_map, g)); + + return index_map; +} + +template +IndexMap get_initialized_index_map(const IndexMap index_map, + const PropertyTag p, Tag, DynamicTag, + Graph& g) +{ + CGAL_USE(g); + CGAL_USE(p); + + // If you are passing a pmap via NPs, it must be initialized + CGAL_assertion(is_index_map_valid(p, index_map, g)); + + return index_map; +} + +// Using the internal to the mesh ------------------------------------------------------------------ +template +InternalIndexMap +get_initialized_internal_index_map(InternalIndexMap index_map, + const PropertyTag p, + const Graph& g) +{ + if(CGAL::internal::Is_writable_property_map::value) + { + if(!is_index_map_valid(p, index_map, g)) + Index_map_initializer{}(p, index_map, g); + } + else // not writable + { + CGAL_assertion(is_index_map_valid(p, index_map, g)); + } + + return index_map; +} + +template +typename boost::property_map::const_type +get_initialized_index_map_const(CGAL::internal_np::Param_not_found, + const PropertyTag p, const Tag tag, DynamicTag, + const Graph& g) +{ + return get_initialized_internal_index_map(get(tag, g), p, g); +} + +// same as above, non-const graph overload +template +typename boost::property_map::type +get_initialized_index_map(CGAL::internal_np::Param_not_found, + const PropertyTag p, const Tag tag, DynamicTag, + Graph& g) +{ + // From now on the correct property map has been acquired + // and there is no need to distinguish between const and non-const mesh + return get_initialized_internal_index_map(get(tag, g), p, g); +} + +// Create a dynamic property and initialize it ----------------------------------------------------- +template +DynamicIndexMap +get_initialized_dynamic_index_map(DynamicIndexMap index_map, + const PropertyTag p, + const Graph& g) +{ +#ifdef CGAL_PERFORMANCE_WARNINGS + std::cerr << "Warning: the automatically selected index map is a dynamic property map," + << " which might not have constant-time access complexity." << std::endl; +#endif + + Index_map_initializer{}(p, index_map, g); + return index_map; +} + +template +typename boost::property_map::const_type +get_initialized_index_map_const(CGAL::internal_np::Param_not_found, + const PropertyTag p, const DynamicTag dtag, DynamicTag, + const Graph& g) +{ + return get_initialized_dynamic_index_map(get(dtag, g), p, g); +} + +// same as above, non-const graph overload +template +typename boost::property_map::type +get_initialized_index_map(CGAL::internal_np::Param_not_found, + const PropertyTag p, const DynamicTag dtag, DynamicTag, + Graph& g) +{ + // From now on the correct property map has been acquired + // and there is no need to distinguish between const and non-const mesh + return get_initialized_dynamic_index_map(get(dtag, g), p, g); +} + +template > +class GetInitializedIndexMap +{ +public: + // Check if there is an internal property map; if not, we must a dynamic property map + typedef typename boost::mpl::if_c< + CGAL::graph_has_property::value, Tag, DynamicTag>::type Final_tag; + + typedef typename internal_np::Lookup_named_param_def< + PropertyTag, + NamedParameters, + typename boost::property_map::const_type>::type const_type; + + typedef typename internal_np::Lookup_named_param_def< + PropertyTag, + NamedParameters, + typename boost::property_map::type>::type type; + + static const_type get_const(const PropertyTag p, const Graph& g, const NamedParameters& np) + { + return BGL::internal::get_initialized_index_map_const(parameters::get_parameter(np, p), + p, Final_tag{}, DynamicTag{}, g); + } + + static type get(const PropertyTag p, Graph& g, const NamedParameters& np) + { + return BGL::internal::get_initialized_index_map(parameters::get_parameter(np, p), + p, Final_tag{}, DynamicTag{}, g); + } +}; + +} // namespace internal +} // namespace BGL +} // namespace CGAL + +#endif // CGAL_BOOST_GRAPH_INITIALIZED_INTERNAL_INDEX_MAPS_HELPERS diff --git a/BGL/include/CGAL/boost/graph/named_params_helper.h b/BGL/include/CGAL/boost/graph/named_params_helper.h index 4c432a311c6..297c93e0f18 100644 --- a/BGL/include/CGAL/boost/graph/named_params_helper.h +++ b/BGL/include/CGAL/boost/graph/named_params_helper.h @@ -19,18 +19,19 @@ #ifndef CGAL_BOOST_GRAPH_NAMED_PARAMETERS_HELPERS_H #define CGAL_BOOST_GRAPH_NAMED_PARAMETERS_HELPERS_H +#include #include - +#include +#include #include #include - #include -#include + #include #include - #include +#include namespace CGAL { @@ -40,8 +41,8 @@ namespace CGAL { class Eigen_svd; class Lapack_svd; // - - + + //helper classes template class property_map_selector @@ -104,7 +105,8 @@ namespace CGAL { property_map_selector pms; return pms.get_const_pmap(p, pmesh); } -// shortcut for accessing the value type of the property map + + // Shortcut for accessing the value type of the property map template class property_map_value { typedef typename boost::property_map::const_type PMap; @@ -175,37 +177,105 @@ namespace CGAL { > ::type type; }; - template - class GetFaceIndexMap - { - typedef typename property_map_selector::type DefaultMap; - typedef typename property_map_selector::const_type DefaultMap_const; - public: - typedef typename internal_np::Lookup_named_param_def < - internal_np::face_index_t, - NamedParameters, - DefaultMap - > ::type type; - typedef typename internal_np::Lookup_named_param_def < - internal_np::face_index_t, - NamedParameters, - DefaultMap_const - > ::type const_type; - typedef typename boost::is_same::type Is_internal_map; - typedef typename boost::is_same::type Is_internal_map_const; - }; +// Define the following structs: +// +// GetInitializedVertexIndexMap +// GetInitializedHalfedgeIndexMap +// GetInitializedEdgeIndexMap +// GetInitializedFaceIndexMap - template - class GetVertexIndexMap - { - typedef typename property_map_selector::type DefaultMap; - public: - typedef typename internal_np::Lookup_named_param_def < - internal_np::vertex_index_t, - NamedParameters, - DefaultMap - > ::type type; - }; +#define CGAL_DEF_GET_INDEX_TYPE(CTYPE, DTYPE, STYPE) \ +template > \ +struct GetInitialized##CTYPE##IndexMap \ + : public BGL::internal::GetInitializedIndexMap, \ + Graph, NamedParameters> \ +{ }; + +CGAL_DEF_GET_INDEX_TYPE(Vertex, vertex, typename boost::graph_traits::vertices_size_type) +CGAL_DEF_GET_INDEX_TYPE(Halfedge, halfedge, typename boost::graph_traits::halfedges_size_type) +CGAL_DEF_GET_INDEX_TYPE(Edge, edge, typename boost::graph_traits::edges_size_type) +CGAL_DEF_GET_INDEX_TYPE(Face, face, typename boost::graph_traits::faces_size_type) + +#undef CGAL_DEF_GET_INDEX_TYPE + +// Define the following functions: +// +// get_initialized_vertex_index_map() +// get_initialized_halfedge_index_map() +// get_initialized_edge_index_map() +// get_initialized_face_index_map() +// +// The function returns: +// - the index property map passed in the NPs, if passed in the NPs; it must be initialized by the user; +// - the internal index property map if it is the graph has one. It is initialized if needed and possible; +// - an initialized dynamic pmap otherwise. + +#define CGAL_DEF_GET_INITIALIZED_INDEX_MAP(DTYPE, STYPE) \ +template \ +typename BGL::internal::GetInitializedIndexMap, \ + Graph, NamedParameters>::const_type \ +get_initialized_##DTYPE##_index_map(const Graph& g, \ + const NamedParameters& np) \ +{ \ + typedef BGL::internal::GetInitializedIndexMap, \ + Graph, NamedParameters> Index_map_getter; \ + return Index_map_getter::get_const(CGAL::internal_np::DTYPE##_index_t{}, g, np); \ +} \ +template \ +typename BGL::internal::GetInitializedIndexMap, \ + Graph>::const_type \ +get_initialized_##DTYPE##_index_map(const Graph& g) \ +{ \ + return get_initialized_##DTYPE##_index_map(g, CGAL::parameters::all_default()); \ +} \ +/* same as above, non-const version*/ \ +template ::type>::value, int> = 0> \ +typename BGL::internal::GetInitializedIndexMap, \ + Graph, NamedParameters>::type \ +get_initialized_##DTYPE##_index_map(Graph& g, \ + const NamedParameters& np) \ +{ \ + typedef BGL::internal::GetInitializedIndexMap, \ + Graph, NamedParameters> Index_map_getter; \ + return Index_map_getter::get(CGAL::internal_np::DTYPE##_index_t{}, g, np); \ +} \ +template ::type>::value, int> = 0> \ +typename BGL::internal::GetInitializedIndexMap, \ + Graph>::type \ +get_initialized_##DTYPE##_index_map(Graph& g) \ +{ \ + return get_initialized_##DTYPE##_index_map(g, CGAL::parameters::all_default()); \ +} + +CGAL_DEF_GET_INITIALIZED_INDEX_MAP(vertex, typename boost::graph_traits::vertices_size_type) +CGAL_DEF_GET_INITIALIZED_INDEX_MAP(halfedge, typename boost::graph_traits::halfedges_size_type) +CGAL_DEF_GET_INITIALIZED_INDEX_MAP(edge, typename boost::graph_traits::edges_size_type) +CGAL_DEF_GET_INITIALIZED_INDEX_MAP(face, typename boost::graph_traits::faces_size_type) + +#undef CGAL_DEF_GET_INITIALIZED_INDEX_MAP template class GetFaceNormalMap @@ -244,7 +314,7 @@ namespace CGAL { typedef std::random_access_iterator_tag iterator_category; }; }; - + namespace parameters { template @@ -258,7 +328,7 @@ namespace CGAL { namespace internal{ BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_nested_type_iterator, iterator, false) } - + template::value> class GetPointMap @@ -380,7 +450,7 @@ namespace CGAL { DefaultPMap > ::type const_type; }; - + template class GetPlaneIndexMap { @@ -428,7 +498,7 @@ namespace CGAL { }; } // namespace Point_set_processing_3 - + template class GetSolver { @@ -461,10 +531,10 @@ namespace CGAL { typedef int Matrix; static FT solve (const Matrix&, Vector&) { return 0.; } }; - + public: typedef DummySvdTraits NoTraits; - + typedef typename internal_np::Lookup_named_param_def < internal_np::svd_traits_t, NamedParameters, @@ -477,6 +547,7 @@ namespace CGAL { #endif > ::type type; }; + } //namespace CGAL diff --git a/BGL/include/CGAL/boost/graph/properties.h b/BGL/include/CGAL/boost/graph/properties.h index a6df7cca1e8..8fd55a00264 100644 --- a/BGL/include/CGAL/boost/graph/properties.h +++ b/BGL/include/CGAL/boost/graph/properties.h @@ -14,14 +14,15 @@ #define CGAL_BOOST_GRAPH_BGL_PROPERTIES_H #include +#include +#include + #include #include -#include -#include -#include -#include #include +#include +#include namespace CGAL { @@ -69,12 +70,16 @@ BOOST_INSTALL_PROPERTY(face, external_index); namespace CGAL { using boost::vertex_point_t; using boost::vertex_point; +using boost::vertex_index_t; +using boost::vertex_index; using boost::vertex_external_index_t; using boost::vertex_external_index; using boost::halfedge_index_t; using boost::halfedge_index; using boost::halfedge_external_index_t; using boost::halfedge_external_index; +using boost::edge_index_t; +using boost::edge_index; using boost::edge_external_index_t; using boost::edge_external_index; using boost::face_index_t; @@ -83,128 +88,7 @@ using boost::face_external_index_t; using boost::face_external_index; } // CGAL -namespace CGAL{ -namespace helpers { - -// matches read-write property maps -template -void init_face_indices(PolygonMesh& pm, - FaceIndexMap& fid, - boost::read_write_property_map_tag, - Tag) -{ - typename boost::property_traits::value_type i = 0; - for(typename boost::graph_traits::face_descriptor fd : - faces(pm)) - { - put(fid, fd, i); - ++i; - } -} -template -void init_vertex_indices(PolygonMesh& pm, - VertexIndexMap& vid, - boost::read_write_property_map_tag, - Tag) -{ - typename boost::property_traits::value_type i = 0; - for(typename boost::graph_traits::vertex_descriptor vd : - vertices(pm)) - { - put(vid, vd, i); - ++i; - } -} -template -void init_halfedge_indices(PolygonMesh& pm, - HalfedgeIndexMap& hid, - boost::read_write_property_map_tag, - Tag) -{ - typename boost::property_traits::value_type i = 0; - for(typename boost::graph_traits::halfedge_descriptor hd : - halfedges(pm)) - { - put(hid, hd, i); - ++i; - } -} - -// matches mutable Lvalue property maps -template -void init_face_indices(PolygonMesh& pm, - FaceIndexMap& fid, - boost::lvalue_property_map_tag, - boost::false_type) -{ - init_face_indices(pm, fid, - boost::read_write_property_map_tag(), boost::false_type()); -} -template -void init_vertex_indices(PolygonMesh& pm, - VertexIndexMap& vid, - boost::lvalue_property_map_tag, - boost::false_type) -{ - init_vertex_indices(pm, vid, - boost::read_write_property_map_tag(), boost::false_type()); -} -template -void init_halfedge_indices(PolygonMesh& pm, - HalfedgeIndexMap& hid, - boost::lvalue_property_map_tag, - boost::false_type) -{ - init_halfedge_indices(pm, hid, - boost::read_write_property_map_tag(), boost::false_type()); -} - -// matches all other types of property map -template -void init_face_indices(PolygonMesh&, FaceIndexMap, MapTag, Tag) -{} -template -void init_vertex_indices(PolygonMesh&, VertexIndexMap, MapTag, Tag) -{} -template -void init_halfedge_indices(PolygonMesh&, HalfedgeIndexMap, MapTag, Tag) -{} - -template -void init_face_indices(PolygonMesh& pm, FaceIndexMap fid) -{ - init_face_indices(pm, fid, - typename boost::property_traits::category(), - typename boost::is_const< - typename boost::remove_reference< - typename boost::property_traits::reference - >::type >::type() ); -} - -template -void init_vertex_indices(PolygonMesh& pm, VertexIndexMap vid) -{ - init_vertex_indices(pm, vid, - typename boost::property_traits::category(), - typename boost::is_const< - typename boost::remove_reference< - typename boost::property_traits::reference - >::type >::type() ); -} - -template -void init_halfedge_indices(PolygonMesh& pm, HalfedgeIndexMap hid) -{ - init_halfedge_indices(pm, hid, - typename boost::property_traits::category(), - typename boost::is_const< - typename boost::remove_reference< - typename boost::property_traits::reference - >::type >::type() ); -} - -} //namespace helpers - +namespace CGAL { namespace internal { template @@ -232,8 +116,8 @@ struct Edge_index_accessor }; template::type >::value> + bool is_const = std::is_const< + typename std::remove_reference::type >::value> struct Point_accessor : boost::put_get_helper< Reference, Point_accessor > { @@ -265,6 +149,32 @@ struct Point_accessor reference operator[](Handle h) const { return h->point(); } }; +// this one is basically 'readable_property_map_tag' +template ::category> +struct Is_writable_property_map : CGAL::Tag_false { }; + +template +struct Is_writable_property_map : CGAL::Tag_true { }; + +template +struct Is_writable_property_map : CGAL::Tag_true { }; + +// 'lvalue_pmap_tag' is annoying, because the property map is allowed to be non-mutable, +// but boost::lvalue_property_map_tag is defined as: +// struct lvalue_property_map_tag : public read_write_property_map_tag +// so we can't just check that 'writable_property_map_tag' is a base of the the lvalue tag. +// +// This checks if the reference is non-const, which is not completely correct: map[key] returning +// a non-const reference doesn't mean that 'put(map, key, val)' exists, which is what a writable +// property map must define. +template +struct Is_writable_property_map + : boost::mpl::if_c::reference>::type>::value, + CGAL::Tag_false, CGAL::Tag_true>::type +{ }; + } // namespace internal // Needed by PMP::detect_features and Mesh_3 @@ -275,12 +185,12 @@ enum vertex_time_stamp_t { vertex_time_stamp}; enum halfedge_time_stamp_t { halfedge_time_stamp}; enum face_time_stamp_t { face_time_stamp}; -template +template struct vertex_incident_patches_t { typedef ID type; }; -template +template struct face_patch_id_t { typedef ID type; }; diff --git a/BGL/include/CGAL/boost/graph/properties_Seam_mesh.h b/BGL/include/CGAL/boost/graph/properties_Seam_mesh.h index 96bf18fa8ab..53acfbce101 100644 --- a/BGL/include/CGAL/boost/graph/properties_Seam_mesh.h +++ b/BGL/include/CGAL/boost/graph/properties_Seam_mesh.h @@ -112,6 +112,39 @@ struct property_map, CGAL::vertex_point_t> typedef CGAL::Seam_mesh_point_map type; typedef type const_type; }; + +template +struct property_map, CGAL::dynamic_vertex_property_t > +{ + typedef typename boost::graph_traits >::vertex_descriptor vertex_descriptor; + typedef CGAL::internal::Dynamic_property_map type; + typedef type const_type; +}; + +template +struct property_map, CGAL::dynamic_halfedge_property_t > +{ + typedef typename boost::graph_traits >::halfedge_descriptor halfedge_descriptor; + typedef CGAL::internal::Dynamic_property_map type; + typedef type const_type; +}; + + +template +struct property_map, CGAL::dynamic_edge_property_t > +{ + typedef typename boost::graph_traits >::edge_descriptor edge_descriptor; + typedef CGAL::internal::Dynamic_property_map type; + typedef type const_type; +}; + +template +struct property_map, CGAL::dynamic_face_property_t > +{ + typedef typename boost::graph_traits >::face_descriptor face_descriptor; + typedef CGAL::internal::Dynamic_property_map type; + typedef type const_type; +}; } // namespace boost namespace CGAL { diff --git a/BGL/test/BGL/test_Face_filtered_graph.cpp b/BGL/test/BGL/test_Face_filtered_graph.cpp index bbf57e5b2c2..0a579fe96cc 100644 --- a/BGL/test/BGL/test_Face_filtered_graph.cpp +++ b/BGL/test/BGL/test_Face_filtered_graph.cpp @@ -491,13 +491,13 @@ int main() typedef boost::graph_traits PolyTraits; - typedef boost::property_map::type VPMap; + typedef boost::property_map::const_type VPMap; typedef PolyTraits::face_descriptor poly_face_descriptor; typedef boost::associative_property_map< std::map > FCMap; - typedef boost::property_map::type FIMap; - typedef boost::property_map::type VIMap; - typedef boost::property_map::type HIMap; + typedef boost::property_map::const_type FIMap; + typedef boost::property_map::const_type VIMap; + typedef boost::property_map::const_type HIMap; typedef CGAL::Face_filtered_graph Poly_Adapter; auto poly = std::make_unique(); CGAL::make_tetrahedron( @@ -516,14 +516,14 @@ int main() 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:: - edge_is_constrained_map(Constraint(*poly, vpmap)). - face_index_map(poly_fimap)); + 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, pids, poly_fccmap, - CGAL::parameters::face_index_map(poly_fimap). - vertex_index_map(poly_vimap). - halfedge_index_map(poly_himap)); + CGAL::parameters::face_index_map(poly_fimap) + .vertex_index_map(poly_vimap) + .halfedge_index_map(poly_himap)); test_mesh(poly_adapter); } diff --git a/BGL/test/BGL/test_Prefix.h b/BGL/test/BGL/test_Prefix.h index 106e8047649..c186b24ee7d 100644 --- a/BGL/test/BGL/test_Prefix.h +++ b/BGL/test/BGL/test_Prefix.h @@ -38,6 +38,7 @@ #include #include #include +#include #include @@ -57,6 +58,10 @@ typedef CGAL::Linear_cell_complex_for_bgl_combinatorial_map_helper typedef CGAL::Surface_mesh SM; +typedef SM::Property_map Seam_edge_pmap; +typedef SM::Property_map Seam_vertex_pmap; +typedef CGAL::Seam_mesh Seam_mesh; + #if defined(CGAL_USE_OPENMESH) #include @@ -73,6 +78,8 @@ typedef OpenMesh::PolyMesh_ArrayKernelT OMesh; typedef CGAL::Triangulation_vertex_base_with_id_2 Vbb; typedef CGAL::Triangulation_face_base_with_id_2 Fbb; +typedef CGAL::Triangulation_2 Triangulation_no_id_2; + typedef CGAL::Triangulation_2 > Triangulation_2; typedef CGAL::Delaunay_triangulation_2 Tr build_dummy_triangulation() { typedef typename Tr::Point Point; - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef typename boost::graph_traits::face_descriptor face_descriptor; Tr t; t.insert(Point(0.1,0)); @@ -202,24 +207,25 @@ Tr build_dummy_triangulation() t.insert(Point(0,1)); t.insert(Point(0,2)); - int id = 0; - for(vertex_descriptor vd : vertices(t)) - vd->id() = id++; - - id = 0; - for(face_descriptor fd : faces(t)) - fd->id() = id++; - return t; } -Triangulation_2 t2_data() { return build_dummy_triangulation(); } -Delaunay_triangulation_2 dt2_data() { return build_dummy_triangulation(); } -Regular_triangulation_2 rt2_data() { return build_dummy_triangulation(); } -Constrained_triangulation_2 ct2_data() { return build_dummy_triangulation(); } -Constrained_Delaunay_triangulation_2 cdt2_data() { return build_dummy_triangulation(); } -CDT_P2 cdtp2_data() { return build_dummy_triangulation(); } -Triangulation_hierarchy_2 t2h_data() { return build_dummy_triangulation(); } +template +Tr build_dummy_triangulation_with_ids() +{ + Tr t = build_dummy_triangulation(); + CGAL::set_triangulation_ids(t); + return t; +} + +Triangulation_no_id_2 t2_no_id_data() { return build_dummy_triangulation(); } +Triangulation_2 t2_data() { return build_dummy_triangulation_with_ids(); } +Delaunay_triangulation_2 dt2_data() { return build_dummy_triangulation_with_ids(); } +Regular_triangulation_2 rt2_data() { return build_dummy_triangulation_with_ids(); } +Constrained_triangulation_2 ct2_data() { return build_dummy_triangulation_with_ids(); } +Constrained_Delaunay_triangulation_2 cdt2_data() { return build_dummy_triangulation_with_ids(); } +CDT_P2 cdtp2_data() { return build_dummy_triangulation_with_ids(); } +Triangulation_hierarchy_2 t2h_data() { return build_dummy_triangulation_with_ids(); } template struct Surface_fixture_1 { diff --git a/BGL/test/BGL/test_Properties.cpp b/BGL/test/BGL/test_Properties.cpp index 3ffd9d1720e..984891b4ca9 100644 --- a/BGL/test/BGL/test_Properties.cpp +++ b/BGL/test/BGL/test_Properties.cpp @@ -1,115 +1,459 @@ #include "test_Prefix.h" +#include + #include -template< typename G, - typename ForwardRange, - typename IndexPropertyMap - > -void index_uniqueness(const G&, - ForwardRange range, - IndexPropertyMap pm) +// #define CGAL_TEST_PROPERTIES_DEBUG + +namespace CGAL { + +template +struct Non_mutable_property_map { + typedef Key key_type; + typedef Value value_type; + typedef value_type reference; + typedef boost::readable_property_map_tag category; + + Non_mutable_property_map(const Container& c) : m_c(c) { } + + friend reference get(const Non_mutable_property_map& pmap, key_type k) + { + return pmap.m_c.at(k); + } + +private: + const Container& m_c; +}; + +template +struct RW_property_map +{ + typedef Key key_type; + typedef Value value_type; + typedef value_type& reference; + typedef boost::read_write_property_map_tag category; + + RW_property_map(Container& c) : m_c(c) { } + + friend void put(RW_property_map& pmap, const key_type& k, const value_type& val) + { + pmap.m_c[k] = val; + } + + friend reference get(RW_property_map& pmap, const key_type& k) + { + return pmap.m_c[k]; + } + +private: + Container& m_c; +}; + +} // namespace CGAL + +template +void test_uniqueness(const Graph&, + const ForwardRange& range, + IndexPropertyMap index_map) +{ +#ifdef CGAL_TEST_PROPERTIES_DEBUG + std::cout << std::endl + << "Checking the uniqueness of the property map of type: " + << typeid(IndexPropertyMap).name() << std::endl; + std::cout << "Element type: " << typeid(typename boost::range_value::type).name() << std::endl; +#endif + typename boost::range_iterator::type - begin = boost::begin(range), + begin = boost::begin(range), begin2 = boost::begin(range), end = boost::end(range); typedef boost::unordered_set id_map; typedef std::pair resultp; - id_map m; - while(begin != end) { - resultp r = m.insert(get(pm, *begin)); + id_map m; + while(begin != end) + { + resultp r = m.insert(get(index_map, *begin)); +#ifdef CGAL_TEST_PROPERTIES_DEBUG + std::cout << "id: " << get(index_map, *begin) << std::endl; +#endif ++begin; - assert(r.second); + assert(r.second); // already seen that id } assert(std::distance(begin2, end) == static_cast(m.size())); } - -void index_uniqueness_poly(const Polyhedron& g) +template +void test_vertex_index_map_uniqueness(const Graph& g, + const NamedParameters& np) { - index_uniqueness(g, edges(g) , get(boost::edge_index, g)); - index_uniqueness(g, vertices(g), get(boost::vertex_index, g)); - index_uniqueness(g, faces(g), get(boost::face_index, g)); - index_uniqueness(g, halfedges(g), get(boost::halfedge_index, g)); + typedef typename CGAL::GetInitializedVertexIndexMap::type VIM; + typedef typename CGAL::GetInitializedVertexIndexMap::const_type CVIM; - index_uniqueness(g, edges(g) , get(boost::edge_external_index, g)); - index_uniqueness(g, vertices(g), get(boost::vertex_external_index, g)); - index_uniqueness(g, faces(g), get(boost::face_external_index, g)); - index_uniqueness(g, halfedges(g), get(boost::halfedge_external_index, g)); + // in the case where the map is passed by NP, its type doesn't depend on whether the mesh is const or not + static_assert((std::is_same::value), "VIM, CVIM must be the same type"); + + VIM ivim = CGAL::get_initialized_vertex_index_map(g, np); + + return test_uniqueness(g, vertices(g), ivim); } -void index_uniqueness_lcc(const LCC& g) +template +void test_halfedge_index_map_uniqueness(const Graph& g, + const NamedParameters& np) { - index_uniqueness(g, edges(g) , get(boost::edge_index, g)); - index_uniqueness(g, vertices(g), get(boost::vertex_index, g)); - index_uniqueness(g, faces(g), get(boost::face_index, g)); - index_uniqueness(g, halfedges(g), get(boost::halfedge_index, g)); + typedef typename CGAL::GetInitializedHalfedgeIndexMap::type HIM; + typedef typename CGAL::GetInitializedHalfedgeIndexMap::const_type CHIM; + + // in the case where the map is passed by NP, its type doesn't depend on whether the mesh is const or not + static_assert((std::is_same::value), "HIM, CHIM must be the same type"); + + HIM ihim = CGAL::get_initialized_halfedge_index_map(g, np); + + return test_uniqueness(g, halfedges(g), ihim); } -void index_uniqueness_sm(const SM& g) +template +void test_edge_index_map_uniqueness(const Graph& g, + const NamedParameters& np) { - index_uniqueness(g, edges(g) , get(boost::edge_index, g)); - index_uniqueness(g, vertices(g), get(boost::vertex_index, g)); - index_uniqueness(g, faces(g), get(boost::face_index, g)); - index_uniqueness(g, halfedges(g), get(boost::halfedge_index, g)); + typedef typename CGAL::GetInitializedEdgeIndexMap::type EIM; + typedef typename CGAL::GetInitializedEdgeIndexMap::const_type CEIM; + + // in the case where the map is passed by NP, its type doesn't depend on whether the mesh is const or not + static_assert((std::is_same::value), "EIM, CEIM must be the same type"); + + EIM ieim = CGAL::get_initialized_edge_index_map(g, np); + + return test_uniqueness(g, edges(g), ieim); } -#if defined(CGAL_USE_OPENMESH) -void index_uniqueness_omesh(const OMesh& g) +template +void test_face_index_map_uniqueness(const Graph& g, + const NamedParameters& np) { - index_uniqueness(g, edges(g) , get(boost::edge_index, g)); - index_uniqueness(g, vertices(g), get(boost::vertex_index, g)); - index_uniqueness(g, faces(g), get(boost::face_index, g)); - index_uniqueness(g, halfedges(g), get(boost::halfedge_index, g)); + typedef typename CGAL::GetInitializedFaceIndexMap::type FIM; + typedef typename CGAL::GetInitializedFaceIndexMap::const_type CFIM; + + // in the case where the map is passed by NP, its type doesn't depend on whether the mesh is const or not + static_assert((std::is_same::value), "FIM, CFIM must be the same type"); + + FIM ifim = CGAL::get_initialized_face_index_map(g, np); + + return test_uniqueness(g, faces(g), ifim); } + +////////////////////////////////////////// const /////////////////////////////////////////////////// + +template +void test_internal_index_maps_const(const Graph& g) +{ + test_uniqueness(g, vertices(g), get(boost::vertex_index, g)); + test_uniqueness(g, halfedges(g), get(boost::halfedge_index, g)); + test_uniqueness(g, edges(g) , get(boost::edge_index, g)); + test_uniqueness(g, faces(g), get(boost::face_index, g)); +} + +template +void test_initialized_index_maps_const(const Graph& g) +{ + typedef typename CGAL::GetInitializedVertexIndexMap::const_type VIM; + VIM ivim = CGAL::get_initialized_vertex_index_map(g); + test_uniqueness(g, vertices(g), ivim); + + typedef typename CGAL::GetInitializedHalfedgeIndexMap::const_type HIM; + HIM ihim = CGAL::get_initialized_halfedge_index_map(g); + test_uniqueness(g, halfedges(g), ihim); + + typedef typename CGAL::GetInitializedEdgeIndexMap::const_type EIM; + EIM ieim = CGAL::get_initialized_edge_index_map(g); + test_uniqueness(g, edges(g), ieim); + + typedef typename CGAL::GetInitializedFaceIndexMap::const_type FIM; + FIM ifim = CGAL::get_initialized_face_index_map(g); + test_uniqueness(g, faces(g), ifim); + + // Passing an index map via NP + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef std::map VertexIndexMap; + typedef boost::associative_property_map VertexIdPropertyMap; // lvalue_pmap + + int vi = static_cast(num_vertices(g)); + VertexIndexMap vim; + VertexIdPropertyMap external_vertex_index_map(vim); + for(vertex_descriptor v : vertices(g)) + put(external_vertex_index_map, v, --vi); + + test_vertex_index_map_uniqueness(g, CGAL::parameters::vertex_index_map(external_vertex_index_map)); + + // Read-only pmap + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef std::map HalfedgeIndexMap; + typedef CGAL::Non_mutable_property_map HalfedgeIdPropertyMap; + + int hi = 0; + HalfedgeIndexMap him; + HalfedgeIdPropertyMap external_halfedge_index_map(him); + + // this should complain that the map is not writable (commented because it does assert) +// CGAL::BGL::internal::initialize_halfedge_index_map(external_halfedge_index_map, g); + + // forced to initialize the underlying map + for(halfedge_descriptor h : halfedges(g)) + him[h] = hi++; + + test_halfedge_index_map_uniqueness(g, CGAL::parameters::halfedge_index_map(external_halfedge_index_map)); + + // Writable pmap + typedef typename boost::graph_traits::edge_descriptor edge_descriptor; + typedef boost::unordered_map EdgeIndexMap; + typedef CGAL::RW_property_map EdgeIdPropertyMap; + + EdgeIndexMap eim; + EdgeIdPropertyMap external_edge_index_map(eim); + CGAL::BGL::internal::initialize_edge_index_map(external_edge_index_map, g); + + test_edge_index_map_uniqueness(g, CGAL::parameters::edge_index_map(external_edge_index_map)); + + // Just so face_index_map don't feel excluded + typedef typename boost::graph_traits::face_descriptor face_descriptor; + typedef std::map FaceIndexMap; + typedef boost::const_associative_property_map FaceIdPropertyMap; + + FaceIndexMap fim; + FaceIdPropertyMap external_face_index_map(fim); + + // 'const_associative_pmap' has category 'lvalue_property_map_tag' but it's not writable + // so below should complain (commented because it does assert) +// CGAL::BGL::internal::initialize_face_index_map(external_face_index_map, g); + + // gotta initialize the underlying map + int fi = 0; + for(face_descriptor f : faces(g)) + fim[f] = fi++; + + test_face_index_map_uniqueness(g, CGAL::parameters::face_index_map(external_face_index_map)); +} + +template +void test_all_index_maps_const(const Graph& g) +{ +#ifdef CGAL_TEST_PROPERTIES_DEBUG + std::cout << " ---------------------------- Const graph tests" << std::endl; #endif -template -void index_uniqueness_tr(const Triangulation& g) -{ - index_uniqueness(g, edges(g) , get(boost::edge_index, g)); - index_uniqueness(g, vertices(g), get(boost::vertex_index, g)); - index_uniqueness(g, faces(g), get(boost::face_index, g)); - index_uniqueness(g, halfedges(g), get(boost::halfedge_index, g)); + test_internal_index_maps_const(g); + test_initialized_index_maps_const(g); } -int main() +///////////////////////////////////// non-const //////////////////////////////////////////////////// + +template +void test_internal_index_maps(Graph& g) +{ + test_uniqueness(g, vertices(g), get(boost::vertex_index, g)); + test_uniqueness(g, halfedges(g), get(boost::halfedge_index, g)); + test_uniqueness(g, edges(g) , get(boost::edge_index, g)); + test_uniqueness(g, faces(g), get(boost::face_index, g)); +} + +template +void test_initialized_index_maps(Graph& g) +{ + typedef typename CGAL::GetInitializedVertexIndexMap::type VIM; + VIM ivim = CGAL::get_initialized_vertex_index_map(g); + test_uniqueness(g, vertices(g), ivim); + + typedef typename CGAL::GetInitializedHalfedgeIndexMap::type HIM; + HIM ihim = CGAL::get_initialized_halfedge_index_map(g); + test_uniqueness(g, halfedges(g), ihim); + + typedef typename CGAL::GetInitializedEdgeIndexMap::type EIM; + EIM ieim = CGAL::get_initialized_edge_index_map(g); + test_uniqueness(g, edges(g), ieim); + + typedef typename CGAL::GetInitializedFaceIndexMap::type FIM; + FIM ifim = CGAL::get_initialized_face_index_map(g); + test_uniqueness(g, faces(g), ifim); + + // Passing an index map via NP + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef std::map VertexIndexMap; + typedef boost::associative_property_map VertexIdPropertyMap; // lvalue_pmap + + int vi = static_cast(num_vertices(g)); + VertexIndexMap vim; + VertexIdPropertyMap external_vertex_index_map(vim); + for(vertex_descriptor v : vertices(g)) + put(external_vertex_index_map, v, --vi); + + test_vertex_index_map_uniqueness(g, CGAL::parameters::vertex_index_map(external_vertex_index_map)); + + // Read-only pmap + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef std::map HalfedgeIndexMap; + typedef CGAL::Non_mutable_property_map HalfedgeIdPropertyMap; + + int hi = 0; + HalfedgeIndexMap him; + HalfedgeIdPropertyMap external_halfedge_index_map(him); + + // this should complain that the map is not writable (commented because it does assert) +// CGAL::BGL::internal::initialize_halfedge_index_map(external_halfedge_index_map, g); + + // forced to initialize the underlying map + for(halfedge_descriptor h : halfedges(g)) + him[h] = hi++; + + test_halfedge_index_map_uniqueness(g, CGAL::parameters::halfedge_index_map(external_halfedge_index_map)); + + // Writable pmap + typedef typename boost::graph_traits::edge_descriptor edge_descriptor; + typedef boost::unordered_map EdgeIndexMap; + typedef CGAL::RW_property_map EdgeIdPropertyMap; + + EdgeIndexMap eim; + EdgeIdPropertyMap external_edge_index_map(eim); + CGAL::BGL::internal::initialize_edge_index_map(external_edge_index_map, g); + + test_edge_index_map_uniqueness(g, CGAL::parameters::edge_index_map(external_edge_index_map)); + + // Just so face_index_map don't feel excluded + typedef typename boost::graph_traits::face_descriptor face_descriptor; + typedef std::map FaceIndexMap; + typedef boost::const_associative_property_map FaceIdPropertyMap; + + FaceIndexMap fim; + FaceIdPropertyMap external_face_index_map(fim); + + // 'const_associative_pmap' has category 'lvalue_property_map_tag' but it's not writable + // so below should complain (commented because it does assert) +// CGAL::BGL::internal::initialize_face_index_map(external_face_index_map, g); + + // gotta initialize the underlying map + int fi = 0; + for(face_descriptor f : faces(g)) + fim[f] = fi++; + + test_face_index_map_uniqueness(g, CGAL::parameters::face_index_map(external_face_index_map)); +} + +template +void test_all_index_maps(Graph& g) +{ +#ifdef CGAL_TEST_PROPERTIES_DEBUG + std::cout << " ---------------------------- Non-const graph tests" << std::endl; +#endif + + test_internal_index_maps(g); + test_initialized_index_maps(g); +} + +template +void test_graph(Graph& g) +{ +#ifdef CGAL_TEST_PROPERTIES_DEBUG + std::cout << "Graph has:" << std::endl + << "\t" << num_vertices(g) << " vertices (actual: " << vertices(g).size() << ")" << std::endl + << "\t" << num_halfedges(g) << " halfedges (actual: " << halfedges(g).size() << ")" << std::endl + << "\t" << num_edges(g) << " edges (actual: " << edges(g).size() << ")" << std::endl + << "\t" << num_faces(g) << " faces (actual: " << faces(g).size() << ")" << std::endl; +#endif + + test_all_index_maps(g); + test_all_index_maps_const(g); +} + +void test_poly(Polyhedron& g) +{ + test_graph(g); + + test_uniqueness(g, edges(g) , get(boost::edge_external_index, g)); + test_uniqueness(g, vertices(g), get(boost::vertex_external_index, g)); + test_uniqueness(g, faces(g), get(boost::face_external_index, g)); + test_uniqueness(g, halfedges(g), get(boost::halfedge_external_index, g)); +} + +int main(int, char**) { std::cout << "testing Polyhedron\n"; std::vector polys = poly_data(); - for(Polyhedron p : polys) - index_uniqueness_poly(p); + for(Polyhedron& p : polys) + test_poly(p); std::cout << "testing Linear_cell_complex\n"; std::vector lccs = lcc_data(); - for(LCC p : lccs) - index_uniqueness_lcc(p); + for(LCC& p : lccs) + test_graph(p); std::cout << "testing Surface_mesh\n"; std::vector sms = sm_data(); - for(SM p : sms) - index_uniqueness_sm(p); + for(SM& sm : sms) + { + assert(!CGAL::is_empty(sm)); + + // Add some garbage + CGAL::Euler::join_vertex(*(halfedges(sm).begin()), sm); + + test_graph(sm); + + // Test on a mesh with no internal index maps + Seam_edge_pmap seam_edges = sm.add_property_map("e:on_seam", false).first; + Seam_vertex_pmap seam_vertices = sm.add_property_map("v:on_seam", false).first; + Seam_mesh seam_mesh(sm, seam_edges, seam_vertices); + + test_initialized_index_maps(seam_mesh); + test_initialized_index_maps_const(seam_mesh); + } #if defined(CGAL_USE_OPENMESH) std::cout << "testing OpenMesh\n"; std::vector omeshs = omesh_data(); - for(OMesh p : omeshs) - index_uniqueness_omesh(p); + for(OMesh& p : omeshs) + test_graph(p); #endif std::cout << "testing Triangulations\n"; - index_uniqueness_tr(t2_data()); - index_uniqueness_tr(dt2_data()); - index_uniqueness_tr(rt2_data()); - index_uniqueness_tr(ct2_data()); - index_uniqueness_tr(cdt2_data()); - index_uniqueness_tr(cdtp2_data()); - index_uniqueness_tr(t2h_data()); - std::cerr << "done\n"; - return 0; + Triangulation_2 t2 = t2_data(); + test_graph(t2); + + Delaunay_triangulation_2 dt2 = dt2_data(); + test_graph(dt2); + + Regular_triangulation_2 rt2 = rt2_data(); + test_graph(rt2); + + Constrained_triangulation_2 ct2 = ct2_data(); + test_graph(ct2); + + Constrained_Delaunay_triangulation_2 cdt2 = cdt2_data(); + test_graph(cdt2); + + CDT_P2 cdtp2 = cdtp2_data(); + test_graph(cdtp2); + + Triangulation_hierarchy_2 t2h = t2h_data(); + test_graph(t2h); + + // no dynamic pmaps in triangulations (yet) +// Triangulation_no_id_2 t2_no_id = t2_no_id_data(); +// test_initialized_index_maps(t2_no_id); +// test_initialized_index_maps_const(t2_no_id); + + std::cout << "Done!" << std::endl; + + return EXIT_SUCCESS; } diff --git a/Mesh_3/include/CGAL/Polyhedral_complex_mesh_domain_3.h b/Mesh_3/include/CGAL/Polyhedral_complex_mesh_domain_3.h index ae6413ca009..9421e883a45 100644 --- a/Mesh_3/include/CGAL/Polyhedral_complex_mesh_domain_3.h +++ b/Mesh_3/include/CGAL/Polyhedral_complex_mesh_domain_3.h @@ -750,8 +750,7 @@ detect_features(FT angle_in_degree, for(Polyhedron_type& p : poly) { initialize_ts(p); - using Mesh_3::internal::Get_face_index_pmap; - Get_face_index_pmap get_face_index_pmap(p); + #ifdef CGAL_MESH_3_VERBOSE std::size_t poly_id = &p-&poly[0]; std::cerr << "Polyhedron #" << poly_id << " :\n"; @@ -768,9 +767,9 @@ detect_features(FT angle_in_degree, , eif , pid_map , PMP::parameters::first_index(nb_of_patch_plus_one) - .face_index_map(get_face_index_pmap(p)) - .vertex_incident_patches_map(vip_map) - .vertex_feature_degree_map(vertex_feature_degree_map)); + .face_index_map(get_initialized_face_index_map(p)) + .vertex_incident_patches_map(vip_map) + .vertex_feature_degree_map(vertex_feature_degree_map)); Mesh_3::internal::Is_featured_edge is_featured_edge(p); diff --git a/Mesh_3/include/CGAL/Polyhedral_mesh_domain_3.h b/Mesh_3/include/CGAL/Polyhedral_mesh_domain_3.h index f9a7a0d5cf4..42abf9d1256 100644 --- a/Mesh_3/include/CGAL/Polyhedral_mesh_domain_3.h +++ b/Mesh_3/include/CGAL/Polyhedral_mesh_domain_3.h @@ -105,47 +105,6 @@ struct IGT_generator } // end namespace details } // end namespace Mesh_3 -namespace Mesh_3 { -namespace internal { - -template ::value> -class Get_face_index_pmap { -public: - typedef typename boost::property_map::const_type Pmap; - Get_face_index_pmap(const Polyhedron_type&) {} - Pmap operator()(const Polyhedron_type& polyhedron) { - return get(CGAL::face_index, polyhedron); - } -}; - -template -class Get_face_index_pmap { - typedef typename boost::graph_traits::face_descriptor - face_descriptor; - typedef std::map Map; -public: - Get_face_index_pmap(const Polyhedron_type& polyhedron) { - int id = 0; - for(face_descriptor f : faces(polyhedron)) - { - face_ids[f] = id++; - } - } - typedef boost::associative_property_map Pmap; - - Pmap operator()(const Polyhedron_type&) { - return Pmap(face_ids); - } -private: - Map face_ids; -}; - -} // end namespace internal -} // end namespace Mesh_3 - /** * @class Polyhedral_mesh_domain_3 * diff --git a/Mesh_3/include/CGAL/Polyhedral_mesh_domain_with_features_3.h b/Mesh_3/include/CGAL/Polyhedral_mesh_domain_with_features_3.h index d5f9979bc9b..ea92e1341ea 100644 --- a/Mesh_3/include/CGAL/Polyhedral_mesh_domain_with_features_3.h +++ b/Mesh_3/include/CGAL/Polyhedral_mesh_domain_with_features_3.h @@ -348,9 +348,6 @@ detect_features(FT angle_in_degree, std::vector& poly) typedef typename boost::property_map >::type VIPMap; typedef typename boost::property_map::type EIFMap; - using Mesh_3::internal::Get_face_index_pmap; - Get_face_index_pmap get_face_index_pmap(p); - PIDMap pid_map = get(face_patch_id_t(), p); VIPMap vip_map = get(vertex_incident_patches_t(), p); EIFMap eif_map = get(CGAL::edge_is_feature, p); @@ -360,8 +357,8 @@ detect_features(FT angle_in_degree, std::vector& poly) , eif_map , pid_map , PMP::parameters::first_index(nb_of_patch_plus_one) - .face_index_map(get_face_index_pmap(p)) - .vertex_incident_patches_map(vip_map)); + .face_index_map(get_initialized_face_index_map(p)) + .vertex_incident_patches_map(vip_map)); Mesh_3::internal::Is_featured_edge is_featured_edge(p); diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt index 20cea4f136f..b95f8671c34 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt @@ -32,20 +32,27 @@ is the property map with the points associated to the vertices of the polygon me \cgalNPEnd \cgalNPBegin{vertex_index_map} \anchor PMP_vertex_index_map -is the property map containing the index of each vertex of the input polygon mesh.\n +is the property map associating a unique index to each vertex of a polygon mesh, +between `0` and `num_vertices(g)-1`. +If this parameter is not passed, internal machinery will create and initialize a vertex index +property map, either using the internal property map if it exists or using an external map. The latter +might result in - slightly - worsened performance in case of non-constant complexity for index access.\n Type: a class model of `ReadablePropertyMap` with `boost::graph_traits::%vertex_descriptor` as key type and the value type \code typename boost::property_traits::type>::value_type \endcode -Default: \code boost::get(CGAL::vertex_index, pmesh)\endcode +Default: an initialized vertex index property map \cgalNPEnd \cgalNPBegin{face_index_map} \anchor PMP_face_index_map -is the property map containing the index of each face of the input polygon mesh.\n +is the property map associating a unique index to each face of a polygon mesh, +between `0` and `num_faces(g)-1`. +If this parameter is not passed, internal machinery will create and initialize a face index +property map, either using the internal property map if it exists or using an external map. The latter +might result in - slightly - worsened performance in case of non-constant complexity for index access.\n Type: a class model of `ReadablePropertyMap` with `boost::graph_traits::%face_descriptor` as key type and the value type: \code typename boost::property_traits::type>::value_type \endcode -Default: \code boost::get(CGAL::face_index, pmesh)\endcode -If this internal property map exists, its values must be initialized. +Default: an initialized face index property map \cgalNPEnd \cgalNPBegin{edge_is_constrained_map} \anchor PMP_edge_is_constrained_map diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/border.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/border.h index d2fab3b6632..c52695b90cf 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/border.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/border.h @@ -53,7 +53,7 @@ std::size_t border_size(typename boost::graph_traits::halfedge_desc template - HalfedgeOutputIterator border_halfedges_impl(const FaceRange& faces + HalfedgeOutputIterator border_halfedges_impl(const FaceRange& face_range , HalfedgeOutputIterator out , const PM& pmesh) { @@ -64,7 +64,7 @@ std::size_t border_size(typename boost::graph_traits::halfedge_desc // the bool is true if the halfedge stored is the one of the face, // false if it is its opposite std::map border; - for(face_descriptor f : faces) + for(face_descriptor f : face_range) { for(halfedge_descriptor h : halfedges_around_face(halfedge(f, pmesh), pmesh)) @@ -94,13 +94,13 @@ std::size_t border_size(typename boost::graph_traits::halfedge_desc , typename FaceRange , typename HalfedgeOutputIterator , typename NamedParameters> - HalfedgeOutputIterator border_halfedges_impl(const FaceRange& faces + HalfedgeOutputIterator border_halfedges_impl(const FaceRange& face_range , typename boost::cgal_no_property::type , HalfedgeOutputIterator out , const PM& pmesh , const NamedParameters& /* np */) { - return border_halfedges_impl(faces, out, pmesh); + return border_halfedges_impl(face_range, out, pmesh); } template::halfedge_desc , typename FaceIndexMap , typename HalfedgeOutputIterator , typename NamedParameters> - HalfedgeOutputIterator border_halfedges_impl(const FaceRange& faces + HalfedgeOutputIterator border_halfedges_impl(const FaceRange& face_range , const FaceIndexMap& fmap , HalfedgeOutputIterator out , const PM& pmesh @@ -117,25 +117,13 @@ std::size_t border_size(typename boost::graph_traits::halfedge_desc typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::face_descriptor face_descriptor; - //make a minimal check that it's properly initialized : - //if the 2 first faces have the same id, we know the property map is not initialized - if (boost::is_same::Is_internal_map, - boost::true_type>::value) - { - typename boost::range_iterator::type it = boost::const_begin(faces); - if (get(fmap, *it) == get(fmap, *std::next(it))) - { - std::cerr << "WARNING : the internal property map for CGAL::face_index_t" << std::endl - << " is not properly initialized." << std::endl - << " Initialize it before calling border_halfedges()" << std::endl; - } - } + CGAL_assertion(BGL::internal::is_index_map_valid(fmap, num_faces(pmesh), faces(pmesh))); std::vector present(num_faces(pmesh), false); - for(face_descriptor fd : faces) + for(face_descriptor fd : face_range) present[get(fmap, fd)] = true; - for(face_descriptor fd : faces) + for(face_descriptor fd : face_range) for(halfedge_descriptor hd : halfedges_around_face(halfedge(fd, pmesh), pmesh)) { @@ -161,21 +149,16 @@ std::size_t border_size(typename boost::graph_traits::halfedge_desc * For each returned halfedge `h`, `opposite(h, pmesh)` belongs to a face of the patch, * but `face(h, pmesh)` does not belong to the patch. * - * @tparam PolygonMesh model of `HalfedgeGraph`. If `PolygonMesh` - * has an internal property map - * for `CGAL::face_index_t` and no `face_index_map` is given - * as a named parameter, then the internal one must be initialized - * @tparam FaceRange range of - `boost::graph_traits::%face_descriptor`, model of `Range`. - Its iterator type is `InputIterator`. + * @tparam PolygonMesh model of `HalfedgeGraph` + * @tparam FaceRange a model of `Range` with value type `boost::graph_traits::%face_descriptor`. * @tparam HalfedgeOutputIterator model of `OutputIterator` holding `boost::graph_traits::%halfedge_descriptor` for patch border * @tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" * - * @param pmesh the polygon mesh to which `faces` belong - * @param faces the range of faces defining the patch whose border halfedges - * are collected + * @param pmesh the polygon mesh to which the faces in `face_range` belong + * @param face_range the range of faces defining the patch whose border halfedges + * are collected * @param out the output iterator that collects the border halfedges of the patch, * seen from outside. * @param np optional sequence of \ref pmp_namedparameters "Named Parameters" among the ones listed below @@ -190,29 +173,18 @@ std::size_t border_size(typename boost::graph_traits::halfedge_desc , typename FaceRange , typename HalfedgeOutputIterator , typename NamedParameters> - HalfedgeOutputIterator border_halfedges(const FaceRange& faces + HalfedgeOutputIterator border_halfedges(const FaceRange& face_range , const PolygonMesh& pmesh , HalfedgeOutputIterator out , const NamedParameters& np) { - if (faces.empty()) return out; + if (face_range.empty()) + return out; - typedef PolygonMesh PM; - typedef typename GetFaceIndexMap::const_type FIMap; - typedef typename boost::property_map::type Unset_FIMap; + typedef typename CGAL::GetInitializedFaceIndexMap::const_type FIMap; + FIMap fim = CGAL::get_initialized_face_index_map(pmesh, np); - if (boost::is_same::value || faces.size() == 1) - { - //face index map is not given in named parameters, nor as an internal property map - return internal::border_halfedges_impl(faces, out, pmesh); - } - - //face index map given as a named parameter, or as an internal property map - FIMap fim = parameters::choose_parameter(parameters::get_parameter(np, internal_np::face_index), - get_const_property_map(CGAL::face_index, pmesh)); - - return internal::border_halfedges_impl(faces, fim, out, pmesh, np); + return internal::border_halfedges_impl(face_range, fim, out, pmesh, np); } template::halfedge_desc template - HalfedgeOutputIterator border_halfedges(const FaceRange& faces + HalfedgeOutputIterator border_halfedges(const FaceRange& face_range , const PolygonMesh& pmesh , HalfedgeOutputIterator out) { - return border_halfedges(faces, pmesh, out, + return border_halfedges(face_range, pmesh, out, CGAL::Polygon_mesh_processing::parameters::all_default()); } @@ -244,7 +216,7 @@ std::size_t border_size(typename boost::graph_traits::halfedge_desc // // @tparam PolygonMesh model of `HalfedgeGraph`. // - // @param pmesh the polygon mesh to which `faces` belong + // @param pmesh the polygon mesh to which `face_range` belong // template unsigned int number_of_borders(const PolygonMesh& pmesh) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/clip.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/clip.h index 6f3ef0e496d..1fdd380c316 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/clip.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/clip.h @@ -274,9 +274,6 @@ clip_to_bbox(const Plane_3& plane, * \pre \link CGAL::Polygon_mesh_processing::does_bound_a_volume() `CGAL::Polygon_mesh_processing::does_bound_a_volume(clipper)` \endlink * * @tparam TriangleMesh a model of `MutableFaceGraph`, `HalfedgeListGraph` and `FaceListGraph`. - * If `TriangleMesh` has an internal property map for `CGAL::face_index_t`, - * as a named parameter, then it must be initialized. - * * @tparam NamedParameters1 a sequence of \ref pmp_namedparameters "Named Parameters" * @tparam NamedParameters2 a sequence of \ref pmp_namedparameters "Named Parameters" * @@ -292,8 +289,8 @@ clip_to_bbox(const Plane_3& plane, * `CGAL::vertex_point_t` must be available in `TriangleMesh` * \cgalParamEnd * \cgalParamBegin{face_index_map} a property map containing the index of each face of `tm` (`clipper`). - * Note that if the property map is writable, the indices of the faces - * of `tm` and `clipper` will be set after refining `tm` with the intersection with `clipper`. + * This property map must be either writable, or be automatically updated + * when new faces are added and removed in the mesh. * \cgalParamEnd * \cgalParamBegin{visitor} a class model of `PMPCorefinementVisitor` * that is used to track the creation of new faces. @@ -334,26 +331,6 @@ clip( TriangleMesh& tm, np_c); } -namespace internal{ -template -bool dispatch_clip_call(TriangleMesh& tm, TriangleMesh& clipper, - const NamedParameters& np, Tag_false) -{ - return clip(tm, clipper, - np.face_index_map(get(CGAL::dynamic_face_property_t(), tm)), - parameters::face_index_map(get(CGAL::dynamic_face_property_t(), clipper))); -} - -template -bool dispatch_clip_call(TriangleMesh& tm, TriangleMesh& clipper, - const NamedParameters& np, Tag_true) -{ - return clip(tm, clipper, - np.face_index_map(get(face_index, tm)), - parameters::face_index_map(get(face_index, clipper))); -} -} - /** * \ingroup PMP_corefinement_grp * clips `tm` by keeping the part that is on the negative side of `plane` (side opposite to its normal vector). @@ -365,8 +342,6 @@ bool dispatch_clip_call(TriangleMesh& tm, TriangleMesh& clipper, * \pre \link CGAL::Polygon_mesh_processing::does_self_intersect() `!CGAL::Polygon_mesh_processing::does_self_intersect(tm)` \endlink * * @tparam TriangleMesh a model of `MutableFaceGraph`, `HalfedgeListGraph` and `FaceListGraph`. - * If `TriangleMesh` has an internal property map for `CGAL::face_index_t`, - * as a named parameter, then it must be initialized. * An internal property map for `CGAL::vertex_point_t` must be available. * * @tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" @@ -428,9 +403,8 @@ bool clip( TriangleMesh& tm, default: break; } - // dispatch is needed because face index map for tm and clipper have to be of the same time - return internal::dispatch_clip_call(tm, clipper, - np, CGAL::graph_has_property()); + + return clip(tm, clipper, np, parameters::all_default()); } /** @@ -444,8 +418,6 @@ bool clip( TriangleMesh& tm, * \pre \link CGAL::Polygon_mesh_processing::does_self_intersect() `!CGAL::Polygon_mesh_processing::does_self_intersect(tm)` \endlink * * @tparam TriangleMesh a model of `MutableFaceGraph`, `HalfedgeListGraph` and `FaceListGraph`. - * If `TriangleMesh` has an internal property map for `CGAL::face_index_t`, - * as a named parameter, then it must be initialized. * An internal property map for `CGAL::vertex_point_t` must be available. * * @tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" @@ -492,9 +464,7 @@ bool clip( TriangleMesh& tm, clipper); triangulate_faces(clipper); - // dispatch is needed because face index map for tm and clipper have to be of the same time - return internal::dispatch_clip_call(tm, clipper, - np, CGAL::graph_has_property()); + return clip(tm, clipper, np, parameters::all_default()); } /// \cond SKIP_IN_MANUAL diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/connected_components.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/connected_components.h index 4935db60735..d0482afc54f 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/connected_components.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/connected_components.h @@ -145,7 +145,7 @@ connected_component(typename boost::graph_traits::face_descriptor s if (!already_processed.insert(seed_face).second) continue; *out++=seed_face; for(halfedge_descriptor hd : - CGAL::halfedges_around_face(halfedge(seed_face, pmesh), pmesh) ) + halfedges_around_face(halfedge(seed_face, pmesh), pmesh) ) { if(! get(ecmap, edge(hd, pmesh))){ face_descriptor neighbor = face( opposite(hd, pmesh), pmesh ); @@ -171,9 +171,6 @@ connected_component(typename boost::graph_traits::face_descriptor s * \ingroup keep_connected_components_grp * computes for each face the index of the corresponding connected component. * - * A property map for `CGAL::face_index_t` must be either available as an internal property map - * to `pmesh` or provided as one of the \ref pmp_namedparameters "Named Parameters". - * * \tparam PolygonMesh a model of `FaceListGraph` * \tparam FaceComponentMap a model of `WritablePropertyMap` with `boost::graph_traits::%face_descriptor` as key type and @@ -213,13 +210,13 @@ connected_components(const PolygonMesh& pmesh, NamedParameters, internal::No_constraint//default > ::type EdgeConstraintMap; + EdgeConstraintMap ecmap = choose_parameter(get_parameter(np, internal_np::edge_is_constrained), internal::No_constraint()); - typedef typename GetFaceIndexMap::const_type FaceIndexMap; - FaceIndexMap fimap = choose_parameter(get_parameter(np, internal_np::face_index), - get_const_property_map(boost::face_index, pmesh)); + typedef typename GetInitializedFaceIndexMap::const_type FaceIndexMap; + FaceIndexMap fimap = get_initialized_face_index_map(pmesh, np); typename boost::property_traits::value_type i=0; std::vector handled(num_faces(pmesh), false); @@ -323,10 +320,6 @@ std::size_t number_of_connected_components(const PolygonMesh& pmesh) * By default, the size of a face is `1` (and thus the size of a connected component is the number * of faces it contains), but it is also possible to pass custom sizes, such as the area of the face. * - * Property maps for `CGAL::face_index_t` and `CGAL::vertex_index_t` - * must be either available as internal property maps - * to `pmesh` or provided as \ref pmp_namedparameters "Named Parameters". - * * \tparam PolygonMesh a model of `FaceListGraph` and `MutableFaceGraph` * \tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" * @@ -368,10 +361,8 @@ std::size_t keep_largest_connected_components(PolygonMesh& pmesh, using parameters::choose_parameter; using parameters::get_parameter; - // FaceIndexMap - typedef typename GetFaceIndexMap::type FaceIndexMap; - FaceIndexMap fimap = choose_parameter(get_parameter(np, internal_np::face_index), - get_property_map(boost::face_index, pmesh)); + typedef typename CGAL::GetInitializedFaceIndexMap::type FaceIndexMap; + FaceIndexMap fimap = CGAL::get_initialized_face_index_map(pmesh, np); // FaceSizeMap typedef typename internal_np::Lookup_named_param_def::type FaceIndexMap; - FaceIndexMap fim = choose_parameter(get_parameter(np, internal_np::face_index), - get_property_map(boost::face_index, pmesh)); + typedef typename CGAL::GetInitializedFaceIndexMap::type FaceIndexMap; + FaceIndexMap fim = CGAL::get_initialized_face_index_map(pmesh, np); typedef typename internal_np::Lookup_named_param_def // default - >::type FaceSizeMap; + NamedParameters, + Constant_property_map // default + >::type FaceSizeMap; typedef typename boost::property_traits::value_type Face_size; CGAL_static_assertion((std::is_convertible::value)); @@ -587,7 +572,6 @@ void keep_or_remove_connected_components(PolygonMesh& pmesh , bool keep , const NamedParameters& np) { - typedef PolygonMesh PM; using parameters::choose_parameter; using parameters::get_parameter; @@ -599,10 +583,8 @@ void keep_or_remove_connected_components(PolygonMesh& pmesh typedef typename boost::graph_traits::edge_descriptor edge_descriptor; typedef typename boost::graph_traits::edge_iterator edge_iterator; - //VertexIndexMap - typedef typename GetVertexIndexMap::type VertexIndexMap; - VertexIndexMap vim = choose_parameter(get_parameter(np, internal_np::vertex_index), - get_const_property_map(boost::vertex_index, pmesh)); + typedef typename GetInitializedVertexIndexMap::type VertexIndexMap; + VertexIndexMap vim = get_initialized_vertex_index_map(pmesh, np); std::set cc_to_keep; for(std::size_t i : components_to_keep) @@ -721,10 +703,6 @@ void keep_or_remove_connected_components(PolygonMesh& pmesh * \note If the removal of the connected components makes `pmesh` a non-manifold surface, * then the behavior of this function is undefined. * -* Property maps for `CGAL::vertex_index_t` -* must be either available as internal property map -* to `pmesh` or provided as \ref pmp_namedparameters "Named Parameters". -* * \tparam PolygonMesh a model of `FaceListGraph` and `MutableFaceGraph` * \tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" * \tparam ComponentRange a range of ids convertible to `std::size` @@ -764,11 +742,6 @@ void keep_connected_components(PolygonMesh& pmesh * \note If the removal of the connected components makes `pmesh` a non-manifold surface, * then the behavior of this function is undefined. * -* Property maps for `CGAL::vertex_index_t` -* must be either available as internal property map -* to `pmesh` or provided as \ref pmp_namedparameters "Named Parameters". -* -* * \tparam PolygonMesh a model of `FaceListGraph` and `MutableFaceGraph` * \tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" * \tparam ComponentRange a range of ids convertible to `std::size` @@ -805,10 +778,6 @@ void remove_connected_components(PolygonMesh& pmesh * keeps the connected components not designated by the faces in `components_to_remove`, * and removes the other connected components and all isolated vertices. * -* Property maps for `CGAL::face_index_t` and `CGAL::vertex_index_t` -* must be either available as internal property maps -* to `pmesh` or provided as \ref pmp_namedparameters "Named Parameters". -* * \note If the removal of the connected components makes `pmesh` a non-manifold surface, * then the behavior of this function is undefined. * @@ -835,20 +804,19 @@ void remove_connected_components(PolygonMesh& pmesh , const FaceRange& components_to_remove , const CGAL_PMP_NP_CLASS& np) { - if (components_to_remove.empty()) return; - typedef PolygonMesh PM; - typedef typename boost::graph_traits::face_descriptor face_descriptor; using parameters::choose_parameter; using parameters::get_parameter; - //FaceIndexMap - typedef typename GetFaceIndexMap::type FaceIndexMap; - FaceIndexMap fim = choose_parameter(get_parameter(np, internal_np::face_index), - get_property_map(boost::face_index, pmesh)); + if (components_to_remove.empty()) + return; + + typedef PolygonMesh PM; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + + typedef typename CGAL::GetInitializedFaceIndexMap::type FaceIndexMap; + FaceIndexMap fim = CGAL::get_initialized_face_index_map(pmesh, np); - //vector_property_map boost::vector_property_map face_cc(fim); - connected_components(pmesh, face_cc, np); std::vector cc_to_remove; @@ -863,10 +831,6 @@ void remove_connected_components(PolygonMesh& pmesh * keeps the connected components designated by the faces in `components_to_keep`, * and removes the other connected components and all isolated vertices. * -* Property maps for `CGAL::face_index_t` and `CGAL::vertex_index_t` -* must be either available as internal property maps -* to `pmesh` or provided as \ref pmp_namedparameters "Named Parameters". -* * \note If the removal of the connected components makes `pmesh` a non-manifold surface, * then the behavior of this function is undefined. * @@ -899,14 +863,10 @@ void keep_connected_components(PolygonMesh& pmesh using parameters::choose_parameter; using parameters::get_parameter; - //FaceIndexMap - typedef typename GetFaceIndexMap::type FaceIndexMap; - FaceIndexMap fim = choose_parameter(get_parameter(np, internal_np::face_index), - get_property_map(boost::face_index, pmesh)); + typedef typename CGAL::GetInitializedFaceIndexMap::type FaceIndexMap; + FaceIndexMap fim = CGAL::get_initialized_face_index_map(pmesh, np); - //vector_property_map boost::vector_property_map face_cc(fim); - connected_components(pmesh, face_cc, np); std::vector cc_to_keep; diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/corefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/corefinement.h index a6f2f052434..3c4f77b9bbe 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/corefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/corefinement.h @@ -17,11 +17,12 @@ #include +#include +#include #include #include #include #include -#include #include namespace CGAL { @@ -39,16 +40,17 @@ namespace internal { template bool recursive_does_bound_a_volume(const TriangleMesh& tm, Vpm& vpm, - Fid_map& fid_map, + Fid_map fid_map, const std::vector& xtrm_vertices, boost::dynamic_bitset<>& cc_handled, const std::vector& face_cc, std::size_t xtrm_cc_id, bool is_parent_outward_oriented) { - typedef boost::graph_traits GT; - typedef typename GT::face_descriptor face_descriptor; - typedef Side_of_triangle_mesh Side_of_tm; + typedef boost::graph_traits Graph_traits; + typedef typename Graph_traits::face_descriptor face_descriptor; + typedef Side_of_triangle_mesh Side_of_tm; + // first check that the orientation of the current cc is consistant with its // parent cc containing it bool new_is_parent_outward_oriented = internal::is_outward_oriented( @@ -170,25 +172,23 @@ enum Boolean_operation_type {UNION = 0, INTERSECTION=1, * \see `CGAL::Polygon_mesh_processing::orient_to_bound_a_volume()` */ template -bool does_bound_a_volume(const TriangleMesh& tm, const NamedParameters& np) +bool does_bound_a_volume(const TriangleMesh& tm, + const NamedParameters& np) { - typedef boost::graph_traits GT; - typedef typename GT::vertex_descriptor vertex_descriptor; - typedef typename GetVertexPointMap::const_type Vpm; - typedef typename GetFaceIndexMap::const_type Fid_map; - typedef typename Kernel_traits< - typename boost::property_traits::value_type >::Kernel Kernel; + typedef boost::graph_traits Graph_traits; + typedef typename Graph_traits::vertex_descriptor vertex_descriptor; + typedef typename GetVertexPointMap::const_type Vpm; + typedef typename boost::property_traits::value_type Point; + typedef typename Kernel_traits::Kernel Kernel; if (!is_closed(tm)) return false; if (!is_triangle_mesh(tm)) return false; Vpm vpm = parameters::choose_parameter(parameters::get_parameter(np, internal_np::vertex_point), - get_const_property_map(boost::vertex_point, tm)); + get_const_property_map(boost::vertex_point, tm)); - Fid_map fid_map = parameters::choose_parameter(parameters::get_parameter(np, internal_np::face_index), - get_const_property_map(boost::face_index, tm)); + typedef typename GetInitializedFaceIndexMap::const_type Fid_map; + Fid_map fid_map = get_initialized_face_index_map(tm, np); std::vector face_cc(num_faces(tm), std::size_t(-1)); @@ -203,11 +203,11 @@ bool does_bound_a_volume(const TriangleMesh& tm, const NamedParameters& np) boost::dynamic_bitset<> cc_handled(nb_cc, 0); // extract a vertex with max z coordinate for each connected component - std::vector xtrm_vertices(nb_cc, GT::null_vertex()); + std::vector xtrm_vertices(nb_cc, Graph_traits::null_vertex()); for(vertex_descriptor vd : vertices(tm)) { std::size_t cc_id = face_cc[get(fid_map, face(halfedge(vd, tm), tm))]; - if (xtrm_vertices[cc_id]==GT::null_vertex()) + if (xtrm_vertices[cc_id] == Graph_traits::null_vertex()) xtrm_vertices[cc_id]=vd; else if (get(vpm, vd).z()>get(vpm,xtrm_vertices[cc_id]).z()) @@ -514,21 +514,14 @@ corefine_and_compute_boolean_operations( typedef std::tuple Edge_mark_map_tuple; -// Face index point maps - typedef typename GetFaceIndexMap::type Fid_map; - typedef typename GetFaceIndexMap::type Fid_map2; - CGAL_USE_TYPE(Fid_map2); - CGAL_assertion_code( - static const bool same_fidmap = (boost::is_same::value);) - CGAL_static_assertion(same_fidmap); + // Face index point maps + typedef typename CGAL::GetInitializedFaceIndexMap::type FaceIndexMap1; + typedef typename CGAL::GetInitializedFaceIndexMap::type FaceIndexMap2; - Fid_map fid_map1 = parameters::choose_parameter(parameters::get_parameter(np1, internal_np::face_index), - get_property_map(boost::face_index, tm1)); - Fid_map fid_map2 = parameters::choose_parameter(parameters::get_parameter(np2, internal_np::face_index), - get_property_map(boost::face_index, tm2)); -// User visitor + FaceIndexMap1 fid_map1 = get_initialized_face_index_map(tm1, np1); + FaceIndexMap2 fid_map2 = get_initialized_face_index_map(tm2, np2); + + // User visitor typedef typename internal_np::Lookup_named_param_def < internal_np::graph_visitor_t, NamedParameters1, @@ -541,7 +534,8 @@ corefine_and_compute_boolean_operations( typedef Corefinement::Face_graph_output_builder Algo_visitor; Ecm_in ecm_in(tm1,tm2,ecm1,ecm2); Edge_mark_map_tuple ecms_out(ecm_out_0, ecm_out_1, ecm_out_2, ecm_out_3); - Ob ob(tm1, tm2, vpm1, vpm2, fid_map1, fid_map2, ecm_in, - vpm_out_tuple, ecms_out, uv, output); + Ob ob(tm1, tm2, vpm1, vpm2, fid_map1, fid_map2, ecm_in, vpm_out_tuple, ecms_out, uv, output); // special case used for clipping open meshes if ( parameters::choose_parameter( parameters::get_parameter(np1, internal_np::use_bool_op_to_clip_surface), @@ -933,8 +926,7 @@ namespace experimental { const NamedParameters& np) { // Vertex point maps - typedef typename GetVertexPointMap::type Vpm; + typedef typename GetVertexPointMap::type Vpm; Vpm vpm = parameters::choose_parameter(parameters::get_parameter(np, internal_np::vertex_point), get_property_map(boost::vertex_point, tm)); @@ -1014,10 +1006,9 @@ namespace experimental { Vpm vpm = parameters::choose_parameter(parameters::get_parameter(np, internal_np::vertex_point), get_property_map(boost::vertex_point, tm)); // Face index map - typedef typename GetFaceIndexMap::type Fid_map; - Fid_map fid_map = parameters::choose_parameter(parameters::get_parameter(np, internal_np::face_index), - get_property_map(boost::face_index, tm)); + typedef typename GetInitializedFaceIndexMap::type Fid_map; + Fid_map fid_map = get_initialized_face_index_map(tm, np); + // Edge is-constrained maps typedef typename internal_np::Lookup_named_param_def < internal_np::edge_is_constrained_t, diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/detect_features.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/detect_features.h index ffbb806305a..55b007d16b3 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/detect_features.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/detect_features.h @@ -138,11 +138,6 @@ detect_surface_patches(PolygonMesh& p, EdgeIsFeatureMap eif, const NamedParameters& np) { - //extract types from NPs - typename GetFaceIndexMap::const_type - fimap = parameters::choose_parameter(parameters::get_parameter(np, internal_np::face_index), - get_const_property_map(boost::face_index, p)); - int offset = static_cast( parameters::choose_parameter(parameters::get_parameter(np, internal_np::first_index), 1)); @@ -150,11 +145,12 @@ detect_surface_patches(PolygonMesh& p, internal::PatchIdMapWrapper::value_type> wrapmap(patch_id_map, offset); + return connected_components(p, wrapmap, parameters::edge_is_constrained_map(eif) - .face_index_map(fimap)); - + .face_index_map(CGAL::get_initialized_face_index_map(p, np))); } + template typename boost::graph_traits::faces_size_type detect_surface_patches(PolygonMesh& p, @@ -373,8 +369,6 @@ namespace internal * computing a * surface patch id for each face. * - * A property map for `CGAL::face_index_t` must be either available - * as an internal property map to `pmesh` or provided as one of the Named Parameters. * * \tparam PolygonMesh a model of `FaceGraph` * \tparam FT a number type. It is diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h index 2f93d176784..602ae2a2fde 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h @@ -60,7 +60,8 @@ namespace params=PMP::parameters; template + template static void fill_polylines_to_skip( Intersection_polylines& polylines, @@ -223,8 +226,8 @@ class Face_graph_output_builder const std::vector& tm2_patch_ids, const boost::dynamic_bitset<>& patches_of_tm1_used, const boost::dynamic_bitset<>& patches_of_tm2_used, - const FIM& fids1, - const FIM& fids2, + const FIM1 fids1, + const FIM2 fids2, const TM& tm1, const TM& tm2) { @@ -341,18 +344,17 @@ class Face_graph_output_builder public: - Face_graph_output_builder( TriangleMesh& tm1, - TriangleMesh& tm2, - const VertexPointMap &vpm1, - const VertexPointMap &vpm2, - const FaceIdMap& fids1, - const FaceIdMap& fids2, - EdgeMarkMapBind& marks_on_input_edges, + Face_graph_output_builder(TriangleMesh& tm1, + TriangleMesh& tm2, + const VertexPointMap vpm1, + const VertexPointMap vpm2, + FaceIdMap1 fids1, + FaceIdMap2 fids2, + EdgeMarkMapBind& marks_on_input_edges, const VpmOutTuple& output_vpms, - EdgeMarkMapTuple& out_edge_mark_maps, - UserVisitor& user_visitor, - const std::array< - boost::optional, 4 >& requested_output) + EdgeMarkMapTuple& out_edge_mark_maps, + UserVisitor& user_visitor, + const std::array, 4 >& requested_output) : tm1(tm1), tm2(tm2) , vpm1(vpm1), vpm2(vpm2) , fids1(fids1), fids2(fids2) @@ -460,9 +462,12 @@ public: Intersection_edge_map& intersection_edges1 = mesh_to_intersection_edges[&tm1]; Intersection_edge_map& intersection_edges2 = mesh_to_intersection_edges[&tm2]; - // this will initialize face indices if the face index map is writable. - helpers::init_face_indices(tm1, fids1); - helpers::init_face_indices(tm2, fids2); + // The property map must be either writable or well-initialized + if(!BGL::internal::is_index_map_valid(fids1, num_faces(tm1), faces(tm1))) + BGL::internal::initialize_face_index_map(fids1, tm1); + + if(!BGL::internal::is_index_map_valid(fids2, num_faces(tm2), faces(tm2))) + BGL::internal::initialize_face_index_map(fids2, tm2); // bitset to identify coplanar faces boost::dynamic_bitset<> tm1_coplanar_faces(num_faces(tm1), 0); @@ -620,9 +625,8 @@ public: std::size_t nb_patches_tm1 = PMP::connected_components(tm1, bind_property_maps(fids1,make_property_map(&tm1_patch_ids[0])), - params::edge_is_constrained_map( - is_marked_1) - .face_index_map(fids1)); + params::edge_is_constrained_map(is_marked_1) + .face_index_map(fids1)); std::vector tm1_patch_sizes(nb_patches_tm1, 0); for(std::size_t i : tm1_patch_ids) @@ -634,9 +638,8 @@ public: std::size_t nb_patches_tm2 = PMP::connected_components(tm2, bind_property_maps(fids2,make_property_map(&tm2_patch_ids[0])), - params::edge_is_constrained_map( - is_marked_2) - .face_index_map(fids2)); + params::edge_is_constrained_map(is_marked_2) + .face_index_map(fids2)); std::vector tm2_patch_sizes(nb_patches_tm2, 0); for(Node_id i : tm2_patch_ids) @@ -1245,9 +1248,8 @@ public: polyline_lengths.push_back(polyline_info.second+1); } - typedef Patch_container Patches; + typedef Patch_container Patches1; + typedef Patch_container Patches2; boost::unordered_set border_nm_vertices; // only used if used_to_clip_a_surface == true if (used_to_clip_a_surface) @@ -1279,8 +1281,8 @@ public: } //store the patch description in a container to avoid recomputing it several times - Patches patches_of_tm1( tm1, tm1_patch_ids, fids1, intersection_edges1, nb_patches_tm1), - patches_of_tm2( tm2, tm2_patch_ids, fids2, intersection_edges2, nb_patches_tm2); + Patches1 patches_of_tm1(tm1, tm1_patch_ids, fids1, intersection_edges1, nb_patches_tm1); + Patches2 patches_of_tm2(tm2, tm2_patch_ids, fids2, intersection_edges2, nb_patches_tm2); // for each boolean operation, define two bitsets of patches contributing // to the result @@ -1460,11 +1462,12 @@ public: // operation in tm1 with removal (and optionally inside-out) delayed // First backup the border edges of patches to be used - Patches tmp_patches_of_tm1(tm1, - patches_of_tm1.patch_ids, - patches_of_tm1.fids, - patches_of_tm1.is_intersection_edge, - patches_of_tm1.patches.size()); + Patches1 tmp_patches_of_tm1(tm1, + patches_of_tm1.patch_ids, + patches_of_tm1.fids, + patches_of_tm1.is_intersection_edge, + patches_of_tm1.patches.size()); + boost::dynamic_bitset<> patches_of_tm1_removed = ~patches_of_tm1_used[inplace_operation_tm1]; for (std::size_t i = patches_of_tm1_removed.find_first(); diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Output_builder_for_autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Output_builder_for_autorefinement.h index 3656f46aea3..031d23a1c36 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Output_builder_for_autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Output_builder_for_autorefinement.h @@ -214,9 +214,6 @@ public: const boost::dynamic_bitset<>& is_node_of_degree_one, const Mesh_to_map_node&) { - // this will initialize face indices if the face index map is writable. - helpers::init_face_indices(tm, fids); - // first build an unordered_map mapping a vertex to its node id + a set // of all intersection edges typedef boost::unordered_set Intersection_edge_map; @@ -239,8 +236,9 @@ public: intersection_edges.insert(edge(p.second.h2, tm)); } - // this will initialize face indices if the face index map is writable. - helpers::init_face_indices(tm, fids); + // The property map must be either writable or well-initialized + if(!BGL::internal::is_index_map_valid(fids, num_faces(tm), faces(tm))) + BGL::internal::initialize_face_index_map(fids, tm); // bitset to identify coplanar faces boost::dynamic_bitset<> tm_coplanar_faces(num_faces(tm), 0); diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h index e75e4ccfce2..c188231238c 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h @@ -424,7 +424,7 @@ template void extract_patch_simplices( std::size_t patch_id, PolygonMesh& pm, - const FaceIndexMap& fids, + const FaceIndexMap fids, const std::vector& patch_ids, std::vector::face_descriptor>& patch_faces, std::set::vertex_descriptor>& interior_vertices, @@ -480,13 +480,13 @@ struct Patch_container{ // external data members PolygonMesh& pm; const std::vector& patch_ids; - const FaceIndexMap& fids; + const FaceIndexMap fids; const IsIntersectionEdge& is_intersection_edge; // constructor Patch_container( PolygonMesh& pm, const std::vector& patch_ids, - const FaceIndexMap& fids, + const FaceIndexMap fids, const IsIntersectionEdge& is_intersection_edge, std::size_t nb_patches ) : patches(nb_patches) @@ -1010,14 +1010,15 @@ template < class TriangleMesh, class EdgeMarkMap2, class EdgeMarkMapOut, class IntersectionPolylines, - class PatchContainer, + class PatchContainer1, + class PatchContainer2, class UserVisitor> void fill_new_triangle_mesh( TriangleMesh& output, const boost::dynamic_bitset<>& patches_of_tm1_to_import, const boost::dynamic_bitset<>& patches_of_tm2_to_import, - PatchContainer& patches_of_tm1, - PatchContainer& patches_of_tm2, + PatchContainer1& patches_of_tm1, + PatchContainer2& patches_of_tm2, bool reverse_orientation_of_patches_from_tm1, bool reverse_orientation_of_patches_from_tm2, const IntersectionPolylines& polylines, @@ -1256,7 +1257,8 @@ void disconnect_patches( } template & patches_of_tm1_to_keep, const boost::dynamic_bitset<>& patches_of_tm2_to_import, - PatchContainer& patches_of_tm1, - PatchContainer& patches_of_tm2, + PatchContainer1& patches_of_tm1, + PatchContainer2& patches_of_tm2, bool reverse_patch_orientation_tm2, const IntersectionPolylines& polylines, const VertexPointMap& vpm1, @@ -1416,7 +1418,8 @@ remove_patches(TriangleMesh& tm, } template & patches_of_tm1_to_keep, const boost::dynamic_bitset<>& patches_of_tm2_to_import, - PatchContainer& patches_of_tm1, - PatchContainer& patches_of_tm2, + PatchContainer1& patches_of_tm1, + PatchContainer2& patches_of_tm2, bool reverse_patch_orientation_tm1, bool reverse_patch_orientation_tm2, const VertexPointMap& vpm1, @@ -1485,14 +1488,15 @@ void compute_inplace_operation( template void compute_border_edge_map( const TriangleMesh& tm1, const TriangleMesh& tm2, const IntersectionPolylines& polylines, - PatchContainer& patches_of_tm1, - PatchContainer& patches_of_tm2, + PatchContainer1& patches_of_tm1, + PatchContainer2& patches_of_tm2, EdgeMap& tm2_edge_to_tm1_edge) { typedef boost::graph_traits GT; @@ -1520,7 +1524,8 @@ void compute_border_edge_map( template & patches_of_tm1_to_keep, const boost::dynamic_bitset<>& patches_of_tm2_to_import, - PatchContainer& patches_of_tm1, - PatchContainer& patches_of_tm2, + PatchContainer1& patches_of_tm1, + PatchContainer2& patches_of_tm2, bool reverse_patch_orientation_tm1, bool reverse_patch_orientation_tm2, const VertexPointMap& vpm1, diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index 182a9a866f7..b70eefd073e 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -438,8 +438,6 @@ void recursive_orient_volume_ccs( TriangleMesh& tm, * inward or outward oriented. * * @tparam TriangleMesh a model of `FaceListGraph` and `MutableFaceGraph` . -* If `TriangleMesh` has an internal property map for `CGAL::face_index_t`, -* as a named parameter, then it must be initialized. * @tparam NamedParameters a sequence of \ref pmp_namedparameters * * @param tm a closed triangulated surface mesh @@ -461,16 +459,15 @@ void recursive_orient_volume_ccs( TriangleMesh& tm, * \cgalNamedParamsEnd */ template -void orient(TriangleMesh& tm, const NamedParameters& np) +void orient(TriangleMesh& tm, + const NamedParameters& np) { - typedef boost::graph_traits Graph_traits; - typedef typename Graph_traits::vertex_descriptor vertex_descriptor; - typedef typename Graph_traits::face_descriptor face_descriptor; - typedef typename Graph_traits::halfedge_descriptor halfedge_descriptor; - typedef typename GetVertexPointMap::const_type Vpm; - typedef typename GetFaceIndexMap::const_type Fid_map; + typedef boost::graph_traits Graph_traits; + typedef typename Graph_traits::vertex_descriptor vertex_descriptor; + typedef typename Graph_traits::face_descriptor face_descriptor; + typedef typename Graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename GetVertexPointMap::const_type Vpm; + typedef typename GetInitializedFaceIndexMap::type FaceIndexMap; CGAL_assertion(is_triangle_mesh(tm)); CGAL_assertion(is_valid_polygon_mesh(tm)); @@ -484,8 +481,7 @@ void orient(TriangleMesh& tm, const NamedParameters& np) Vpm vpm = CGAL::parameters::choose_parameter(get_parameter(np, internal_np::vertex_point), get_const_property_map(boost::vertex_point, tm)); - Fid_map fid_map = CGAL::parameters::choose_parameter(get_parameter(np, internal_np::face_index), - get_const_property_map(boost::face_index, tm)); + FaceIndexMap fid_map = CGAL::get_initialized_face_index_map(tm, np); std::vector face_cc(num_faces(tm), std::size_t(-1)); @@ -542,8 +538,6 @@ void orient(TriangleMesh& tm) * See \ref coref_def_subsec for a precise definition. * * @tparam TriangleMesh a model of `MutableFaceGraph`, `HalfedgeListGraph` and `FaceListGraph`. - * If `TriangleMesh` has an internal property map for `CGAL::face_index_t`, - * as a named parameter, then it must be initialized. * @tparam NamedParameters a sequence of \ref pmp_namedparameters * * @param tm a closed triangulated surface mesh @@ -569,20 +563,20 @@ void orient(TriangleMesh& tm) */ template void orient_to_bound_a_volume(TriangleMesh& tm, - const NamedParameters& np) + const NamedParameters& np) { - typedef boost::graph_traits Graph_traits; - typedef typename Graph_traits::vertex_descriptor vertex_descriptor; - typedef typename GetVertexPointMap::const_type Vpm; - typedef typename GetFaceIndexMap::const_type Fid_map; - typedef typename Kernel_traits< - typename boost::property_traits::value_type >::Kernel Kernel; + typedef boost::graph_traits Graph_traits; + typedef typename Graph_traits::vertex_descriptor vertex_descriptor; + + typedef typename GetVertexPointMap::const_type Vpm; + typedef typename boost::property_traits::value_type Point; + typedef typename Kernel_traits::Kernel Kernel; + + typedef typename GetInitializedFaceIndexMap::type FaceIndexMap; + if (!is_closed(tm)) return; if (!is_triangle_mesh(tm)) return; - using parameters::get_parameter; bool orient_outward = CGAL::parameters::choose_parameter( @@ -591,8 +585,7 @@ void orient_to_bound_a_volume(TriangleMesh& tm, Vpm vpm = CGAL::parameters::choose_parameter(get_parameter(np, internal_np::vertex_point), get_const_property_map(boost::vertex_point, tm)); - Fid_map fid_map = CGAL::parameters::choose_parameter(get_parameter(np, internal_np::face_index), - get_const_property_map(boost::face_index, tm)); + FaceIndexMap fid_map = CGAL::get_initialized_face_index_map(tm, np); std::vector face_cc(num_faces(tm), std::size_t(-1)); diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh.h index c5a1b649f89..5290d6b03fc 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh.h @@ -41,9 +41,7 @@ namespace Polygon_mesh_processing { * The descriptor types `boost::graph_traits::%face_descriptor` * and `boost::graph_traits::%halfedge_descriptor` must be * models of `Hashable`. -* If `PolygonMesh` has an internal property map for `CGAL::face_index_t`, -* and no `face_index_map` is given -* as a named parameter, then the internal one must be initialized +* * @tparam FaceRange range of `boost::graph_traits::%face_descriptor`, model of `Range`. Its iterator type is `ForwardIterator`. * @tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" @@ -160,9 +158,8 @@ void isotropic_remeshing(const FaceRange& faces VPMap vpmap = choose_parameter(get_parameter(np, internal_np::vertex_point), get_property_map(vertex_point, pmesh)); - typedef typename GetFaceIndexMap::type FIMap; - FIMap fimap = choose_parameter(get_parameter(np, internal_np::face_index), - get_property_map(face_index, pmesh)); + typedef typename GetInitializedFaceIndexMap::type FIMap; + FIMap fimap = CGAL::get_initialized_face_index_map(pmesh, np); typedef typename internal_np::Lookup_named_param_def < internal_np::edge_is_constrained_t, @@ -338,9 +335,8 @@ void split_long_edges(const EdgeRange& edges VPMap vpmap = choose_parameter(get_parameter(np, internal_np::vertex_point), get_property_map(vertex_point, pmesh)); - typedef typename GetFaceIndexMap::type FIMap; - FIMap fimap = choose_parameter(get_parameter(np, internal_np::face_index), - get_property_map(face_index, pmesh)); + typedef typename GetInitializedFaceIndexMap::type FIMap; + FIMap fimap = CGAL::get_initialized_face_index_map(pmesh, np); typedef typename internal_np::Lookup_named_param_def < internal_np::edge_is_constrained_t, diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair.h index 509957423d5..833523b575e 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair.h @@ -111,10 +111,6 @@ std::size_t remove_isolated_vertices(PolygonMesh& pmesh) /// As a consequence of the last sentence, the area or volume criteria can be disabled /// by passing zero (`0`) as threshold value. /// -/// Property maps for `CGAL::face_index_t` and `CGAL::vertex_index_t` -/// must be either available as internal property maps -/// to `tmesh` or provided as \ref pmp_namedparameters "Named Parameters". -/// /// \tparam TriangleMesh a model of `FaceListGraph` and `MutableFaceGraph` /// \tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" /// @@ -129,8 +125,6 @@ std::size_t remove_isolated_vertices(PolygonMesh& pmesh) /// \cgalParamBegin{edge_is_constrained_map} a property map containing the constrained-or-not status of each edge of `pmesh` \cgalParamEnd /// \cgalParamBegin{face_index_map} a property map containing the index of each face of `tmesh` \cgalParamEnd /// \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `tmesh`. -/// If this parameter is omitted, an internal property map for -/// `CGAL::vertex_point_t` should be available in `TriangleMesh` \cgalParamEnd /// \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `Kernel` \cgalParamEnd /// \cgalParamBegin{dry_run} a Boolean parameter. If set to `true`, the mesh will not be altered, /// but the number of components that would be removed is returned. The default value is `false`.\cgalParamEnd @@ -162,9 +156,8 @@ std::size_t remove_connected_components_of_negligible_size(TriangleMesh& tmesh, const VPM vpm = choose_parameter(get_parameter(np, internal_np::vertex_point), get_const_property_map(CGAL::vertex_point, tmesh)); - typedef typename GetFaceIndexMap::type FaceIndexMap; - FaceIndexMap fim = choose_parameter(get_parameter(np, internal_np::face_index), - get_property_map(boost::face_index, tmesh)); + typedef typename GetInitializedFaceIndexMap::type FaceIndexMap; + FaceIndexMap fim = CGAL::get_initialized_face_index_map(tmesh, np); FT area_threshold = choose_parameter(get_parameter(np, internal_np::area_threshold), FT(-1)); FT volume_threshold = choose_parameter(get_parameter(np, internal_np::volume_threshold), FT(-1)); diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/stitch_borders.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/stitch_borders.h index c805217f87a..9e565d205f8 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/stitch_borders.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/stitch_borders.h @@ -185,10 +185,8 @@ collect_duplicated_stitchable_boundary_edges if(per_cc) { cc = get(Face_property_tag(), pmesh); - typedef typename GetFaceIndexMap::const_type FIMap; - FIMap fim = parameters::choose_parameter(parameters::get_parameter(np, internal_np::face_index), - get_const_property_map(face_index, pmesh)); - num_component = num_component_wrapper(pmesh, cc, fim); + + num_component = num_component_wrapper(pmesh, cc, CGAL::get_initialized_face_index_map(pmesh, np)); border_edges_per_cc.resize(num_component); } @@ -862,16 +860,18 @@ std::size_t stitch_borders(PolygonMesh& pmesh, /// @param np optional sequence of \ref pmp_namedparameters "Named Parameters" among the ones listed below /// /// \cgalNamedParamsBegin -/// \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. -/// If this parameter is omitted, an internal property map for -/// `CGAL::vertex_point_t` must be available in `PolygonMesh`.\cgalParamEnd -/// \cgalParamBegin{apply_per_connected_component} -/// specifies if the borders should only be stitched inside their own connected component. -/// In that case, a property map for `CGAL::face_index_t` should be either available as an internal property map -/// to `pmesh` or provided as the \ref pmp_namedparameters "Named Parameter" `face_index_map`. If this is not the case, -/// a default map will be created on the fly. -/// Default value is `false`.\cgalParamEnd -/// \cgalParamBegin{face_index_map} a property map containing the index of each face of `pmesh` \cgalParamEnd +/// \cgalParamBegin{vertex_point_map} +/// the property map with the points associated to the vertices of `pmesh`. +/// If this parameter is omitted, an internal property map for +/// `CGAL::vertex_point_t` must be available in `PolygonMesh`. +/// \cgalParamEnd +/// \cgalParamBegin{apply_per_connected_component} +/// specifies if the borders should only be stitched inside their own connected component. +/// Default value is `false`. +/// \cgalParamEnd +/// \cgalParamBegin{face_index_map} +/// a property map containing for each face of `pmesh` a unique index between `0` and `num_faces(pmesh)-1` +/// \cgalParamEnd /// \cgalNamedParamsEnd /// /// @return the number of pairs of halfedges that were stitched. diff --git a/Polygon_mesh_processing/include/CGAL/Rigid_triangle_mesh_collision_detection.h b/Polygon_mesh_processing/include/CGAL/Rigid_triangle_mesh_collision_detection.h index ec20752cf83..2ce1278e7ae 100644 --- a/Polygon_mesh_processing/include/CGAL/Rigid_triangle_mesh_collision_detection.h +++ b/Polygon_mesh_processing/include/CGAL/Rigid_triangle_mesh_collision_detection.h @@ -537,11 +537,8 @@ public: std::vector cc_ids(num_faces(tm)); // face index map - typedef typename CGAL::GetFaceIndexMap::type Fid_map; - - Fid_map fid_map = - parameters::choose_parameter(parameters::get_parameter(np, internal_np::face_index), - get_const_property_map(boost::face_index, tm)); + typedef typename GetInitializedFaceIndexMap::const_type FaceIndexMap; + FaceIndexMap fid_map = CGAL::get_initialized_face_index_map(tm, np); std::size_t nb_cc = Polygon_mesh_processing::connected_components( diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/connected_component_polyhedron.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/connected_component_polyhedron.cpp index 4a9fcec8ec7..35a7e3a75f0 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/connected_component_polyhedron.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/connected_component_polyhedron.cpp @@ -37,8 +37,8 @@ void mesh_with_id(const char* argv1, const bool save_output) std::cerr << cc.size() << " faces in the CC of " << &*fd << std::endl; boost::vector_property_map::type> - fccmap(get(boost::face_index,sm)); + boost::property_map::type> + fccmap(get(CGAL::face_index,sm)); std::size_t num = PMP::connected_components(sm, fccmap); if (strcmp(argv1, "data/blobby_3cc.off") == 0) @@ -84,17 +84,17 @@ void mesh_no_id(const char* argv1, const bool save_output) PMP::connected_component(fd, sm, std::back_inserter(cc)); std::cerr << cc.size() << " faces in the CC of " << &*fd << std::endl; - boost::property_map::type vim + boost::property_map::type vim = get(boost::vertex_external_index,sm); - boost::property_map::type fim + boost::property_map::type fim = get(boost::face_external_index,sm); boost::vector_property_map::type> fccmap(fim); - std::size_t num = PMP::connected_components(sm, fccmap, PMP::parameters::face_index_map(fim)); + std::size_t num = PMP::connected_components(sm, fccmap); if (strcmp(argv1, "data/blobby_3cc.off") == 0) assert(num == 3); @@ -104,8 +104,7 @@ void mesh_no_id(const char* argv1, const bool save_output) // std::cout << &*f << " in connected component " << fccmap[f] << std::endl; //} - PMP::keep_largest_connected_components(sm, 2, PMP::parameters::vertex_index_map(vim) - .face_index_map(fim)); + PMP::keep_largest_connected_components(sm, 2, PMP::parameters::vertex_index_map(vim)); if (save_output) return; diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/remeshing_test_P_SM_OM.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/remeshing_test_P_SM_OM.cpp index 1769df9e09c..bed1ad1c583 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/remeshing_test_P_SM_OM.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/remeshing_test_P_SM_OM.cpp @@ -31,15 +31,21 @@ int main() } { - typedef CGAL::Polyhedron_3 P; - std::map::face_descriptor, std::size_t> fim; - P p; - std::ifstream in("data/elephant.off"); - in >> p; - PMP::isotropic_remeshing(faces(p), + typedef CGAL::Polyhedron_3 P; + + std::ifstream in("data/elephant.off"); + P p; + in >> p; + + std::map::face_descriptor, std::size_t> fim; + std::size_t fid = 0; + for(const boost::graph_traits

::face_descriptor f : faces(p)) + fim[f] = fid++; + + PMP::isotropic_remeshing(faces(p), 0.02, - p, - PMP::parameters::face_index_map(boost::make_assoc_property_map(fim))); + p, + PMP::parameters::face_index_map(boost::make_assoc_property_map(fim))); std::ofstream out("p.off"); out << p << std::endl; } diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_orient_cc.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_orient_cc.cpp index 34a54ecd273..8f846d3c455 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_orient_cc.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_orient_cc.cpp @@ -1,5 +1,7 @@ #include #include + +#include #include #include @@ -12,13 +14,13 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef CGAL::Surface_mesh SMesh; template -bool test_orientation(TriangleMesh& tm, bool is_positive, const NamedParameters& np) +bool test_orientation(const TriangleMesh& tm, bool is_positive, const NamedParameters& np) { typedef boost::graph_traits Graph_traits; typedef typename Graph_traits::vertex_descriptor vertex_descriptor; typedef typename Graph_traits::face_descriptor face_descriptor; typedef typename CGAL::GetVertexPointMap::const_type Vpm; - typedef typename CGAL::GetFaceIndexMap::const_type Fid_map; + typedef typename CGAL::GetInitializedFaceIndexMap::const_type Fid_map; using CGAL::parameters::choose_parameter; using CGAL::parameters::get_parameter; @@ -26,8 +28,7 @@ bool test_orientation(TriangleMesh& tm, bool is_positive, const NamedParameters& Vpm vpm = choose_parameter(get_parameter(np, CGAL::internal_np::vertex_point), CGAL::get_const_property_map(boost::vertex_point, tm)); - Fid_map fid_map = choose_parameter(get_parameter(np, CGAL::internal_np::face_index), - CGAL::get_const_property_map(boost::face_index, tm)); + Fid_map fid_map = CGAL::get_initialized_face_index_map(tm, np); std::vector face_cc(num_faces(tm), std::size_t(-1)); @@ -127,5 +128,6 @@ int main() return 1; } + std::cout << "Done!" << std::endl; return 0; } diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_clip.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_clip.cpp index b7fe169bd6c..6c8b77d5ce8 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_clip.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_clip.cpp @@ -19,374 +19,458 @@ template void test() { // test with a clipper mesh - TriangleMesh tm1, tm2; + { + TriangleMesh tm1, tm2; + std::ifstream("data-coref/elephant.off") >> tm1; + std::ifstream("data-coref/sphere.off") >> tm2; - std::ifstream input("data-coref/elephant.off"); - input >> tm1; - input.close(); - input.open("data-coref/sphere.off"); - input >> tm2; - input.close(); + auto custom_face_index_map_1 = get(CGAL::dynamic_face_property_t(), tm1); + CGAL::BGL::internal::initialize_face_index_map(custom_face_index_map_1, tm1); + auto custom_face_index_map_2 = get(CGAL::dynamic_face_property_t(), tm2); + CGAL::BGL::internal::initialize_face_index_map(custom_face_index_map_2, tm2); - PMP::clip(tm1, tm2, - params::clip_volume(false) - .face_index_map(get(CGAL::dynamic_face_property_t(), tm1)), - params::face_index_map(get(CGAL::dynamic_face_property_t(), tm2)) - ); - assert(!CGAL::is_closed(tm1)); - CGAL::clear(tm1); - CGAL::clear(tm2); + PMP::clip(tm1, tm2, + params::clip_volume(false).face_index_map(custom_face_index_map_1), + params::face_index_map(custom_face_index_map_2)); + assert(!CGAL::is_closed(tm1)); + } - input.open("data-coref/elephant.off"); - input >> tm1; - input.close(); - input.open("data-coref/sphere.off"); - input >> tm2; - input.close(); + { + TriangleMesh tm1, tm2; + std::ifstream("data-coref/elephant.off") >> tm1; + std::ifstream("data-coref/sphere.off") >> tm2; - PMP::clip(tm1, tm2, params::clip_volume(true) - .face_index_map(get(CGAL::dynamic_face_property_t(), tm1)), - params::face_index_map(get(CGAL::dynamic_face_property_t(), tm2))); - assert(CGAL::is_closed(tm1)); - CGAL::clear(tm1); - CGAL::clear(tm2); + auto custom_face_index_map_1 = get(CGAL::dynamic_face_property_t(), tm1); + CGAL::BGL::internal::initialize_face_index_map(custom_face_index_map_1, tm1); + auto custom_face_index_map_2 = get(CGAL::dynamic_face_property_t(), tm2); + CGAL::BGL::internal::initialize_face_index_map(custom_face_index_map_2, tm2); + PMP::clip(tm1, tm2, + params::clip_volume(true).face_index_map(custom_face_index_map_1), + params::face_index_map(custom_face_index_map_2)); + assert(CGAL::is_closed(tm1)); + } // test with a iso-cuboid - input.open("data-coref/elephant.off"); - input >> tm1; - input.close(); - K::Iso_cuboid_3 iso_cuboid(K::Point_3(0,0,0), K::Point_3(0.4, 0.6, 0.4)); + { + TriangleMesh tm1; + std::ifstream("data-coref/elephant.off") >> tm1; + K::Iso_cuboid_3 iso_cuboid(K::Point_3(0,0,0), K::Point_3(0.4, 0.6, 0.4)); - PMP::clip(tm1, iso_cuboid, params::clip_volume(true)); - assert(CGAL::is_closed(tm1)); - CGAL::clear(tm1); + auto custom_face_index_map_1 = get(CGAL::dynamic_face_property_t(), tm1); + CGAL::BGL::internal::initialize_face_index_map(custom_face_index_map_1, tm1); + + PMP::clip(tm1, iso_cuboid, params::clip_volume(true).face_index_map(custom_face_index_map_1)); + assert(CGAL::is_closed(tm1)); + } // test with a plane - input.open("data-coref/cube.off"); - input >> tm1; - input.close(); + { + TriangleMesh tm1; + std::ifstream("data-coref/cube.off") >> tm1; + K::Plane_3 plane(0, 0, 1, -1); - K::Plane_3 plane(0, 0, 1, -1); + PMP::clip(tm1, plane, params::clip_volume(true)); + assert(CGAL::is_closed(tm1)); + } - PMP::clip(tm1, plane, params::clip_volume(true)); - assert(CGAL::is_closed(tm1)); - CGAL::clear(tm1); + { + TriangleMesh tm1; + std::ifstream("data-coref/cube.off") >> tm1; + K::Plane_3 plane(0, 0, 1, -1); - input.open("data-coref/cube.off"); - input >> tm1; - input.close(); - PMP::clip(tm1, plane, params::clip_volume(false) - .use_compact_clipper(false)); - assert(!CGAL::is_closed(tm1)); - CGAL::clear(tm1); + PMP::clip(tm1, plane, params::clip_volume(false).use_compact_clipper(false)); + assert(!CGAL::is_closed(tm1)); + } - input.open("data-coref/cube.off"); - input >> tm1; - input.close(); - PMP::clip(tm1, plane, params::clip_volume(false) - .use_compact_clipper(true)); - assert(CGAL::is_closed(tm1)); - CGAL::clear(tm1); + { + TriangleMesh tm1; + std::ifstream("data-coref/cube.off") >> tm1; + K::Plane_3 plane(0, 0, 1, -1); - input.open("data-coref/cube.off"); - input >> tm1; - input.close(); - PMP::clip(tm1, K::Plane_3(-0.236474, 0.437732, 0.867451, -0.838791), params::clip_volume(true)); - assert(CGAL::is_closed(tm1)); - assert(!CGAL::is_empty(tm1)); - CGAL::clear(tm1); + PMP::clip(tm1, plane, params::clip_volume(false).use_compact_clipper(true)); + assert(CGAL::is_closed(tm1)); + } - input.open("data-coref/cube.off"); - input >> tm1; - input.close(); - PMP::clip(tm1, K::Plane_3(0, 0, 1, 2)); - assert(CGAL::is_empty(tm1)); - CGAL::clear(tm1); + { + TriangleMesh tm1; + std::ifstream("data-coref/cube.off") >> tm1; - input.open("data-coref/cube.off"); - input >> tm1; - input.close(); - PMP::clip(tm1, K::Plane_3(0, 0, 1, -2)); - assert(!CGAL::is_empty(tm1)); - CGAL::clear(tm1); + PMP::clip(tm1, K::Plane_3(-0.236474, 0.437732, 0.867451, -0.838791), params::clip_volume(true)); + assert(CGAL::is_closed(tm1)); + assert(!CGAL::is_empty(tm1)); + } + + { + TriangleMesh tm1; + std::ifstream("data-coref/cube.off") >> tm1; + + PMP::clip(tm1, K::Plane_3(0, 0, 1, 2)); + assert(CGAL::is_empty(tm1)); + } + + { + TriangleMesh tm1; + std::ifstream("data-coref/cube.off") >> tm1; + + PMP::clip(tm1, K::Plane_3(0, 0, 1, -2)); + assert(!CGAL::is_empty(tm1)); + } // clipping with identity - input.open("data-coref/cube.off"); - input >> tm1; - input.close(); - input.open("data-coref/cube.off"); - input >> tm2; - input.close(); - PMP::clip(tm1, tm2,params::clip_volume(true) - .use_compact_clipper(true) - .face_index_map(get(CGAL::dynamic_face_property_t(), tm1)), - params::face_index_map(get(CGAL::dynamic_face_property_t(), tm2))); - assert(num_vertices(tm1)==8); - CGAL::clear(tm1); - CGAL::clear(tm2); + { + TriangleMesh tm1, tm2; + std::ifstream("data-coref/cube.off") >> tm1; + std::ifstream("data-coref/cube.off") >> tm2; - input.open("data-coref/cube.off"); - input >> tm1; - input.close(); - input.open("data-coref/cube.off"); - input >> tm2; - input.close(); - PMP::clip(tm1, tm2,params::clip_volume(false) - .use_compact_clipper(false) - .face_index_map(get(CGAL::dynamic_face_property_t(), tm1)), - params::face_index_map(get(CGAL::dynamic_face_property_t(), tm2))); - assert(CGAL::is_empty(tm1)); - CGAL::clear(tm1); - CGAL::clear(tm2); + auto custom_face_index_map_1 = get(CGAL::dynamic_face_property_t(), tm1); + CGAL::BGL::internal::initialize_face_index_map(custom_face_index_map_1, tm1); + auto custom_face_index_map_2 = get(CGAL::dynamic_face_property_t(), tm2); + CGAL::BGL::internal::initialize_face_index_map(custom_face_index_map_2, tm2); - input.open("data-coref/cube.off"); - input >> tm1; - input.close(); - input.open("data-coref/cube.off"); - input >> tm2; - input.close(); - PMP::clip(tm1, tm2,params::clip_volume(false) - .use_compact_clipper(true) - .face_index_map(get(CGAL::dynamic_face_property_t(), tm1)), - params::face_index_map(get(CGAL::dynamic_face_property_t(), tm2))); - assert(num_vertices(tm1)==8); - CGAL::clear(tm1); - CGAL::clear(tm2); + PMP::clip(tm1, tm2, + params::clip_volume(true) + .use_compact_clipper(true) + .face_index_map(custom_face_index_map_1), + params::face_index_map(custom_face_index_map_2)); + assert(num_vertices(tm1) == 8); + } - input.open("data-coref/cube.off"); - input >> tm1; - input.close(); - input.open("data-coref/cube.off"); - input >> tm2; - input.close(); - PMP::transform(K::Aff_transformation_3(CGAL::TRANSLATION, K::Vector_3(1,0,0)), tm2); - PMP::clip(tm1, tm2,params::clip_volume(false) - .use_compact_clipper(false) - .face_index_map(get(CGAL::dynamic_face_property_t(), tm1)), - params::face_index_map(get(CGAL::dynamic_face_property_t(), tm2))); - assert(CGAL::is_empty(tm1)); - CGAL::clear(tm1); - CGAL::clear(tm2); + { + TriangleMesh tm1, tm2; + std::ifstream("data-coref/cube.off") >> tm1; + std::ifstream("data-coref/cube.off") >> tm2; - input.open("data-coref/cube.off"); - input >> tm1; - input.close(); - input.open("data-coref/cube.off"); - input >> tm2; - input.close(); - PMP::transform(K::Aff_transformation_3(CGAL::TRANSLATION, K::Vector_3(1,0,0)), tm2); - PMP::clip(tm1, tm2,params::clip_volume(false) - .use_compact_clipper(true) - .face_index_map(get(CGAL::dynamic_face_property_t(), tm1)), - params::face_index_map(get(CGAL::dynamic_face_property_t(), tm2))); - assert(vertices(tm1).size()==4); - CGAL::clear(tm1); - CGAL::clear(tm2); + auto custom_face_index_map_1 = get(CGAL::dynamic_face_property_t(), tm1); + CGAL::BGL::internal::initialize_face_index_map(custom_face_index_map_1, tm1); + auto custom_face_index_map_2 = get(CGAL::dynamic_face_property_t(), tm2); + CGAL::BGL::internal::initialize_face_index_map(custom_face_index_map_2, tm2); + + PMP::clip(tm1, tm2, + params::clip_volume(false) + .use_compact_clipper(false) + .face_index_map(custom_face_index_map_1), + params::face_index_map(custom_face_index_map_2)); + assert(CGAL::is_empty(tm1)); + } + + { + TriangleMesh tm1, tm2; + std::ifstream("data-coref/cube.off") >> tm1; + std::ifstream("data-coref/cube.off") >> tm2; + + auto custom_face_index_map_1 = get(CGAL::dynamic_face_property_t(), tm1); + CGAL::BGL::internal::initialize_face_index_map(custom_face_index_map_1, tm1); + auto custom_face_index_map_2 = get(CGAL::dynamic_face_property_t(), tm2); + CGAL::BGL::internal::initialize_face_index_map(custom_face_index_map_2, tm2); + + PMP::clip(tm1, tm2, + params::clip_volume(false) + .use_compact_clipper(true) + .face_index_map(custom_face_index_map_1), + params::face_index_map(custom_face_index_map_2)); + assert(num_vertices(tm1) == 8); + } + + { + TriangleMesh tm1, tm2; + std::ifstream("data-coref/cube.off") >> tm1; + std::ifstream("data-coref/cube.off") >> tm2; + + auto custom_face_index_map_1 = get(CGAL::dynamic_face_property_t(), tm1); + CGAL::BGL::internal::initialize_face_index_map(custom_face_index_map_1, tm1); + auto custom_face_index_map_2 = get(CGAL::dynamic_face_property_t(), tm2); + CGAL::BGL::internal::initialize_face_index_map(custom_face_index_map_2, tm2); + + PMP::transform(K::Aff_transformation_3(CGAL::TRANSLATION, K::Vector_3(1,0,0)), tm2); + PMP::clip(tm1, tm2, + params::clip_volume(false) + .use_compact_clipper(false) + .face_index_map(custom_face_index_map_1), + params::face_index_map(custom_face_index_map_2)); + assert(CGAL::is_empty(tm1)); + } + + { + TriangleMesh tm1, tm2; + std::ifstream("data-coref/cube.off") >> tm1; + std::ifstream("data-coref/cube.off") >> tm2; + + auto custom_face_index_map_1 = get(CGAL::dynamic_face_property_t(), tm1); + CGAL::BGL::internal::initialize_face_index_map(custom_face_index_map_1, tm1); + auto custom_face_index_map_2 = get(CGAL::dynamic_face_property_t(), tm2); + CGAL::BGL::internal::initialize_face_index_map(custom_face_index_map_2, tm2); + + PMP::transform(K::Aff_transformation_3(CGAL::TRANSLATION, K::Vector_3(1,0,0)), tm2); + PMP::clip(tm1, tm2, + params::clip_volume(false) + .use_compact_clipper(true) + .face_index_map(custom_face_index_map_1), + params::face_index_map(custom_face_index_map_2)); + assert(vertices(tm1).size() == 4); + } // test orientation + patch without input vertex - CGAL::make_tetrahedron( - K::Point_3(0.53, -1.3, 0.2), - K::Point_3(0.53, 1.1, 0.2), - K::Point_3(0.53, -1.3, 0.4), - K::Point_3(0.73, -1.3, 0.2), - tm2); - input.open("data-coref/cube.off"); - input >> tm1; - input.close(); - PMP::clip(tm1, tm2,params::clip_volume(false) - .face_index_map(get(CGAL::dynamic_face_property_t(), tm1)), - params::face_index_map(get(CGAL::dynamic_face_property_t(), tm2))); - assert(vertices(tm1).size()==6); - CGAL::clear(tm1); - CGAL::clear(tm2); + { + TriangleMesh tm1, tm2; + std::ifstream("data-coref/cube.off") >> tm1; - CGAL::make_tetrahedron( - K::Point_3(0.53, -1.3, 0.2), - K::Point_3(0.53, 1.1, 0.2), - K::Point_3(0.53, -1.3, 0.4), - K::Point_3(0.73, -1.3, 0.2), - tm2); - PMP::reverse_face_orientations(tm2); - input.open("data-coref/cube.off"); - input >> tm1; - input.close(); - PMP::clip(tm1, tm2,params::clip_volume(false) - .face_index_map(get(CGAL::dynamic_face_property_t(), tm1)), - params::face_index_map(get(CGAL::dynamic_face_property_t(), tm2))); - assert(vertices(tm1).size()==6+8); - CGAL::clear(tm1); - CGAL::clear(tm2); + CGAL::make_tetrahedron(K::Point_3(0.53, -1.3, 0.2), + K::Point_3(0.53, 1.1, 0.2), + K::Point_3(0.53, -1.3, 0.4), + K::Point_3(0.73, -1.3, 0.2), + tm2); + + auto custom_face_index_map_1 = get(CGAL::dynamic_face_property_t(), tm1); + CGAL::BGL::internal::initialize_face_index_map(custom_face_index_map_1, tm1); + auto custom_face_index_map_2 = get(CGAL::dynamic_face_property_t(), tm2); + CGAL::BGL::internal::initialize_face_index_map(custom_face_index_map_2, tm2); + + PMP::clip(tm1, tm2, + params::clip_volume(false) + .face_index_map(custom_face_index_map_1), + params::face_index_map(custom_face_index_map_2)); + assert(vertices(tm1).size() == 6); + } + + { + TriangleMesh tm1, tm2; + std::ifstream("data-coref/cube.off") >> tm1; + + CGAL::make_tetrahedron(K::Point_3(0.53, -1.3, 0.2), + K::Point_3(0.53, 1.1, 0.2), + K::Point_3(0.53, -1.3, 0.4), + K::Point_3(0.73, -1.3, 0.2), + tm2); + PMP::reverse_face_orientations(tm2); + + auto custom_face_index_map_1 = get(CGAL::dynamic_face_property_t(), tm1); + CGAL::BGL::internal::initialize_face_index_map(custom_face_index_map_1, tm1); + auto custom_face_index_map_2 = get(CGAL::dynamic_face_property_t(), tm2); + CGAL::BGL::internal::initialize_face_index_map(custom_face_index_map_2, tm2); + + PMP::clip(tm1, tm2, + params::clip_volume(false) + .face_index_map(custom_face_index_map_1), + params::face_index_map(custom_face_index_map_2)); + assert(vertices(tm1).size() == 6+8); + } // clip meshes with intersection polyline opened - make_triangle( K::Point_3(0, 0, 0), K::Point_3(0, 4, 0), K::Point_3(4, 0, 0), tm1 ); - PMP::clip(tm1, K::Plane_3(1, 0, 0, -2)); - assert(vertices(tm1).size()==4); - CGAL::clear(tm1); + { + TriangleMesh tm1; + make_triangle( K::Point_3(0, 0, 0), K::Point_3(0, 4, 0), K::Point_3(4, 0, 0), tm1 ); + PMP::clip(tm1, K::Plane_3(1, 0, 0, -2)); + assert(vertices(tm1).size() == 4); + } - make_triangle( K::Point_3(0, 0, 0), K::Point_3(0, 4, 0), K::Point_3(4, 0, 0), tm1 ); - PMP::clip(tm1, K::Plane_3(-1, 0, 0, 2)); - assert(vertices(tm1).size()==3); - CGAL::clear(tm1); + { + TriangleMesh tm1; + make_triangle( K::Point_3(0, 0, 0), K::Point_3(0, 4, 0), K::Point_3(4, 0, 0), tm1 ); + PMP::clip(tm1, K::Plane_3(-1, 0, 0, 2)); + assert(vertices(tm1).size() == 3); + } // test with clipper on border edge - make_triangle( K::Point_3(0, 0, 0), K::Point_3(0, 1, 0), K::Point_3(1, 0, 0), tm1 ); - PMP::clip(tm1, K::Plane_3(0, 1, 0 , 0)); - assert(vertices(tm1).size()==0); - CGAL::clear(tm1); + { + TriangleMesh tm1; + make_triangle( K::Point_3(0, 0, 0), K::Point_3(0, 1, 0), K::Point_3(1, 0, 0), tm1 ); + PMP::clip(tm1, K::Plane_3(0, 1, 0 , 0)); + assert(vertices(tm1).size() == 0); + } - make_triangle( K::Point_3(0, 0, 0), K::Point_3(0, 1, 0), K::Point_3(1, 0, 0), tm1 ); - PMP::clip(tm1, K::Plane_3(0, -1, 0 , 0)); - assert(vertices(tm1).size()==4); - CGAL::clear(tm1); + { + TriangleMesh tm1; + make_triangle( K::Point_3(0, 0, 0), K::Point_3(0, 1, 0), K::Point_3(1, 0, 0), tm1 ); + PMP::clip(tm1, K::Plane_3(0, -1, 0 , 0)); + assert(vertices(tm1).size() == 4); + } // test with clipper on border edge: full triangle - make_triangle( K::Point_3(0, 0, 0), K::Point_3(0, 4, 0), K::Point_3(4, 0, 0), tm1 ); - PMP::clip(tm1, K::Plane_3(0, 0, 1, 0), params::use_compact_clipper(true)); - assert(vertices(tm1).size()!=0); - CGAL::clear(tm1); + { + TriangleMesh tm1; + make_triangle( K::Point_3(0, 0, 0), K::Point_3(0, 4, 0), K::Point_3(4, 0, 0), tm1 ); + PMP::clip(tm1, K::Plane_3(0, 0, 1, 0), params::use_compact_clipper(true)); + assert(vertices(tm1).size()!=0); + } - make_triangle( K::Point_3(0, 0, 0), K::Point_3(0, 4, 0), K::Point_3(4, 0, 0), tm1 ); - PMP::clip(tm1, K::Plane_3(0, 0, 1, 0), params::use_compact_clipper(false)); - assert(vertices(tm1).size()==0); - CGAL::clear(tm1); + { + TriangleMesh tm1; + make_triangle( K::Point_3(0, 0, 0), K::Point_3(0, 4, 0), K::Point_3(4, 0, 0), tm1 ); + PMP::clip(tm1, K::Plane_3(0, 0, 1, 0), params::use_compact_clipper(false)); + assert(vertices(tm1).size() == 0); + } // test tangencies - make_triangle( K::Point_3(0, 0, 0), K::Point_3(0, 2, 0), K::Point_3(1, 1, 0), tm1 ); - PMP::clip(tm1, K::Plane_3(1, 0, 0, -1)); - assert(vertices(tm1).size()==3); - CGAL::clear(tm1); + { + TriangleMesh tm1; + make_triangle( K::Point_3(0, 0, 0), K::Point_3(0, 2, 0), K::Point_3(1, 1, 0), tm1 ); + PMP::clip(tm1, K::Plane_3(1, 0, 0, -1)); + assert(vertices(tm1).size() == 3); + } - make_triangle( K::Point_3(0, 0, 0), K::Point_3(0, 2, 0), K::Point_3(1, 1, 0), tm1 ); - PMP::clip(tm1, K::Plane_3(-1, 0, 0, 1)); - assert(vertices(tm1).size()==0); - CGAL::clear(tm1); + { + TriangleMesh tm1; + make_triangle( K::Point_3(0, 0, 0), K::Point_3(0, 2, 0), K::Point_3(1, 1, 0), tm1 ); + PMP::clip(tm1, K::Plane_3(-1, 0, 0, 1)); + assert(vertices(tm1).size() == 0); + } - make_triangle( K::Point_3(0.5, 0, 0.5), K::Point_3(1, 0.5, 0.5), K::Point_3(0.5, 1, 0.5), tm1 ); - input.open("data-coref/cube.off"); - input >> tm2; - input.close(); - PMP::clip(tm1, tm2, params::face_index_map(get(CGAL::dynamic_face_property_t(), tm1)), - params::face_index_map(get(CGAL::dynamic_face_property_t(), tm2))); - assert(vertices(tm1).size()==3); - CGAL::clear(tm1); - CGAL::clear(tm2); + { + TriangleMesh tm1, tm2; + make_triangle( K::Point_3(0.5, 0, 0.5), K::Point_3(1, 0.5, 0.5), K::Point_3(0.5, 1, 0.5), tm1 ); + std::ifstream("data-coref/cube.off") >> tm2; - make_triangle( K::Point_3(0.5, 0, 0.5), K::Point_3(1, 0.5, 0.5), K::Point_3(0.5, 1, 0.5), tm1 ); - input.open("data-coref/cube.off"); - input >> tm2; - input.close(); - PMP::reverse_face_orientations(tm2); - PMP::clip(tm1, tm2, params::face_index_map(get(CGAL::dynamic_face_property_t(), tm1)), - params::face_index_map(get(CGAL::dynamic_face_property_t(), tm2))); - assert(vertices(tm1).size()==0); - CGAL::clear(tm1); - CGAL::clear(tm2); + auto custom_face_index_map_1 = get(CGAL::dynamic_face_property_t(), tm1); + CGAL::BGL::internal::initialize_face_index_map(custom_face_index_map_1, tm1); + auto custom_face_index_map_2 = get(CGAL::dynamic_face_property_t(), tm2); + CGAL::BGL::internal::initialize_face_index_map(custom_face_index_map_2, tm2); -// test combinaison of use_compact_clipper and clip_volume - input.open("data-coref/cube.off"); - input >> tm1; - input.close(); + PMP::clip(tm1, tm2, + params::face_index_map(custom_face_index_map_1), + params::face_index_map(custom_face_index_map_2)); + assert(vertices(tm1).size() == 3); + } - // -> closed mesh, true/true - PMP::clip(tm1, K::Plane_3(-1,0,0,0), params::use_compact_clipper(true).clip_volume(true)); - assert(CGAL::is_closed(tm1)); - assert(faces(tm1).size()==12); + { + TriangleMesh tm1, tm2; + make_triangle( K::Point_3(0.5, 0, 0.5), K::Point_3(1, 0.5, 0.5), K::Point_3(0.5, 1, 0.5), tm1 ); + std::ifstream("data-coref/cube.off") >> tm2; - // -> closed mesh, false/true - PMP::clip(tm1, K::Plane_3(-1,0,0,0), params::use_compact_clipper(false).clip_volume(true)); - assert(faces(tm1).size()==12); - assert(CGAL::is_closed(tm1)); + auto custom_face_index_map_1 = get(CGAL::dynamic_face_property_t(), tm1); + CGAL::BGL::internal::initialize_face_index_map(custom_face_index_map_1, tm1); + auto custom_face_index_map_2 = get(CGAL::dynamic_face_property_t(), tm2); + CGAL::BGL::internal::initialize_face_index_map(custom_face_index_map_2, tm2); - // -> closed mesh, true/false - PMP::clip(tm1, K::Plane_3(-1,0,0,0), params::use_compact_clipper(true).clip_volume(false)); - assert(faces(tm1).size()==12); - assert(CGAL::is_closed(tm1)); + PMP::reverse_face_orientations(tm2); + PMP::clip(tm1, tm2, + params::face_index_map(custom_face_index_map_1), + params::face_index_map(custom_face_index_map_2)); + assert(vertices(tm1).size() == 0); + } - // -> closed mesh, false/false - PMP::clip(tm1, K::Plane_3(1,0,0,-1), params::use_compact_clipper(false).clip_volume(false)); - assert(faces(tm1).size()==10); - assert(!CGAL::is_closed(tm1)); + // test combinaison of use_compact_clipper and clip_volume + { + TriangleMesh tm1; + std::ifstream("data-coref/cube.off") >> tm1; - // -> open mesh true/true - PMP::clip(tm1, K::Plane_3(-1,0,0,0), params::use_compact_clipper(true).clip_volume(true)); - assert(faces(tm1).size()==10); + // -> closed mesh, true/true + PMP::clip(tm1, K::Plane_3(-1,0,0,0), params::use_compact_clipper(true).clip_volume(true)); + assert(faces(tm1).size() == 12); + assert(CGAL::is_closed(tm1)); - // -> open mesh true/false - PMP::clip(tm1, K::Plane_3(-1,0,0,0), params::use_compact_clipper(true).clip_volume(false)); - assert(faces(tm1).size()==10); + // -> closed mesh, false/true + PMP::clip(tm1, K::Plane_3(-1,0,0,0), params::use_compact_clipper(false).clip_volume(true)); + assert(faces(tm1).size() == 12); + assert(CGAL::is_closed(tm1)); - // -> open mesh false/false - PMP::clip(tm1, K::Plane_3(-1,0,0,0), params::use_compact_clipper(false).clip_volume(false)); - assert(faces(tm1).size()==8); + // -> closed mesh, true/false + PMP::clip(tm1, K::Plane_3(-1,0,0,0), params::use_compact_clipper(true).clip_volume(false)); + assert(faces(tm1).size() == 12); + assert(CGAL::is_closed(tm1)); - // -> open mesh false/true - PMP::clip(tm1, K::Plane_3(0,-1,0,0), params::use_compact_clipper(false).clip_volume(true)); - assert(faces(tm1).size()==6); - CGAL::clear(tm1); -// done! + // -> closed mesh, false/false + PMP::clip(tm1, K::Plane_3(1,0,0,-1), params::use_compact_clipper(false).clip_volume(false)); + assert(faces(tm1).size() == 10); + assert(!CGAL::is_closed(tm1)); + + // -> open mesh true/true + PMP::clip(tm1, K::Plane_3(-1,0,0,0), params::use_compact_clipper(true).clip_volume(true)); + assert(faces(tm1).size() == 10); + + // -> open mesh true/false + PMP::clip(tm1, K::Plane_3(-1,0,0,0), params::use_compact_clipper(true).clip_volume(false)); + assert(faces(tm1).size() == 10); + + // -> open mesh false/false + PMP::clip(tm1, K::Plane_3(-1,0,0,0), params::use_compact_clipper(false).clip_volume(false)); + assert(faces(tm1).size() == 8); + + // -> open mesh false/true + PMP::clip(tm1, K::Plane_3(0,-1,0,0), params::use_compact_clipper(false).clip_volume(true)); + assert(faces(tm1).size() == 6); + } // test special case - input.open("data-clip/tm_1.off"); - input >> tm1; - input.close(); - input.open("data-clip/clipper_1.off"); - input >> tm2; - input.close(); - PMP::clip(tm1, tm2, params::face_index_map(get(CGAL::dynamic_face_property_t(), tm1)), - params::face_index_map(get(CGAL::dynamic_face_property_t(), tm2))); - assert(is_valid_polygon_mesh(tm1)); - CGAL::clear(tm1); - CGAL::clear(tm2); + { + TriangleMesh tm1, tm2; + std::ifstream("data-clip/tm_1.off") >> tm2; + std::ifstream("data-clip/clipper_1.off") >> tm2; + + auto custom_face_index_map_1 = get(CGAL::dynamic_face_property_t(), tm1); + CGAL::BGL::internal::initialize_face_index_map(custom_face_index_map_1, tm1); + auto custom_face_index_map_2 = get(CGAL::dynamic_face_property_t(), tm2); + CGAL::BGL::internal::initialize_face_index_map(custom_face_index_map_2, tm2); + + PMP::clip(tm1, tm2, + params::face_index_map(custom_face_index_map_1), + params::face_index_map(custom_face_index_map_2)); + assert(is_valid_polygon_mesh(tm1)); + } // non-manifold border vertices - std::stringstream ss; - ss << "OFF\n 5 2 0\n 0 0 0\n2 0 0\n4 0 0\n4 1 0\n0 1 0\n3 0 1 4\n3 1 2 3\n"; - ss >> tm1; - PMP::clip(tm1, K::Plane_3(-1,0,0,2)); - assert(vertices(tm1).size()==3); - CGAL::clear(tm1); + { + TriangleMesh tm1; + std::stringstream ss; + ss << "OFF\n 5 2 0\n 0 0 0\n2 0 0\n4 0 0\n4 1 0\n0 1 0\n3 0 1 4\n3 1 2 3\n"; + ss >> tm1; + PMP::clip(tm1, K::Plane_3(-1,0,0,2)); + assert(vertices(tm1).size() == 3); + } - ss.str(std::string()); - ss << "OFF\n 7 4 0\n 0 0 0\n2 0 0\n4 0 0\n4 1 0\n0 1 0\n3 1 0\n 1 1 0\n3 0 1 4\n3 1 2 3\n3 1 5 6\n3 1 3 5\n"; - ss >> tm1; - CGAL::Euler::remove_face(halfedge(*std::prev(faces(tm1).end()),tm1),tm1); - PMP::clip(tm1, K::Plane_3(-1,0,0,2)); - assert(vertices(tm1).size()==6); - CGAL::clear(tm1); - - ss.str(std::string()); - ss << "OFF\n 9 7 0\n 0 0 0\n2 0 0\n4 0 0\n4 1 0\n0 1 0\n3 1 0\n 1 1 0\n3 -1 0\n1 -1 0\n3 0 1 4\n3 1 2 3\n3 1 5 6\n3 1 8 7\n3 1 3 5\n3 1 6 4\n3 1 0 8\n"; - ss >> tm1; - for (int i=0;i<3;++i) + { + TriangleMesh tm1; + std::stringstream ss; + ss << "OFF\n 7 4 0\n 0 0 0\n2 0 0\n4 0 0\n4 1 0\n0 1 0\n3 1 0\n 1 1 0\n3 0 1 4\n3 1 2 3\n3 1 5 6\n3 1 3 5\n"; + ss >> tm1; CGAL::Euler::remove_face(halfedge(*std::prev(faces(tm1).end()),tm1),tm1); - PMP::clip(tm1, K::Plane_3(-1,0,0,2)); - assert(vertices(tm1).size()==7); - CGAL::clear(tm1); + PMP::clip(tm1, K::Plane_3(-1,0,0,2)); + assert(vertices(tm1).size() == 6); + } - ss.str(std::string()); - ss << "OFF\n 9 7 0\n 0 0 0\n2 0 0\n4 0 0\n4 1 0\n0 1 0\n3 1 0\n 1 1 0\n3 -1 0\n1 -1 0\n3 0 1 4\n3 1 2 3\n3 1 5 6\n3 1 8 7\n3 1 3 5\n3 1 6 4\n3 1 0 8\n"; - ss >> tm1; - for (int i=0;i<3;++i) - CGAL::Euler::remove_face(halfedge(*std::prev(faces(tm1).end()),tm1),tm1); - PMP::clip(tm1, K::Plane_3(0,1,0,0)); - assert(vertices(tm1).size()==3); - CGAL::clear(tm1); + { + TriangleMesh tm1; + std::stringstream ss; + ss << "OFF\n 9 7 0\n 0 0 0\n2 0 0\n4 0 0\n4 1 0\n0 1 0\n3 1 0\n 1 1 0\n3 -1 0\n1 -1 0\n3 0 1 4\n3 1 2 3\n3 1 5 6\n3 1 8 7\n3 1 3 5\n3 1 6 4\n3 1 0 8\n"; + ss >> tm1; + for (int i=0;i<3;++i) + CGAL::Euler::remove_face(halfedge(*std::prev(faces(tm1).end()),tm1),tm1); + PMP::clip(tm1, K::Plane_3(-1,0,0,2)); + assert(vertices(tm1).size() == 7); + } - ss.str(std::string()); - ss << "OFF\n 9 7 0\n 0 0 0\n2 0 0\n4 0 0\n4 1 0\n0 1 0\n3 1 0\n 1 1 0\n3 -1 0\n1 -1 0\n3 0 1 4\n3 1 2 3\n3 1 5 6\n3 1 8 7\n3 1 3 5\n3 1 6 4\n3 1 0 8\n"; - ss >> tm1; - for (int i=0;i<3;++i) - CGAL::Euler::remove_face(halfedge(*std::prev(faces(tm1).end()),tm1),tm1); - PMP::clip(tm1, K::Plane_3(0,-1,0,0)); - assert(vertices(tm1).size()==7); - CGAL::clear(tm1); + { + TriangleMesh tm1; + std::stringstream ss; + ss << "OFF\n 9 7 0\n 0 0 0\n2 0 0\n4 0 0\n4 1 0\n0 1 0\n3 1 0\n 1 1 0\n3 -1 0\n1 -1 0\n3 0 1 4\n3 1 2 3\n3 1 5 6\n3 1 8 7\n3 1 3 5\n3 1 6 4\n3 1 0 8\n"; + ss >> tm1; + for (int i=0;i<3;++i) + CGAL::Euler::remove_face(halfedge(*std::prev(faces(tm1).end()),tm1),tm1); + PMP::clip(tm1, K::Plane_3(0,1,0,0)); + assert(vertices(tm1).size() == 3); + } + + { + TriangleMesh tm1; + std::stringstream ss; + ss << "OFF\n 9 7 0\n 0 0 0\n2 0 0\n4 0 0\n4 1 0\n0 1 0\n3 1 0\n 1 1 0\n3 -1 0\n1 -1 0\n3 0 1 4\n3 1 2 3\n3 1 5 6\n3 1 8 7\n3 1 3 5\n3 1 6 4\n3 1 0 8\n"; + ss >> tm1; + for (int i=0;i<3;++i) + CGAL::Euler::remove_face(halfedge(*std::prev(faces(tm1).end()),tm1),tm1); + PMP::clip(tm1, K::Plane_3(0,-1,0,0)); + assert(vertices(tm1).size() == 7); + } } int main() { + std::cout << "Surface Mesh" << std::endl; test(); + + std::cout << "Polyhedron" << std::endl; test(); - return 0; + std::cout << "Done!" << std::endl; + + return EXIT_SUCCESS; } diff --git a/Property_map/include/CGAL/Dynamic_property_map.h b/Property_map/include/CGAL/Dynamic_property_map.h index 35cdcd5f4db..2300b4b5efe 100644 --- a/Property_map/include/CGAL/Dynamic_property_map.h +++ b/Property_map/include/CGAL/Dynamic_property_map.h @@ -13,11 +13,13 @@ #define CGAL_DYNAMIC_PROPERTY_MAP_H #include +#include + #include #include + #include #include - #include #include diff --git a/Surface_mesh_deformation/include/CGAL/Surface_mesh_deformation.h b/Surface_mesh_deformation/include/CGAL/Surface_mesh_deformation.h index a3c6080dee3..06a8151e9b7 100644 --- a/Surface_mesh_deformation/include/CGAL/Surface_mesh_deformation.h +++ b/Surface_mesh_deformation/include/CGAL/Surface_mesh_deformation.h @@ -16,10 +16,11 @@ #include +#include +#include #include #include #include - #include #include @@ -215,13 +216,9 @@ public: // Index maps #ifndef DOXYGEN_RUNNING typedef typename Default::Get< - VIM, - typename boost::property_map::type - >::type Vertex_index_map; + VIM, typename CGAL::GetInitializedVertexIndexMap::type>::type Vertex_index_map; typedef typename Default::Get< - HIM, - typename boost::property_map::type - >::type Hedge_index_map; + HIM, typename CGAL::GetInitializedHalfedgeIndexMap::type>::type Hedge_index_map; #else /// vertex index map type typedef VIM Vertex_index_map; @@ -356,9 +353,10 @@ public: //vertex_point_map set by default Surface_mesh_deformation(Triangle_mesh& triangle_mesh, Vertex_index_map vertex_index_map, - Hedge_index_map hedge_index_map - ) - : m_triangle_mesh(triangle_mesh), vertex_index_map(vertex_index_map), hedge_index_map(hedge_index_map), + Hedge_index_map hedge_index_map) + : m_triangle_mesh(triangle_mesh), + vertex_index_map(vertex_index_map), + hedge_index_map(hedge_index_map), ros_id_map(std::vector(num_vertices(triangle_mesh), (std::numeric_limits::max)() )), is_roi_map(std::vector(num_vertices(triangle_mesh), false)), is_ctrl_map(std::vector(num_vertices(triangle_mesh), false)), @@ -374,10 +372,10 @@ public: //vertex_point_map and hedge_index_map set by default Surface_mesh_deformation(Triangle_mesh& triangle_mesh, - Vertex_index_map vertex_index_map - ) - : m_triangle_mesh(triangle_mesh), vertex_index_map(vertex_index_map), - hedge_index_map(get(boost::halfedge_index, triangle_mesh)), + Vertex_index_map vertex_index_map) + : m_triangle_mesh(triangle_mesh), + vertex_index_map(vertex_index_map), + hedge_index_map(CGAL::get_initialized_halfedge_index_map(triangle_mesh)), ros_id_map(std::vector(num_vertices(triangle_mesh), (std::numeric_limits::max)() )), is_roi_map(std::vector(num_vertices(triangle_mesh), false)), is_ctrl_map(std::vector(num_vertices(triangle_mesh), false)), @@ -393,8 +391,8 @@ public: //vertex_point_map, hedge_index_map and vertex_index_map set by default Surface_mesh_deformation(Triangle_mesh& triangle_mesh) : m_triangle_mesh(triangle_mesh), - vertex_index_map(get(boost::vertex_index, triangle_mesh)), - hedge_index_map(get(boost::halfedge_index, triangle_mesh)), + vertex_index_map(CGAL::get_initialized_vertex_index_map(triangle_mesh)), + hedge_index_map(CGAL::get_initialized_halfedge_index_map(triangle_mesh)), ros_id_map(std::vector(num_vertices(triangle_mesh), (std::numeric_limits::max)() )), is_roi_map(std::vector(num_vertices(triangle_mesh), false)), is_ctrl_map(std::vector(num_vertices(triangle_mesh), false)), @@ -413,18 +411,19 @@ public: Vertex_index_map vertex_index_map, Hedge_index_map hedge_index_map, Vertex_point_map vertex_point_map, - Weight_calculator weight_calculator = Weight_calculator() - ) - : m_triangle_mesh(triangle_mesh), vertex_index_map(vertex_index_map), hedge_index_map(hedge_index_map), - ros_id_map(std::vector(num_vertices(triangle_mesh), (std::numeric_limits::max)() )), - is_roi_map(std::vector(num_vertices(triangle_mesh), false)), - is_ctrl_map(std::vector(num_vertices(triangle_mesh), false)), - m_iterations(5), m_tolerance(1e-4), - need_preprocess_factorization(true), - need_preprocess_region_of_solution(true), - last_preprocess_successful(false), - weight_calculator(weight_calculator), - vertex_point_map(vertex_point_map) + Weight_calculator weight_calculator = Weight_calculator()) + : m_triangle_mesh(triangle_mesh), + vertex_index_map(vertex_index_map), + hedge_index_map(hedge_index_map), + ros_id_map(std::vector(num_vertices(triangle_mesh), (std::numeric_limits::max)() )), + is_roi_map(std::vector(num_vertices(triangle_mesh), false)), + is_ctrl_map(std::vector(num_vertices(triangle_mesh), false)), + m_iterations(5), m_tolerance(1e-4), + need_preprocess_factorization(true), + need_preprocess_region_of_solution(true), + last_preprocess_successful(false), + weight_calculator(weight_calculator), + vertex_point_map(vertex_point_map) { init(); } @@ -433,21 +432,23 @@ public: /// \name Construction /// @{ /** - * The constructor of a deformation object + * The constructor of a deformation object. * * @pre `triangle_mesh` consists of only triangular facets * @param triangle_mesh triangulated surface mesh to deform - * @param vertex_index_map property map which associates an id to each vertex, from `0` to `num_vertices(triangle_mesh)-1`. - * @param hedge_index_map property map which associates an id to each halfedge, from `0` to `2*num_edges(triangle_mesh)-1`. + * @param vertex_index_map a property map which associates a unique id to each vertex, + * between `0` to `num_vertices(triangle_mesh)-1`. + * @param hedge_index_map property map which associates a unique id to each halfedge, + * between `0` to `2*num_edges(triangle_mesh)-1`. * @param vertex_point_map property map which associates a point to each vertex of the triangle mesh. * @param weight_calculator function object or pointer for weight calculation + * */ Surface_mesh_deformation(Triangle_mesh& triangle_mesh, - Vertex_index_map vertex_index_map=get(boost::vertex_index, triangle_mesh), - Hedge_index_map hedge_index_map=get(boost::halfedge_index, triangle_mesh), - Vertex_point_map vertex_point_map=get(boost::vertex_point, triangle_mesh), - Weight_calculator weight_calculator = Weight_calculator() - ); + Vertex_index_map vertex_index_map = unspecified_internal_vertex_index_map, + Hedge_index_map hedge_index_map = unspecified_internal_halfedge_index_map, + Vertex_point_map vertex_point_map = get(boost::vertex_point, triangle_mesh), + Weight_calculator weight_calculator = Weight_calculator()); /// @} #endif diff --git a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Orbifold_Tutte_parameterizer_3.h b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Orbifold_Tutte_parameterizer_3.h index 3d570311b53..068a882f0e1 100644 --- a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Orbifold_Tutte_parameterizer_3.h +++ b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Orbifold_Tutte_parameterizer_3.h @@ -25,6 +25,7 @@ #include #include +#include #include #include diff --git a/Surface_mesh_shortest_path/include/CGAL/Surface_mesh_shortest_path/Surface_mesh_shortest_path.h b/Surface_mesh_shortest_path/include/CGAL/Surface_mesh_shortest_path/Surface_mesh_shortest_path.h index a54781c1ae1..01057be54ca 100644 --- a/Surface_mesh_shortest_path/include/CGAL/Surface_mesh_shortest_path/Surface_mesh_shortest_path.h +++ b/Surface_mesh_shortest_path/include/CGAL/Surface_mesh_shortest_path/Surface_mesh_shortest_path.h @@ -67,7 +67,7 @@ Refer to those respective papers for the details of the implementation. If index property maps are not provided through the constructor of the class, internal property maps must be available and initialized. -\sa \link PkgBGLHelper `CGAL::set_halfedgeds_items_id()`\endlink +\sa \link BGLGraphExternalIndices `CGAL::set_halfedgeds_items_id()`\endlink */ template()), choose_parameter(get_parameter(np, internal_np::get_cost_policy), diff --git a/Triangulation_2/include/CGAL/Triangulation_face_base_with_id_2.h b/Triangulation_2/include/CGAL/Triangulation_face_base_with_id_2.h index d47a256a245..8d5a54281e1 100644 --- a/Triangulation_2/include/CGAL/Triangulation_face_base_with_id_2.h +++ b/Triangulation_2/include/CGAL/Triangulation_face_base_with_id_2.h @@ -42,11 +42,15 @@ public: : Fb(v0, v1, v2, n0, n1, n2) { } - int& id() { return _id; } - int id() const { return _id; } + int& id() { return face_id; } + int id() const { return face_id; } + + int& edge_id(const std::size_t i) { return edge_ids[i]; } + int edge_id(const std::size_t i) const { return edge_ids[i]; } private: - int _id; + int face_id; + std::array edge_ids; }; } //namespace CGAL diff --git a/Triangulation_2/include/CGAL/boost/graph/internal/properties_2D_triangulation.h b/Triangulation_2/include/CGAL/boost/graph/internal/properties_2D_triangulation.h index 6bad3c9aa0c..16895ba78a8 100644 --- a/Triangulation_2/include/CGAL/boost/graph/internal/properties_2D_triangulation.h +++ b/Triangulation_2/include/CGAL/boost/graph/internal/properties_2D_triangulation.h @@ -111,7 +111,7 @@ public: T2_halfedge_id_map(const Tr& tr) : tr(tr) { } // Halfedge id is twice the edge id, and +0/+1 depending whether - // h.first is such that h.first < opposite(h).first --> different ids + // h.first is such that h.first < opposite(h).first value_type operator[](key_type h) const { const Face_handle f1 = h.first; @@ -119,13 +119,13 @@ public: CGAL_assertion(!tr.is_infinite(f1) || !tr.is_infinite(f2)); if(tr.is_infinite(f1)) - return 2*(3 * f2->id() + f2->index(f1)); + return 2*(f2->edge_id(f2->index(f1))); else if(tr.is_infinite(f2)) - return 2*(3 * f1->id() + h.second) + 1; + return 2*(f1->edge_id(h.second)) + 1; else if(f1->id() < f2->id()) - return 2*(3 * f1->id() + h.second); + return 2*(f1->edge_id(h.second)); else - return 2*(3 * f2->id() + f2->index(f1)) + 1; + return 2*(f1->edge_id(h.second)) + 1; } private: @@ -152,13 +152,9 @@ public: CGAL_assertion(!tr.is_infinite(f1) || !tr.is_infinite(f2)); if(tr.is_infinite(f1)) - return 3 * f2->id() + f2->index(f1); - else if(tr.is_infinite(f2)) - return 3 * f1->id() + e.second; - else if(f1->id() < f2->id()) - return 3 * f1->id() + e.second; + return f2->edge_id(f2->index(f1)); else - return 3 * f2->id() + f2->index(f1); + return f1->edge_id(e.second); } private: @@ -368,6 +364,39 @@ put(PropertyTag p, CGAL_2D_TRIANGULATION& g, const Key& key, const Value& value) put(pmap, key, value); } +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +void set_triangulation_ids(CGAL_2D_TRIANGULATION& g) +{ + typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_descriptor edge_descriptor; + typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::face_descriptor face_descriptor; + + int vid = 0; + for(vertex_descriptor vd : vertices(g)) + vd->id() = vid++; + + int eid = 0; + for(edge_descriptor ed : edges(g)) + { + halfedge_descriptor hd = halfedge(ed, g); + face_descriptor fd = face(hd, g); + if(fd != boost::graph_traits< CGAL_2D_TRIANGULATION >::null_face()) + fd->edge_id(hd.second) = eid; + + halfedge_descriptor opp_hd = opposite(hd, g); + face_descriptor opp_fd = face(opp_hd, g); + if(opp_fd != boost::graph_traits< CGAL_2D_TRIANGULATION >::null_face()) + opp_fd->edge_id(opp_hd.second) = eid; + + ++eid; + } + + int fid = 0; + for(face_descriptor fd : faces(g)) + fd->id() = fid++; +} + } // namespace CGAL #undef CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS