Rework vertex-index/bool maps in SMP to use dynamic properties rather than sets

This commit is contained in:
Mael Rouxel-Labbé 2020-07-07 16:04:47 +02:00
parent 87bb4d1d28
commit c9279b6e4b
3 changed files with 65 additions and 46 deletions

View File

@ -14,11 +14,13 @@
#include <CGAL/license/Surface_mesh_parameterization.h> #include <CGAL/license/Surface_mesh_parameterization.h>
#include <CGAL/disable_warnings.h> #include <CGAL/boost/graph/internal/initialized_index_maps_helpers.h>
#include <CGAL/Polygon_mesh_processing/connected_components.h>
#include "boost/tuple/tuple.hpp" #include <boost/tuple/tuple.hpp>
#include <boost/unordered_set.hpp> #include <boost/unordered_set.hpp>
#include <boost/graph/graph_traits.hpp> #include <boost/graph/graph_traits.hpp>
#include <vector> #include <vector>
namespace CGAL { namespace CGAL {
@ -56,7 +58,7 @@ public:
: mesh(mesh_), vertices(vertices_), faces(nullptr) : mesh(mesh_), vertices(vertices_), faces(nullptr)
{ } { }
void operator()(face_descriptor fd) void operator()(const face_descriptor fd)
{ {
halfedge_descriptor hd = halfedge(fd, mesh); halfedge_descriptor hd = halfedge(fd, mesh);
for(vertex_descriptor vd : vertices_around_face(hd, mesh)) { for(vertex_descriptor vd : vertices_around_face(hd, mesh)) {
@ -78,10 +80,10 @@ struct Index_map_filler
: mesh(mesh), map(&map), index(0) : mesh(mesh), map(&map), index(0)
{ } { }
void operator()(const face_descriptor& fd) void operator()(const face_descriptor fd)
{ {
for(vertex_descriptor vd : for(vertex_descriptor vd : vertices_around_face(halfedge(fd, mesh), mesh))
vertices_around_face(halfedge(fd, mesh), mesh)) { {
typename Map::iterator it; typename Map::iterator it;
bool new_element; bool new_element;
boost::tie(it,new_element) = map->insert(std::make_pair(vd,1)); boost::tie(it,new_element) = map->insert(std::make_pair(vd,1));
@ -96,12 +98,47 @@ struct Index_map_filler
int index; int index;
}; };
template <typename TriangleMesh, typename VertexIndexMap>
void fill_index_map_of_cc(const typename boost::graph_traits<TriangleMesh>::halfedge_descriptor bhd,
const TriangleMesh& mesh,
VertexIndexMap vimap)
{
namespace PMP = CGAL::Polygon_mesh_processing;
typedef typename boost::graph_traits<TriangleMesh>::vertex_descriptor vertex_descriptor;
typedef typename boost::graph_traits<TriangleMesh>::face_descriptor face_descriptor;
std::vector<face_descriptor> CC_faces;
// 'reserve' might cause a huge amount of memory to be used for a tiny CC,
// but if this is a problem as a user, one could simply parameterize a Face_filtered_graph instead.
CC_faces.reserve(num_faces(mesh));
PMP::connected_component(face(opposite(bhd, mesh), mesh), mesh, std::back_inserter(CC_faces));
// If all vertices are involved, avoid walking all the faces
if(CC_faces.size() == faces(mesh).size())
{
BGL::internal::Index_map_initializer<VertexIndexMap, TriangleMesh> id_initializer;
id_initializer(CGAL::internal_np::vertex_index, vimap, mesh);
}
else
{
for(vertex_descriptor v : vertices(mesh))
put(vimap, v, -1);
int index = 0;
for(face_descriptor f : CC_faces)
for(vertex_descriptor v : vertices_around_face(halfedge(f, mesh), mesh))
if(get(vimap, v) == -1)
put(vimap, v, index++);
}
}
} // namespace internal } // namespace internal
} // namespace Surface_mesh_parameterization } // namespace Surface_mesh_parameterization
} // namespace CGAL } // namespace CGAL
#include <CGAL/enable_warnings.h>
#endif // CGAL_SURFACE_MESH_PARAMETERIZATION_INTERNAL_CONTAINERS_FILLER_H #endif // CGAL_SURFACE_MESH_PARAMETERIZATION_INTERNAL_CONTAINERS_FILLER_H

View File

@ -15,19 +15,10 @@
#include <CGAL/license/Surface_mesh_parameterization.h> #include <CGAL/license/Surface_mesh_parameterization.h>
#include <CGAL/disable_warnings.h>
#include <CGAL/Surface_mesh_parameterization/internal/Bool_property_map.h>
#include <CGAL/Surface_mesh_parameterization/Error_code.h> #include <CGAL/Surface_mesh_parameterization/Error_code.h>
#include <CGAL/Surface_mesh_parameterization/Mean_value_coordinates_parameterizer_3.h> #include <CGAL/Surface_mesh_parameterization/Mean_value_coordinates_parameterizer_3.h>
#include <CGAL/Polygon_mesh_processing/connected_components.h>
#include <boost/function_output_iterator.hpp>
#include <boost/property_map/property_map.hpp> #include <boost/property_map/property_map.hpp>
#include <boost/unordered_set.hpp>
#include <boost/unordered_map.hpp>
/// \file parameterize.h /// \file parameterize.h
@ -57,7 +48,7 @@ namespace Surface_mesh_parameterization {
/// \param mesh a triangulated surface. /// \param mesh a triangulated surface.
/// \param parameterizer a parameterizer. /// \param parameterizer a parameterizer.
/// \param bhd a halfedge descriptor on the boundary of `mesh`. /// \param bhd a halfedge descriptor on the boundary of `mesh`.
/// \param uvm an instanciation of the class `VertexUVmap`. /// \param uvmap an instanciation of the class `VertexUVmap`.
/// ///
/// \pre `mesh` must be a triangular mesh. /// \pre `mesh` must be a triangular mesh.
/// \pre The mesh border must be mapped onto a convex polygon /// \pre The mesh border must be mapped onto a convex polygon
@ -68,23 +59,18 @@ template <class TriangleMesh, class Parameterizer, class HD, class VertexUVmap>
Error_code parameterize(TriangleMesh& mesh, Error_code parameterize(TriangleMesh& mesh,
Parameterizer parameterizer, Parameterizer parameterizer,
HD bhd, HD bhd,
VertexUVmap uvm) VertexUVmap uvmap)
{ {
typedef typename boost::graph_traits<TriangleMesh>::vertex_descriptor vertex_descriptor; typedef CGAL::dynamic_vertex_property_t<int> Vertex_int_tag;
typedef typename boost::property_map<TriangleMesh, Vertex_int_tag>::type Vertex_int_map;
Vertex_int_map vimap = get(Vertex_int_tag(), mesh);
internal::fill_index_map_of_cc(bhd, mesh, vimap);
typedef boost::unordered_map<vertex_descriptor, int> Indices; typedef CGAL::dynamic_vertex_property_t<bool> Vertex_bool_tag;
Indices indices; typedef typename boost::property_map<TriangleMesh, Vertex_bool_tag>::type Vertex_bool_map;
CGAL::Polygon_mesh_processing::connected_component( Vertex_bool_map vpmap = get(Vertex_bool_tag(), mesh);
face(opposite(bhd, mesh), mesh),
mesh,
boost::make_function_output_iterator(
internal::Index_map_filler<TriangleMesh, Indices>(mesh, indices)));
boost::associative_property_map<Indices> vipm(indices);
boost::unordered_set<vertex_descriptor> vs; return parameterizer.parameterize(mesh, bhd, uvmap, vimap, vpmap);
internal::Bool_property_map<boost::unordered_set<vertex_descriptor> > vpm(vs);
return parameterizer.parameterize(mesh, bhd, uvm, vipm, vpm);
} }
/// \ingroup PkgSurfaceMeshParameterizationMainFunction /// \ingroup PkgSurfaceMeshParameterizationMainFunction
@ -106,7 +92,7 @@ Error_code parameterize(TriangleMesh& mesh,
/// ///
/// \param mesh a triangulated surface. /// \param mesh a triangulated surface.
/// \param bhd a halfedge descriptor on the boundary of `mesh`. /// \param bhd a halfedge descriptor on the boundary of `mesh`.
/// \param uvm an instanciation of the class `VertexUVmap`. /// \param uvmap an instanciation of the class `VertexUVmap`.
/// ///
/// \pre `mesh` must be a triangular mesh. /// \pre `mesh` must be a triangular mesh.
/// \pre The vertices must be indexed (vimap must be initialized). /// \pre The vertices must be indexed (vimap must be initialized).
@ -114,16 +100,14 @@ Error_code parameterize(TriangleMesh& mesh,
template <class TriangleMesh, class HD, class VertexUVmap> template <class TriangleMesh, class HD, class VertexUVmap>
Error_code parameterize(TriangleMesh& mesh, Error_code parameterize(TriangleMesh& mesh,
HD bhd, HD bhd,
VertexUVmap uvm) VertexUVmap uvmap)
{ {
Mean_value_coordinates_parameterizer_3<TriangleMesh> parameterizer; Mean_value_coordinates_parameterizer_3<TriangleMesh> parameterizer;
return parameterize(mesh, parameterizer, bhd, uvm); return parameterize(mesh, parameterizer, bhd, uvmap);
} }
} // namespace Surface_mesh_parameterization } // namespace Surface_mesh_parameterization
} // namespace CGAL } // namespace CGAL
#include <CGAL/enable_warnings.h>
#endif // CGAL_PARAMETERIZE_H #endif // CGAL_PARAMETERIZE_H

View File

@ -143,17 +143,15 @@ int main(int, char**)
boost::hash<PM_vertex_descriptor> > > uvpm(uvhm); boost::hash<PM_vertex_descriptor> > > uvpm(uvhm);
// Indices map // Indices map
typedef boost::unordered_map<PM_vertex_descriptor, int> Indices; typedef CGAL::dynamic_vertex_property_t<int> Vertex_int_tag;
Indices indices; typedef typename boost::property_map<PMesh, Vertex_int_tag>::type Vertex_int_map;
PMP::connected_component(face(opposite(hd, pm), pm), pm, Vertex_int_map vipm = get(Vertex_int_tag(), pm);
boost::make_function_output_iterator( CGAL::Surface_mesh_parameterization::internal::fill_index_map_of_cc(hd, pm, vipm);
SMP::internal::Index_map_filler<PMesh, Indices>(pm, indices)));
boost::associative_property_map<Indices> vipm(indices);
// Vertex parameterized map // Vertex parameterized map
boost::unordered_set<PM_vertex_descriptor> vs; typedef CGAL::dynamic_vertex_property_t<bool> Vertex_bool_tag;
SMP::internal::Bool_property_map<boost::unordered_set<PM_vertex_descriptor> > vpm(vs); typedef typename boost::property_map<PMesh, Vertex_bool_tag>::type Vertex_bool_map;
Vertex_bool_map vpm = get(Vertex_bool_tag(), pm);
// Parameterizer // Parameterizer
SMP::ARAP_parameterizer_3<PMesh> parameterizer; SMP::ARAP_parameterizer_3<PMesh> parameterizer;