Fix weight calculator initialization in Surface mesh deformation

This commit is contained in:
Mael Rouxel-Labbé 2022-10-20 17:28:42 +02:00
parent 91336eb213
commit 010e24f4ff
1 changed files with 110 additions and 142 deletions

View File

@ -55,49 +55,72 @@ enum Deformation_algorithm_tag
/// @cond CGAL_DOCUMENT_INTERNAL /// @cond CGAL_DOCUMENT_INTERNAL
namespace internal { namespace internal {
template<class TriangleMesh, Deformation_algorithm_tag deformation_algorithm_tag> // property map that create a Simple_cartesian<double>::Point_3
// on the fly in order the deformation class to be used
// with points with minimal requirements
template <class Vertex_point_map>
struct SC_on_the_fly_pmap
: public Vertex_point_map
{
typedef boost::readable_property_map_tag category;
typedef CGAL::Simple_cartesian<double>::Point_3 value_type;
typedef value_type reference;
typedef typename boost::property_traits<Vertex_point_map>::key_type key_type;
SC_on_the_fly_pmap(Vertex_point_map base):
Vertex_point_map(base) {}
friend value_type
get(const SC_on_the_fly_pmap map, key_type k)
{
typename boost::property_traits<Vertex_point_map>::reference base=
get(static_cast<const Vertex_point_map&>(map), k);
return value_type(base[0], base[1], base[2]);
}
};
template<typename TriangleMesh, typename VertexPointMap,
Deformation_algorithm_tag deformation_algorithm_tag>
struct Types_selectors; struct Types_selectors;
template<class TriangleMesh> template<typename TriangleMesh, typename VertexPointMap>
struct Types_selectors<TriangleMesh, CGAL::SPOKES_AND_RIMS> { struct Types_selectors<TriangleMesh, VertexPointMap, CGAL::SPOKES_AND_RIMS>
{
typedef SC_on_the_fly_pmap<VertexPointMap> Wrapped_VertexPointMap;
typedef CGAL::Weights::Single_cotangent_weight<TriangleMesh, Wrapped_VertexPointMap> Weight_calculator;
// Get weight from the weight interface. struct ARAP_visitor
typedef CGAL::Weights::Single_cotangent_weight<TriangleMesh> Weight_calculator; {
struct ARAP_visitor{
template <class VertexPointMap>
void init(TriangleMesh, VertexPointMap){} void init(TriangleMesh, VertexPointMap){}
void rotation_matrix_pre( void rotation_matrix_pre(typename boost::graph_traits<TriangleMesh>::vertex_descriptor,
typename boost::graph_traits<TriangleMesh>::vertex_descriptor,
TriangleMesh&){} TriangleMesh&){}
template <class Square_matrix_3> template <class Square_matrix_3>
void update_covariance_matrix( void update_covariance_matrix(Square_matrix_3&,
Square_matrix_3&,
const Square_matrix_3&){} const Square_matrix_3&){}
void set_sre_arap_alpha(double){} void set_sre_arap_alpha(double){}
}; };
}; };
template<class TriangleMesh> template<class TriangleMesh, typename VertexPointMap>
struct Types_selectors<TriangleMesh, CGAL::ORIGINAL_ARAP> { struct Types_selectors<TriangleMesh, VertexPointMap, CGAL::ORIGINAL_ARAP>
{
typedef SC_on_the_fly_pmap<VertexPointMap> Wrapped_VertexPointMap;
typedef CGAL::Weights::Cotangent_weight<TriangleMesh, Wrapped_VertexPointMap> Weight_calculator;
// Get weight from the weight interface. typedef typename Types_selectors<TriangleMesh, VertexPointMap, CGAL::SPOKES_AND_RIMS>::ARAP_visitor ARAP_visitor;
typedef CGAL::Weights::Cotangent_weight<TriangleMesh> Weight_calculator;
typedef typename Types_selectors<TriangleMesh, CGAL::SPOKES_AND_RIMS>
::ARAP_visitor ARAP_visitor;
}; };
template<class TriangleMesh> template<class TriangleMesh, typename VertexPointMap>
struct Types_selectors<TriangleMesh, CGAL::SRE_ARAP> { struct Types_selectors<TriangleMesh, VertexPointMap, CGAL::SRE_ARAP>
{
typedef SC_on_the_fly_pmap<VertexPointMap> Wrapped_VertexPointMap;
typedef CGAL::Weights::Cotangent_weight<TriangleMesh, Wrapped_VertexPointMap> Weight_calculator;
// Get weight from the weight interface. class ARAP_visitor
typedef CGAL::Weights::Cotangent_weight<TriangleMesh> Weight_calculator; {
class ARAP_visitor{
double m_nb_edges_incident; double m_nb_edges_incident;
double m_area; double m_area;
double m_alpha; double m_alpha;
@ -105,7 +128,6 @@ struct Types_selectors<TriangleMesh, CGAL::SRE_ARAP> {
public: public:
ARAP_visitor(): m_alpha(0.02) {} ARAP_visitor(): m_alpha(0.02) {}
template<class VertexPointMap>
void init(TriangleMesh triangle_mesh, const VertexPointMap& vpmap) void init(TriangleMesh triangle_mesh, const VertexPointMap& vpmap)
{ {
// calculate area // calculate area
@ -144,31 +166,6 @@ struct Types_selectors<TriangleMesh, CGAL::SRE_ARAP> {
}; };
}; };
// property map that create a Simple_cartesian<double>::Point_3
// on the fly in order the deformation class to be used
// with points with minimal requirements
template <class Vertex_point_map>
struct SC_on_the_fly_pmap
: public Vertex_point_map
{
typedef boost::readable_property_map_tag category;
typedef CGAL::Simple_cartesian<double>::Point_3 value_type;
typedef value_type reference;
typedef typename boost::property_traits<Vertex_point_map>::key_type key_type;
SC_on_the_fly_pmap(Vertex_point_map base):
Vertex_point_map(base) {}
friend value_type
get(const SC_on_the_fly_pmap map, key_type k)
{
typename boost::property_traits<Vertex_point_map>::reference base=
get(static_cast<const Vertex_point_map&>(map), k);
return value_type(base[0], base[1], base[2]);
}
};
}//namespace internal }//namespace internal
/// @endcond /// @endcond
@ -235,17 +232,6 @@ public:
typedef HIM Hedge_index_map; typedef HIM Hedge_index_map;
#endif #endif
// weight calculator
#ifndef DOXYGEN_RUNNING
typedef typename Default::Get<
WC,
typename internal::Types_selectors<TM, TAG>::Weight_calculator
>::type Weight_calculator;
#else
/// weight calculator functor type
typedef WC Weight_calculator;
#endif
// sparse linear solver // sparse linear solver
#ifndef DOXYGEN_RUNNING #ifndef DOXYGEN_RUNNING
typedef typename Default::Get< typedef typename Default::Get<
@ -290,6 +276,17 @@ public:
typedef VPM Vertex_point_map; typedef VPM Vertex_point_map;
#endif #endif
// weight calculator
#ifndef DOXYGEN_RUNNING
typedef typename Default::Get<
WC,
typename internal::Types_selectors<Triangle_mesh, Vertex_point_map, TAG>::Weight_calculator
>::type Weight_calculator;
#else
/// weight calculator functor type
typedef WC Weight_calculator;
#endif
/// The type for vertex descriptor /// The type for vertex descriptor
typedef typename boost::graph_traits<Triangle_mesh>::vertex_descriptor vertex_descriptor; typedef typename boost::graph_traits<Triangle_mesh>::vertex_descriptor vertex_descriptor;
/// The type for halfedge descriptor /// The type for halfedge descriptor
@ -304,8 +301,6 @@ public:
private: private:
typedef Surface_mesh_deformation<TM, VIM, HIM, TAG, WC, ST, CR> Self; typedef Surface_mesh_deformation<TM, VIM, HIM, TAG, WC, ST, CR> Self;
// Repeat Triangle_mesh types // Repeat Triangle_mesh types
typedef typename boost::graph_traits<Triangle_mesh>::vertex_iterator vertex_iterator;
typedef typename boost::graph_traits<Triangle_mesh>::halfedge_iterator halfedge_iterator;
typedef typename boost::graph_traits<Triangle_mesh>::in_edge_iterator in_edge_iterator; typedef typename boost::graph_traits<Triangle_mesh>::in_edge_iterator in_edge_iterator;
typedef typename boost::graph_traits<Triangle_mesh>::out_edge_iterator out_edge_iterator; typedef typename boost::graph_traits<Triangle_mesh>::out_edge_iterator out_edge_iterator;
@ -340,12 +335,11 @@ private:
bool last_preprocess_successful; ///< stores the result of last call to preprocess() bool last_preprocess_successful; ///< stores the result of last call to preprocess()
Vertex_point_map vertex_point_map;
Weight_calculator weight_calculator; Weight_calculator weight_calculator;
Vertex_point_map vertex_point_map;
public: public:
typename internal::Types_selectors<TM, TAG>::ARAP_visitor arap_visitor; typename internal::Types_selectors<Triangle_mesh, Vertex_point_map, TAG>::ARAP_visitor arap_visitor;
private: private:
#ifdef CGAL_DEFORM_MESH_USE_EXPERIMENTAL_SCALE #ifdef CGAL_DEFORM_MESH_USE_EXPERIMENTAL_SCALE
@ -359,68 +353,13 @@ public:
public: public:
/// \cond SKIP_FROM_MANUAL /// \cond SKIP_FROM_MANUAL
//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),
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(get(vertex_point, triangle_mesh))
{
init();
}
//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(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)),
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(get(vertex_point, triangle_mesh))
{
init();
}
//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(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)),
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(get(vertex_point, triangle_mesh))
{
init();
}
// Constructor with all the parameters provided // Constructor with all the parameters provided
Surface_mesh_deformation(Triangle_mesh& triangle_mesh, Surface_mesh_deformation(Triangle_mesh& triangle_mesh,
Vertex_index_map vertex_index_map, Vertex_index_map vertex_index_map,
Hedge_index_map hedge_index_map, Hedge_index_map hedge_index_map,
Vertex_point_map vertex_point_map, Vertex_point_map vertex_point_map,
Weight_calculator weight_calculator = Weight_calculator()) Weight_calculator weight_calculator)
: m_triangle_mesh(triangle_mesh), : m_triangle_mesh(triangle_mesh),
vertex_index_map(vertex_index_map), vertex_index_map(vertex_index_map),
hedge_index_map(hedge_index_map), hedge_index_map(hedge_index_map),
@ -431,12 +370,46 @@ public:
need_preprocess_factorization(true), need_preprocess_factorization(true),
need_preprocess_region_of_solution(true), need_preprocess_region_of_solution(true),
last_preprocess_successful(false), last_preprocess_successful(false),
weight_calculator(weight_calculator), vertex_point_map(vertex_point_map),
vertex_point_map(vertex_point_map) weight_calculator(weight_calculator)
{ {
init(); init();
} }
Surface_mesh_deformation(Triangle_mesh& triangle_mesh,
Vertex_index_map vertex_index_map,
Hedge_index_map hedge_index_map,
Vertex_point_map vertex_point_map)
: Surface_mesh_deformation(triangle_mesh,
vertex_index_map,
hedge_index_map,
vertex_point_map,
Weight_calculator(triangle_mesh, internal::SC_on_the_fly_pmap<Vertex_point_map>(vertex_point_map)))
{ }
Surface_mesh_deformation(Triangle_mesh& triangle_mesh,
Vertex_index_map vertex_index_map,
Hedge_index_map hedge_index_map)
: Surface_mesh_deformation(triangle_mesh,
vertex_index_map,
hedge_index_map,
get(vertex_point, triangle_mesh))
{ }
Surface_mesh_deformation(Triangle_mesh& triangle_mesh,
Vertex_index_map vertex_index_map)
: Surface_mesh_deformation(triangle_mesh,
vertex_index_map,
CGAL::get_initialized_halfedge_index_map(triangle_mesh))
{ }
Surface_mesh_deformation(Triangle_mesh& triangle_mesh)
: Surface_mesh_deformation(triangle_mesh,
CGAL::get_initialized_vertex_index_map(triangle_mesh))
{ }
/// \endcond /// \endcond
#if DOXYGEN_RUNNING #if DOXYGEN_RUNNING
/// \name Construction /// \name Construction
/// @{ /// @{
@ -457,21 +430,17 @@ public:
Vertex_index_map vertex_index_map = unspecified_internal_vertex_index_map, Vertex_index_map vertex_index_map = unspecified_internal_vertex_index_map,
Hedge_index_map hedge_index_map = unspecified_internal_halfedge_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), Vertex_point_map vertex_point_map = get(boost::vertex_point, triangle_mesh),
Weight_calculator weight_calculator = Weight_calculator()); Weight_calculator weight_calculator = Weight_calculator(triangle_mesh, vertex_point_map));
/// @} /// @}
#endif #endif
private: private:
void init() { void init()
typedef internal::SC_on_the_fly_pmap<Vertex_point_map> Wrapper;
// compute halfedge weights
halfedge_iterator eb, ee;
hedge_weight.reserve(2*num_edges(m_triangle_mesh));
for(std::tie(eb, ee) = halfedges(m_triangle_mesh); eb != ee; ++eb)
{ {
hedge_weight.push_back( hedge_weight.reserve(num_halfedges(m_triangle_mesh));
this->weight_calculator(*eb, m_triangle_mesh, Wrapper(vertex_point_map))); for(halfedge_descriptor he : halfedges(m_triangle_mesh))
} hedge_weight.push_back(this->weight_calculator(he));
arap_visitor.init(m_triangle_mesh, vertex_point_map); arap_visitor.init(m_triangle_mesh, vertex_point_map);
} }
@ -854,7 +823,6 @@ public:
*/ */
void overwrite_initial_geometry() void overwrite_initial_geometry()
{ {
typedef internal::SC_on_the_fly_pmap<Vertex_point_map> Wrapper;
if(roi.empty()) { return; } // no ROI to overwrite if(roi.empty()) { return; } // no ROI to overwrite
region_of_solution(); // the roi should be preprocessed since we are using original_position vec region_of_solution(); // the roi should be preprocessed since we are using original_position vec
@ -875,13 +843,13 @@ public:
std::size_t id_e = id(he); std::size_t id_e = id(he);
if(is_weight_computed[id_e]) { continue; } if(is_weight_computed[id_e]) { continue; }
hedge_weight[id_e] = weight_calculator(he, m_triangle_mesh, Wrapper(vertex_point_map)); hedge_weight[id_e] = weight_calculator(he);
is_weight_computed[id_e] = true; is_weight_computed[id_e] = true;
halfedge_descriptor e_opp = opposite(he, m_triangle_mesh); halfedge_descriptor e_opp = opposite(he, m_triangle_mesh);
std::size_t id_e_opp = id(e_opp); std::size_t id_e_opp = id(e_opp);
hedge_weight[id_e_opp] = weight_calculator(e_opp, m_triangle_mesh, Wrapper(vertex_point_map)); hedge_weight[id_e_opp] = weight_calculator(e_opp);
is_weight_computed[id_e_opp] = true; is_weight_computed[id_e_opp] = true;
} }
} }