diff --git a/Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/GarlandHeckbert_composed_policies.h b/Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/GarlandHeckbert_composed_policies.h new file mode 100644 index 00000000000..2dddb8f0b2a --- /dev/null +++ b/Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/GarlandHeckbert_composed_policies.h @@ -0,0 +1,130 @@ +// Copyright (c) 2025 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// Author(s) : Leo Valque + +#ifndef CGAL_SURFACE_MESH_SIMPLIFICATION_POLICIES_GARLANDHECKBERT_COMPOSED_POLICIES_H +#define CGAL_SURFACE_MESH_SIMPLIFICATION_POLICIES_GARLANDHECKBERT_COMPOSED_POLICIES_H + +#include + +#include +#include +#include + +namespace CGAL { +namespace Surface_mesh_simplification { +namespace internal { + +template +class Composed_quadric_calculator +{ + typedef typename GarlandHeckbert_matrix_types::Mat_4 Mat_4; + typedef typename GarlandHeckbert_matrix_types::Col_4 Col_4; + typedef typename GarlandHeckbert_matrix_types::Row_4 Row_4; + + Quadric_calculator_1 quadric_calculator_1; + Quadric_calculator_2 quadric_calculator_2; + double weight_1; + double weight_2; + +public: + Composed_quadric_calculator(Quadric_calculator_1 &&qc1, Quadric_calculator_2 &&qc2, double w1=1., double w2=1.): + quadric_calculator_1(qc1), quadric_calculator_2(qc2), weight_1(w1), weight_2(w2){} + Composed_quadric_calculator(double w1=1., double w2=1.): weight_1(w1), weight_2(w2){} + + template + Mat_4 construct_quadric_from_vertex(typename boost::graph_traits::vertex_descriptor v, + const TriangleMesh& tmesh, + const VertexPointMap point_map, + const GeomTraits& gt) const + { + return weight_1 * quadric_calculator_1.construct_quadric_from_vertex(v, tmesh, point_map, gt) + + weight_2 * quadric_calculator_2.construct_quadric_from_vertex(v, tmesh, point_map, gt); + } + + template + Mat_4 construct_quadric_from_edge(typename boost::graph_traits::halfedge_descriptor he, + const TriangleMesh& tmesh, + const VertexPointMap point_map, + const GeomTraits& gt) const + { + return weight_1 * Quadric_calculator_1().construct_quadric_from_edge(he, tmesh, point_map, gt) + + weight_2 * Quadric_calculator_2().construct_quadric_from_edge(he, tmesh, point_map, gt); + } + + template + Mat_4 construct_quadric_from_face(typename boost::graph_traits::face_descriptor f, + const TriangleMesh& tmesh, + const VertexPointMap point_map, + const GeomTraits& gt) const + { + return weight_1 * Quadric_calculator_1().construct_quadric_from_face(f, tmesh, point_map, gt) + + weight_2 * Quadric_calculator_2().construct_quadric_from_face(f, tmesh, point_map, gt); + } + + + Col_4 construct_optimal_point(const Mat_4& quadric, + const Col_4& p0, + const Col_4& p1) const + { + //TODO How merge here? + return construct_optimal_point_singular(quadric, p0, p1); + } +}; + +} // namespace internal + +template +class GarlandHeckbert_composed_policies + : public internal::GarlandHeckbert_cost_and_placement< + internal::Composed_quadric_calculator, + TriangleMesh, GeomTraits> +{ +public: + typedef internal::Composed_quadric_calculator + Quadric_calculator; + +private: + typedef internal::GarlandHeckbert_cost_and_placement< + Quadric_calculator, TriangleMesh, GeomTraits> Base; + typedef GarlandHeckbert_composed_policies Self; + +public: + typedef Self Get_cost; + typedef Self Get_placement; + + typedef typename GeomTraits::FT FT; + +public: + GarlandHeckbert_composed_policies(TriangleMesh& tmesh, + double w1=1., double w2=1.,const FT dm = FT(100)) + : Base(tmesh, Quadric_calculator(w1, w2), dm) + { } + + // GarlandHeckbert_composed_policies(TriangleMesh& tmesh, + // GH_policies_1 + // double w1=1., double w2=1.,const FT dm = FT(100)) + // : Base(tmesh, Quadric_calculator(w1, w2), dm) + // { } + +public: + const Get_cost& get_cost() const { return *this; } + const Get_placement& get_placement() const { return *this; } + + using Base::operator(); +}; + +} // namespace Surface_mesh_simplification +} // namespace CGAL + +#endif // CGAL_SURFACE_MESH_SIMPLIFICATION_POLICIES_GARLANDHECKBERT_COMPOSED_POLICIES_H \ No newline at end of file