Merge remote-tracking branch 'maxgimeno/PMP-Default_pmap-maxGimeno' into CGAL_IO-maxGimeno

This commit is contained in:
Mael Rouxel-Labbé 2020-03-17 09:33:19 +01:00
commit c33e8b60d7
54 changed files with 1852 additions and 1206 deletions

View File

@ -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.

View File

@ -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.

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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

View File

@ -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 <typename Triangulation>
void set_triangulation_ids(Triangulation& tr);
} /* end namespace CGAL */

View File

@ -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`.

View File

@ -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
///

View File

@ -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
<b>Type:</b> a class model of `ReadablePropertyMap` with
`boost::graph_traits<PolygonMesh>::%vertex_descriptor` as key type and the value type
\code typename boost::property_traits<typename boost::property_map<PolygonMesh, CGAL::vertex_index_t>::type>::value_type \endcode
<b>Default:</b> \code boost::get(CGAL::vertex_index, pmesh)\endcode
<b>Default:</b> 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
<b>Type:</b> a class model of `ReadablePropertyMap` with
`boost::graph_traits<PolygonMesh>::%halfedge_descriptor` as key type and the value type:
\code typename boost::property_traits<typename boost::property_map<PolygonMesh, CGAL::halfedge_index_t>::type>::value_type \endcode
<b>Default:</b> \code boost::get(CGAL::halfedge_index, pmesh)\endcode
If this internal property map exists, its values should be initialized.
<b>Default:</b> 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
<b>Type:</b> a class model of `ReadablePropertyMap` with
`boost::graph_traits<PolygonMesh>::%edge_descriptor` as key type and the value type:
\code typename boost::property_traits<typename boost::property_map<PolygonMesh, CGAL::edge_index_t>::type>::value_type \endcode
<b>Default:</b> \code boost::get(CGAL::edge_index, pmesh)\endcode
If this internal property map exists, its values should be initialized.
<b>Default:</b> 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
<b>Type:</b> a class model of `ReadablePropertyMap` with
`boost::graph_traits<PolygonMesh>::%face_descriptor` as key type and the value type:
\code typename boost::property_traits<typename boost::property_map<PolygonMesh, CGAL::face_index_t>::type>::value_type \endcode
<b>Default:</b> \code boost::get(CGAL::face_index, pmesh)\endcode
If this internal property map exists, its values should be initialized.
<b>Default:</b> an initialized face index property map
\cgalNPEnd
\cgalNPBegin{edge_is_constrained_map} \anchor BGL_edge_is_constrained_map

View File

@ -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<P> >` \endlink
- \link BGLSMGT `boost::graph_traits<CGAL::Surface_mesh<P> >` \endlink
- \link BGLPolyGT `boost::graph_traits< CGAL::Polyhedron_3<K> >` \endlink
- \link BGLLCCGT `boost::graph_traits< CGAL::Linear_cell_complex_for_combinatorial_map<...> >` \endlink
- \link BGLLCCGT `boost::graph_traits<CGAL::Linear_cell_complex_for_combinatorial_map<...> >` \endlink
- \link BGLSeam_meshGT `boost::graph_traits< CGAL::Seam_mesh<G> >` \endlink
- \link BGLT2GT `boost::graph_traits< CGAL::Triangulation_2<GT, TDS> >` \endlink
- \link BGLArgtGT `boost::graph_traits< CGAL::Arrangement_2<T,DC> >` \endlink
- \link BGLT2GT `boost::graph_traits<CGAL::Triangulation_2<GT, TDS> >` \endlink and other 2D triangulations
- \link BGLArgtGT `boost::graph_traits<CGAL::Arrangement_2<T, DC> >` \endlink
- \link BGLOMPAK `boost::graph_traits<OpenMesh::PolyMesh_ArrayKernelT<K> >` \endlink
- \link BGLOMTMAK `boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >` \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`

View File

@ -16,23 +16,24 @@
#include <CGAL/boost/graph/properties.h>
#include <CGAL/boost/graph/iterator.h>
#include <CGAL/boost/graph/Named_function_parameters.h>
#include <CGAL/boost/graph/named_params_helper.h>
#include <CGAL/boost/graph/helpers.h>
#include <CGAL/Dynamic_property_map.h>
#include <CGAL/assertions.h>
#include <boost/unordered_set.hpp>
#include <boost/graph/graph_traits.hpp>
#include <CGAL/boost/iterator/transform_iterator.hpp>
#include <boost/iterator/filter_iterator.hpp>
#include <CGAL/Default.h>
#include <CGAL/Dynamic_property_map.h>
#include <boost/dynamic_bitset.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/iterator/filter_iterator.hpp>
#include <boost/range/has_range_iterator.hpp>
#include <boost/unordered_set.hpp>
#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<Graph>::%faces_size_type` as value
* \tparam VIMap a model of `ReadablePropertyMap` with `vertex_descriptor` as key and `graph_traits<Graph>::%vertices_size_type` as value
* \tparam HIMap a model of `ReadablePropertyMap` with `halfedge_descriptor` as key and `graph_traits<Graph>::%halfedges_size_type` as value
* \tparam FIMap a model of `ReadablePropertyMap` with `graph_traits<Graph>::%face_descriptor` as key and `graph_traits<Graph>::%faces_size_type` as value
* \tparam VIMap a model of `ReadablePropertyMap` with `graph_traits<Graph>::%vertex_descriptor` as key and `graph_traits<Graph>::%vertices_size_type` as value
* \tparam HIMap a model of `ReadablePropertyMap` with `graph_traits<Graph>::%halfedge_descriptor` as key and `graph_traits<Graph>::%halfedges_size_type` as value
*
* \cgalModels `FaceListGraph`
* \cgalModels `HalfedgeListGraph`
* \cgalModels \bgllink{VertexListGraph}
*/
template<typename Graph,
typename FIMap = typename boost::property_map<Graph, CGAL::face_index_t>::type,
typename VIMap = typename boost::property_map<Graph, boost::vertex_index_t>::type,
typename HIMap = typename boost::property_map<Graph, CGAL::halfedge_index_t>::type>
typename FIMap = Default,
typename VIMap = Default,
typename HIMap = Default>
struct Face_filtered_graph
{
typedef boost::graph_traits<Graph> 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<Graph, FIMap, VIMap, HIMap> Self;
typedef typename Default::Get<FIMap, typename CGAL::GetInitializedFaceIndexMap<Graph>::const_type>::type FIM;
typedef typename Default::Get<VIMap, typename CGAL::GetInitializedVertexIndexMap<Graph>::const_type>::type VIM;
typedef typename Default::Get<HIMap, typename CGAL::GetInitializedHalfedgeIndexMap<Graph>::const_type>::type HIM;
typedef typename boost::property_traits<FIM>::value_type face_index_type;
typedef typename boost::property_traits<VIM>::value_type vertex_index_type;
typedef typename boost::property_traits<HIM>::value_type halfedge_index_type;
typedef Face_filtered_graph<Graph, FIMap, VIMap, HIMap> 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 <typename FacePatchIndexMap, class FacePatchIndexRange, class CGAL_BGL_NP_TEMPLATE_PARAMETERS>
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<FacePatchIndexRange>::type
>::type* = 0
#endif
)
: _graph(const_cast<Graph&>(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<FacePatchIndexRange>::type
>::type* = 0
#endif
)
: _graph(const_cast<Graph&>(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<FacePatchIndexRange>::type
>::type* = 0
)
: _graph(const_cast<Graph&>(graph))
, fimap(get(CGAL::face_index, graph))
, vimap(get(boost::vertex_index, graph))
, himap(get(CGAL::halfedge_index, graph))
: _graph(const_cast<Graph&>(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 <typename FacePatchIndexMap, class CGAL_BGL_NP_TEMPLATE_PARAMETERS>
Face_filtered_graph(const Graph& graph,
typename boost::property_traits<FacePatchIndexMap>::value_type selected_face_patch_index,
FacePatchIndexMap face_patch_index_map,
const CGAL_BGL_NP_CLASS& np
)
: _graph(const_cast<Graph&>(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<FacePatchIndexMap>::value_type selected_face_patch_index,
FacePatchIndexMap face_patch_index_map,
const CGAL_BGL_NP_CLASS& np)
: _graph(const_cast<Graph&>(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 <typename FacePatchIndexMap>
Face_filtered_graph(const Graph& graph,
typename boost::property_traits<FacePatchIndexMap>::value_type pid,
FacePatchIndexMap face_patch_index_map)
: _graph(const_cast<Graph&>(graph))
, fimap(get(CGAL::face_index, graph))
, vimap(get(boost::vertex_index, graph))
, himap(get(CGAL::halfedge_index, graph))
typename boost::property_traits<FacePatchIndexMap>::value_type pid,
FacePatchIndexMap face_patch_index_map)
: _graph(const_cast<Graph&>(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&>(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&>(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 <typename FaceRange>
Face_filtered_graph(const Graph& graph,
const FaceRange& selected_faces)
: _graph(const_cast<Graph&>(graph))
, fimap(get(CGAL::face_index, graph))
, vimap(get(boost::vertex_index, graph))
, himap(get(CGAL::halfedge_index, graph))
: _graph(const_cast<Graph&>(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<class FacePatchIndexRange, class FacePatchIndexMap>
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<FacePatchIndexRange>::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<FIM, typename Pointer_property_map<typename boost::property_traits<FIM>::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<VIM, typename Pointer_property_map<typename boost::property_traits<VIM>::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<HIM, typename Pointer_property_map<typename boost::property_traits<HIM>::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<typename Graph,
typename FIMap,
typename VIMap,
typename HIMap>
struct property_map<CGAL::Face_filtered_graph<Graph, FIMap, VIMap, HIMap>, 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<typename Graph, typename FIMap, typename VIMap, typename HIMap>
struct property_map<CGAL::Face_filtered_graph<Graph, FIMap, VIMap, HIMap>, CGAL::face_index_t>
{
typedef typename CGAL::Face_filtered_graph<Graph, FIMap, VIMap, HIMap>::FIM FIM;
typedef typename CGAL::Property_map_binder<FIM,
typename CGAL::Pointer_property_map<
typename boost::property_traits<FIM>::value_type>::type> type;
typedef type const_type;
};
template<typename Graph, typename FIMap, typename VIMap, typename HIMap>
struct property_map<CGAL::Face_filtered_graph<Graph, FIMap, VIMap, HIMap>, boost::vertex_index_t>
{
typedef typename CGAL::Face_filtered_graph<Graph, FIMap, VIMap, HIMap>::VIM VIM;
typedef typename CGAL::Property_map_binder<VIM,
typename CGAL::Pointer_property_map<
typename boost::property_traits<VIM>::value_type>::type> type;
typedef type const_type;
};
template<typename Graph,
typename FIMap,
typename VIMap,
typename HIMap>
struct property_map<CGAL::Face_filtered_graph<Graph, FIMap, VIMap, HIMap>, 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::Face_filtered_graph<Graph, FIMap, VIMap, HIMap>, CGAL::halfedge_index_t>
{
typedef typename CGAL::Face_filtered_graph<Graph, FIMap, VIMap, HIMap>::HIM HIM;
typedef typename CGAL::Property_map_binder<HIM,
typename CGAL::Pointer_property_map<
typename boost::property_traits<HIM>::value_type>::type> type;
typedef type const_type;
};
template<typename Graph,
typename FIMap,
typename VIMap,
typename HIMap>
} // namespace boost
struct property_map<CGAL::Face_filtered_graph<Graph, FIMap, VIMap, HIMap>, 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

View File

@ -148,13 +148,8 @@ void write_polys(std::ostream& os,
typedef typename boost::graph_traits<FaceGraph>::vertex_descriptor vertex_descriptor;
typedef typename boost::graph_traits<FaceGraph>::face_descriptor face_descriptor;
typedef typename CGAL::GetVertexIndexMap<FaceGraph, NamedParameters>::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<Mesh, NamedParameters>::const_type Vimap;
Vimap V = CGAL::get_initialized_vertex_index_map(mesh, np);
std::vector<std::size_t> connectivity_table;
std::vector<std::size_t> offsets;
@ -186,13 +181,8 @@ void write_polys_tag(std::ostream& os,
typedef typename boost::graph_traits<FaceGraph>::vertex_descriptor vertex_descriptor;
typedef typename boost::graph_traits<FaceGraph>::face_descriptor face_descriptor;
typedef typename CGAL::GetVertexIndexMap<FaceGraph, NamedParameters>::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<Mesh, NamedParameters>::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

View File

@ -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<TriangleMesh>::vertex_descriptor vertex_descriptor;
typedef typename boost::graph_traits<TriangleMesh>::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits<TriangleMesh>::face_iterator face_iterator;
// vertex index map
typedef typename CGAL::GetVertexIndexMap<TriangleMesh, NamedParameters>::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<TriangleMesh, NamedParameters>::type Indices;
Indices indices = CGAL::get_initialized_vertex_index_map(tm, np);
idx_t nn = static_cast<idx_t>(num_vertices(tm));
idx_t ne = static_cast<idx_t>(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

View File

@ -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<TriangleMesh>::vertex_descriptor vertex_descriptor;
typedef typename boost::graph_traits<TriangleMesh>::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits<TriangleMesh>::face_iterator face_iterator;
//Vertex index map
typedef typename CGAL::GetVertexIndexMap<TriangleMesh, NamedParameters>::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<TriangleMesh, NamedParameters>::type Indices;
Indices indices = CGAL::get_initialized_vertex_index_map(tm, np);
idx_t nn = static_cast<idx_t>(num_vertices(tm));
idx_t ne = static_cast<idx_t>(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

View File

@ -124,8 +124,8 @@ public:
/// The type for the objects used to identify halfedges in the underlying mesh.
typedef typename boost::graph_traits<TM>::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<TM>::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<TM>::halfedge_iterator TM_halfedge_iterator;
/// The type for the objects used to identify edges in the underlying mesh.
typedef typename boost::graph_traits<TM>::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

View File

@ -199,13 +199,8 @@ void copy_face_graph(const SourceMesh& sm, TargetMesh& tm,
typedef typename boost::graph_traits<TargetMesh>::halfedge_descriptor tm_halfedge_descriptor;
std::vector<tm_halfedge_descriptor> hedges(num_halfedges(sm));
// init halfedge index map
/// \TODO shall we keep that?
helpers::init_halfedge_indices(const_cast<SourceMesh&>(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);

View File

@ -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 <CGAL/assertions.h>
#include <CGAL/boost/graph/Named_function_parameters.h>
#include <CGAL/boost/graph/properties.h>
#include <CGAL/Dynamic_property_map.h>
#include <CGAL/use.h>
#include <vector>
#include <type_traits>
namespace CGAL {
namespace BGL {
namespace internal {
// Check that an index map has been correctly initialized
template <typename DescriptorRange, typename IndexMap>
bool is_index_map_valid(IndexMap idmap,
const std::size_t num_simplices,
const DescriptorRange& range)
{
typedef typename boost::property_traits<IndexMap>::value_type Id_type;
Id_type max_id = static_cast<Id_type>(num_simplices);
std::vector<bool> 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 <typename VertexIndexPropertyMap, typename Graph>
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 <typename HalfedgeIndexPropertyMap, typename Graph>
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 <typename EdgeIndexPropertyMap, typename Graph>
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 <typename FaceIndexPropertyMap, typename Graph>
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 <typename PropertyTag, typename IndexPropertyMap, typename Graph>
void initialize_index_map(const PropertyTag, IndexPropertyMap, const Graph&)
{
// Unknown parameter; should never be here.
CGAL_assertion(false);
}
template <typename IndexPropertyMap,
typename Graph,
bool is_writable = CGAL::internal::Is_writable_property_map<IndexPropertyMap>::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<IndexPropertyMap>::value_type i = 0;
for(typename boost::graph_traits<Graph>::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<IndexPropertyMap>::value_type i = 0;
for(typename boost::graph_traits<Graph>::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<IndexPropertyMap>::value_type i = 0;
for(typename boost::graph_traits<Graph>::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<IndexPropertyMap>::value_type i = 0;
for(typename boost::graph_traits<Graph>::face_descriptor fd : faces(g))
put(face_index_map, fd, i++);
}
template <typename PropertyTag>
void operator()(const PropertyTag, IndexPropertyMap, const Graph&)
{
// Unknown parameter; should never be here.
CGAL_assertion(false);
}
};
template <typename IndexPropertyMap, typename Graph>
struct Index_map_initializer<IndexPropertyMap, Graph, false>
{
template <typename PropertyTag>
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 <typename WritableIndexPropertyMap, typename Graph> \
void initialize_##TYPE##_index_map(WritableIndexPropertyMap index_map, \
const Graph& g) \
{ \
Index_map_initializer<WritableIndexPropertyMap, Graph> 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 <typename IndexMap, typename PropertyTag, typename Tag, typename DynamicTag, typename Graph>
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 <typename IndexMap, typename PropertyTag, typename Tag, typename DynamicTag, typename Graph>
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 <typename InternalIndexMap, typename PropertyTag, typename Graph>
InternalIndexMap
get_initialized_internal_index_map(InternalIndexMap index_map,
const PropertyTag p,
const Graph& g)
{
if(CGAL::internal::Is_writable_property_map<InternalIndexMap>::value)
{
if(!is_index_map_valid(p, index_map, g))
Index_map_initializer<InternalIndexMap, Graph>{}(p, index_map, g);
}
else // not writable
{
CGAL_assertion(is_index_map_valid(p, index_map, g));
}
return index_map;
}
template <typename PropertyTag, typename Tag, typename DynamicTag, typename Graph>
typename boost::property_map<Graph, Tag>::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 PropertyTag, typename Tag, typename DynamicTag, typename Graph>
typename boost::property_map<Graph, Tag>::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 <typename DynamicIndexMap, typename PropertyTag, typename Graph>
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<DynamicIndexMap, Graph>{}(p, index_map, g);
return index_map;
}
template <typename PropertyTag, typename DynamicTag, typename Graph>
typename boost::property_map<Graph, DynamicTag>::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 PropertyTag, typename DynamicTag, typename Graph>
typename boost::property_map<Graph, DynamicTag>::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 <typename PropertyTag, typename Tag, typename DynamicTag,
typename Graph,
typename NamedParameters = Named_function_parameters<bool, internal_np::all_default_t> >
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<Graph, Tag>::value, Tag, DynamicTag>::type Final_tag;
typedef typename internal_np::Lookup_named_param_def<
PropertyTag,
NamedParameters,
typename boost::property_map<Graph, Final_tag>::const_type>::type const_type;
typedef typename internal_np::Lookup_named_param_def<
PropertyTag,
NamedParameters,
typename boost::property_map<Graph, Final_tag>::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

View File

@ -19,18 +19,19 @@
#ifndef CGAL_BOOST_GRAPH_NAMED_PARAMETERS_HELPERS_H
#define CGAL_BOOST_GRAPH_NAMED_PARAMETERS_HELPERS_H
#include <CGAL/boost/graph/internal/initialized_index_maps_helpers.h>
#include <CGAL/boost/graph/Named_function_parameters.h>
#include <CGAL/boost/graph/properties.h>
#include <CGAL/Dynamic_property_map.h>
#include <CGAL/Kernel_traits.h>
#include <CGAL/Origin.h>
#include <CGAL/property_map.h>
#include <CGAL/boost/graph/properties.h>
#include <boost/mpl/if.hpp>
#include <boost/mpl/has_xxx.hpp>
#include <boost/type_traits/is_same.hpp>
#include <type_traits>
namespace CGAL {
@ -40,8 +41,8 @@ namespace CGAL {
class Eigen_svd;
class Lapack_svd;
//
//helper classes
template<typename PolygonMesh, typename PropertyTag>
class property_map_selector
@ -104,7 +105,8 @@ namespace CGAL {
property_map_selector<PolygonMesh, PropertyTag> 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 Graph, class Property>
class property_map_value {
typedef typename boost::property_map<Graph, Property>::const_type PMap;
@ -175,37 +177,105 @@ namespace CGAL {
> ::type type;
};
template<typename PolygonMesh, typename NamedParameters>
class GetFaceIndexMap
{
typedef typename property_map_selector<PolygonMesh, boost::face_index_t>::type DefaultMap;
typedef typename property_map_selector<PolygonMesh, boost::face_index_t>::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, DefaultMap>::type Is_internal_map;
typedef typename boost::is_same<const_type, DefaultMap_const>::type Is_internal_map_const;
};
// Define the following structs:
//
// GetInitializedVertexIndexMap
// GetInitializedHalfedgeIndexMap
// GetInitializedEdgeIndexMap
// GetInitializedFaceIndexMap
template<typename PolygonMesh, typename NamedParameters>
class GetVertexIndexMap
{
typedef typename property_map_selector<PolygonMesh, boost::vertex_index_t>::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 <typename Graph, \
typename NamedParameters = \
CGAL::Named_function_parameters<bool, CGAL::internal_np::all_default_t> > \
struct GetInitialized##CTYPE##IndexMap \
: public BGL::internal::GetInitializedIndexMap<internal_np::DTYPE##_index_t, \
boost::DTYPE##_index_t, \
CGAL::dynamic_##DTYPE##_property_t<STYPE>, \
Graph, NamedParameters> \
{ };
CGAL_DEF_GET_INDEX_TYPE(Vertex, vertex, typename boost::graph_traits<Graph>::vertices_size_type)
CGAL_DEF_GET_INDEX_TYPE(Halfedge, halfedge, typename boost::graph_traits<Graph>::halfedges_size_type)
CGAL_DEF_GET_INDEX_TYPE(Edge, edge, typename boost::graph_traits<Graph>::edges_size_type)
CGAL_DEF_GET_INDEX_TYPE(Face, face, typename boost::graph_traits<Graph>::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 Graph, \
typename NamedParameters> \
typename BGL::internal::GetInitializedIndexMap<CGAL::internal_np::DTYPE##_index_t, \
boost::DTYPE##_index_t, \
CGAL::dynamic_##DTYPE##_property_t<STYPE>, \
Graph, NamedParameters>::const_type \
get_initialized_##DTYPE##_index_map(const Graph& g, \
const NamedParameters& np) \
{ \
typedef BGL::internal::GetInitializedIndexMap<CGAL::internal_np::DTYPE##_index_t, \
boost::DTYPE##_index_t, \
CGAL::dynamic_##DTYPE##_property_t<STYPE>, \
Graph, NamedParameters> Index_map_getter; \
return Index_map_getter::get_const(CGAL::internal_np::DTYPE##_index_t{}, g, np); \
} \
template <typename Graph> \
typename BGL::internal::GetInitializedIndexMap<CGAL::internal_np::DTYPE##_index_t, \
boost::DTYPE##_index_t, \
CGAL::dynamic_##DTYPE##_property_t<STYPE>, \
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 <typename Graph, \
typename NamedParameters, \
/*otherwise compilers will try to use 'Graph := const PM' and things will go badly*/ \
std::enable_if_t< \
!std::is_const<typename std::remove_reference<Graph>::type>::value, int> = 0> \
typename BGL::internal::GetInitializedIndexMap<CGAL::internal_np::DTYPE##_index_t, \
boost::DTYPE##_index_t, \
CGAL::dynamic_##DTYPE##_property_t<STYPE>, \
Graph, NamedParameters>::type \
get_initialized_##DTYPE##_index_map(Graph& g, \
const NamedParameters& np) \
{ \
typedef BGL::internal::GetInitializedIndexMap<CGAL::internal_np::DTYPE##_index_t, \
boost::DTYPE##_index_t, \
CGAL::dynamic_##DTYPE##_property_t<STYPE>, \
Graph, NamedParameters> Index_map_getter; \
return Index_map_getter::get(CGAL::internal_np::DTYPE##_index_t{}, g, np); \
} \
template <typename Graph, \
std::enable_if_t< \
!std::is_const<typename std::remove_reference<Graph>::type>::value, int> = 0> \
typename BGL::internal::GetInitializedIndexMap<CGAL::internal_np::DTYPE##_index_t, \
boost::DTYPE##_index_t, \
CGAL::dynamic_##DTYPE##_property_t<STYPE>, \
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<Graph>::vertices_size_type)
CGAL_DEF_GET_INITIALIZED_INDEX_MAP(halfedge, typename boost::graph_traits<Graph>::halfedges_size_type)
CGAL_DEF_GET_INITIALIZED_INDEX_MAP(edge, typename boost::graph_traits<Graph>::edges_size_type)
CGAL_DEF_GET_INITIALIZED_INDEX_MAP(face, typename boost::graph_traits<Graph>::faces_size_type)
#undef CGAL_DEF_GET_INITIALIZED_INDEX_MAP
template<typename PolygonMesh, typename NamedParameters>
class GetFaceNormalMap
@ -244,7 +314,7 @@ namespace CGAL {
typedef std::random_access_iterator_tag iterator_category;
};
};
namespace parameters
{
template <typename PointRange>
@ -258,7 +328,7 @@ namespace CGAL {
namespace internal{
BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_nested_type_iterator, iterator, false)
}
template<typename PointRange, typename NamedParameters,
bool has_nested_iterator=internal::Has_nested_type_iterator<PointRange>::value>
class GetPointMap
@ -380,7 +450,7 @@ namespace CGAL {
DefaultPMap
> ::type const_type;
};
template<typename NamedParameters>
class GetPlaneIndexMap
{
@ -428,7 +498,7 @@ namespace CGAL {
};
} // namespace Point_set_processing_3
template<typename NamedParameters, typename DefaultSolver>
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

View File

@ -14,14 +14,15 @@
#define CGAL_BOOST_GRAPH_BGL_PROPERTIES_H
#include <CGAL/property_map.h>
#include <CGAL/Dynamic_property_map.h>
#include <CGAL/basic.h>
#include <boost/graph/properties.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <CGAL/Dynamic_property_map.h>
#include <CGAL/basic.h>
#include <string>
#include <vector>
#include <type_traits>
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 <class PolygonMesh, class FaceIndexMap, class Tag>
void init_face_indices(PolygonMesh& pm,
FaceIndexMap& fid,
boost::read_write_property_map_tag,
Tag)
{
typename boost::property_traits<FaceIndexMap>::value_type i = 0;
for(typename boost::graph_traits<PolygonMesh>::face_descriptor fd :
faces(pm))
{
put(fid, fd, i);
++i;
}
}
template <class PolygonMesh, class VertexIndexMap, class Tag>
void init_vertex_indices(PolygonMesh& pm,
VertexIndexMap& vid,
boost::read_write_property_map_tag,
Tag)
{
typename boost::property_traits<VertexIndexMap>::value_type i = 0;
for(typename boost::graph_traits<PolygonMesh>::vertex_descriptor vd :
vertices(pm))
{
put(vid, vd, i);
++i;
}
}
template <class PolygonMesh, class HalfedgeIndexMap, class Tag>
void init_halfedge_indices(PolygonMesh& pm,
HalfedgeIndexMap& hid,
boost::read_write_property_map_tag,
Tag)
{
typename boost::property_traits<HalfedgeIndexMap>::value_type i = 0;
for(typename boost::graph_traits<PolygonMesh>::halfedge_descriptor hd :
halfedges(pm))
{
put(hid, hd, i);
++i;
}
}
// matches mutable Lvalue property maps
template <class PolygonMesh, class FaceIndexMap>
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 <class PolygonMesh, class VertexIndexMap>
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 <class PolygonMesh, class HalfedgeIndexMap>
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 <class PolygonMesh, class FaceIndexMap, class MapTag, class Tag>
void init_face_indices(PolygonMesh&, FaceIndexMap, MapTag, Tag)
{}
template <class PolygonMesh, class VertexIndexMap, class MapTag, class Tag>
void init_vertex_indices(PolygonMesh&, VertexIndexMap, MapTag, Tag)
{}
template <class PolygonMesh, class HalfedgeIndexMap, class MapTag, class Tag>
void init_halfedge_indices(PolygonMesh&, HalfedgeIndexMap, MapTag, Tag)
{}
template <class PolygonMesh, class FaceIndexMap>
void init_face_indices(PolygonMesh& pm, FaceIndexMap fid)
{
init_face_indices(pm, fid,
typename boost::property_traits<FaceIndexMap>::category(),
typename boost::is_const<
typename boost::remove_reference<
typename boost::property_traits<FaceIndexMap>::reference
>::type >::type() );
}
template <class PolygonMesh, class VertexIndexMap>
void init_vertex_indices(PolygonMesh& pm, VertexIndexMap vid)
{
init_vertex_indices(pm, vid,
typename boost::property_traits<VertexIndexMap>::category(),
typename boost::is_const<
typename boost::remove_reference<
typename boost::property_traits<VertexIndexMap>::reference
>::type >::type() );
}
template <class PolygonMesh, class HalfedgeIndexMap>
void init_halfedge_indices(PolygonMesh& pm, HalfedgeIndexMap hid)
{
init_halfedge_indices(pm, hid,
typename boost::property_traits<HalfedgeIndexMap>::category(),
typename boost::is_const<
typename boost::remove_reference<
typename boost::property_traits<HalfedgeIndexMap>::reference
>::type >::type() );
}
} //namespace helpers
namespace CGAL {
namespace internal {
template<typename Polyhedron, typename Handle>
@ -232,8 +116,8 @@ struct Edge_index_accessor
};
template<typename Handle, typename ValueType, typename Reference,
bool is_const = boost::is_const<
typename boost::remove_reference<Reference>::type >::value>
bool is_const = std::is_const<
typename std::remove_reference<Reference>::type >::value>
struct Point_accessor
: boost::put_get_helper< Reference, Point_accessor<Handle, ValueType, Reference> >
{
@ -265,6 +149,32 @@ struct Point_accessor<Handle, ValueType, ConstReference, true>
reference operator[](Handle h) const { return h->point(); }
};
// this one is basically 'readable_property_map_tag'
template <typename PropertyMap,
typename PropertyMapCategory = typename boost::property_traits<PropertyMap>::category>
struct Is_writable_property_map : CGAL::Tag_false { };
template <typename PropertyMap>
struct Is_writable_property_map<PropertyMap, boost::writable_property_map_tag> : CGAL::Tag_true { };
template <typename PropertyMap>
struct Is_writable_property_map<PropertyMap, boost::read_write_property_map_tag> : 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 <typename PropertyMap>
struct Is_writable_property_map<PropertyMap, boost::lvalue_property_map_tag>
: boost::mpl::if_c<std::is_const<typename std::remove_reference<
typename boost::property_traits<PropertyMap>::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 <typename ID>
template<typename ID>
struct vertex_incident_patches_t {
typedef ID type;
};
template <typename ID>
template<typename ID>
struct face_patch_id_t {
typedef ID type;
};

View File

@ -112,6 +112,39 @@ struct property_map<CGAL::Seam_mesh<TM, SEM, SVM>, CGAL::vertex_point_t>
typedef CGAL::Seam_mesh_point_map<TM, SEM, SVM> type;
typedef type const_type;
};
template <class TM, class SEM, class SVM, typename T>
struct property_map<CGAL::Seam_mesh<TM, SEM, SVM>, CGAL::dynamic_vertex_property_t<T> >
{
typedef typename boost::graph_traits<CGAL::Seam_mesh<TM, SEM, SVM> >::vertex_descriptor vertex_descriptor;
typedef CGAL::internal::Dynamic_property_map<vertex_descriptor,T> type;
typedef type const_type;
};
template <class TM, class SEM, class SVM, typename T>
struct property_map<CGAL::Seam_mesh<TM, SEM, SVM>, CGAL::dynamic_halfedge_property_t<T> >
{
typedef typename boost::graph_traits<CGAL::Seam_mesh<TM, SEM, SVM> >::halfedge_descriptor halfedge_descriptor;
typedef CGAL::internal::Dynamic_property_map<halfedge_descriptor,T> type;
typedef type const_type;
};
template <class TM, class SEM, class SVM, typename T>
struct property_map<CGAL::Seam_mesh<TM, SEM, SVM>, CGAL::dynamic_edge_property_t<T> >
{
typedef typename boost::graph_traits<CGAL::Seam_mesh<TM, SEM, SVM> >::edge_descriptor edge_descriptor;
typedef CGAL::internal::Dynamic_property_map<edge_descriptor,T> type;
typedef type const_type;
};
template <class TM, class SEM, class SVM, typename T>
struct property_map<CGAL::Seam_mesh<TM, SEM, SVM>, CGAL::dynamic_face_property_t<T> >
{
typedef typename boost::graph_traits<CGAL::Seam_mesh<TM, SEM, SVM> >::face_descriptor face_descriptor;
typedef CGAL::internal::Dynamic_property_map<face_descriptor,T> type;
typedef type const_type;
};
} // namespace boost
namespace CGAL {

View File

@ -491,13 +491,13 @@ int main()
typedef boost::graph_traits<Polyhedron> PolyTraits;
typedef boost::property_map<Polyhedron, boost::vertex_point_t>::type VPMap;
typedef boost::property_map<Polyhedron, boost::vertex_point_t>::const_type VPMap;
typedef PolyTraits::face_descriptor poly_face_descriptor;
typedef boost::associative_property_map< std::map<poly_face_descriptor,
PolyTraits::faces_size_type> > FCMap;
typedef boost::property_map<Polyhedron, CGAL::face_external_index_t>::type FIMap;
typedef boost::property_map<Polyhedron, CGAL::vertex_external_index_t>::type VIMap;
typedef boost::property_map<Polyhedron, CGAL::halfedge_external_index_t>::type HIMap;
typedef boost::property_map<Polyhedron, CGAL::face_external_index_t>::const_type FIMap;
typedef boost::property_map<Polyhedron, CGAL::vertex_external_index_t>::const_type VIMap;
typedef boost::property_map<Polyhedron, CGAL::halfedge_external_index_t>::const_type HIMap;
typedef CGAL::Face_filtered_graph<Polyhedron, FIMap, VIMap, HIMap> Poly_Adapter;
auto poly = std::make_unique<Polyhedron>();
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<Polyhedron, VPMap >(*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<Polyhedron, VPMap >(*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<Polyhedron, FCMap, Poly_Adapter>(poly_adapter);
}

View File

@ -38,6 +38,7 @@
#include <CGAL/boost/graph/properties_Constrained_Delaunay_triangulation_2.h>
#include <CGAL/boost/graph/graph_traits_Constrained_triangulation_plus_2.h>
#include <CGAL/boost/graph/properties_Constrained_triangulation_plus_2.h>
#include <CGAL/boost/graph/Seam_mesh.h>
#include <CGAL/boost/graph/io.h>
@ -57,6 +58,10 @@ typedef CGAL::Linear_cell_complex_for_bgl_combinatorial_map_helper
typedef CGAL::Surface_mesh<Point_3> SM;
typedef SM::Property_map<SM::Edge_index, bool> Seam_edge_pmap;
typedef SM::Property_map<SM::Vertex_index, bool> Seam_vertex_pmap;
typedef CGAL::Seam_mesh<SM, Seam_edge_pmap, Seam_vertex_pmap> Seam_mesh;
#if defined(CGAL_USE_OPENMESH)
#include <OpenMesh/Core/IO/MeshIO.hh>
@ -73,6 +78,8 @@ typedef OpenMesh::PolyMesh_ArrayKernelT</* MyTraits*/> OMesh;
typedef CGAL::Triangulation_vertex_base_with_id_2<Kernel> Vbb;
typedef CGAL::Triangulation_face_base_with_id_2<Kernel> Fbb;
typedef CGAL::Triangulation_2<Kernel> Triangulation_no_id_2;
typedef CGAL::Triangulation_2<Kernel,
CGAL::Triangulation_data_structure_2<Vbb, Fbb> > Triangulation_2;
typedef CGAL::Delaunay_triangulation_2<Kernel,
@ -192,8 +199,6 @@ template <typename Tr>
Tr build_dummy_triangulation()
{
typedef typename Tr::Point Point;
typedef typename boost::graph_traits<Tr>::vertex_descriptor vertex_descriptor;
typedef typename boost::graph_traits<Tr>::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<Triangulation_2>(); }
Delaunay_triangulation_2 dt2_data() { return build_dummy_triangulation<Delaunay_triangulation_2>(); }
Regular_triangulation_2 rt2_data() { return build_dummy_triangulation<Regular_triangulation_2>(); }
Constrained_triangulation_2 ct2_data() { return build_dummy_triangulation<Constrained_triangulation_2>(); }
Constrained_Delaunay_triangulation_2 cdt2_data() { return build_dummy_triangulation<Constrained_Delaunay_triangulation_2>(); }
CDT_P2 cdtp2_data() { return build_dummy_triangulation<CDT_P2>(); }
Triangulation_hierarchy_2 t2h_data() { return build_dummy_triangulation<Triangulation_hierarchy_2>(); }
template <typename Tr>
Tr build_dummy_triangulation_with_ids()
{
Tr t = build_dummy_triangulation<Tr>();
CGAL::set_triangulation_ids(t);
return t;
}
Triangulation_no_id_2 t2_no_id_data() { return build_dummy_triangulation<Triangulation_no_id_2>(); }
Triangulation_2 t2_data() { return build_dummy_triangulation_with_ids<Triangulation_2>(); }
Delaunay_triangulation_2 dt2_data() { return build_dummy_triangulation_with_ids<Delaunay_triangulation_2>(); }
Regular_triangulation_2 rt2_data() { return build_dummy_triangulation_with_ids<Regular_triangulation_2>(); }
Constrained_triangulation_2 ct2_data() { return build_dummy_triangulation_with_ids<Constrained_triangulation_2>(); }
Constrained_Delaunay_triangulation_2 cdt2_data() { return build_dummy_triangulation_with_ids<Constrained_Delaunay_triangulation_2>(); }
CDT_P2 cdtp2_data() { return build_dummy_triangulation_with_ids<CDT_P2>(); }
Triangulation_hierarchy_2 t2h_data() { return build_dummy_triangulation_with_ids<Triangulation_hierarchy_2>(); }
template <typename Graph>
struct Surface_fixture_1 {

View File

@ -1,115 +1,459 @@
#include "test_Prefix.h"
#include <CGAL/boost/graph/Euler_operations.h>
#include <boost/unordered_set.hpp>
template< typename G,
typename ForwardRange,
typename IndexPropertyMap
>
void index_uniqueness(const G&,
ForwardRange range,
IndexPropertyMap pm)
// #define CGAL_TEST_PROPERTIES_DEBUG
namespace CGAL {
template <typename Key, typename Value, typename Container>
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<Key, Value, Container>& pmap, key_type k)
{
return pmap.m_c.at(k);
}
private:
const Container& m_c;
};
template <typename Key, typename Value, typename Container>
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<Key, Value, Container>& pmap, const key_type& k, const value_type& val)
{
pmap.m_c[k] = val;
}
friend reference get(RW_property_map<Key, Value, Container>& pmap, const key_type& k)
{
return pmap.m_c[k];
}
private:
Container& m_c;
};
} // namespace CGAL
template<typename Graph,
typename ForwardRange,
typename IndexPropertyMap>
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<ForwardRange>::type).name() << std::endl;
#endif
typename boost::range_iterator<ForwardRange>::type
begin = boost::begin(range),
begin = boost::begin(range),
begin2 = boost::begin(range),
end = boost::end(range);
typedef boost::unordered_set<typename IndexPropertyMap::value_type> id_map;
typedef std::pair<typename id_map::iterator, bool> 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<std::ptrdiff_t>(m.size()));
}
void index_uniqueness_poly(const Polyhedron& g)
template<typename Graph,
typename NamedParameters>
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<Graph, NamedParameters>::type VIM;
typedef typename CGAL::GetInitializedVertexIndexMap<Graph, NamedParameters>::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<VIM, CVIM>::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<typename Graph,
typename NamedParameters>
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<Graph, NamedParameters>::type HIM;
typedef typename CGAL::GetInitializedHalfedgeIndexMap<Graph, NamedParameters>::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<HIM, CHIM>::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<typename Graph,
typename NamedParameters>
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<Graph, NamedParameters>::type EIM;
typedef typename CGAL::GetInitializedEdgeIndexMap<Graph, NamedParameters>::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<EIM, CEIM>::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<typename Graph,
typename NamedParameters>
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<Graph, NamedParameters>::type FIM;
typedef typename CGAL::GetInitializedFaceIndexMap<Graph, NamedParameters>::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<FIM, CFIM>::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 <typename Graph>
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 <typename Graph>
void test_initialized_index_maps_const(const Graph& g)
{
typedef typename CGAL::GetInitializedVertexIndexMap<Graph>::const_type VIM;
VIM ivim = CGAL::get_initialized_vertex_index_map(g);
test_uniqueness(g, vertices(g), ivim);
typedef typename CGAL::GetInitializedHalfedgeIndexMap<Graph>::const_type HIM;
HIM ihim = CGAL::get_initialized_halfedge_index_map(g);
test_uniqueness(g, halfedges(g), ihim);
typedef typename CGAL::GetInitializedEdgeIndexMap<Graph>::const_type EIM;
EIM ieim = CGAL::get_initialized_edge_index_map(g);
test_uniqueness(g, edges(g), ieim);
typedef typename CGAL::GetInitializedFaceIndexMap<Graph>::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<Graph>::vertex_descriptor vertex_descriptor;
typedef std::map<vertex_descriptor, int> VertexIndexMap;
typedef boost::associative_property_map<VertexIndexMap> VertexIdPropertyMap; // lvalue_pmap
int vi = static_cast<int>(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<Graph>::halfedge_descriptor halfedge_descriptor;
typedef std::map<halfedge_descriptor, int> HalfedgeIndexMap;
typedef CGAL::Non_mutable_property_map<halfedge_descriptor, int,
HalfedgeIndexMap> 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<Graph>::edge_descriptor edge_descriptor;
typedef boost::unordered_map<edge_descriptor, int> EdgeIndexMap;
typedef CGAL::RW_property_map<edge_descriptor, int, EdgeIndexMap> 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<Graph>::face_descriptor face_descriptor;
typedef std::map<face_descriptor, int> FaceIndexMap;
typedef boost::const_associative_property_map<FaceIndexMap> 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 <typename Graph>
void test_all_index_maps_const(const Graph& g)
{
#ifdef CGAL_TEST_PROPERTIES_DEBUG
std::cout << " ---------------------------- Const graph tests" << std::endl;
#endif
template <typename Triangulation>
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 <typename Graph>
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 <typename Graph>
void test_initialized_index_maps(Graph& g)
{
typedef typename CGAL::GetInitializedVertexIndexMap<Graph>::type VIM;
VIM ivim = CGAL::get_initialized_vertex_index_map(g);
test_uniqueness(g, vertices(g), ivim);
typedef typename CGAL::GetInitializedHalfedgeIndexMap<Graph>::type HIM;
HIM ihim = CGAL::get_initialized_halfedge_index_map(g);
test_uniqueness(g, halfedges(g), ihim);
typedef typename CGAL::GetInitializedEdgeIndexMap<Graph>::type EIM;
EIM ieim = CGAL::get_initialized_edge_index_map(g);
test_uniqueness(g, edges(g), ieim);
typedef typename CGAL::GetInitializedFaceIndexMap<Graph>::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<Graph>::vertex_descriptor vertex_descriptor;
typedef std::map<vertex_descriptor, int> VertexIndexMap;
typedef boost::associative_property_map<VertexIndexMap> VertexIdPropertyMap; // lvalue_pmap
int vi = static_cast<int>(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<Graph>::halfedge_descriptor halfedge_descriptor;
typedef std::map<halfedge_descriptor, int> HalfedgeIndexMap;
typedef CGAL::Non_mutable_property_map<halfedge_descriptor, int,
HalfedgeIndexMap> 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<Graph>::edge_descriptor edge_descriptor;
typedef boost::unordered_map<edge_descriptor, int> EdgeIndexMap;
typedef CGAL::RW_property_map<edge_descriptor, int, EdgeIndexMap> 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<Graph>::face_descriptor face_descriptor;
typedef std::map<face_descriptor, int> FaceIndexMap;
typedef boost::const_associative_property_map<FaceIndexMap> 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 <typename Graph>
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 <typename Graph>
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<Polyhedron> 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<LCC> 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<SM> 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<SM::Edge_index, bool>("e:on_seam", false).first;
Seam_vertex_pmap seam_vertices = sm.add_property_map<SM::Vertex_index, bool>("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<OMesh> 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;
}

View File

@ -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<Polyhedron_type> 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<Polyhedron_type> is_featured_edge(p);

View File

@ -105,47 +105,6 @@ struct IGT_generator<Gt,CGAL::Tag_false>
} // end namespace details
} // end namespace Mesh_3
namespace Mesh_3 {
namespace internal {
template <typename Polyhedron_type,
bool = CGAL::graph_has_property<Polyhedron_type,
CGAL::face_index_t>::value>
class Get_face_index_pmap {
public:
typedef typename boost::property_map<Polyhedron_type,
CGAL::face_index_t>::const_type Pmap;
Get_face_index_pmap(const Polyhedron_type&) {}
Pmap operator()(const Polyhedron_type& polyhedron) {
return get(CGAL::face_index, polyhedron);
}
};
template <typename Polyhedron_type>
class Get_face_index_pmap<Polyhedron_type, false> {
typedef typename boost::graph_traits<Polyhedron_type>::face_descriptor
face_descriptor;
typedef std::map<face_descriptor, int> 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<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
*

View File

@ -348,9 +348,6 @@ detect_features(FT angle_in_degree, std::vector<Polyhedron>& poly)
typedef typename boost::property_map<Polyhedron,CGAL::vertex_incident_patches_t<P_id> >::type VIPMap;
typedef typename boost::property_map<Polyhedron, CGAL::edge_is_feature_t>::type EIFMap;
using Mesh_3::internal::Get_face_index_pmap;
Get_face_index_pmap<Polyhedron> get_face_index_pmap(p);
PIDMap pid_map = get(face_patch_id_t<Tag_>(), p);
VIPMap vip_map = get(vertex_incident_patches_t<P_id>(), p);
EIFMap eif_map = get(CGAL::edge_is_feature, p);
@ -360,8 +357,8 @@ detect_features(FT angle_in_degree, std::vector<Polyhedron>& 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<Polyhedron> is_featured_edge(p);

View File

@ -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
<b>Type:</b> a class model of `ReadablePropertyMap` with
`boost::graph_traits<PolygonMesh>::%vertex_descriptor` as key type and the value type
\code typename boost::property_traits<typename boost::property_map<PolygonMesh, CGAL::vertex_index_t>::type>::value_type \endcode
<b>Default:</b> \code boost::get(CGAL::vertex_index, pmesh)\endcode
<b>Default:</b> 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
<b>Type:</b> a class model of `ReadablePropertyMap` with
`boost::graph_traits<PolygonMesh>::%face_descriptor` as key type and the value type:
\code typename boost::property_traits<typename boost::property_map<PolygonMesh, CGAL::face_index_t>::type>::value_type \endcode
<b>Default:</b> \code boost::get(CGAL::face_index, pmesh)\endcode
If this internal property map exists, its values must be initialized.
<b>Default:</b> an initialized face index property map
\cgalNPEnd
\cgalNPBegin{edge_is_constrained_map} \anchor PMP_edge_is_constrained_map

View File

@ -53,7 +53,7 @@ std::size_t border_size(typename boost::graph_traits<PolygonMesh>::halfedge_desc
template<typename PM
, typename FaceRange
, typename HalfedgeOutputIterator>
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<PolygonMesh>::halfedge_desc
// the bool is true if the halfedge stored is the one of the face,
// false if it is its opposite
std::map<halfedge_descriptor, bool> 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<PolygonMesh>::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<typename PM
@ -108,7 +108,7 @@ std::size_t border_size(typename boost::graph_traits<PolygonMesh>::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<PolygonMesh>::halfedge_desc
typedef typename boost::graph_traits<PM>::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits<PM>::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<typename GetFaceIndexMap<PM, NamedParameters>::Is_internal_map,
boost::true_type>::value)
{
typename boost::range_iterator<const FaceRange>::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<bool> 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<PolygonMesh>::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<PolygonMesh>::%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<PolygonMesh>::%face_descriptor`.
* @tparam HalfedgeOutputIterator model of `OutputIterator`
holding `boost::graph_traits<PolygonMesh>::%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<PolygonMesh>::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<PM, NamedParameters>::const_type FIMap;
typedef typename boost::property_map<typename internal::Dummy_PM,
CGAL::face_index_t>::type Unset_FIMap;
typedef typename CGAL::GetInitializedFaceIndexMap<PolygonMesh, NamedParameters>::const_type FIMap;
FIMap fim = CGAL::get_initialized_face_index_map(pmesh, np);
if (boost::is_same<FIMap, Unset_FIMap>::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<typename PolygonMesh
@ -231,11 +203,11 @@ std::size_t border_size(typename boost::graph_traits<PolygonMesh>::halfedge_desc
template<typename PolygonMesh
, typename FaceRange
, typename HalfedgeOutputIterator>
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<PolygonMesh>::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<typename PolygonMesh>
unsigned int number_of_borders(const PolygonMesh& pmesh)

View File

@ -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 <class TriangleMesh, class NamedParameters>
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<std::size_t>(), tm)),
parameters::face_index_map(get(CGAL::dynamic_face_property_t<std::size_t>(), clipper)));
}
template <class TriangleMesh, class NamedParameters>
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<TriangleMesh, CGAL::face_index_t>());
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<TriangleMesh, CGAL::face_index_t>());
return clip(tm, clipper, np, parameters::all_default());
}
/// \cond SKIP_IN_MANUAL

View File

@ -145,7 +145,7 @@ connected_component(typename boost::graph_traits<PolygonMesh>::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<PolygonMesh>::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<PolygonMesh>::%face_descriptor` as key type and
@ -213,13 +210,13 @@ connected_components(const PolygonMesh& pmesh,
NamedParameters,
internal::No_constraint<PolygonMesh>//default
> ::type EdgeConstraintMap;
EdgeConstraintMap ecmap
= choose_parameter(get_parameter(np, internal_np::edge_is_constrained),
internal::No_constraint<PolygonMesh>());
typedef typename GetFaceIndexMap<PolygonMesh, NamedParameters>::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<PolygonMesh, NamedParameters>::const_type FaceIndexMap;
FaceIndexMap fimap = get_initialized_face_index_map(pmesh, np);
typename boost::property_traits<FaceComponentMap>::value_type i=0;
std::vector<bool> 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<PM, NamedParameters>::type FaceIndexMap;
FaceIndexMap fimap = choose_parameter(get_parameter(np, internal_np::face_index),
get_property_map(boost::face_index, pmesh));
typedef typename CGAL::GetInitializedFaceIndexMap<PolygonMesh, NamedParameters>::type FaceIndexMap;
FaceIndexMap fimap = CGAL::get_initialized_face_index_map(pmesh, np);
// FaceSizeMap
typedef typename internal_np::Lookup_named_param_def<internal_np::face_size_map_t,
@ -456,10 +447,6 @@ std::size_t keep_largest_connected_components(PolygonMesh& pmesh,
* 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 ThresholdValueType the type of the threshold value
* \tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters"
@ -505,15 +492,13 @@ std::size_t keep_large_connected_components(PolygonMesh& pmesh,
using parameters::choose_parameter;
using parameters::get_parameter;
// FaceIndexMap
typedef typename GetFaceIndexMap<PM, NamedParameters>::type FaceIndexMap;
FaceIndexMap fim = choose_parameter(get_parameter(np, internal_np::face_index),
get_property_map(boost::face_index, pmesh));
typedef typename CGAL::GetInitializedFaceIndexMap<PolygonMesh, NamedParameters>::type FaceIndexMap;
FaceIndexMap fim = CGAL::get_initialized_face_index_map(pmesh, np);
typedef typename internal_np::Lookup_named_param_def<internal_np::face_size_map_t,
NamedParameters,
Constant_property_map<face_descriptor, std::size_t> // default
>::type FaceSizeMap;
NamedParameters,
Constant_property_map<face_descriptor, std::size_t> // default
>::type FaceSizeMap;
typedef typename boost::property_traits<FaceSizeMap>::value_type Face_size;
CGAL_static_assertion((std::is_convertible<ThresholdValueType, Face_size>::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<PolygonMesh>::edge_descriptor edge_descriptor;
typedef typename boost::graph_traits<PolygonMesh>::edge_iterator edge_iterator;
//VertexIndexMap
typedef typename GetVertexIndexMap<PM, NamedParameters>::type VertexIndexMap;
VertexIndexMap vim = choose_parameter(get_parameter(np, internal_np::vertex_index),
get_const_property_map(boost::vertex_index, pmesh));
typedef typename GetInitializedVertexIndexMap<PolygonMesh, NamedParameters>::type VertexIndexMap;
VertexIndexMap vim = get_initialized_vertex_index_map(pmesh, np);
std::set<std::size_t> 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<PM>::face_descriptor face_descriptor;
using parameters::choose_parameter;
using parameters::get_parameter;
//FaceIndexMap
typedef typename GetFaceIndexMap<PM, CGAL_PMP_NP_CLASS>::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<PM>::face_descriptor face_descriptor;
typedef typename CGAL::GetInitializedFaceIndexMap<PolygonMesh, CGAL_PMP_NP_CLASS>::type FaceIndexMap;
FaceIndexMap fim = CGAL::get_initialized_face_index_map(pmesh, np);
//vector_property_map
boost::vector_property_map<std::size_t, FaceIndexMap> face_cc(fim);
connected_components(pmesh, face_cc, np);
std::vector<std::size_t> 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<PM, CGAL_PMP_NP_CLASS>::type FaceIndexMap;
FaceIndexMap fim = choose_parameter(get_parameter(np, internal_np::face_index),
get_property_map(boost::face_index, pmesh));
typedef typename CGAL::GetInitializedFaceIndexMap<PolygonMesh, CGAL_PMP_NP_CLASS>::type FaceIndexMap;
FaceIndexMap fim = CGAL::get_initialized_face_index_map(pmesh, np);
//vector_property_map
boost::vector_property_map<std::size_t, FaceIndexMap> face_cc(fim);
connected_components(pmesh, face_cc, np);
std::vector<std::size_t> cc_to_keep;

View File

@ -17,11 +17,12 @@
#include <CGAL/disable_warnings.h>
#include <CGAL/boost/graph/copy_face_graph.h>
#include <CGAL/boost/graph/named_params_helper.h>
#include <CGAL/Polygon_mesh_processing/intersection.h>
#include <CGAL/Polygon_mesh_processing/internal/Corefinement/Visitor.h>
#include <CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h>
#include <CGAL/Polygon_mesh_processing/internal/Corefinement/Output_builder_for_autorefinement.h>
#include <CGAL/boost/graph/copy_face_graph.h>
#include <CGAL/iterator.h>
namespace CGAL {
@ -39,16 +40,17 @@ namespace internal {
template <class Kernel, class TriangleMesh, class VD, class Fid_map, class Vpm>
bool recursive_does_bound_a_volume(const TriangleMesh& tm,
Vpm& vpm,
Fid_map& fid_map,
Fid_map fid_map,
const std::vector<VD>& xtrm_vertices,
boost::dynamic_bitset<>& cc_handled,
const std::vector<std::size_t>& face_cc,
std::size_t xtrm_cc_id,
bool is_parent_outward_oriented)
{
typedef boost::graph_traits<TriangleMesh> GT;
typedef typename GT::face_descriptor face_descriptor;
typedef Side_of_triangle_mesh<TriangleMesh, Kernel, Vpm> Side_of_tm;
typedef boost::graph_traits<TriangleMesh> Graph_traits;
typedef typename Graph_traits::face_descriptor face_descriptor;
typedef Side_of_triangle_mesh<TriangleMesh, Kernel, Vpm> 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 <class TriangleMesh, class NamedParameters>
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<TriangleMesh> GT;
typedef typename GT::vertex_descriptor vertex_descriptor;
typedef typename GetVertexPointMap<TriangleMesh,
NamedParameters>::const_type Vpm;
typedef typename GetFaceIndexMap<TriangleMesh,
NamedParameters>::const_type Fid_map;
typedef typename Kernel_traits<
typename boost::property_traits<Vpm>::value_type >::Kernel Kernel;
typedef boost::graph_traits<TriangleMesh> Graph_traits;
typedef typename Graph_traits::vertex_descriptor vertex_descriptor;
typedef typename GetVertexPointMap<TriangleMesh, NamedParameters>::const_type Vpm;
typedef typename boost::property_traits<Vpm>::value_type Point;
typedef typename Kernel_traits<Point>::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<TriangleMesh, NamedParameters>::const_type Fid_map;
Fid_map fid_map = get_initialized_face_index_map(tm, np);
std::vector<std::size_t> 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<vertex_descriptor> xtrm_vertices(nb_cc, GT::null_vertex());
std::vector<vertex_descriptor> 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<Ecm_out_0, Ecm_out_1, Ecm_out_2, Ecm_out_3>
Edge_mark_map_tuple;
// Face index point maps
typedef typename GetFaceIndexMap<TriangleMesh,
NamedParameters1>::type Fid_map;
typedef typename GetFaceIndexMap<TriangleMesh,
NamedParameters2>::type Fid_map2;
CGAL_USE_TYPE(Fid_map2);
CGAL_assertion_code(
static const bool same_fidmap = (boost::is_same<Fid_map,Fid_map2>::value);)
CGAL_static_assertion(same_fidmap);
// Face index point maps
typedef typename CGAL::GetInitializedFaceIndexMap<TriangleMesh, NamedParameters1>::type FaceIndexMap1;
typedef typename CGAL::GetInitializedFaceIndexMap<TriangleMesh, NamedParameters2>::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<TriangleMesh,
Vpm,
Vpm_out_tuple,
Fid_map,
FaceIndexMap1,
FaceIndexMap2,
Default,
Ecm_in,
Edge_mark_map_tuple,
@ -551,8 +545,7 @@ corefine_and_compute_boolean_operations(
TriangleMesh, Vpm, Ob, Ecm_in, User_visitor> 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<TriangleMesh,
NamedParameters>::type Vpm;
typedef typename GetVertexPointMap<TriangleMesh, NamedParameters>::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<TriangleMesh,
NamedParameters>::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<TriangleMesh, NamedParameters>::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,

View File

@ -138,11 +138,6 @@ detect_surface_patches(PolygonMesh& p,
EdgeIsFeatureMap eif,
const NamedParameters& np)
{
//extract types from NPs
typename GetFaceIndexMap<PolygonMesh, NamedParameters>::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<int>(
parameters::choose_parameter(parameters::get_parameter(np, internal_np::first_index),
1));
@ -150,11 +145,12 @@ detect_surface_patches(PolygonMesh& p,
internal::PatchIdMapWrapper<PatchIdMap,
typename boost::property_traits<PatchIdMap>::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 PolygonMesh, typename EdgeIsFeatureMap, typename PatchIdMap>
typename boost::graph_traits<PolygonMesh>::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

View File

@ -60,7 +60,8 @@ namespace params=PMP::parameters;
template <class TriangleMesh,
class VertexPointMap,
class VpmOutTuple,
class FaceIdMap,
class FaceIdMap1,
class FaceIdMap2,
class Kernel_=Default,
class EdgeMarkMapBind_ = Default,
class EdgeMarkMapTuple_ = Default,
@ -110,8 +111,10 @@ class Face_graph_output_builder
//Data members
TriangleMesh &tm1, &tm2;
// property maps of input meshes
const VertexPointMap &vpm1, &vpm2;
const FaceIdMap &fids1, &fids2;
const VertexPointMap vpm1;
const VertexPointMap vpm2;
FaceIdMap1 fids1;
FaceIdMap2 fids2;
EdgeMarkMapBind& marks_on_input_edges;
// property maps of output meshes
const VpmOutTuple& output_vpms;
@ -215,7 +218,7 @@ class Face_graph_output_builder
// detect if a polyline is incident to two patches that won't be imported
// for the current operation (polylines skipt are always incident to a
// coplanar patch)
template <class TM, class FIM>
template <class TM, class FIM1, class FIM2>
static
void fill_polylines_to_skip(
Intersection_polylines& polylines,
@ -223,8 +226,8 @@ class Face_graph_output_builder
const std::vector<std::size_t>& 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<TriangleMesh*>, 4 >& requested_output)
EdgeMarkMapTuple& out_edge_mark_maps,
UserVisitor& user_visitor,
const std::array<boost::optional<TriangleMesh*>, 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 <std::size_t> 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 <std::size_t> 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<TriangleMesh,
FaceIdMap,
Intersection_edge_map> Patches;
typedef Patch_container<TriangleMesh, FaceIdMap1, Intersection_edge_map> Patches1;
typedef Patch_container<TriangleMesh, FaceIdMap2, Intersection_edge_map> Patches2;
boost::unordered_set<vertex_descriptor> 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();

View File

@ -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<edge_descriptor> 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);

View File

@ -424,7 +424,7 @@ template <class PolygonMesh, class FaceIndexMap, class IsIntersectionEdge>
void extract_patch_simplices(
std::size_t patch_id,
PolygonMesh& pm,
const FaceIndexMap& fids,
const FaceIndexMap fids,
const std::vector<std::size_t>& patch_ids,
std::vector<typename boost::graph_traits<PolygonMesh>::face_descriptor>& patch_faces,
std::set<typename boost::graph_traits<PolygonMesh>::vertex_descriptor>& interior_vertices,
@ -480,13 +480,13 @@ struct Patch_container{
// external data members
PolygonMesh& pm;
const std::vector<std::size_t>& patch_ids;
const FaceIndexMap& fids;
const FaceIndexMap fids;
const IsIntersectionEdge& is_intersection_edge;
// constructor
Patch_container(
PolygonMesh& pm,
const std::vector<std::size_t>& 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 <class TriangleMesh,
class PatchContainer,
class PatchContainer1,
class PatchContainer2,
class IntersectionPolylines,
class EdgeMap,
class VertexPointMap,
@ -1269,8 +1271,8 @@ void compute_inplace_operation_delay_removal_and_insideout(
TriangleMesh& tm2,
const boost::dynamic_bitset<>& 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 <class TriangleMesh,
class PatchContainer,
class PatchContainer1,
class PatchContainer2,
class VertexPointMap,
class EdgeMarkMapIn1,
class EdgeMarkMapIn2,
@ -1427,8 +1430,8 @@ void compute_inplace_operation(
const TriangleMesh& /*tm2*/,
const boost::dynamic_bitset<>& 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 <class TriangleMesh,
class IntersectionPolylines,
class PatchContainer,
class PatchContainer1,
class PatchContainer2,
class EdgeMap>
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<TriangleMesh> GT;
@ -1520,7 +1524,8 @@ void compute_border_edge_map(
template <class TriangleMesh,
class PatchContainer,
class PatchContainer1,
class PatchContainer2,
class IntersectionPolylines,
class VertexPointMap,
class EdgeMarkMapIn1,
@ -1532,8 +1537,8 @@ void compute_inplace_operation(
const TriangleMesh& tm2,
const boost::dynamic_bitset<>& 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,

View File

@ -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<class TriangleMesh, class NamedParameters>
void orient(TriangleMesh& tm, const NamedParameters& np)
void orient(TriangleMesh& tm,
const NamedParameters& np)
{
typedef boost::graph_traits<TriangleMesh> 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<TriangleMesh,
NamedParameters>::const_type Vpm;
typedef typename GetFaceIndexMap<TriangleMesh,
NamedParameters>::const_type Fid_map;
typedef boost::graph_traits<TriangleMesh> 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<TriangleMesh, NamedParameters>::const_type Vpm;
typedef typename GetInitializedFaceIndexMap<TriangleMesh, NamedParameters>::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<std::size_t> 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 <class TriangleMesh, class NamedParameters>
void orient_to_bound_a_volume(TriangleMesh& tm,
const NamedParameters& np)
const NamedParameters& np)
{
typedef boost::graph_traits<TriangleMesh> Graph_traits;
typedef typename Graph_traits::vertex_descriptor vertex_descriptor;
typedef typename GetVertexPointMap<TriangleMesh,
NamedParameters>::const_type Vpm;
typedef typename GetFaceIndexMap<TriangleMesh,
NamedParameters>::const_type Fid_map;
typedef typename Kernel_traits<
typename boost::property_traits<Vpm>::value_type >::Kernel Kernel;
typedef boost::graph_traits<TriangleMesh> Graph_traits;
typedef typename Graph_traits::vertex_descriptor vertex_descriptor;
typedef typename GetVertexPointMap<TriangleMesh, NamedParameters>::const_type Vpm;
typedef typename boost::property_traits<Vpm>::value_type Point;
typedef typename Kernel_traits<Point>::Kernel Kernel;
typedef typename GetInitializedFaceIndexMap<TriangleMesh, NamedParameters>::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<std::size_t> face_cc(num_faces(tm), std::size_t(-1));

View File

@ -41,9 +41,7 @@ namespace Polygon_mesh_processing {
* The descriptor types `boost::graph_traits<PolygonMesh>::%face_descriptor`
* and `boost::graph_traits<PolygonMesh>::%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<PolygonMesh>::%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<PM, NamedParameters>::type FIMap;
FIMap fimap = choose_parameter(get_parameter(np, internal_np::face_index),
get_property_map(face_index, pmesh));
typedef typename GetInitializedFaceIndexMap<PolygonMesh, NamedParameters>::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<PM, NamedParameters>::type FIMap;
FIMap fimap = choose_parameter(get_parameter(np, internal_np::face_index),
get_property_map(face_index, pmesh));
typedef typename GetInitializedFaceIndexMap<PolygonMesh, NamedParameters>::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,

View File

@ -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<TriangleMesh, NamedParameters>::type FaceIndexMap;
FaceIndexMap fim = choose_parameter(get_parameter(np, internal_np::face_index),
get_property_map(boost::face_index, tmesh));
typedef typename GetInitializedFaceIndexMap<TriangleMesh, NamedParameters>::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));

View File

@ -185,10 +185,8 @@ collect_duplicated_stitchable_boundary_edges
if(per_cc)
{
cc = get(Face_property_tag(), pmesh);
typedef typename GetFaceIndexMap<PM, CGAL_PMP_NP_CLASS>::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.

View File

@ -537,11 +537,8 @@ public:
std::vector<std::size_t> cc_ids(num_faces(tm));
// face index map
typedef typename CGAL::GetFaceIndexMap<TriangleMesh, NamedParameters>::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<TriangleMesh, NamedParameters>::const_type FaceIndexMap;
FaceIndexMap fid_map = CGAL::get_initialized_face_index_map(tm, np);
std::size_t nb_cc =
Polygon_mesh_processing::connected_components(

View File

@ -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<int,
boost::property_map<Mesh_with_id, boost::face_index_t>::type>
fccmap(get(boost::face_index,sm));
boost::property_map<Mesh_with_id, CGAL::face_index_t>::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<Mesh,boost::vertex_external_index_t>::type vim
boost::property_map<Mesh,boost::vertex_external_index_t>::type vim
= get(boost::vertex_external_index,sm);
boost::property_map<Mesh,boost::face_external_index_t>::type fim
boost::property_map<Mesh,boost::face_external_index_t>::type fim
= get(boost::face_external_index,sm);
boost::vector_property_map<int,
boost::property_map<Mesh, boost::face_external_index_t>::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;

View File

@ -31,15 +31,21 @@ int main()
}
{
typedef CGAL::Polyhedron_3<Epic> P;
std::map<boost::graph_traits<P>::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<Epic> P;
std::ifstream in("data/elephant.off");
P p;
in >> p;
std::map<boost::graph_traits<P>::face_descriptor, std::size_t> fim;
std::size_t fid = 0;
for(const boost::graph_traits<P>::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;
}

View File

@ -1,5 +1,7 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/boost/graph/named_params_helper.h>
#include <CGAL/Polygon_mesh_processing/orientation.h>
#include <CGAL/Polygon_mesh_processing/corefinement.h>
@ -12,13 +14,13 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef CGAL::Surface_mesh<Kernel::Point_3> SMesh;
template<class TriangleMesh, class NamedParameters>
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<TriangleMesh> Graph_traits;
typedef typename Graph_traits::vertex_descriptor vertex_descriptor;
typedef typename Graph_traits::face_descriptor face_descriptor;
typedef typename CGAL::GetVertexPointMap<TriangleMesh, NamedParameters>::const_type Vpm;
typedef typename CGAL::GetFaceIndexMap<TriangleMesh, NamedParameters>::const_type Fid_map;
typedef typename CGAL::GetInitializedFaceIndexMap<TriangleMesh, NamedParameters>::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<std::size_t> face_cc(num_faces(tm), std::size_t(-1));
@ -127,5 +128,6 @@ int main()
return 1;
}
std::cout << "Done!" << std::endl;
return 0;
}

View File

@ -19,374 +19,458 @@ template <class TriangleMesh>
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<std::size_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<std::size_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<std::size_t>(), tm1)),
params::face_index_map(get(CGAL::dynamic_face_property_t<std::size_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<std::size_t>(), tm1)),
params::face_index_map(get(CGAL::dynamic_face_property_t<std::size_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<std::size_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<std::size_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<std::size_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<std::size_t>(), tm1)),
params::face_index_map(get(CGAL::dynamic_face_property_t<std::size_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<std::size_t>(), tm1)),
params::face_index_map(get(CGAL::dynamic_face_property_t<std::size_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<std::size_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<std::size_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<std::size_t>(), tm1)),
params::face_index_map(get(CGAL::dynamic_face_property_t<std::size_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<std::size_t>(), tm1)),
params::face_index_map(get(CGAL::dynamic_face_property_t<std::size_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<std::size_t>(), tm1)),
params::face_index_map(get(CGAL::dynamic_face_property_t<std::size_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<std::size_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<std::size_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<std::size_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<std::size_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<std::size_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<std::size_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<std::size_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<std::size_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<std::size_t>(), tm1)),
params::face_index_map(get(CGAL::dynamic_face_property_t<std::size_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<std::size_t>(), tm1)),
params::face_index_map(get(CGAL::dynamic_face_property_t<std::size_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<std::size_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<std::size_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<std::size_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<std::size_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<std::size_t>(), tm1)),
params::face_index_map(get(CGAL::dynamic_face_property_t<std::size_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<std::size_t>(), tm1)),
params::face_index_map(get(CGAL::dynamic_face_property_t<std::size_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<std::size_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<std::size_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<std::size_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<std::size_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<std::size_t>(), tm1)),
params::face_index_map(get(CGAL::dynamic_face_property_t<std::size_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<std::size_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<std::size_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<Surface_mesh>();
std::cout << "Polyhedron" << std::endl;
test<Polyhedron>();
return 0;
std::cout << "Done!" << std::endl;
return EXIT_SUCCESS;
}

View File

@ -13,11 +13,13 @@
#define CGAL_DYNAMIC_PROPERTY_MAP_H
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/properties.hpp>
#include <CGAL/boost/graph/properties.h>
#include <CGAL/property_map.h>
#include <boost/shared_ptr.hpp>
#include <boost/unordered_map.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/if.hpp>

View File

@ -16,10 +16,11 @@
#include <CGAL/disable_warnings.h>
#include <CGAL/assertions.h>
#include <CGAL/boost/graph/named_params_helper.h>
#include <CGAL/config.h>
#include <CGAL/Default.h>
#include <CGAL/tuple.h>
#include <CGAL/Polygon_mesh_processing/Weights.h>
#include <CGAL/Simple_cartesian.h>
@ -215,13 +216,9 @@ public:
// Index maps
#ifndef DOXYGEN_RUNNING
typedef typename Default::Get<
VIM,
typename boost::property_map<Triangle_mesh, boost::vertex_index_t>::type
>::type Vertex_index_map;
VIM, typename CGAL::GetInitializedVertexIndexMap<Triangle_mesh>::type>::type Vertex_index_map;
typedef typename Default::Get<
HIM,
typename boost::property_map<Triangle_mesh, boost::halfedge_index_t>::type
>::type Hedge_index_map;
HIM, typename CGAL::GetInitializedHalfedgeIndexMap<Triangle_mesh>::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<std::size_t>(num_vertices(triangle_mesh), (std::numeric_limits<std::size_t>::max)() )),
is_roi_map(std::vector<bool>(num_vertices(triangle_mesh), false)),
is_ctrl_map(std::vector<bool>(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<std::size_t>(num_vertices(triangle_mesh), (std::numeric_limits<std::size_t>::max)() )),
is_roi_map(std::vector<bool>(num_vertices(triangle_mesh), false)),
is_ctrl_map(std::vector<bool>(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<std::size_t>(num_vertices(triangle_mesh), (std::numeric_limits<std::size_t>::max)() )),
is_roi_map(std::vector<bool>(num_vertices(triangle_mesh), false)),
is_ctrl_map(std::vector<bool>(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<std::size_t>(num_vertices(triangle_mesh), (std::numeric_limits<std::size_t>::max)() )),
is_roi_map(std::vector<bool>(num_vertices(triangle_mesh), false)),
is_ctrl_map(std::vector<bool>(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<std::size_t>(num_vertices(triangle_mesh), (std::numeric_limits<std::size_t>::max)() )),
is_roi_map(std::vector<bool>(num_vertices(triangle_mesh), false)),
is_ctrl_map(std::vector<bool>(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

View File

@ -25,6 +25,7 @@
#include <CGAL/Surface_mesh_parameterization/Error_code.h>
#include <CGAL/Surface_mesh_parameterization/orbifold_shortest_path.h>
#include <CGAL/assertions.h>
#include <CGAL/Polygon_mesh_processing/Weights.h>
#include <CGAL/assertions.h>

View File

@ -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<class Traits,
@ -2199,7 +2199,7 @@ public:
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
*/
Surface_mesh_shortest_path(const Triangle_mesh& tm,
const Traits& traits = Traits())

View File

@ -16,17 +16,16 @@ the number of edges effectively removed.
@param np optional sequence of \ref sms_namedparameters "Named Parameters" among the ones listed below
\cgalNamedParamsBegin
\cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of the mesh.
If this parameter is omitted, an internal property map for
`CGAL::vertex_point_t` should be available in `TriangleMesh`.
\cgalParamBegin{vertex_point_map}
the property map with the points associated to the vertices of the mesh.
\cgalParamEnd
\cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `Kernel`,
compatible with the value type of the vertex point map.
\cgalParamEnd
\cgalParamBegin{halfedge_index_map} the property map containing an index for each halfedge,
initialized 0 to `num_halfedges(graph)`.
\cgalParamBegin{halfedge_index_map}
the property map containing for each halfedge of `surface_mesh` a unique index between `0` to `num_halfedges(graph)`.
\cgalParamEnd
\cgalParamBegin{get_cost}

View File

@ -42,7 +42,7 @@ int main(int argc, char** argv)
// The surface mesh and stop conditions are mandatory arguments.
// The index maps are needed because the vertices and edges
// of this surface mesh lack an "id()" field.
std::cout << "Collapsing edges of LCC: " << filename << ", aiming for " << edge_count_treshold << " final edges..." << std::endl;
std::cout << "Collapsing edges of Polyhedron: " << filename << ", aiming for " << edge_count_treshold << " final edges..." << std::endl;
int r = SMS::edge_collapse(surface_mesh, stop,
CGAL::parameters::vertex_index_map(get(CGAL::vertex_external_index, surface_mesh))
.halfedge_index_map(get(CGAL::halfedge_external_index, surface_mesh)));

View File

@ -92,12 +92,10 @@ int edge_collapse(TM& tmesh,
return internal::edge_collapse(tmesh, should_stop,
choose_parameter(get_parameter(np, internal_np::geom_traits),
Geom_traits()),
choose_parameter(get_parameter(np, internal_np::vertex_index),
get_const_property_map(boost::vertex_index, tmesh)),
CGAL::get_initialized_vertex_index_map(tmesh, np),
choose_parameter(get_parameter(np, internal_np::vertex_point),
get_property_map(vertex_point, tmesh)),
choose_parameter(get_parameter(np, internal_np::halfedge_index),
get_const_property_map(boost::halfedge_index, tmesh)),
CGAL::get_initialized_halfedge_index_map(tmesh, np),
choose_parameter(get_parameter(np, internal_np::edge_is_constrained),
No_constrained_edge_map<TM>()),
choose_parameter(get_parameter(np, internal_np::get_cost_policy),

View File

@ -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<int, 3> edge_ids;
};
} //namespace CGAL

View File

@ -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