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/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/graph/graph_traits.hpp>
#include <vector>
namespace CGAL {
@ -56,7 +58,7 @@ public:
: mesh(mesh_), vertices(vertices_), faces(nullptr)
{ }
void operator()(face_descriptor fd)
void operator()(const face_descriptor fd)
{
halfedge_descriptor hd = halfedge(fd, mesh);
for(vertex_descriptor vd : vertices_around_face(hd, mesh)) {
@ -78,10 +80,10 @@ struct Index_map_filler
: mesh(mesh), map(&map), index(0)
{ }
void operator()(const face_descriptor& fd)
void operator()(const face_descriptor fd)
{
for(vertex_descriptor vd : vertices_around_face(halfedge(fd, mesh), mesh))
{
for(vertex_descriptor vd :
vertices_around_face(halfedge(fd, mesh), mesh)) {
typename Map::iterator it;
bool new_element;
boost::tie(it,new_element) = map->insert(std::make_pair(vd,1));
@ -96,12 +98,47 @@ struct Index_map_filler
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 Surface_mesh_parameterization
} // namespace CGAL
#include <CGAL/enable_warnings.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/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/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/unordered_set.hpp>
#include <boost/unordered_map.hpp>
/// \file parameterize.h
@ -57,7 +48,7 @@ namespace Surface_mesh_parameterization {
/// \param mesh a triangulated surface.
/// \param parameterizer a parameterizer.
/// \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 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,
Parameterizer parameterizer,
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;
Indices indices;
CGAL::Polygon_mesh_processing::connected_component(
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);
typedef CGAL::dynamic_vertex_property_t<bool> Vertex_bool_tag;
typedef typename boost::property_map<TriangleMesh, Vertex_bool_tag>::type Vertex_bool_map;
Vertex_bool_map vpmap = get(Vertex_bool_tag(), mesh);
boost::unordered_set<vertex_descriptor> vs;
internal::Bool_property_map<boost::unordered_set<vertex_descriptor> > vpm(vs);
return parameterizer.parameterize(mesh, bhd, uvm, vipm, vpm);
return parameterizer.parameterize(mesh, bhd, uvmap, vimap, vpmap);
}
/// \ingroup PkgSurfaceMeshParameterizationMainFunction
@ -106,7 +92,7 @@ Error_code parameterize(TriangleMesh& mesh,
///
/// \param mesh a triangulated surface.
/// \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 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>
Error_code parameterize(TriangleMesh& mesh,
HD bhd,
VertexUVmap uvm)
VertexUVmap uvmap)
{
Mean_value_coordinates_parameterizer_3<TriangleMesh> parameterizer;
return parameterize(mesh, parameterizer, bhd, uvm);
return parameterize(mesh, parameterizer, bhd, uvmap);
}
} // namespace Surface_mesh_parameterization
} // namespace CGAL
#include <CGAL/enable_warnings.h>
#endif // CGAL_PARAMETERIZE_H

View File

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