Merge pull request #5863 from MaelRL/BGL-Fix_FFG_nonconst_index_pmaps-GF

Fix index maps for non-const Face_filtered_graph
This commit is contained in:
Laurent Rineau 2021-07-27 15:52:23 +02:00
commit 71175aad53
3 changed files with 234 additions and 150 deletions

View File

@ -28,6 +28,10 @@
#include <boost/range/has_range_iterator.hpp>
#include <boost/unordered_set.hpp>
#include <bitset>
#include <utility>
#include <vector>
#ifdef DOXYGEN_RUNNING
#define CGAL_BGL_NP_TEMPLATE_PARAMETERS NamedParameters
#define CGAL_BGL_NP_CLASS NamedParameters
@ -393,21 +397,68 @@ struct Face_filtered_graph
///returns a reference to the underlying graph.
Graph& graph(){ return _graph; }
///change the set of selected faces using a patch id
template<class FacePatchIndexMap>
void set_selected_faces(typename boost::property_traits<FacePatchIndexMap>::value_type face_patch_id,
FacePatchIndexMap face_patch_index_map)
// Handling of internal correspondency for index maps.
// The indices must be kept valid when the selection changes.
void initialize_face_indices() const
{
if(face_indices.empty())
{
face_index_type index = 0;
face_indices.resize(num_faces(_graph));
for(std::size_t i=selected_faces.find_first(); i<selected_faces.npos; i=selected_faces.find_next(i))
face_indices[i] = index++;
}
}
void initialize_vertex_indices() const
{
if(vertex_indices.empty())
{
vertex_index_type index = 0;
vertex_indices.resize(num_vertices(_graph));
for(std::size_t i=selected_vertices.find_first(); i<selected_vertices.npos; i=selected_vertices.find_next(i))
vertex_indices[i] = index++;
}
}
void initialize_halfedge_indices() const
{
if(halfedge_indices.empty())
{
halfedge_index_type index = 0;
halfedge_indices.resize(num_halfedges(_graph));
for(std::size_t i=selected_halfedges.find_first(); i<selected_halfedges.npos; i=selected_halfedges.find_next(i))
halfedge_indices[i] = index++;
}
}
void reset_indices()
{
face_indices.clear();
vertex_indices.clear();
halfedge_indices.clear();
if(is_imap_in_use.test(0))
initialize_face_indices();
if(is_imap_in_use.test(1))
initialize_vertex_indices();
if(is_imap_in_use.test(2))
initialize_halfedge_indices();
}
///change the set of selected faces using a patch id
template<class FacePatchIndexMap>
void set_selected_faces(typename boost::property_traits<FacePatchIndexMap>::value_type face_patch_id,
FacePatchIndexMap face_patch_index_map)
{
selected_faces.resize(num_faces(_graph));
selected_vertices.resize(num_vertices(_graph));
selected_halfedges.resize(num_halfedges(_graph));
selected_faces.reset();
selected_vertices.reset();
selected_halfedges.reset();
for(face_descriptor fd : faces(_graph) )
{
if(get(face_patch_index_map, fd) == face_patch_id)
@ -421,6 +472,8 @@ struct Face_filtered_graph
}
}
}
reset_indices();
}
/// change the set of selected faces using a range of patch ids
template<class FacePatchIndexRange, class FacePatchIndexMap>
@ -433,16 +486,14 @@ struct Face_filtered_graph
#endif
)
{
face_indices.clear();
vertex_indices.clear();
halfedge_indices.clear();
selected_faces.resize(num_faces(_graph));
selected_vertices.resize(num_vertices(_graph));
selected_halfedges.resize(num_halfedges(_graph));
selected_faces.reset();
selected_vertices.reset();
selected_halfedges.reset();
typedef typename boost::property_traits<FacePatchIndexMap>::value_type Patch_index;
boost::unordered_set<Patch_index> pids(boost::begin(selected_face_patch_indices),
boost::end(selected_face_patch_indices));
@ -460,21 +511,22 @@ struct Face_filtered_graph
}
}
}
reset_indices();
}
/// change the set of selected faces using a range of face descriptors
template<class FaceRange>
void set_selected_faces(const FaceRange& selection)
{
face_indices.clear();
vertex_indices.clear();
halfedge_indices.clear();
selected_faces.resize(num_faces(_graph));
selected_vertices.resize(num_vertices(_graph));
selected_halfedges.resize(num_halfedges(_graph));
selected_faces.reset();
selected_vertices.reset();
selected_halfedges.reset();
for(face_descriptor fd : selection)
{
selected_faces.set(get(fimap, fd));
@ -485,6 +537,8 @@ struct Face_filtered_graph
selected_vertices.set(get(vimap, target(hd, _graph)));
}
}
reset_indices();
}
struct Is_simplex_valid
@ -543,45 +597,27 @@ struct Face_filtered_graph
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())
{
face_index_type index = 0;
face_indices.resize(num_faces(_graph));
for (std::size_t i=selected_faces.find_first(); i < selected_faces.npos; i = selected_faces.find_next(i))
{
face_indices[i] = index++;
}
}
return bind_property_maps(fimap, make_property_map(face_indices) );
is_imap_in_use.set(0);
initialize_face_indices();
return bind_property_maps(fimap, make_property_map(face_indices));
}
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())
{
vertex_index_type index = 0;
vertex_indices.resize(num_vertices(_graph));
for (std::size_t i=selected_vertices.find_first(); i < selected_vertices.npos; i = selected_vertices.find_next(i))
{
vertex_indices[i] = index++;
}
}
is_imap_in_use.set(1);
initialize_vertex_indices();
return bind_property_maps(vimap, make_property_map(vertex_indices) );
}
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())
{
halfedge_index_type index = 0;
halfedge_indices.resize(num_halfedges(_graph));
for (std::size_t i=selected_halfedges.find_first(); i < selected_halfedges.npos; i = selected_halfedges.find_next(i))
{
halfedge_indices[i] = index++;
}
}
is_imap_in_use.set(2);
initialize_halfedge_indices();
return bind_property_maps(himap, make_property_map(halfedge_indices) );
}
@ -649,9 +685,11 @@ private:
boost::dynamic_bitset<> selected_faces;
boost::dynamic_bitset<> selected_vertices;
boost::dynamic_bitset<> selected_halfedges;
mutable std::vector<face_index_type> face_indices;
mutable std::vector<vertex_index_type> vertex_indices;
mutable std::vector<halfedge_index_type> halfedge_indices;
mutable std::bitset<3> is_imap_in_use; // one per descriptor type (face, vertex, halfedge)
};
} // namespace CGAL
@ -1206,40 +1244,6 @@ CGAL_FFG_DYNAMIC_PMAP_SPEC(dynamic_face_property_t)
#undef CGAL_FFG_DYNAMIC_PMAP_SPEC
//specializations for indices
template <class Graph,
typename FIMap,
typename VIMap,
typename HIMap>
typename boost::property_map<Face_filtered_graph<Graph, FIMap, VIMap, HIMap>, CGAL::face_index_t >::type
get(CGAL::face_index_t, const Face_filtered_graph<Graph, FIMap, VIMap, HIMap>& w)
{
return w.get_face_index_map();
}
template <class Graph,
typename FIMap,
typename VIMap,
typename HIMap>
typename boost::property_map<Face_filtered_graph<Graph, FIMap, VIMap, HIMap>, boost::vertex_index_t >::type
get(boost::vertex_index_t, const Face_filtered_graph<Graph, FIMap, VIMap, HIMap>& w)
{
return w.get_vertex_index_map();
}
template <class Graph,
typename FIMap,
typename VIMap,
typename HIMap>
typename boost::property_map<Face_filtered_graph<Graph, FIMap, VIMap, HIMap>, CGAL::halfedge_index_t >::type
get(CGAL::halfedge_index_t, const Face_filtered_graph<Graph, FIMap, VIMap, HIMap>& w)
{
return w.get_halfedge_index_map();
}
template <class Graph,
typename FIMap,
typename VIMap,
@ -1307,9 +1311,11 @@ CGAL_FILTERED_FACE_GRAPH_DYNAMIC_PMAP_SPECIALIZATION(dynamic_face_property_t)
//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>
struct property_map<CGAL::Face_filtered_graph<Graph, FIMap, VIMap, HIMap>, boost::face_index_t>
{
typedef typename CGAL::Face_filtered_graph<Graph, FIMap, VIMap, HIMap>::FIM FIM;
typedef CGAL::Face_filtered_graph<Graph, FIMap, VIMap, HIMap> FFG;
typedef typename FFG::FIM FIM;
typedef typename CGAL::Property_map_binder<FIM,
typename CGAL::Pointer_property_map<
typename boost::property_traits<FIM>::value_type>::type> type;
@ -1319,20 +1325,21 @@ struct property_map<CGAL::Face_filtered_graph<Graph, FIMap, VIMap, HIMap>, CGAL:
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 CGAL::Face_filtered_graph<Graph, FIMap, VIMap, HIMap> FFG;
typedef typename FFG::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>, CGAL::halfedge_index_t>
template<typename Graph, typename FIMap, typename VIMap, typename HIMap>
struct property_map<CGAL::Face_filtered_graph<Graph, FIMap, VIMap, HIMap>, boost::halfedge_index_t>
{
typedef typename CGAL::Face_filtered_graph<Graph, FIMap, VIMap, HIMap>::HIM HIM;
typedef CGAL::Face_filtered_graph<Graph, FIMap, VIMap, HIMap> FFG;
typedef typename FFG::HIM HIM;
typedef typename CGAL::Property_map_binder<HIM,
typename CGAL::Pointer_property_map<
typename boost::property_traits<HIM>::value_type>::type> type;
@ -1341,4 +1348,52 @@ struct property_map<CGAL::Face_filtered_graph<Graph, FIMap, VIMap, HIMap>, CGAL:
} // namespace boost
namespace CGAL {
//specializations for indices
template <class Graph, typename FIMap, typename VIMap, typename HIMap>
typename boost::property_map<Face_filtered_graph<Graph, FIMap, VIMap, HIMap>, boost::face_index_t >::const_type
get(boost::face_index_t, const Face_filtered_graph<Graph, FIMap, VIMap, HIMap>& w)
{
return w.get_face_index_map();
}
template <class Graph, typename FIMap, typename VIMap, typename HIMap>
typename boost::property_map<Face_filtered_graph<Graph, FIMap, VIMap, HIMap>, boost::vertex_index_t >::const_type
get(boost::vertex_index_t, const Face_filtered_graph<Graph, FIMap, VIMap, HIMap>& w)
{
return w.get_vertex_index_map();
}
template <class Graph, typename FIMap, typename VIMap, typename HIMap>
typename boost::property_map<Face_filtered_graph<Graph, FIMap, VIMap, HIMap>, boost::halfedge_index_t >::const_type
get(boost::halfedge_index_t, const Face_filtered_graph<Graph, FIMap, VIMap, HIMap>& w)
{
return w.get_halfedge_index_map();
}
// non-const
template <class Graph, typename FIMap, typename VIMap, typename HIMap>
typename boost::property_map<Face_filtered_graph<Graph, FIMap, VIMap, HIMap>, boost::face_index_t >::type
get(boost::face_index_t, Face_filtered_graph<Graph, FIMap, VIMap, HIMap>& w)
{
return w.get_face_index_map();
}
template <class Graph, typename FIMap, typename VIMap, typename HIMap>
typename boost::property_map<Face_filtered_graph<Graph, FIMap, VIMap, HIMap>, boost::vertex_index_t >::type
get(boost::vertex_index_t, Face_filtered_graph<Graph, FIMap, VIMap, HIMap>& w)
{
return w.get_vertex_index_map();
}
template <class Graph, typename FIMap, typename VIMap, typename HIMap>
typename boost::property_map<Face_filtered_graph<Graph, FIMap, VIMap, HIMap>, boost::halfedge_index_t >::type
get(boost::halfedge_index_t, Face_filtered_graph<Graph, FIMap, VIMap, HIMap>& w)
{
return w.get_halfedge_index_map();
}
} // namespace CGAL
#endif // CGAL_BOOST_GRAPH_FACE_FILTERED_GRAPH_H

View File

@ -1,15 +1,23 @@
#include <CGAL/boost/graph/Face_filtered_graph.h>
#include <CGAL/Polygon_mesh_processing/connected_components.h>
#include <CGAL/boost/graph/copy_face_graph.h>
#include <CGAL/boost/graph/Face_filtered_graph.h>
#include <CGAL/boost/graph/named_params_helper.h>
#include <CGAL/Polygon_mesh_processing/connected_components.h>
#include <CGAL/use.h>
#include "test_Prefix.h"
#include <boost/numeric/conversion/cast.hpp>
#include <boost/unordered_set.hpp>
#include <boost/unordered_map.hpp>
#include <CGAL/use.h>
#include <fstream>
#include <map>
#include <memory>
#include <utility>
typedef boost::unordered_set<std::size_t> id_map;
namespace PMP = CGAL::Polygon_mesh_processing;
template <typename Graph>
void test_halfedge_around_vertex_iterator(const Graph& g)
{
@ -17,8 +25,7 @@ void test_halfedge_around_vertex_iterator(const Graph& g)
typedef CGAL::Face_filtered_graph<Graph> Adapter;
CGAL_GRAPH_TRAITS_MEMBERS(Adapter);
boost::unordered_map<g_face_descriptor, std::size_t> map(num_faces(g));
CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default());
PMP::connected_components(g, boost::make_assoc_property_map(map), CGAL::parameters::all_default());
Adapter fg(g, 0, boost::make_assoc_property_map(map));
typename boost::graph_traits<Adapter >::vertex_iterator vit, vend;
@ -45,8 +52,9 @@ void test_halfedge_around_face_iterator(const Graph& g)
typedef CGAL::Face_filtered_graph<Graph> Adapter;
CGAL_GRAPH_TRAITS_MEMBERS(Adapter);
std::map<g_face_descriptor, std::size_t> map;
CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default());
PMP::connected_components(g, boost::make_assoc_property_map(map), CGAL::parameters::all_default());
Adapter fg(g, 0, boost::make_assoc_property_map(map));
face_iterator fit, fend;
for(boost::tie(fit, fend) = faces(fg); fit != fend; ++fit) {
halfedge_around_face_iterator hafit, hafend;
@ -65,7 +73,7 @@ void test_edge_iterators(const Graph& g)
typedef CGAL::Face_filtered_graph<Graph> Adapter;
CGAL_GRAPH_TRAITS_MEMBERS(Adapter);
std::map<g_face_descriptor, std::size_t> map;
CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default());
PMP::connected_components(g, boost::make_assoc_property_map(map), CGAL::parameters::all_default());
Adapter fg(g, 0, boost::make_assoc_property_map(map));
// do we iterate as many as that?
@ -91,7 +99,7 @@ void test_vertex_iterators(Graph& g)
typedef CGAL::Face_filtered_graph<Graph> Adapter;
CGAL_GRAPH_TRAITS_MEMBERS(Adapter);
std::map<g_face_descriptor, std::size_t> map;
CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default());
PMP::connected_components(g, boost::make_assoc_property_map(map), CGAL::parameters::all_default());
Adapter fg(g, 0, boost::make_assoc_property_map(map));
vertex_iterator vb, ve;
std::size_t count = 0;
@ -121,7 +129,7 @@ void test_out_edges(const Graph& g)
typedef CGAL::Face_filtered_graph<Graph> Adapter;
CGAL_GRAPH_TRAITS_MEMBERS(Adapter);
std::map<g_face_descriptor, std::size_t> map;
CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default());
PMP::connected_components(g, boost::make_assoc_property_map(map), CGAL::parameters::all_default());
Adapter fg(g, 0, boost::make_assoc_property_map(map));
vertex_iterator vb, ve;
@ -150,7 +158,7 @@ void test_in_edges(const Graph& g)
typedef CGAL::Face_filtered_graph<Graph> Adapter;
CGAL_GRAPH_TRAITS_MEMBERS(Adapter);
std::map<g_face_descriptor, std::size_t> map;
CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default());
PMP::connected_components(g, boost::make_assoc_property_map(map), CGAL::parameters::all_default());
Adapter fg(g, 0, boost::make_assoc_property_map(map));
vertex_iterator vb, ve;
@ -177,7 +185,7 @@ void test_in_out_edges(const Graph& g)
typedef CGAL::Face_filtered_graph<Graph> Adapter;
CGAL_GRAPH_TRAITS_MEMBERS(Adapter);
std::map<g_face_descriptor, std::size_t> map;
CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default());
PMP::connected_components(g, boost::make_assoc_property_map(map), CGAL::parameters::all_default());
Adapter fg(g, 0, boost::make_assoc_property_map(map));
// check that the sets of in out edges are the same
@ -219,7 +227,7 @@ void test_edge_find(const Graph& g)
typedef CGAL::Face_filtered_graph<Graph> Adapter;
CGAL_GRAPH_TRAITS_MEMBERS(Adapter);
std::map<g_face_descriptor, std::size_t> map;
CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default());
PMP::connected_components(g, boost::make_assoc_property_map(map), CGAL::parameters::all_default());
Adapter fg(g, 0, boost::make_assoc_property_map(map));
typedef std::pair<edge_descriptor, bool> ret;
@ -243,7 +251,7 @@ void test_faces(const Graph& g)
typedef CGAL::Face_filtered_graph<Graph> Adapter;
CGAL_GRAPH_TRAITS_MEMBERS(Adapter);
std::map<g_face_descriptor, std::size_t> map;
CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default());
PMP::connected_components(g, boost::make_assoc_property_map(map), CGAL::parameters::all_default());
Adapter fg(g, 0, boost::make_assoc_property_map(map));
unsigned int count = 0;
@ -262,6 +270,53 @@ void test_faces(const Graph& g)
assert(count == num_faces(fg));
}
template<typename Graph>
void test_index_property_maps(const Graph& g)
{
typedef CGAL::Face_filtered_graph<Graph> Adapter;
CGAL_GRAPH_TRAITS_MEMBERS(Adapter);
typedef typename boost::graph_traits<Graph>::face_descriptor g_face_descriptor;
std::map<g_face_descriptor, std::size_t> map;
PMP::connected_components(g, boost::make_assoc_property_map(map), CGAL::parameters::all_default());
Adapter fg(g, -1, boost::make_assoc_property_map(map));
assert(is_empty(fg));
// Non const
typedef typename CGAL::GetInitializedVertexIndexMap<Adapter>::type VIMap;
VIMap vim = CGAL::get_initialized_vertex_index_map(fg);
assert(CGAL::BGL::internal::is_index_map_valid(vim, num_vertices(fg), vertices(fg)));
typedef typename CGAL::GetInitializedHalfedgeIndexMap<Adapter>::type HIMap;
HIMap him = CGAL::get_initialized_halfedge_index_map(fg);
assert(CGAL::BGL::internal::is_index_map_valid(him, num_halfedges(fg), halfedges(fg)));
typedef typename CGAL::GetInitializedFaceIndexMap<Adapter>::type FIMap;
FIMap fim = CGAL::get_initialized_face_index_map(fg);
assert(CGAL::BGL::internal::is_index_map_valid(fim, num_faces(fg), faces(fg)));
fg.set_selected_faces(0, boost::make_assoc_property_map(map));
assert(!is_empty(fg));
assert(CGAL::BGL::internal::is_index_map_valid(vim, num_vertices(fg), vertices(fg)));
assert(CGAL::BGL::internal::is_index_map_valid(him, num_halfedges(fg), halfedges(fg)));
assert(CGAL::BGL::internal::is_index_map_valid(fim, num_faces(fg), faces(fg)));
// Const
const Adapter cfg(g, 0, boost::make_assoc_property_map(map));
typedef typename CGAL::GetInitializedVertexIndexMap<Adapter>::const_type CVIMap;
CVIMap cvim = CGAL::get_initialized_vertex_index_map(cfg);
assert(CGAL::BGL::internal::is_index_map_valid(cvim, num_vertices(cfg), vertices(cfg)));
typedef typename CGAL::GetInitializedHalfedgeIndexMap<Adapter>::const_type CHIMap;
CHIMap chim = CGAL::get_initialized_halfedge_index_map(cfg);
assert(CGAL::BGL::internal::is_index_map_valid(chim, num_halfedges(cfg), halfedges(cfg)));
typedef typename CGAL::GetInitializedFaceIndexMap<Adapter>::const_type CFIMap;
CFIMap cfim = CGAL::get_initialized_face_index_map(cfg);
assert(CGAL::BGL::internal::is_index_map_valid(cfim, num_faces(cfg), faces(cfg)));
}
template<typename Graph>
void test_read(const Graph& g)
{
@ -270,7 +325,7 @@ void test_read(const Graph& g)
CGAL_GRAPH_TRAITS_MEMBERS(Adapter);
std::map<g_face_descriptor, std::size_t> map;
CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default());
PMP::connected_components(g, boost::make_assoc_property_map(map), CGAL::parameters::all_default());
Adapter fg(g, 0, boost::make_assoc_property_map(map));
assert(fg.is_selection_valid());
assert(CGAL::is_valid_polygon_mesh(fg));
@ -292,6 +347,7 @@ test_graph_range(const std::vector<Graph>& graphs)
test_edge_iterators(p);
test_halfedge_around_face_iterator(p);
test_halfedge_around_vertex_iterator(p);
test_index_property_maps(p);
}
}
@ -356,7 +412,6 @@ struct Constraint : public boost::put_get_helper<bool,Constraint<Mesh, VertexPoi
template<class Mesh, class FCCMAP, class Adapter>
void test_mesh(Adapter fga)
{
CGAL_GRAPH_TRAITS_MEMBERS(Adapter);
//check that there is the right number of simplices in fga
CGAL_assertion(CGAL::is_valid_polygon_mesh(fga));
@ -365,31 +420,23 @@ void test_mesh(Adapter fga)
CGAL_assertion(num_halfedges(fga) == 10);
CGAL_assertion(num_vertices(fga) == 4);
halfedge_descriptor h = halfedge(*faces(fga).first, fga);
CGAL_assertion_code( vertex_descriptor v = source(h, fga) );
CGAL_assertion_code( vertex_descriptor v = source(h, fga));
//check that next() works inside the patch
CGAL_assertion(
next(next(next(h, fga), fga), fga) == h
);
CGAL_assertion(next(next(next(h, fga), fga), fga) == h);
//check that next() works on bordure of the patch
h = opposite(h, fga);
CGAL_assertion(
next(next(next(next(h, fga), fga), fga), fga) == h
);
CGAL_assertion(next(next(next(next(h, fga), fga), fga), fga) == h);
//check that prev() works inside the patch
h = halfedge(*faces(fga).first, fga);
CGAL_assertion(
prev(prev(prev(h, fga), fga), fga) == h
);
CGAL_assertion(prev(prev(prev(h, fga), fga), fga) == h);
//check that prev() works on bordure of the patch
h = opposite(h, fga);
CGAL_assertion(
prev(prev(prev(prev(h, fga), fga), fga), fga) == h
);
CGAL_assertion(prev(prev(prev(prev(h, fga), fga), fga), fga) == h);
//check degree
CGAL_assertion(degree(v, fga) == 3);
//check in_edges and out_edges
CGAL_assertion(std::distance(in_edges(v, fga).first ,in_edges(v, fga).second) == 3 );
CGAL_assertion(std::distance(out_edges(v, fga).first ,out_edges(v, fga).second) == 3 );
CGAL_assertion(std::distance(in_edges(v, fga).first ,in_edges(v, fga).second) == 3);
CGAL_assertion(std::distance(out_edges(v, fga).first ,out_edges(v, fga).second) == 3);
Mesh copy;
CGAL::copy_face_graph(fga, copy);
@ -454,7 +501,7 @@ int main()
{
test_graph_range(poly_data());
#if defined(CGAL_USE_SURFACE_MESH)
#ifdef CGAL_USE_SURFACE_MESH
test_graph_range(sm_data());
#endif
@ -464,64 +511,47 @@ int main()
test_invalid_selections();
//Make a tetrahedron and test the adapter for a patch that only contains 2 faces
// Make a tetrahedron and test the adapter for a patch that only contains 2 faces
typedef CGAL::Face_filtered_graph<SM> SM_Adapter;
typedef SM::Property_map<boost::graph_traits<SM>::face_descriptor , std::size_t> SM_FCCMap;
auto sm = std::make_unique<SM>();
CGAL::make_tetrahedron(
Point_3(1,1,1),
Point_3(0,0,0),
Point_3(0,0,1),
Point_3(1,0,1),
*sm);
SM_FCCMap fccmap =
sm->add_property_map<boost::graph_traits<SM>::face_descriptor, std::size_t>("f:CC").first;
SM::Property_map<boost::graph_traits<SM>::vertex_descriptor, SM::Point> positions =
sm->points();
CGAL::Polygon_mesh_processing::connected_components(*sm, fccmap, CGAL::Polygon_mesh_processing::parameters::
edge_is_constrained_map(Constraint<SM, SM::Property_map<boost::graph_traits<SM>::vertex_descriptor,
SM::Point> >(*sm, positions)));
CGAL::make_tetrahedron(Point_3(1,1,1), Point_3(0,0,0), Point_3(0,0,1), Point_3(1,0,1), *sm);
SM_FCCMap fccmap = sm->add_property_map<boost::graph_traits<SM>::face_descriptor, std::size_t>("f:CC").first;
SM::Property_map<boost::graph_traits<SM>::vertex_descriptor, SM::Point> positions = sm->points();
CGAL::Polygon_mesh_processing::connected_components(
*sm, fccmap, CGAL::parameters::edge_is_constrained_map(Constraint<SM, SM::Property_map<boost::graph_traits<SM>::vertex_descriptor,
SM::Point> >(*sm, positions)));
boost::unordered_set<long unsigned int> pids;
pids.insert(0);
pids.insert(2);
SM_Adapter sm_adapter(*sm, pids, fccmap);
test_mesh<SM,SM_FCCMap, SM_Adapter>(sm_adapter);
typedef boost::graph_traits<Polyhedron> PolyTraits;
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::associative_property_map<std::map<poly_face_descriptor, PolyTraits::faces_size_type> > FCMap;
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(
Point_3(1,1,1),
Point_3(0,0,0),
Point_3(0,0,1),
Point_3(1,0,1),
*poly);
auto poly = std::make_unique<Polyhedron>();
CGAL::make_tetrahedron(Point_3(1,1,1), Point_3(0,0,0), Point_3(0,0,1), Point_3(1,0,1), *poly);
FIMap poly_fimap = get(CGAL::face_external_index, *poly);
VIMap poly_vimap = get(CGAL::vertex_external_index, *poly);
HIMap poly_himap = get(CGAL::halfedge_external_index, *poly);
std::map<poly_face_descriptor,
PolyTraits::faces_size_type> fc_map;
std::map<poly_face_descriptor, PolyTraits::faces_size_type> fc_map;
FCMap poly_fccmap(fc_map);
VPMap vpmap = get(boost::vertex_point, *poly);
CGAL::Polygon_mesh_processing::connected_components(*poly, poly_fccmap,
CGAL::Polygon_mesh_processing::parameters::edge_is_constrained_map(Constraint<Polyhedron, VPMap >(*poly, vpmap))
.face_index_map(poly_fimap));
Poly_Adapter poly_adapter(*poly,
pids,
poly_fccmap,
PMP::connected_components(*poly, poly_fccmap,
CGAL::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));

View File

@ -2450,8 +2450,7 @@ QString Scene_polyhedron_selection_item::computeStats(int type)
// Extract the part n°0 of the partition into a new, independent mesh
if(selected_facets.size() == 0)
return QString("n/a");
boost::vector_property_map<int,
boost::property_map<SMesh, boost::face_index_t>::type>
boost::vector_property_map<int, boost::property_map<CGAL::Face_filtered_graph<SMesh>, boost::face_index_t>::type>
fccmap(get(boost::face_index, *d->filtered_graph));
return QString::number(CGAL::Polygon_mesh_processing::connected_components(*d->filtered_graph, fccmap));