From fd6745af6248576b0aabc21698a4dfd843475d0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 17 Oct 2022 16:20:48 +0200 Subject: [PATCH 01/35] Use a more standard indentation in Weights/include --- .../include/CGAL/Weights/authalic_weights.h | 265 ++-- .../CGAL/Weights/barycentric_region_weights.h | 166 +-- .../include/CGAL/Weights/cotangent_weights.h | 829 ++++++----- .../CGAL/Weights/discrete_harmonic_weights.h | 717 +++++---- .../Weights/internal/pmp_weights_deprecated.h | 320 ++-- .../CGAL/Weights/internal/polygon_utils_2.h | 584 ++++---- Weights/include/CGAL/Weights/internal/utils.h | 1326 ++++++++--------- .../CGAL/Weights/inverse_distance_weights.h | 230 ++- .../include/CGAL/Weights/mean_value_weights.h | 852 +++++------ .../Weights/mixed_voronoi_region_weights.h | 206 ++- .../include/CGAL/Weights/shepard_weights.h | 339 +++-- .../include/CGAL/Weights/tangent_weights.h | 836 +++++------ .../CGAL/Weights/three_point_family_weights.h | 221 ++- .../CGAL/Weights/triangular_region_weights.h | 132 +- .../CGAL/Weights/uniform_region_weights.h | 135 +- .../include/CGAL/Weights/uniform_weights.h | 102 +- Weights/include/CGAL/Weights/utils.h | 303 ++-- .../CGAL/Weights/voronoi_region_weights.h | 168 +-- .../include/CGAL/Weights/wachspress_weights.h | 681 ++++----- 19 files changed, 4089 insertions(+), 4323 deletions(-) diff --git a/Weights/include/CGAL/Weights/authalic_weights.h b/Weights/include/CGAL/Weights/authalic_weights.h index 5b76f7a9480..25d38e60f26 100644 --- a/Weights/include/CGAL/Weights/authalic_weights.h +++ b/Weights/include/CGAL/Weights/authalic_weights.h @@ -14,186 +14,185 @@ #ifndef CGAL_AUTHALIC_WEIGHTS_H #define CGAL_AUTHALIC_WEIGHTS_H -// Internal includes. #include namespace CGAL { namespace Weights { - /// \cond SKIP_IN_MANUAL - namespace authalic_ns { +/// \cond SKIP_IN_MANUAL +namespace authalic_ns { - template - FT half_weight(const FT cot, const FT r2) { - - FT w = FT(0); - CGAL_precondition(r2 != FT(0)); - if (r2 != FT(0)) { - const FT inv = FT(2) / r2; - w = cot * inv; - } - return w; - } - - template - FT weight(const FT cot_gamma, const FT cot_beta, const FT r2) { - - FT w = FT(0); - CGAL_precondition(r2 != FT(0)); - if (r2 != FT(0)) { - const FT inv = FT(2) / r2; - w = (cot_gamma + cot_beta) * inv; - } - return w; - } +template +FT half_weight(const FT cot, const FT r2) +{ + FT w = FT(0); + CGAL_precondition(r2 != FT(0)); + if (r2 != FT(0)) { + const FT inv = FT(2) / r2; + w = cot * inv; } - /// \endcond + return w; +} - /*! - \ingroup PkgWeightsRefAuthalicWeights - - \brief computes the half value of the authalic weight. - - This function constructs the half of the authalic weight using the precomputed - cotangent and squared distance values. The returned value is - \f$\frac{2\textbf{cot}}{\textbf{d2}}\f$. - - \tparam FT - a model of `FieldNumberType` - - \param cot - the cotangent value - - \param d2 - the squared distance value - - \pre d2 != 0 - - \sa `authalic_weight()` - */ - template - FT half_authalic_weight(const FT cot, const FT d2) { - return authalic_ns::half_weight(cot, d2); +template +FT weight(const FT cot_gamma, const FT cot_beta, const FT r2) +{ + FT w = FT(0); + CGAL_precondition(r2 != FT(0)); + if (r2 != FT(0)) + { + const FT inv = FT(2) / r2; + w = (cot_gamma + cot_beta) * inv; } - #if defined(DOXYGEN_RUNNING) + return w; +} - /*! - \ingroup PkgWeightsRefAuthalicWeights +} // namespace authalic_ns - \brief computes the authalic weight in 2D at `q` using the points `p0`, `p1`, - and `p2`, given a traits class `traits` with geometric objects, predicates, and constructions. - */ - template - typename GeomTraits::FT authalic_weight( +/// \endcond + +/*! + \ingroup PkgWeightsRefAuthalicWeights + + \brief computes the half value of the authalic weight. + + This function constructs the half of the authalic weight using the precomputed + cotangent and squared distance values. The returned value is + \f$\frac{2\textbf{cot}}{\textbf{d2}}\f$. + + \tparam FT a model of `FieldNumberType` + + \param cot the cotangent value + \param d2 the squared distance value + + \pre d2 != 0 + + \sa `authalic_weight()` +*/ +template +FT half_authalic_weight(const FT cot, const FT d2) +{ + return authalic_ns::half_weight(cot, d2); +} + +#if defined(DOXYGEN_RUNNING) + +/*! + \ingroup PkgWeightsRefAuthalicWeights + + \brief computes the authalic weight in 2D at `q` using the points `p0`, `p1`, + and `p2`, given a traits class `traits` with geometric objects, predicates, and constructions. +*/ +template +typename GeomTraits::FT authalic_weight( const typename GeomTraits::Point_2& p0, const typename GeomTraits::Point_2& p1, const typename GeomTraits::Point_2& p2, const typename GeomTraits::Point_2& q, const GeomTraits& traits) { } - /*! - \ingroup PkgWeightsRefAuthalicWeights +/*! + \ingroup PkgWeightsRefAuthalicWeights - \brief computes the authalic weight in 3D at `q` using the points `p0`, `p1`, - and `p2`, given a traits class `traits` with geometric objects, predicates, and constructions. - */ - template - typename GeomTraits::FT authalic_weight( + \brief computes the authalic weight in 3D at `q` using the points `p0`, `p1`, + and `p2`, given a traits class `traits` with geometric objects, predicates, and constructions. +*/ +template +typename GeomTraits::FT authalic_weight( const typename GeomTraits::Point_3& p0, const typename GeomTraits::Point_3& p1, const typename GeomTraits::Point_3& p2, const typename GeomTraits::Point_3& q, const GeomTraits& traits) { } - /*! - \ingroup PkgWeightsRefAuthalicWeights +/*! + \ingroup PkgWeightsRefAuthalicWeights - \brief computes the authalic weight in 2D at `q` using the points `p0`, `p1`, - and `p2` which are parameterized by a `Kernel` K. - */ - template - typename K::FT authalic_weight( + \brief computes the authalic weight in 2D at `q` using the points `p0`, `p1`, + and `p2` which are parameterized by a `Kernel` K. +*/ +template +typename K::FT authalic_weight( const CGAL::Point_2& p0, const CGAL::Point_2& p1, const CGAL::Point_2& p2, const CGAL::Point_2& q) { } - /*! - \ingroup PkgWeightsRefAuthalicWeights +/*! + \ingroup PkgWeightsRefAuthalicWeights - \brief computes the authalic weight in 3D at `q` using the points `p0`, `p1`, - and `p2` which are parameterized by a `Kernel` K. - */ - template - typename K::FT authalic_weight( + \brief computes the authalic weight in 3D at `q` using the points `p0`, `p1`, + and `p2` which are parameterized by a `Kernel` K. +*/ +template +typename K::FT authalic_weight( const CGAL::Point_3& p0, const CGAL::Point_3& p1, const CGAL::Point_3& p2, const CGAL::Point_3& q) { } - #endif // DOXYGEN_RUNNING +#endif // DOXYGEN_RUNNING - /// \cond SKIP_IN_MANUAL - // Overloads! - template - typename GeomTraits::FT authalic_weight( - const typename GeomTraits::Point_2& t, - const typename GeomTraits::Point_2& r, - const typename GeomTraits::Point_2& p, - const typename GeomTraits::Point_2& q, - const GeomTraits& traits) { +/// \cond SKIP_IN_MANUAL +// Overloads! +template +typename GeomTraits::FT authalic_weight(const typename GeomTraits::Point_2& t, + const typename GeomTraits::Point_2& r, + const typename GeomTraits::Point_2& p, + const typename GeomTraits::Point_2& q, + const GeomTraits& traits) +{ + using FT = typename GeomTraits::FT; - using FT = typename GeomTraits::FT; - const FT cot_gamma = internal::cotangent_2(traits, t, r, q); - const FT cot_beta = internal::cotangent_2(traits, q, r, p); + const auto squared_distance_2 = traits.compute_squared_distance_2_object(); - const auto squared_distance_2 = - traits.compute_squared_distance_2_object(); - const FT d2 = squared_distance_2(q, r); - return authalic_ns::weight(cot_gamma, cot_beta, d2); - } + const FT cot_gamma = internal::cotangent_2(traits, t, r, q); + const FT cot_beta = internal::cotangent_2(traits, q, r, p); - template - typename GeomTraits::FT authalic_weight( - const CGAL::Point_2& t, - const CGAL::Point_2& r, - const CGAL::Point_2& p, - const CGAL::Point_2& q) { + const FT d2 = squared_distance_2(q, r); + return authalic_ns::weight(cot_gamma, cot_beta, d2); +} - const GeomTraits traits; - return authalic_weight(t, r, p, q, traits); - } +template +typename GeomTraits::FT authalic_weight(const CGAL::Point_2& t, + const CGAL::Point_2& r, + const CGAL::Point_2& p, + const CGAL::Point_2& q) +{ + const GeomTraits traits; + return authalic_weight(t, r, p, q, traits); +} - template - typename GeomTraits::FT authalic_weight( - const typename GeomTraits::Point_3& t, - const typename GeomTraits::Point_3& r, - const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3& q, - const GeomTraits& traits) { +template +typename GeomTraits::FT authalic_weight(const typename GeomTraits::Point_3& t, + const typename GeomTraits::Point_3& r, + const typename GeomTraits::Point_3& p, + const typename GeomTraits::Point_3& q, + const GeomTraits& traits) +{ + using FT = typename GeomTraits::FT; - using FT = typename GeomTraits::FT; - const FT cot_gamma = internal::cotangent_3(traits, t, r, q); - const FT cot_beta = internal::cotangent_3(traits, q, r, p); + const auto squared_distance_3 = traits.compute_squared_distance_3_object(); - const auto squared_distance_3 = - traits.compute_squared_distance_3_object(); - const FT d2 = squared_distance_3(q, r); - return authalic_ns::weight(cot_gamma, cot_beta, d2); - } + const FT cot_gamma = internal::cotangent_3(traits, t, r, q); + const FT cot_beta = internal::cotangent_3(traits, q, r, p); + const FT d2 = squared_distance_3(q, r); - template - typename GeomTraits::FT authalic_weight( - const CGAL::Point_3& t, - const CGAL::Point_3& r, - const CGAL::Point_3& p, - const CGAL::Point_3& q) { + return authalic_ns::weight(cot_gamma, cot_beta, d2); +} - const GeomTraits traits; - return authalic_weight(t, r, p, q, traits); - } - /// \endcond +template +typename GeomTraits::FT authalic_weight(const CGAL::Point_3& t, + const CGAL::Point_3& r, + const CGAL::Point_3& p, + const CGAL::Point_3& q) +{ + const GeomTraits traits; + return authalic_weight(t, r, p, q, traits); +} + +/// \endcond } // namespace Weights } // namespace CGAL diff --git a/Weights/include/CGAL/Weights/barycentric_region_weights.h b/Weights/include/CGAL/Weights/barycentric_region_weights.h index 46fe69bcfa4..c095bd8c520 100644 --- a/Weights/include/CGAL/Weights/barycentric_region_weights.h +++ b/Weights/include/CGAL/Weights/barycentric_region_weights.h @@ -14,131 +14,125 @@ #ifndef CGAL_BARYCENTRIC_REGION_WEIGHTS_H #define CGAL_BARYCENTRIC_REGION_WEIGHTS_H -// Internal includes. #include namespace CGAL { namespace Weights { - #if defined(DOXYGEN_RUNNING) +#if defined(DOXYGEN_RUNNING) - /*! - \ingroup PkgWeightsRefBarycentricRegionWeights +/*! + \ingroup PkgWeightsRefBarycentricRegionWeights - \brief computes the area of the barycentric cell in 2D using the points `p`, `q` - and `r`, given a traits class `traits` with geometric objects, predicates, and constructions. - */ - template - typename GeomTraits::FT barycentric_area( + \brief computes the area of the barycentric cell in 2D using the points `p`, `q` + and `r`, given a traits class `traits` with geometric objects, predicates, and constructions. +*/ +template +typename GeomTraits::FT barycentric_area( const typename GeomTraits::Point_2& p, const typename GeomTraits::Point_2& q, const typename GeomTraits::Point_2& r, const GeomTraits& traits) { } - /*! - \ingroup PkgWeightsRefBarycentricRegionWeights +/*! + \ingroup PkgWeightsRefBarycentricRegionWeights - \brief computes the area of the barycentric cell in 3D using the points `p`, `q` - and `r`, given a traits class `traits` with geometric objects, predicates, and constructions. - */ - template - typename GeomTraits::FT barycentric_area( + \brief computes the area of the barycentric cell in 3D using the points `p`, `q` + and `r`, given a traits class `traits` with geometric objects, predicates, and constructions. +*/ +template +typename GeomTraits::FT barycentric_area( const typename GeomTraits::Point_3& p, const typename GeomTraits::Point_3& q, const typename GeomTraits::Point_3& r, const GeomTraits& traits) { } - /*! - \ingroup PkgWeightsRefBarycentricRegionWeights +/*! + \ingroup PkgWeightsRefBarycentricRegionWeights - \brief computes the area of the barycentric cell in 2D using the points `p`, `q` - and `r` which are parameterized by a `Kernel` K. - */ - template - typename K::FT barycentric_area( + \brief computes the area of the barycentric cell in 2D using the points `p`, `q` + and `r` which are parameterized by a `Kernel` K. +*/ +template +typename K::FT barycentric_area( const CGAL::Point_2& p, const CGAL::Point_2& q, const CGAL::Point_2& r) { } - /*! - \ingroup PkgWeightsRefBarycentricRegionWeights +/*! + \ingroup PkgWeightsRefBarycentricRegionWeights - \brief computes the area of the barycentric cell in 3D using the points `p`, `q` - and `r` which are parameterized by a `Kernel` K. - */ - template - typename K::FT barycentric_area( + \brief computes the area of the barycentric cell in 3D using the points `p`, `q` + and `r` which are parameterized by a `Kernel` K. +*/ +template +typename K::FT barycentric_area( const CGAL::Point_3& p, const CGAL::Point_3& q, const CGAL::Point_3& r) { } - #endif // DOXYGEN_RUNNING +#endif // DOXYGEN_RUNNING - /// \cond SKIP_IN_MANUAL - template - typename GeomTraits::FT barycentric_area( - const typename GeomTraits::Point_2& p, - const typename GeomTraits::Point_2& q, - const typename GeomTraits::Point_2& r, - const GeomTraits& traits) { +/// \cond SKIP_IN_MANUAL +template +typename GeomTraits::FT barycentric_area(const typename GeomTraits::Point_2& p, + const typename GeomTraits::Point_2& q, + const typename GeomTraits::Point_2& r, + const GeomTraits& traits) +{ + using FT = typename GeomTraits::FT; - using FT = typename GeomTraits::FT; - const auto midpoint_2 = - traits.construct_midpoint_2_object(); - const auto centroid_2 = - traits.construct_centroid_2_object(); + const auto midpoint_2 = traits.construct_midpoint_2_object(); + const auto centroid_2 = traits.construct_centroid_2_object(); - const auto center = centroid_2(p, q, r); - const auto m1 = midpoint_2(q, r); - const auto m2 = midpoint_2(q, p); + const auto center = centroid_2(p, q, r); + const auto m1 = midpoint_2(q, r); + const auto m2 = midpoint_2(q, p); - const FT A1 = internal::positive_area_2(traits, q, m1, center); - const FT A2 = internal::positive_area_2(traits, q, center, m2); - return A1 + A2; - } + const FT A1 = internal::positive_area_2(traits, q, m1, center); + const FT A2 = internal::positive_area_2(traits, q, center, m2); + return A1 + A2; +} - template - typename GeomTraits::FT barycentric_area( - const CGAL::Point_2& p, - const CGAL::Point_2& q, - const CGAL::Point_2& r) { +template +typename GeomTraits::FT barycentric_area(const CGAL::Point_2& p, + const CGAL::Point_2& q, + const CGAL::Point_2& r) +{ + const GeomTraits traits; + return barycentric_area(p, q, r, traits); +} - const GeomTraits traits; - return barycentric_area(p, q, r, traits); - } +template +typename GeomTraits::FT barycentric_area(const typename GeomTraits::Point_3& p, + const typename GeomTraits::Point_3& q, + const typename GeomTraits::Point_3& r, + const GeomTraits& traits) +{ + using FT = typename GeomTraits::FT; - template - typename GeomTraits::FT barycentric_area( - const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3& q, - const typename GeomTraits::Point_3& r, - const GeomTraits& traits) { + const auto midpoint_3 = traits.construct_midpoint_3_object(); + const auto centroid_3 = traits.construct_centroid_3_object(); - using FT = typename GeomTraits::FT; - const auto midpoint_3 = - traits.construct_midpoint_3_object(); - const auto centroid_3 = - traits.construct_centroid_3_object(); + const auto center = centroid_3(p, q, r); + const auto m1 = midpoint_3(q, r); + const auto m2 = midpoint_3(q, p); - const auto center = centroid_3(p, q, r); - const auto m1 = midpoint_3(q, r); - const auto m2 = midpoint_3(q, p); + const FT A1 = internal::positive_area_3(traits, q, m1, center); + const FT A2 = internal::positive_area_3(traits, q, center, m2); + return A1 + A2; +} - const FT A1 = internal::positive_area_3(traits, q, m1, center); - const FT A2 = internal::positive_area_3(traits, q, center, m2); - return A1 + A2; - } +template +typename GeomTraits::FT barycentric_area(const CGAL::Point_3& p, + const CGAL::Point_3& q, + const CGAL::Point_3& r) +{ + const GeomTraits traits; + return barycentric_area(p, q, r, traits); +} - template - typename GeomTraits::FT barycentric_area( - const CGAL::Point_3& p, - const CGAL::Point_3& q, - const CGAL::Point_3& r) { - - const GeomTraits traits; - return barycentric_area(p, q, r, traits); - } - /// \endcond +/// \endcond } // namespace Weights } // namespace CGAL diff --git a/Weights/include/CGAL/Weights/cotangent_weights.h b/Weights/include/CGAL/Weights/cotangent_weights.h index 0591d105d0d..5b8a5617fa7 100644 --- a/Weights/include/CGAL/Weights/cotangent_weights.h +++ b/Weights/include/CGAL/Weights/cotangent_weights.h @@ -14,482 +14,505 @@ #ifndef CGAL_COTANGENT_WEIGHTS_H #define CGAL_COTANGENT_WEIGHTS_H -// Internal includes. #include namespace CGAL { namespace Weights { - /// \cond SKIP_IN_MANUAL - namespace cotangent_ns { +/// \cond SKIP_IN_MANUAL - template - FT half_weight(const FT cot) { - return FT(2) * cot; - } +namespace cotangent_ns { - template - FT weight(const FT cot_beta, const FT cot_gamma) { - return FT(2) * (cot_beta + cot_gamma); - } - } - /// \endcond +template +FT half_weight(const FT cot) +{ + return FT(2) * cot; +} - /*! - \ingroup PkgWeightsRefCotangentWeights +template +FT weight(const FT cot_beta, const FT cot_gamma) +{ + return FT(2) * (cot_beta + cot_gamma); +} - \brief computes the half value of the cotangent weight. +} // namespace cotangent_ns - This function constructs the half of the cotangent weight using the precomputed - cotangent value. The returned value is - \f$2\textbf{cot}\f$. +/// \endcond - \tparam FT - a model of `FieldNumberType` +/*! + \ingroup PkgWeightsRefCotangentWeights - \param cot - the cotangent value + \brief computes the half value of the cotangent weight. - \sa `cotangent_weight()` - */ - template - FT half_cotangent_weight(const FT cot) { - return cotangent_ns::half_weight(cot); - } + This function constructs the half of the cotangent weight using the precomputed + cotangent value. The returned value is \f$2\textbf{cot}\f$. - #if defined(DOXYGEN_RUNNING) + \tparam FT a model of `FieldNumberType` - /*! - \ingroup PkgWeightsRefCotangentWeights + \param cot the cotangent value - \brief computes the cotangent weight in 2D at `q` using the points `p0`, `p1`, - and `p2`, given a traits class `traits` with geometric objects, predicates, and constructions. - */ - template - typename GeomTraits::FT cotangent_weight( + \sa `cotangent_weight()` +*/ +template +FT half_cotangent_weight(const FT cot) +{ + return cotangent_ns::half_weight(cot); +} + +#if defined(DOXYGEN_RUNNING) + +/*! + \ingroup PkgWeightsRefCotangentWeights + + \brief computes the cotangent weight in 2D at `q` using the points `p0`, `p1`, + and `p2`, given a traits class `traits` with geometric objects, predicates, and constructions. +*/ +template +typename GeomTraits::FT cotangent_weight( const typename GeomTraits::Point_2& p0, const typename GeomTraits::Point_2& p1, const typename GeomTraits::Point_2& p2, const typename GeomTraits::Point_2& q, const GeomTraits& traits) { } - /*! - \ingroup PkgWeightsRefCotangentWeights +/*! + \ingroup PkgWeightsRefCotangentWeights - \brief computes the cotangent weight in 3D at `q` using the points `p0`, `p1`, - and `p2`, given a traits class `traits` with geometric objects, predicates, and constructions. - */ - template - typename GeomTraits::FT cotangent_weight( + \brief computes the cotangent weight in 3D at `q` using the points `p0`, `p1`, + and `p2`, given a traits class `traits` with geometric objects, predicates, and constructions. +*/ +template +typename GeomTraits::FT cotangent_weight( const typename GeomTraits::Point_3& p0, const typename GeomTraits::Point_3& p1, const typename GeomTraits::Point_3& p2, const typename GeomTraits::Point_3& q, const GeomTraits& traits) { } - /*! - \ingroup PkgWeightsRefCotangentWeights +/*! + \ingroup PkgWeightsRefCotangentWeights - \brief computes the cotangent weight in 2D at `q` using the points `p0`, `p1`, - and `p2` which are parameterized by a `Kernel` K. - */ - template - typename K::FT cotangent_weight( + \brief computes the cotangent weight in 2D at `q` using the points `p0`, `p1`, + and `p2` which are parameterized by a `Kernel` K. +*/ +template +typename K::FT cotangent_weight( const CGAL::Point_2& p0, const CGAL::Point_2& p1, const CGAL::Point_2& p2, const CGAL::Point_2& q) { } - /*! - \ingroup PkgWeightsRefCotangentWeights +/*! + \ingroup PkgWeightsRefCotangentWeights - \brief computes the cotangent weight in 3D at `q` using the points `p0`, `p1`, - and `p2` which are parameterized by a `Kernel` K. - */ - template - typename K::FT cotangent_weight( + \brief computes the cotangent weight in 3D at `q` using the points `p0`, `p1`, + and `p2` which are parameterized by a `Kernel` K. +*/ +template +typename K::FT cotangent_weight( const CGAL::Point_3& p0, const CGAL::Point_3& p1, const CGAL::Point_3& p2, const CGAL::Point_3& q) { } - #endif // DOXYGEN_RUNNING +#endif // DOXYGEN_RUNNING - /// \cond SKIP_IN_MANUAL - template - typename GeomTraits::FT cotangent_weight( - const typename GeomTraits::Point_2& t, - const typename GeomTraits::Point_2& r, - const typename GeomTraits::Point_2& p, - const typename GeomTraits::Point_2& q, - const GeomTraits& traits) { +/// \cond SKIP_IN_MANUAL +template +typename GeomTraits::FT cotangent_weight(const typename GeomTraits::Point_2& t, + const typename GeomTraits::Point_2& r, + const typename GeomTraits::Point_2& p, + const typename GeomTraits::Point_2& q, + const GeomTraits& traits) +{ + using FT = typename GeomTraits::FT; - using FT = typename GeomTraits::FT; - const FT cot_beta = internal::cotangent_2(traits, q, t, r); - const FT cot_gamma = internal::cotangent_2(traits, r, p, q); - return cotangent_ns::weight(cot_beta, cot_gamma); - } + const FT cot_beta = internal::cotangent_2(traits, q, t, r); + const FT cot_gamma = internal::cotangent_2(traits, r, p, q); - template - typename GeomTraits::FT cotangent_weight( - const CGAL::Point_2& t, - const CGAL::Point_2& r, - const CGAL::Point_2& p, - const CGAL::Point_2& q) { - GeomTraits traits; - return cotangent_weight(t, r, p, q, traits); - } + return cotangent_ns::weight(cot_beta, cot_gamma); +} - template - typename GeomTraits::FT cotangent_weight( - const typename GeomTraits::Point_3& t, - const typename GeomTraits::Point_3& r, - const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3& q, - const GeomTraits& traits) { +template +typename GeomTraits::FT cotangent_weight(const CGAL::Point_2& t, + const CGAL::Point_2& r, + const CGAL::Point_2& p, + const CGAL::Point_2& q) +{ + GeomTraits traits; + return cotangent_weight(t, r, p, q, traits); +} - using FT = typename GeomTraits::FT; - const FT cot_beta = internal::cotangent_3(traits, q, t, r); - const FT cot_gamma = internal::cotangent_3(traits, r, p, q); - return cotangent_ns::weight(cot_beta, cot_gamma); - } +template +typename GeomTraits::FT cotangent_weight(const typename GeomTraits::Point_3& t, + const typename GeomTraits::Point_3& r, + const typename GeomTraits::Point_3& p, + const typename GeomTraits::Point_3& q, + const GeomTraits& traits) +{ + using FT = typename GeomTraits::FT; - template - typename GeomTraits::FT cotangent_weight( - const CGAL::Point_3& t, - const CGAL::Point_3& r, - const CGAL::Point_3& p, - const CGAL::Point_3& q) { + const FT cot_beta = internal::cotangent_3(traits, q, t, r); + const FT cot_gamma = internal::cotangent_3(traits, r, p, q); - GeomTraits traits; - return cotangent_weight(t, r, p, q, traits); - } + return cotangent_ns::weight(cot_beta, cot_gamma); +} - // Undocumented cotangent weight class. - // Its constructor takes a polygon mesh and a vertex to point map - // and its operator() is defined based on the halfedge_descriptor only. - // This version is currently used in: - // Polygon_mesh_processing -> curvature_flow_impl.h - template< - typename PolygonMesh, - typename VertexPointMap = typename boost::property_map::type> - class Edge_cotangent_weight { +template +typename GeomTraits::FT cotangent_weight(const CGAL::Point_3& t, + const CGAL::Point_3& r, + const CGAL::Point_3& p, + const CGAL::Point_3& q) +{ + GeomTraits traits; + return cotangent_weight(t, r, p, q, traits); +} - using GeomTraits = typename CGAL::Kernel_traits< - typename boost::property_traits::value_type>::type; - using FT = typename GeomTraits::FT; +// Undocumented cotangent weight class. +// Its constructor takes a polygon mesh and a vertex to point map +// and its operator() is defined based on the halfedge_descriptor only. +// This version is currently used in: +// Polygon_mesh_processing -> curvature_flow_impl.h +template< + typename PolygonMesh, + typename VertexPointMap = typename boost::property_map::type> +class Edge_cotangent_weight +{ + using GeomTraits = typename CGAL::Kernel_traits::value_type>::type; + using FT = typename GeomTraits::FT; - const PolygonMesh& m_pmesh; - const VertexPointMap m_pmap; - GeomTraits m_traits; + const PolygonMesh& m_pmesh; + const VertexPointMap m_pmap; + GeomTraits m_traits; - public: - using vertex_descriptor = typename boost::graph_traits::vertex_descriptor; - using halfedge_descriptor = typename boost::graph_traits::halfedge_descriptor; +public: + using vertex_descriptor = typename boost::graph_traits::vertex_descriptor; + using halfedge_descriptor = typename boost::graph_traits::halfedge_descriptor; - Edge_cotangent_weight(const PolygonMesh& pmesh, const VertexPointMap pmap) : - m_pmesh(pmesh), m_pmap(pmap), m_traits() { } + Edge_cotangent_weight(const PolygonMesh& pmesh, const VertexPointMap pmap) + : m_pmesh(pmesh), m_pmap(pmap), m_traits() + { } - FT operator()(const halfedge_descriptor he) const { + FT operator()(const halfedge_descriptor he) const + { - FT weight = FT(0); - if (is_border_edge(he, m_pmesh)) { - const auto h1 = next(he, m_pmesh); - - const auto v0 = target(he, m_pmesh); - const auto v1 = source(he, m_pmesh); - const auto v2 = target(h1, m_pmesh); - - const auto& p0 = get(m_pmap, v0); - const auto& p1 = get(m_pmap, v1); - const auto& p2 = get(m_pmap, v2); - - weight = internal::cotangent_3(m_traits, p0, p2, p1); - - } else { - const auto h1 = next(he, m_pmesh); - const auto h2 = prev(opposite(he, m_pmesh), m_pmesh); - - const auto v0 = target(he, m_pmesh); - const auto v1 = source(he, m_pmesh); - const auto v2 = target(h1, m_pmesh); - const auto v3 = source(h2, m_pmesh); - - const auto& p0 = get(m_pmap, v0); - const auto& p1 = get(m_pmap, v1); - const auto& p2 = get(m_pmap, v2); - const auto& p3 = get(m_pmap, v3); - - weight = cotangent_weight(p2, p1, p3, p0) / FT(2); - } - return weight; - } - }; - - // Undocumented cotangent weight class. - // Returns a single cotangent weight, its operator() is defined based on the - // halfedge_descriptor, polygon mesh, and vertex to point map. - // For border edges it returns zero. - // This version is currently used in: - // Surface_mesh_deformation -> Surface_mesh_deformation.h - template - class Single_cotangent_weight { - - public: - using vertex_descriptor = typename boost::graph_traits::vertex_descriptor; - using halfedge_descriptor = typename boost::graph_traits::halfedge_descriptor; - - template - decltype(auto) operator()(const halfedge_descriptor he, - const PolygonMesh& pmesh, const VertexPointMap pmap) const { - - using GeomTraits = typename CGAL::Kernel_traits< - typename boost::property_traits::value_type>::type; - using FT = typename GeomTraits::FT; - GeomTraits traits; - - if (is_border(he, pmesh)) { - return FT(0); - } - - const vertex_descriptor v0 = target(he, pmesh); - const vertex_descriptor v1 = source(he, pmesh); - const vertex_descriptor v2 = target(next(he, pmesh), pmesh); - - const auto& p0 = get(pmap, v0); - const auto& p1 = get(pmap, v1); - const auto& p2 = get(pmap, v2); - - return internal::cotangent_3(traits, p0, p2, p1); - } - }; - - // Undocumented cotangent weight class. - // Its constructor takes a boolean flag to choose between default and clamped - // versions of the cotangent weights and its operator() is defined based on the - // halfedge_descriptor, polygon mesh, and vertex to point map. - // This version is currently used in: - // Surface_mesh_deformation -> Surface_mesh_deformation.h (default version) - // Surface_mesh_parameterizer -> Orbifold_Tutte_parameterizer_3.h (default version) - // Surface_mesh_skeletonization -> Mean_curvature_flow_skeletonization.h (clamped version) - template - class Cotangent_weight { - bool m_use_clamped_version; - - public: - using vertex_descriptor = typename boost::graph_traits::vertex_descriptor; - using halfedge_descriptor = typename boost::graph_traits::halfedge_descriptor; - - Cotangent_weight(const bool use_clamped_version = false) : - m_use_clamped_version(use_clamped_version) { } - - template - decltype(auto) operator()(const halfedge_descriptor he, - const PolygonMesh& pmesh, const VertexPointMap pmap) const { - - using GeomTraits = typename CGAL::Kernel_traits< - typename boost::property_traits::value_type>::type; - using FT = typename GeomTraits::FT; - GeomTraits traits; - - const auto v0 = target(he, pmesh); - const auto v1 = source(he, pmesh); - - const auto& p0 = get(pmap, v0); - const auto& p1 = get(pmap, v1); - - FT weight = FT(0); - if (is_border_edge(he, pmesh)) { - const auto he_cw = opposite(next(he, pmesh), pmesh); - auto v2 = source(he_cw, pmesh); - - if (is_border_edge(he_cw, pmesh)) { - const auto he_ccw = prev(opposite(he, pmesh), pmesh); - v2 = source(he_ccw, pmesh); - - const auto& p2 = get(pmap, v2); - if (m_use_clamped_version) { - weight = internal::cotangent_3_clamped(traits, p1, p2, p0); - } else { - weight = internal::cotangent_3(traits, p1, p2, p0); - } - weight = (CGAL::max)(FT(0), weight); - weight /= FT(2); - } else { - const auto& p2 = get(pmap, v2); - if (m_use_clamped_version) { - weight = internal::cotangent_3_clamped(traits, p0, p2, p1); - } else { - weight = internal::cotangent_3(traits, p0, p2, p1); - } - weight = (CGAL::max)(FT(0), weight); - weight /= FT(2); - } - - } else { - const auto he_cw = opposite(next(he, pmesh), pmesh); - const auto v2 = source(he_cw, pmesh); - const auto he_ccw = prev(opposite(he, pmesh), pmesh); - const auto v3 = source(he_ccw, pmesh); - - const auto& p2 = get(pmap, v2); - const auto& p3 = get(pmap, v3); - FT cot_beta = FT(0), cot_gamma = FT(0); - - if (m_use_clamped_version) { - cot_beta = internal::cotangent_3_clamped(traits, p0, p2, p1); - } else { - cot_beta = internal::cotangent_3(traits, p0, p2, p1); - } - - if (m_use_clamped_version) { - cot_gamma = internal::cotangent_3_clamped(traits, p1, p3, p0); - } else { - cot_gamma = internal::cotangent_3(traits, p1, p3, p0); - } - - cot_beta = (CGAL::max)(FT(0), cot_beta); cot_beta /= FT(2); - cot_gamma = (CGAL::max)(FT(0), cot_gamma); cot_gamma /= FT(2); - weight = cot_beta + cot_gamma; - } - return weight; - } - }; - - // Undocumented cotangent weight class. - // Its constructor takes a polygon mesh and a vertex to point map - // and its operator() is defined based on the halfedge_descriptor only. - // This class is using a special clamped version of the cotangent weights. - // This version is currently used in: - // Polygon_mesh_processing -> fair.h - // Polyhedron demo -> Hole_filling_plugin.cpp - template< - typename PolygonMesh, - typename VertexPointMap = typename boost::property_map::type> - class Secure_cotangent_weight_with_voronoi_area { - - using GeomTraits = typename CGAL::Kernel_traits< - typename boost::property_traits::value_type>::type; - using FT = typename GeomTraits::FT; - - const PolygonMesh& m_pmesh; - const VertexPointMap m_pmap; - GeomTraits m_traits; - - public: - using vertex_descriptor = typename boost::graph_traits::vertex_descriptor; - using halfedge_descriptor = typename boost::graph_traits::halfedge_descriptor; - - Secure_cotangent_weight_with_voronoi_area(const PolygonMesh& pmesh, const VertexPointMap pmap) : - m_pmesh(pmesh), m_pmap(pmap), m_traits() { } - - FT w_i(const vertex_descriptor v_i) const { - return FT(1) / (FT(2) * voronoi(v_i)); - } - - FT w_ij(const halfedge_descriptor he) const { - return cotangent_clamped(he); - } - - private: - FT cotangent_clamped(const halfedge_descriptor he) const { + FT weight = FT(0); + if (is_border_edge(he, m_pmesh)) + { + const auto h1 = next(he, m_pmesh); const auto v0 = target(he, m_pmesh); const auto v1 = source(he, m_pmesh); + const auto v2 = target(h1, m_pmesh); const auto& p0 = get(m_pmap, v0); const auto& p1 = get(m_pmap, v1); + const auto& p2 = get(m_pmap, v2); - FT weight = FT(0); - if (is_border_edge(he, m_pmesh)) { - const auto he_cw = opposite(next(he, m_pmesh), m_pmesh); - auto v2 = source(he_cw, m_pmesh); + weight = internal::cotangent_3(m_traits, p0, p2, p1); - if (is_border_edge(he_cw, m_pmesh)) { - const auto he_ccw = prev(opposite(he, m_pmesh), m_pmesh); - v2 = source(he_ccw, m_pmesh); + } + else + { + const auto h1 = next(he, m_pmesh); + const auto h2 = prev(opposite(he, m_pmesh), m_pmesh); - const auto& p2 = get(m_pmap, v2); - weight = internal::cotangent_3_clamped(m_traits, p1, p2, p0); - } else { - const auto& p2 = get(m_pmap, v2); - weight = internal::cotangent_3_clamped(m_traits, p0, p2, p1); - } + const auto v0 = target(he, m_pmesh); + const auto v1 = source(he, m_pmesh); + const auto v2 = target(h1, m_pmesh); + const auto v3 = source(h2, m_pmesh); - } else { - const auto he_cw = opposite(next(he, m_pmesh), m_pmesh); - const auto v2 = source(he_cw, m_pmesh); + const auto& p0 = get(m_pmap, v0); + const auto& p1 = get(m_pmap, v1); + const auto& p2 = get(m_pmap, v2); + const auto& p3 = get(m_pmap, v3); + + weight = cotangent_weight(p2, p1, p3, p0) / FT(2); + } + return weight; + } +}; + +// Undocumented cotangent weight class. +// +// Returns a single cotangent weight, its operator() is defined based on the +// halfedge_descriptor, polygon mesh, and vertex to point map. +// For border edges it returns zero. +// This version is currently used in: +// Surface_mesh_deformation -> Surface_mesh_deformation.h +template +class Single_cotangent_weight +{ +public: + using vertex_descriptor = typename boost::graph_traits::vertex_descriptor; + using halfedge_descriptor = typename boost::graph_traits::halfedge_descriptor; + + template + decltype(auto) operator()(const halfedge_descriptor he, + const PolygonMesh& pmesh, + const VertexPointMap pmap) const + { + using GeomTraits = typename CGAL::Kernel_traits::value_type>::type; + using FT = typename GeomTraits::FT; + GeomTraits traits; + + if (is_border(he, pmesh)) + return FT(0); + + const vertex_descriptor v0 = target(he, pmesh); + const vertex_descriptor v1 = source(he, pmesh); + const vertex_descriptor v2 = target(next(he, pmesh), pmesh); + + const auto& p0 = get(pmap, v0); + const auto& p1 = get(pmap, v1); + const auto& p2 = get(pmap, v2); + + return internal::cotangent_3(traits, p0, p2, p1); + } +}; + +// Undocumented cotangent weight class. +// Its constructor takes a boolean flag to choose between default and clamped +// versions of the cotangent weights and its operator() is defined based on the +// halfedge_descriptor, polygon mesh, and vertex to point map. +// This version is currently used in: +// Surface_mesh_deformation -> Surface_mesh_deformation.h (default version) +// Surface_mesh_parameterizer -> Orbifold_Tutte_parameterizer_3.h (default version) +// Surface_mesh_skeletonization -> Mean_curvature_flow_skeletonization.h (clamped version) +template +class Cotangent_weight +{ + bool m_use_clamped_version; + +public: + using vertex_descriptor = typename boost::graph_traits::vertex_descriptor; + using halfedge_descriptor = typename boost::graph_traits::halfedge_descriptor; + + Cotangent_weight(const bool use_clamped_version = false) + : m_use_clamped_version(use_clamped_version) + { } + + template + decltype(auto) operator()(const halfedge_descriptor he, + const PolygonMesh& pmesh, + const VertexPointMap pmap) const + { + using GeomTraits = typename CGAL::Kernel_traits::value_type>::type; + using FT = typename GeomTraits::FT; + + GeomTraits traits; + + const auto v0 = target(he, pmesh); + const auto v1 = source(he, pmesh); + + const auto& p0 = get(pmap, v0); + const auto& p1 = get(pmap, v1); + + FT weight = FT(0); + if (is_border_edge(he, pmesh)) + { + const auto he_cw = opposite(next(he, pmesh), pmesh); + auto v2 = source(he_cw, pmesh); + + if (is_border_edge(he_cw, pmesh)) + { + const auto he_ccw = prev(opposite(he, pmesh), pmesh); + v2 = source(he_ccw, pmesh); + + const auto& p2 = get(pmap, v2); + if (m_use_clamped_version) + weight = internal::cotangent_3_clamped(traits, p1, p2, p0); + else + weight = internal::cotangent_3(traits, p1, p2, p0); + + weight = (CGAL::max)(FT(0), weight); + weight /= FT(2); + } + else + { + const auto& p2 = get(pmap, v2); + if (m_use_clamped_version) + weight = internal::cotangent_3_clamped(traits, p0, p2, p1); + else + weight = internal::cotangent_3(traits, p0, p2, p1); + + weight = (CGAL::max)(FT(0), weight); + weight /= FT(2); + } + } + else + { + const auto he_cw = opposite(next(he, pmesh), pmesh); + const auto v2 = source(he_cw, pmesh); + const auto he_ccw = prev(opposite(he, pmesh), pmesh); + const auto v3 = source(he_ccw, pmesh); + + const auto& p2 = get(pmap, v2); + const auto& p3 = get(pmap, v3); + FT cot_beta = FT(0), cot_gamma = FT(0); + + if (m_use_clamped_version) + cot_beta = internal::cotangent_3_clamped(traits, p0, p2, p1); + else + cot_beta = internal::cotangent_3(traits, p0, p2, p1); + + if (m_use_clamped_version) + cot_gamma = internal::cotangent_3_clamped(traits, p1, p3, p0); + else + cot_gamma = internal::cotangent_3(traits, p1, p3, p0); + + cot_beta = (CGAL::max)(FT(0), cot_beta); cot_beta /= FT(2); + cot_gamma = (CGAL::max)(FT(0), cot_gamma); cot_gamma /= FT(2); + weight = cot_beta + cot_gamma; + } + + return weight; + } +}; + +// Undocumented cotangent weight class. +// Its constructor takes a polygon mesh and a vertex to point map +// and its operator() is defined based on the halfedge_descriptor only. +// This class is using a special clamped version of the cotangent weights. +// This version is currently used in: +// Polygon_mesh_processing -> fair.h +// Polyhedron demo -> Hole_filling_plugin.cpp +template< + typename PolygonMesh, + typename VertexPointMap = typename boost::property_map::type> +class Secure_cotangent_weight_with_voronoi_area +{ + using GeomTraits = typename CGAL::Kernel_traits::value_type>::type; + using FT = typename GeomTraits::FT; + + const PolygonMesh& m_pmesh; + const VertexPointMap m_pmap; + GeomTraits m_traits; + +public: + using vertex_descriptor = typename boost::graph_traits::vertex_descriptor; + using halfedge_descriptor = typename boost::graph_traits::halfedge_descriptor; + + Secure_cotangent_weight_with_voronoi_area(const PolygonMesh& pmesh, + const VertexPointMap pmap) + : m_pmesh(pmesh), m_pmap(pmap), m_traits() + { } + + FT w_i(const vertex_descriptor v_i) const + { + return FT(1) / (FT(2) * voronoi(v_i)); + } + + FT w_ij(const halfedge_descriptor he) const + { + return cotangent_clamped(he); + } + +private: + FT cotangent_clamped(const halfedge_descriptor he) const + { + + const auto v0 = target(he, m_pmesh); + const auto v1 = source(he, m_pmesh); + + const auto& p0 = get(m_pmap, v0); + const auto& p1 = get(m_pmap, v1); + + FT weight = FT(0); + if (is_border_edge(he, m_pmesh)) + { + const auto he_cw = opposite(next(he, m_pmesh), m_pmesh); + auto v2 = source(he_cw, m_pmesh); + + if (is_border_edge(he_cw, m_pmesh)) + { const auto he_ccw = prev(opposite(he, m_pmesh), m_pmesh); - const auto v3 = source(he_ccw, m_pmesh); + v2 = source(he_ccw, m_pmesh); const auto& p2 = get(m_pmap, v2); - const auto& p3 = get(m_pmap, v3); - - const FT cot_beta = internal::cotangent_3_clamped(m_traits, p0, p2, p1); - const FT cot_gamma = internal::cotangent_3_clamped(m_traits, p1, p3, p0); - weight = cot_beta + cot_gamma; + weight = internal::cotangent_3_clamped(m_traits, p1, p2, p0); } - return weight; - } - - FT voronoi(const vertex_descriptor v0) const { - - const auto squared_length_3 = - m_traits.compute_squared_length_3_object(); - const auto construct_vector_3 = - m_traits.construct_vector_3_object(); - - FT voronoi_area = FT(0); - CGAL_assertion(CGAL::is_triangle_mesh(m_pmesh)); - for (const auto& he : halfedges_around_target(halfedge(v0, m_pmesh), m_pmesh)) { - CGAL_assertion(v0 == target(he, m_pmesh)); - if (is_border(he, m_pmesh)) { - continue; - } - - const auto v1 = source(he, m_pmesh); - const auto v2 = target(next(he, m_pmesh), m_pmesh); - - const auto& p0 = get(m_pmap, v0); - const auto& p1 = get(m_pmap, v1); + else + { const auto& p2 = get(m_pmap, v2); - - const auto angle0 = CGAL::angle(p1, p0, p2); - const auto angle1 = CGAL::angle(p2, p1, p0); - const auto angle2 = CGAL::angle(p0, p2, p1); - - const bool obtuse = - (angle0 == CGAL::OBTUSE) || - (angle1 == CGAL::OBTUSE) || - (angle2 == CGAL::OBTUSE); - - if (!obtuse) { - const FT cot_p1 = internal::cotangent_3(m_traits, p2, p1, p0); - const FT cot_p2 = internal::cotangent_3(m_traits, p0, p2, p1); - - const auto v1 = construct_vector_3(p0, p1); - const auto v2 = construct_vector_3(p0, p2); - - const FT t1 = cot_p1 * squared_length_3(v2); - const FT t2 = cot_p2 * squared_length_3(v1); - voronoi_area += (t1 + t2) / FT(8); - - } else { - - const FT A = internal::positive_area_3(m_traits, p0, p1, p2); - if (angle0 == CGAL::OBTUSE) { - voronoi_area += A / FT(2); - } else { - voronoi_area += A / FT(4); - } - } + weight = internal::cotangent_3_clamped(m_traits, p0, p2, p1); } - CGAL_assertion(voronoi_area != FT(0)); - return voronoi_area; } - }; + else + { + const auto he_cw = opposite(next(he, m_pmesh), m_pmesh); + const auto v2 = source(he_cw, m_pmesh); + const auto he_ccw = prev(opposite(he, m_pmesh), m_pmesh); + const auto v3 = source(he_ccw, m_pmesh); - /// \endcond + const auto& p2 = get(m_pmap, v2); + const auto& p3 = get(m_pmap, v3); + + const FT cot_beta = internal::cotangent_3_clamped(m_traits, p0, p2, p1); + const FT cot_gamma = internal::cotangent_3_clamped(m_traits, p1, p3, p0); + weight = cot_beta + cot_gamma; + } + + return weight; + } + + FT voronoi(const vertex_descriptor v0) const + { + const auto squared_length_3 = m_traits.compute_squared_length_3_object(); + const auto construct_vector_3 = m_traits.construct_vector_3_object(); + + FT voronoi_area = FT(0); + CGAL_assertion(CGAL::is_triangle_mesh(m_pmesh)); + for (const auto& he : halfedges_around_target(halfedge(v0, m_pmesh), m_pmesh)) + { + CGAL_assertion(v0 == target(he, m_pmesh)); + if (is_border(he, m_pmesh)) + continue; + + const auto v1 = source(he, m_pmesh); + const auto v2 = target(next(he, m_pmesh), m_pmesh); + + const auto& p0 = get(m_pmap, v0); + const auto& p1 = get(m_pmap, v1); + const auto& p2 = get(m_pmap, v2); + + const auto angle0 = CGAL::angle(p1, p0, p2); + const auto angle1 = CGAL::angle(p2, p1, p0); + const auto angle2 = CGAL::angle(p0, p2, p1); + + const bool obtuse = (angle0 == CGAL::OBTUSE) || + (angle1 == CGAL::OBTUSE) || + (angle2 == CGAL::OBTUSE); + + if (!obtuse) + { + const FT cot_p1 = internal::cotangent_3(m_traits, p2, p1, p0); + const FT cot_p2 = internal::cotangent_3(m_traits, p0, p2, p1); + + const auto v1 = construct_vector_3(p0, p1); + const auto v2 = construct_vector_3(p0, p2); + + const FT t1 = cot_p1 * squared_length_3(v2); + const FT t2 = cot_p2 * squared_length_3(v1); + voronoi_area += (t1 + t2) / FT(8); + + } + else + { + const FT A = internal::positive_area_3(m_traits, p0, p1, p2); + if (angle0 == CGAL::OBTUSE) + voronoi_area += A / FT(2); + else + voronoi_area += A / FT(4); + } + } + + CGAL_assertion(voronoi_area != FT(0)); + return voronoi_area; + } +}; + +/// \endcond } // namespace Weights } // namespace CGAL diff --git a/Weights/include/CGAL/Weights/discrete_harmonic_weights.h b/Weights/include/CGAL/Weights/discrete_harmonic_weights.h index 42a7056afc2..170b73a67b3 100644 --- a/Weights/include/CGAL/Weights/discrete_harmonic_weights.h +++ b/Weights/include/CGAL/Weights/discrete_harmonic_weights.h @@ -14,429 +14,396 @@ #ifndef CGAL_DISCRETE_HARMONIC_WEIGHTS_H #define CGAL_DISCRETE_HARMONIC_WEIGHTS_H -// Internal includes. #include #include namespace CGAL { namespace Weights { - /// \cond SKIP_IN_MANUAL - namespace discrete_harmonic_ns { +/// \cond SKIP_IN_MANUAL - template - FT weight( - const FT r1, const FT r2, const FT r3, - const FT A1, const FT A2, const FT B) { +namespace discrete_harmonic_ns { - FT w = FT(0); - CGAL_precondition(A1 != FT(0) && A2 != FT(0)); - const FT prod = A1 * A2; - if (prod != FT(0)) { - const FT inv = FT(1) / prod; - w = (r3 * A1 - r2 * B + r1 * A2) * inv; - } - return w; - } +template +FT weight(const FT r1, const FT r2, const FT r3, + const FT A1, const FT A2, const FT B) +{ + FT w = FT(0); + CGAL_precondition(A1 != FT(0) && A2 != FT(0)); + const FT prod = A1 * A2; + if (prod != FT(0)) + { + const FT inv = FT(1) / prod; + w = (r3 * A1 - r2 * B + r1 * A2) * inv; } - /// \endcond - #if defined(DOXYGEN_RUNNING) + return w; +} - /*! - \ingroup PkgWeightsRefDiscreteHarmonicWeights +} // namespace discrete_harmonic_ns - \brief computes the discrete harmonic weight in 2D at `q` using the points `p0`, `p1`, - and `p2`, given a traits class `traits` with geometric objects, predicates, and constructions. - */ - template - typename GeomTraits::FT discrete_harmonic_weight( +/// \endcond + +#if defined(DOXYGEN_RUNNING) + +/*! + \ingroup PkgWeightsRefDiscreteHarmonicWeights + + \brief computes the discrete harmonic weight in 2D at `q` using the points `p0`, `p1`, + and `p2`, given a traits class `traits` with geometric objects, predicates, and constructions. +*/ +template +typename GeomTraits::FT discrete_harmonic_weight( const typename GeomTraits::Point_2& p0, const typename GeomTraits::Point_2& p1, const typename GeomTraits::Point_2& p2, const typename GeomTraits::Point_2& q, const GeomTraits& traits) { } - /*! - \ingroup PkgWeightsRefDiscreteHarmonicWeights +/*! + \ingroup PkgWeightsRefDiscreteHarmonicWeights - \brief computes the discrete harmonic weight in 2D at `q` using the points `p0`, `p1`, - and `p2` which are parameterized by a `Kernel` K. - */ - template - typename K::FT discrete_harmonic_weight( + \brief computes the discrete harmonic weight in 2D at `q` using the points `p0`, `p1`, + and `p2` which are parameterized by a `Kernel` K. +*/ +template +typename K::FT discrete_harmonic_weight( const CGAL::Point_2& p0, const CGAL::Point_2& p1, const CGAL::Point_2& p2, const CGAL::Point_2& q) { } - #endif // DOXYGEN_RUNNING +#endif // DOXYGEN_RUNNING + +/// \cond SKIP_IN_MANUAL +template +typename GeomTraits::FT discrete_harmonic_weight(const typename GeomTraits::Point_2& t, + const typename GeomTraits::Point_2& r, + const typename GeomTraits::Point_2& p, + const typename GeomTraits::Point_2& q, + const GeomTraits& traits) +{ + using FT = typename GeomTraits::FT; + + const auto squared_distance_2 = traits.compute_squared_distance_2_object(); + + const FT d1 = squared_distance_2(q, t); + const FT d2 = squared_distance_2(q, r); + const FT d3 = squared_distance_2(q, p); + + const FT A1 = internal::area_2(traits, r, q, t); + const FT A2 = internal::area_2(traits, p, q, r); + const FT B = internal::area_2(traits, p, q, t); + + return discrete_harmonic_ns::weight(d1, d2, d3, A1, A2, B); +} + +template +typename GeomTraits::FT discrete_harmonic_weight(const CGAL::Point_2& t, + const CGAL::Point_2& r, + const CGAL::Point_2& p, + const CGAL::Point_2& q) +{ + const GeomTraits traits; + return discrete_harmonic_weight(t, r, p, q, traits); +} + +namespace internal { + +template +typename GeomTraits::FT discrete_harmonic_weight(const typename GeomTraits::Point_3& t, + const typename GeomTraits::Point_3& r, + const typename GeomTraits::Point_3& p, + const typename GeomTraits::Point_3& q, + const GeomTraits& traits) +{ + using Point_2 = typename GeomTraits::Point_2; + + Point_2 tf, rf, pf, qf; + internal::flatten(traits, + t, r, p, q, + tf, rf, pf, qf); + return CGAL::Weights::discrete_harmonic_weight(tf, rf, pf, qf, traits); +} + +template +typename GeomTraits::FT discrete_harmonic_weight(const CGAL::Point_3& t, + const CGAL::Point_3& r, + const CGAL::Point_3& p, + const CGAL::Point_3& q) +{ + const GeomTraits traits; + return discrete_harmonic_weight(t, r, p, q, traits); +} + +} // namespace internal + +/// \endcond + +/*! + \ingroup PkgWeightsRefBarycentricDiscreteHarmonicWeights + + \brief 2D discrete harmonic weights for polygons. + + This class implements 2D discrete harmonic weights (\cite cgal:bc:eddhls-maam-95, + \cite cgal:bc:fhk-gcbcocp-06, \cite cgal:pp-cdmsc-93) which can be computed + at any point inside a strictly convex polygon. + + Discrete harmonic weights are well-defined inside a strictly convex polygon + but they are not necessarily positive. These weights are computed analytically + using the formulation from the `discrete_harmonic_weight()`. + + \tparam VertexRange a model of `ConstRange` whose iterator type is `RandomAccessIterator` + \tparam GeomTraits a model of `AnalyticWeightTraits_2` + \tparam PointMap a model of `ReadablePropertyMap` whose key type is `VertexRange::value_type` and + value type is `Point_2`. The default is `CGAL::Identity_property_map`. + + \cgalModels `BarycentricWeights_2` +*/ +template > +class Discrete_harmonic_weights_2 +{ +public: + /// \name Types + /// @{ /// \cond SKIP_IN_MANUAL - template - typename GeomTraits::FT discrete_harmonic_weight( - const typename GeomTraits::Point_2& t, - const typename GeomTraits::Point_2& r, - const typename GeomTraits::Point_2& p, - const typename GeomTraits::Point_2& q, - const GeomTraits& traits) { - - using FT = typename GeomTraits::FT; - const auto squared_distance_2 = - traits.compute_squared_distance_2_object(); - - const FT d1 = squared_distance_2(q, t); - const FT d2 = squared_distance_2(q, r); - const FT d3 = squared_distance_2(q, p); - - const FT A1 = internal::area_2(traits, r, q, t); - const FT A2 = internal::area_2(traits, p, q, r); - const FT B = internal::area_2(traits, p, q, t); - - return discrete_harmonic_ns::weight( - d1, d2, d3, A1, A2, B); - } - - template - typename GeomTraits::FT discrete_harmonic_weight( - const CGAL::Point_2& t, - const CGAL::Point_2& r, - const CGAL::Point_2& p, - const CGAL::Point_2& q) { - - const GeomTraits traits; - return discrete_harmonic_weight(t, r, p, q, traits); - } - - namespace internal { - - template - typename GeomTraits::FT discrete_harmonic_weight( - const typename GeomTraits::Point_3& t, - const typename GeomTraits::Point_3& r, - const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3& q, - const GeomTraits& traits) { - - using Point_2 = typename GeomTraits::Point_2; - Point_2 tf, rf, pf, qf; - internal::flatten( - traits, - t, r, p, q, - tf, rf, pf, qf); - return CGAL::Weights:: - discrete_harmonic_weight(tf, rf, pf, qf, traits); - } - - template - typename GeomTraits::FT discrete_harmonic_weight( - const CGAL::Point_3& t, - const CGAL::Point_3& r, - const CGAL::Point_3& p, - const CGAL::Point_3& q) { - - const GeomTraits traits; - return discrete_harmonic_weight(t, r, p, q, traits); - } - - } // namespace internal + using Vertex_range = VertexRange; + using Geom_traits = GeomTraits; + using Point_map = PointMap; + using Area_2 = typename GeomTraits::Compute_area_2; + using Squared_distance_2 = typename GeomTraits::Compute_squared_distance_2; /// \endcond - /*! - \ingroup PkgWeightsRefBarycentricDiscreteHarmonicWeights + /// Number type. + typedef typename GeomTraits::FT FT; - \brief 2D discrete harmonic weights for polygons. + /// Point type. + typedef typename GeomTraits::Point_2 Point_2; - This class implements 2D discrete harmonic weights ( \cite cgal:bc:fhk-gcbcocp-06, - \cite cgal:pp-cdmsc-93, \cite cgal:bc:eddhls-maam-95 ) which can be computed - at any point inside a strictly convex polygon. + /// @} - Discrete harmonic weights are well-defined inside a strictly convex polygon - but they are not necessarily positive. These weights are computed analytically - using the formulation from the `discrete_harmonic_weight()`. - - \tparam VertexRange - a model of `ConstRange` whose iterator type is `RandomAccessIterator` - - \tparam GeomTraits - a model of `AnalyticWeightTraits_2` - - \tparam PointMap - a model of `ReadablePropertyMap` whose key type is `VertexRange::value_type` and - value type is `Point_2`. The default is `CGAL::Identity_property_map`. - - \cgalModels `BarycentricWeights_2` - */ - template< - typename VertexRange, - typename GeomTraits, - typename PointMap = CGAL::Identity_property_map > - class Discrete_harmonic_weights_2 { - - public: - - /// \name Types - /// @{ - - /// \cond SKIP_IN_MANUAL - using Vertex_range = VertexRange; - using Geom_traits = GeomTraits; - using Point_map = PointMap; - - using Area_2 = typename GeomTraits::Compute_area_2; - using Squared_distance_2 = typename GeomTraits::Compute_squared_distance_2; - /// \endcond - - /// Number type. - typedef typename GeomTraits::FT FT; - - /// Point type. - typedef typename GeomTraits::Point_2 Point_2; - - /// @} - - /// \name Initialization - /// @{ - - /*! - \brief initializes all internal data structures. - - This class implements the behavior of discrete harmonic weights - for 2D query points inside strictly convex polygons. - - \param polygon - an instance of `VertexRange` with the vertices of a strictly convex polygon - - \param traits - a traits class with geometric objects, predicates, and constructions; - the default initialization is provided - - \param point_map - an instance of `PointMap` that maps a vertex from `polygon` to `Point_2`; - the default initialization is provided - - \pre polygon.size() >= 3 - \pre polygon is simple - \pre polygon is strictly convex - */ - Discrete_harmonic_weights_2( - const VertexRange& polygon, - const GeomTraits traits = GeomTraits(), - const PointMap point_map = PointMap()) : - m_polygon(polygon), - m_traits(traits), - m_point_map(point_map), - m_area_2(m_traits.compute_area_2_object()), - m_squared_distance_2(m_traits.compute_squared_distance_2_object()) { - - CGAL_precondition( - polygon.size() >= 3); - CGAL_precondition( - internal::is_simple_2(polygon, traits, point_map)); - CGAL_precondition( - internal::polygon_type_2(polygon, traits, point_map) == - internal::Polygon_type::STRICTLY_CONVEX); - resize(); - } - - /// @} - - /// \name Access - /// @{ - - /*! - \brief computes 2D discrete harmonic weights. - - This function fills a destination range with 2D discrete harmonic weights - computed at the `query` point with respect to the vertices of the input polygon. - - The number of computed weights is equal to the number of polygon vertices. - - \tparam OutIterator - a model of `OutputIterator` whose value type is `FT` - - \param query - a query point - - \param w_begin - the beginning of the destination range with the computed weights - - \return an output iterator to the element in the destination range, - one past the last weight stored - */ - template - OutIterator operator()(const Point_2& query, OutIterator w_begin) { - const bool normalize = false; - return operator()(query, w_begin, normalize); - } - - /// @} - - /// \cond SKIP_IN_MANUAL - template - OutIterator operator()(const Point_2& query, OutIterator w_begin, const bool normalize) { - return optimal_weights(query, w_begin, normalize); - } - /// \endcond - - private: - - // Fields. - const VertexRange& m_polygon; - const GeomTraits m_traits; - const PointMap m_point_map; - - const Area_2 m_area_2; - const Squared_distance_2 m_squared_distance_2; - - std::vector r; - std::vector A; - std::vector B; - std::vector w; - - // Functions. - void resize() { - r.resize(m_polygon.size()); - A.resize(m_polygon.size()); - B.resize(m_polygon.size()); - w.resize(m_polygon.size()); - } - - template - OutputIterator optimal_weights( - const Point_2& query, OutputIterator weights, const bool normalize) { - - // Get the number of vertices in the polygon. - const std::size_t n = m_polygon.size(); - - // Compute areas A, B, and distances r following the notation from [1]. - // Split the loop to make this computation faster. - const auto& p1 = get(m_point_map, *(m_polygon.begin() + 0)); - const auto& p2 = get(m_point_map, *(m_polygon.begin() + 1)); - const auto& pn = get(m_point_map, *(m_polygon.begin() + (n - 1))); - - r[0] = m_squared_distance_2(p1, query); - A[0] = m_area_2(p1, p2, query); - B[0] = m_area_2(pn, p2, query); - - for (std::size_t i = 1; i < n - 1; ++i) { - const auto& pi0 = get(m_point_map, *(m_polygon.begin() + (i - 1))); - const auto& pi1 = get(m_point_map, *(m_polygon.begin() + (i + 0))); - const auto& pi2 = get(m_point_map, *(m_polygon.begin() + (i + 1))); - - r[i] = m_squared_distance_2(pi1, query); - A[i] = m_area_2(pi1, pi2, query); - B[i] = m_area_2(pi0, pi2, query); - } - - const auto& pm = get(m_point_map, *(m_polygon.begin() + (n - 2))); - r[n - 1] = m_squared_distance_2(pn, query); - A[n - 1] = m_area_2(pn, p1, query); - B[n - 1] = m_area_2(pm, p1, query); - - // Compute unnormalized weights following the formula (25) with p = 2 from [1]. - CGAL_assertion(A[n - 1] != FT(0) && A[0] != FT(0)); - w[0] = (r[1] * A[n - 1] - r[0] * B[0] + r[n - 1] * A[0]) / (A[n - 1] * A[0]); - - for (std::size_t i = 1; i < n - 1; ++i) { - CGAL_assertion(A[i - 1] != FT(0) && A[i] != FT(0)); - w[i] = (r[i + 1] * A[i - 1] - r[i] * B[i] + r[i - 1] * A[i]) / (A[i - 1] * A[i]); - } - - CGAL_assertion(A[n - 2] != FT(0) && A[n - 1] != FT(0)); - w[n - 1] = (r[0] * A[n - 2] - r[n - 1] * B[n - 1] + r[n - 2] * A[n - 1]) / (A[n - 2] * A[n - 1]); - - // Normalize if necessary. - if (normalize) { - internal::normalize(w); - } - - // Return weights. - for (std::size_t i = 0; i < n; ++i) { - *(weights++) = w[i]; - } - return weights; - } - }; + /// \name Initialization + /// @{ /*! - \ingroup PkgWeightsRefBarycentricDiscreteHarmonicWeights + \brief initializes all internal data structures. - \brief computes 2D discrete harmonic weights for polygons. + This class implements the behavior of discrete harmonic weights + for 2D query points inside strictly convex polygons. - This function computes 2D discrete harmonic weights at a given `query` point - with respect to the vertices of a strictly convex `polygon`, that is one - weight per vertex. The weights are stored in a destination range - beginning at `w_begin`. - - Internally, the class `Discrete_harmonic_weights_2` is used. If one wants to process - multiple query points, it is better to use that class. When using the free function, - internal memory is allocated for each query point, while when using the class, - it is allocated only once which is much more efficient. However, for a few query - points, it is easier to use this function. It can also be used when the processing - time is not a concern. - - \tparam PointRange - a model of `ConstRange` whose iterator type is `RandomAccessIterator` - and value type is `GeomTraits::Point_2` - - \tparam OutIterator - a model of `OutputIterator` whose value type is `GeomTraits::FT` - - \tparam GeomTraits - a model of `AnalyticWeightTraits_2` - - \param polygon - an instance of `PointRange` with 2D points which form a strictly convex polygon - - \param query - a query point - - \param w_begin - the beginning of the destination range with the computed weights - - \param traits - a traits class with geometric objects, predicates, and constructions; - this parameter can be omitted if the traits class can be deduced from the point type - - \return an output iterator to the element in the destination range, - one past the last weight stored + \param polygon an instance of `VertexRange` with the vertices of a strictly convex polygon + \param traits a traits class with geometric objects, predicates, and constructions; + the default initialization is provided + \param point_map an instance of `PointMap` that maps a vertex from `polygon` to `Point_2`; + the default initialization is provided \pre polygon.size() >= 3 \pre polygon is simple \pre polygon is strictly convex */ - template< - typename PointRange, - typename OutIterator, - typename GeomTraits> - OutIterator discrete_harmonic_weights_2( - const PointRange& polygon, const typename GeomTraits::Point_2& query, - OutIterator w_begin, const GeomTraits& traits) { + Discrete_harmonic_weights_2(const VertexRange& polygon, + const GeomTraits traits = GeomTraits(), + const PointMap point_map = PointMap()) + : m_polygon(polygon), + m_traits(traits), + m_point_map(point_map), + m_area_2(m_traits.compute_area_2_object()), + m_squared_distance_2(m_traits.compute_squared_distance_2_object()) + { + CGAL_precondition(polygon.size() >= 3); + CGAL_precondition(internal::is_simple_2(polygon, traits, point_map)); + CGAL_precondition(internal::polygon_type_2(polygon, traits, point_map) == internal::Polygon_type::STRICTLY_CONVEX); - Discrete_harmonic_weights_2 - discrete_harmonic(polygon, traits); - return discrete_harmonic(query, w_begin); + resize(); } + /// @} + + /// \name Access + /// @{ + + /*! + \brief computes 2D discrete harmonic weights. + + This function fills a destination range with 2D discrete harmonic weights + computed at the `query` point with respect to the vertices of the input polygon. + + The number of computed weights is equal to the number of polygon vertices. + + \tparam OutIterator a model of `OutputIterator` whose value type is `FT` + + \param query a query point + \param w_begin the beginning of the destination range with the computed weights + + \return an output iterator to the element in the destination range, one past the last weight stored + */ + template + OutIterator operator()(const Point_2& query, + OutIterator w_begin) + { + const bool normalize = false; + return operator()(query, w_begin, normalize); + } + + /// @} + /// \cond SKIP_IN_MANUAL - template< - typename PointRange, - typename OutIterator> - OutIterator discrete_harmonic_weights_2( - const PointRange& polygon, - const typename PointRange::value_type& query, - OutIterator w_begin) { - - using Point_2 = typename PointRange::value_type; - using GeomTraits = typename Kernel_traits::Kernel; - const GeomTraits traits; - return discrete_harmonic_weights_2( - polygon, query, w_begin, traits); + template + OutIterator operator()(const Point_2& query, + OutIterator w_begin, + const bool normalize) + { + return optimal_weights(query, w_begin, normalize); } + /// \endcond +private: + const VertexRange& m_polygon; + const GeomTraits m_traits; + const PointMap m_point_map; + + const Area_2 m_area_2; + const Squared_distance_2 m_squared_distance_2; + + std::vector r; + std::vector A; + std::vector B; + std::vector w; + + void resize() + { + r.resize(m_polygon.size()); + A.resize(m_polygon.size()); + B.resize(m_polygon.size()); + w.resize(m_polygon.size()); + } + + template + OutputIterator optimal_weights(const Point_2& query, + OutputIterator weights, + const bool normalize) + { + // Get the number of vertices in the polygon. + const std::size_t n = m_polygon.size(); + + // Compute areas A, B, and distances r following the notation from [1]. + // Split the loop to make this computation faster. + const auto& p1 = get(m_point_map, *(m_polygon.begin() + 0)); + const auto& p2 = get(m_point_map, *(m_polygon.begin() + 1)); + const auto& pn = get(m_point_map, *(m_polygon.begin() + (n - 1))); + + r[0] = m_squared_distance_2(p1, query); + A[0] = m_area_2(p1, p2, query); + B[0] = m_area_2(pn, p2, query); + + for (std::size_t i = 1; i < n - 1; ++i) + { + const auto& pi0 = get(m_point_map, *(m_polygon.begin() + (i - 1))); + const auto& pi1 = get(m_point_map, *(m_polygon.begin() + (i + 0))); + const auto& pi2 = get(m_point_map, *(m_polygon.begin() + (i + 1))); + + r[i] = m_squared_distance_2(pi1, query); + A[i] = m_area_2(pi1, pi2, query); + B[i] = m_area_2(pi0, pi2, query); + } + + const auto& pm = get(m_point_map, *(m_polygon.begin() + (n - 2))); + r[n - 1] = m_squared_distance_2(pn, query); + A[n - 1] = m_area_2(pn, p1, query); + B[n - 1] = m_area_2(pm, p1, query); + + // Compute unnormalized weights following the formula (25) with p = 2 from [1]. + CGAL_assertion(A[n - 1] != FT(0) && A[0] != FT(0)); + w[0] = (r[1] * A[n - 1] - r[0] * B[0] + r[n - 1] * A[0]) / (A[n - 1] * A[0]); + + for (std::size_t i = 1; i < n - 1; ++i) + { + CGAL_assertion(A[i - 1] != FT(0) && A[i] != FT(0)); + w[i] = (r[i + 1] * A[i - 1] - r[i] * B[i] + r[i - 1] * A[i]) / (A[i - 1] * A[i]); + } + + CGAL_assertion(A[n - 2] != FT(0) && A[n - 1] != FT(0)); + w[n - 1] = (r[0] * A[n - 2] - r[n - 1] * B[n - 1] + r[n - 2] * A[n - 1]) / (A[n - 2] * A[n - 1]); + + // Normalize if necessary. + if (normalize) + internal::normalize(w); + + // Return weights. + for (std::size_t i = 0; i < n; ++i) + *(weights++) = w[i]; + + return weights; + } +}; + +/*! + \ingroup PkgWeightsRefBarycentricDiscreteHarmonicWeights + + \brief computes 2D discrete harmonic weights for polygons. + + This function computes 2D discrete harmonic weights at a given `query` point + with respect to the vertices of a strictly convex `polygon`, that is one + weight per vertex. The weights are stored in a destination range + beginning at `w_begin`. + + Internally, the class `Discrete_harmonic_weights_2` is used. If one wants to process + multiple query points, it is better to use that class. When using the free function, + internal memory is allocated for each query point, while when using the class, + it is allocated only once which is much more efficient. However, for a few query + points, it is easier to use this function. It can also be used when the processing + time is not a concern. + + \tparam PointRange a model of `ConstRange` whose iterator type is `RandomAccessIterator` + and value type is `GeomTraits::Point_2` + \tparam OutIterator a model of `OutputIterator` whose value type is `GeomTraits::FT` + \tparam GeomTraits a model of `AnalyticWeightTraits_2` + + \param polygon an instance of `PointRange` with 2D points which form a strictly convex polygon + \param query a query point + \param w_begin the beginning of the destination range with the computed weights + \param traits a traits class with geometric objects, predicates, and constructions; + this parameter can be omitted if the traits class can be deduced from the point type + + \return an output iterator to the element in the destination range, one past the last weight stored + + \pre polygon.size() >= 3 + \pre polygon is simple + \pre polygon is strictly convex +*/ +template +OutIterator discrete_harmonic_weights_2(const PointRange& polygon, + const typename GeomTraits::Point_2& query, + OutIterator w_begin, + const GeomTraits& traits) +{ + Discrete_harmonic_weights_2 discrete_harmonic(polygon, traits); + return discrete_harmonic(query, w_begin); +} + +/// \cond SKIP_IN_MANUAL + +template +OutIterator discrete_harmonic_weights_2(const PointRange& polygon, + const typename PointRange::value_type& query, + OutIterator w_begin) +{ + using Point_2 = typename PointRange::value_type; + using GeomTraits = typename Kernel_traits::Kernel; + + const GeomTraits traits; + return discrete_harmonic_weights_2(polygon, query, w_begin, traits); +} +/// \endcond + } // namespace Weights } // namespace CGAL diff --git a/Weights/include/CGAL/Weights/internal/pmp_weights_deprecated.h b/Weights/include/CGAL/Weights/internal/pmp_weights_deprecated.h index 0170e812d1f..942ad0dc8d5 100644 --- a/Weights/include/CGAL/Weights/internal/pmp_weights_deprecated.h +++ b/Weights/include/CGAL/Weights/internal/pmp_weights_deprecated.h @@ -20,7 +20,7 @@ #include // README: -// This header collects all weights, which have been in CGAL before unifying them +// This header collects all weights which have been in CGAL before unifying them // into the new package Weights. This header is for information purpose only. It // will be removed in the next release. @@ -47,13 +47,13 @@ struct Cotangent_value_Meyer_impl { template double operator()( - vertex_descriptor v0, - vertex_descriptor v1, - vertex_descriptor v2, - const VertexPointMap& ppmap) { + vertex_descriptor v0, + vertex_descriptor v1, + vertex_descriptor v2, + const VertexPointMap& ppmap) { typedef typename Kernel_traits< - typename boost::property_traits::value_type >::Kernel::Vector_3 Vector; + typename boost::property_traits::value_type >::Kernel::Vector_3 Vector; const Vector a = get(ppmap, v0) - get(ppmap, v1); const Vector b = get(ppmap, v2) - get(ppmap, v1); @@ -67,16 +67,16 @@ struct Cotangent_value_Meyer_impl { const Vector cross_ab = CGAL::cross_product(a, b); const double divider = CGAL::to_double( - CGAL::approximate_sqrt(cross_ab * cross_ab)); + CGAL::approximate_sqrt(cross_ab * cross_ab)); if (divider == 0.0 /* || divider != divider */) { CGAL::collinear(get(ppmap, v0), get(ppmap, v1), get(ppmap, v2)) ? - CGAL_warning_msg(false, "Infinite Cotangent value with the degenerate triangle!") : - CGAL_warning_msg(false, "Infinite Cotangent value due to the floating point arithmetic!"); + CGAL_warning_msg(false, "Infinite Cotangent value with the degenerate triangle!") : + CGAL_warning_msg(false, "Infinite Cotangent value due to the floating point arithmetic!"); return dot_ab > 0.0 ? - (std::numeric_limits::max)() : - -(std::numeric_limits::max)(); + (std::numeric_limits::max)() : + -(std::numeric_limits::max)(); } return dot_ab / divider; } @@ -84,8 +84,8 @@ struct Cotangent_value_Meyer_impl { // Same as above but with a different API. template< -typename PolygonMesh, -typename VertexPointMap = typename boost::property_map::type> + typename PolygonMesh, + typename VertexPointMap = typename boost::property_map::type> class Cotangent_value_Meyer { protected: @@ -99,10 +99,10 @@ protected: public: Cotangent_value_Meyer( - PolygonMesh& pmesh_, - VertexPointMap vpmap_) : - pmesh_(pmesh_), - ppmap_(vpmap_) + PolygonMesh& pmesh_, + VertexPointMap vpmap_) : + pmesh_(pmesh_), + ppmap_(vpmap_) { } PolygonMesh& pmesh() { @@ -114,9 +114,9 @@ public: } double operator()( - vertex_descriptor v0, - vertex_descriptor v1, - vertex_descriptor v2) { + vertex_descriptor v0, + vertex_descriptor v1, + vertex_descriptor v2) { return Cotangent_value_Meyer_impl()(v0, v1, v2, ppmap()); } @@ -124,8 +124,8 @@ public: // Imported from skeletonization. template< -typename PolygonMesh, -typename VertexPointMap = typename boost::property_map::type> + typename PolygonMesh, + typename VertexPointMap = typename boost::property_map::type> class Cotangent_value_Meyer_secure { typedef VertexPointMap Point_property_map; @@ -138,10 +138,10 @@ class Cotangent_value_Meyer_secure { public: Cotangent_value_Meyer_secure( - PolygonMesh& pmesh_, - VertexPointMap vpmap_) : - pmesh_(pmesh_), - ppmap_(vpmap_) + PolygonMesh& pmesh_, + VertexPointMap vpmap_) : + pmesh_(pmesh_), + ppmap_(vpmap_) { } PolygonMesh& pmesh() { @@ -153,9 +153,9 @@ public: } double operator()( - vertex_descriptor v0, - vertex_descriptor v1, - vertex_descriptor v2) { + vertex_descriptor v0, + vertex_descriptor v1, + vertex_descriptor v2) { const Vector a = get(ppmap(), v0) - get(ppmap(), v1); const Vector b = get(ppmap(), v2) - get(ppmap(), v1); @@ -175,9 +175,9 @@ public: // Returns the cotangent value of the half angle [v0, v1, v2] by clamping between // [1, 89] degrees as suggested by -[Friedel] Unconstrained Spherical Parameterization-. template< -typename PolygonMesh, -typename VertexPointMap = typename boost::property_map::type, -typename CotangentValue = Cotangent_value_Meyer > + typename PolygonMesh, + typename VertexPointMap = typename boost::property_map::type, + typename CotangentValue = Cotangent_value_Meyer > class Cotangent_value_clamped : CotangentValue { Cotangent_value_clamped() @@ -185,9 +185,9 @@ class Cotangent_value_clamped : CotangentValue { public: Cotangent_value_clamped( - PolygonMesh& pmesh_, - VertexPointMap vpmap_) : - CotangentValue(pmesh_, vpmap_) + PolygonMesh& pmesh_, + VertexPointMap vpmap_) : + CotangentValue(pmesh_, vpmap_) { } PolygonMesh& pmesh() { @@ -201,9 +201,9 @@ public: typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; double operator()( - vertex_descriptor v0, - vertex_descriptor v1, - vertex_descriptor v2) { + vertex_descriptor v0, + vertex_descriptor v1, + vertex_descriptor v2) { const double cot_1 = 57.289962; const double cot_89 = 0.017455; @@ -213,9 +213,9 @@ public: }; template< -typename PolygonMesh, -typename VertexPointMap = typename boost::property_map::type, -typename CotangentValue = Cotangent_value_Meyer > + typename PolygonMesh, + typename VertexPointMap = typename boost::property_map::type, + typename CotangentValue = Cotangent_value_Meyer > class Cotangent_value_clamped_2 : CotangentValue { Cotangent_value_clamped_2() @@ -223,9 +223,9 @@ class Cotangent_value_clamped_2 : CotangentValue { public: Cotangent_value_clamped_2( - PolygonMesh& pmesh_, - VertexPointMap vpmap_) : - CotangentValue(pmesh_, vpmap_) + PolygonMesh& pmesh_, + VertexPointMap vpmap_) : + CotangentValue(pmesh_, vpmap_) { } PolygonMesh& pmesh() { @@ -239,9 +239,9 @@ public: typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; double operator()( - vertex_descriptor v0, - vertex_descriptor v1, - vertex_descriptor v2) { + vertex_descriptor v0, + vertex_descriptor v1, + vertex_descriptor v2) { const double cot_5 = 5.671282; const double cot_175 = -cot_5; @@ -251,18 +251,18 @@ public: }; template< -typename PolygonMesh, -typename CotangentValue = Cotangent_value_Meyer_impl > + typename PolygonMesh, + typename CotangentValue = Cotangent_value_Meyer_impl > struct Cotangent_value_minimum_zero_impl : CotangentValue { typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; template double operator()( - vertex_descriptor v0, - vertex_descriptor v1, - vertex_descriptor v2, - const VertexPointMap ppmap) { + vertex_descriptor v0, + vertex_descriptor v1, + vertex_descriptor v2, + const VertexPointMap ppmap) { const double value = CotangentValue::operator()(v0, v1, v2, ppmap); return (std::max)(0.0, value); @@ -270,9 +270,9 @@ struct Cotangent_value_minimum_zero_impl : CotangentValue { }; template< -typename PolygonMesh, -typename VertexPointMap = typename boost::property_map::type, -typename CotangentValue = Cotangent_value_Meyer > + typename PolygonMesh, + typename VertexPointMap = typename boost::property_map::type, + typename CotangentValue = Cotangent_value_Meyer > class Cotangent_value_minimum_zero : CotangentValue { Cotangent_value_minimum_zero() @@ -280,9 +280,9 @@ class Cotangent_value_minimum_zero : CotangentValue { public: Cotangent_value_minimum_zero( - PolygonMesh& pmesh_, - VertexPointMap vpmap_) : - CotangentValue(pmesh_, vpmap_) + PolygonMesh& pmesh_, + VertexPointMap vpmap_) : + CotangentValue(pmesh_, vpmap_) { } PolygonMesh& pmesh() { @@ -296,25 +296,25 @@ public: typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; double operator()( - vertex_descriptor v0, - vertex_descriptor v1, - vertex_descriptor v2) { + vertex_descriptor v0, + vertex_descriptor v1, + vertex_descriptor v2) { const double value = CotangentValue::operator()(v0, v1, v2); return (std::max)(0.0, value); } }; template< -typename PolygonMesh, -typename VertexPointMap = typename boost::property_map::type, -typename CotangentValue = Cotangent_value_Meyer > + typename PolygonMesh, + typename VertexPointMap = typename boost::property_map::type, + typename CotangentValue = Cotangent_value_Meyer > class Voronoi_area : CotangentValue { public: Voronoi_area( - PolygonMesh& pmesh_, - VertexPointMap vpmap_) : - CotangentValue(pmesh_, vpmap_) + PolygonMesh& pmesh_, + VertexPointMap vpmap_) : + CotangentValue(pmesh_, vpmap_) { } PolygonMesh& pmesh() { @@ -338,7 +338,7 @@ public: // return 1.0; double voronoi_area = 0.0; for (const halfedge_descriptor he : - halfedges_around_target(halfedge(v0, pmesh()), pmesh())) { + halfedges_around_target(halfedge(v0, pmesh()), pmesh())) { if (is_border(he, pmesh()) ) { continue; } @@ -357,9 +357,9 @@ public: const CGAL::Angle angle_op = CGAL::angle(v0_p, v_op_p, v1_p); bool obtuse = - (angle0 == CGAL::OBTUSE) || - (angle1 == CGAL::OBTUSE) || - (angle_op == CGAL::OBTUSE); + (angle0 == CGAL::OBTUSE) || + (angle1 == CGAL::OBTUSE) || + (angle_op == CGAL::OBTUSE); if (!obtuse) { const double cot_v1 = CotangentValue::operator()(v_op, v1, v0); @@ -371,8 +371,8 @@ public: } else { const double area_t = to_double( - CGAL::approximate_sqrt( - CGAL::squared_area(v0_p, v1_p, v_op_p))); + CGAL::approximate_sqrt( + CGAL::squared_area(v0_p, v1_p, v_op_p))); if (angle0 == CGAL::OBTUSE) { voronoi_area += area_t / 2.0; @@ -389,9 +389,9 @@ public: // Returns the cotangent value of the half angle [v0, v1, v2] by dividing the triangle area // as suggested by -[Mullen08] Spectral Conformal Parameterization-. template< -typename PolygonMesh, -typename VertexPointMap = typename boost::property_map::type, -typename CotangentValue = Cotangent_value_Meyer > + typename PolygonMesh, + typename VertexPointMap = typename boost::property_map::type, + typename CotangentValue = Cotangent_value_Meyer > class Cotangent_value_area_weighted : CotangentValue { Cotangent_value_area_weighted() @@ -399,9 +399,9 @@ class Cotangent_value_area_weighted : CotangentValue { public: Cotangent_value_area_weighted( - PolygonMesh& pmesh_, - VertexPointMap vpmap_) : - CotangentValue(pmesh_, vpmap_) + PolygonMesh& pmesh_, + VertexPointMap vpmap_) : + CotangentValue(pmesh_, vpmap_) { } PolygonMesh& pmesh() { @@ -415,15 +415,15 @@ public: typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; double operator()( - vertex_descriptor v0, - vertex_descriptor v1, - vertex_descriptor v2) { + vertex_descriptor v0, + vertex_descriptor v1, + vertex_descriptor v2) { return CotangentValue::operator()(v0, v1, v2) / - CGAL::sqrt(CGAL::squared_area( - get(this->ppmap(), v0), - get(this->ppmap(), v1), - get(this->ppmap(), v2))); + CGAL::sqrt(CGAL::squared_area( + get(this->ppmap(), v0), + get(this->ppmap(), v1), + get(this->ppmap(), v2))); } }; @@ -431,8 +431,8 @@ public: // Cotangent_value: as suggested by -[Sorkine07] ARAP Surface Modeling-. // Cotangent_value_area_weighted: as suggested by -[Mullen08] Spectral Conformal Parameterization-. template< -typename PolygonMesh, -typename CotangentValue = Cotangent_value_minimum_zero_impl > + typename PolygonMesh, + typename CotangentValue = Cotangent_value_minimum_zero_impl > struct Cotangent_weight_impl : CotangentValue { typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; @@ -442,9 +442,9 @@ struct Cotangent_weight_impl : CotangentValue { // Edge orientation is trivial. template double operator()( - halfedge_descriptor he, - PolygonMesh& pmesh, - const VertexPointMap& ppmap) { + halfedge_descriptor he, + PolygonMesh& pmesh, + const VertexPointMap& ppmap) { const vertex_descriptor v0 = target(he, pmesh); const vertex_descriptor v1 = source(he, pmesh); @@ -467,16 +467,16 @@ struct Cotangent_weight_impl : CotangentValue { const vertex_descriptor v3 = source(he_ccw, pmesh); return ( - CotangentValue::operator()(v0, v2, v1, ppmap) / 2.0 + - CotangentValue::operator()(v0, v3, v1, ppmap) / 2.0 ); + CotangentValue::operator()(v0, v2, v1, ppmap) / 2.0 + + CotangentValue::operator()(v0, v3, v1, ppmap) / 2.0 ); } } }; template< -typename PolygonMesh, -typename VertexPointMap = typename boost::property_map::type, -typename CotangentValue = Cotangent_value_minimum_zero > + typename PolygonMesh, + typename VertexPointMap = typename boost::property_map::type, + typename CotangentValue = Cotangent_value_minimum_zero > class Cotangent_weight : CotangentValue { Cotangent_weight() @@ -484,13 +484,13 @@ class Cotangent_weight : CotangentValue { public: Cotangent_weight( - PolygonMesh& pmesh_, - VertexPointMap vpmap_) : - CotangentValue(pmesh_, vpmap_) + PolygonMesh& pmesh_, + VertexPointMap vpmap_) : + CotangentValue(pmesh_, vpmap_) { } Cotangent_weight(PolygonMesh& pmesh_) : - CotangentValue(pmesh_, get(CGAL::vertex_point, pmesh_)) + CotangentValue(pmesh_, get(CGAL::vertex_point, pmesh_)) { } PolygonMesh& pmesh() { @@ -532,16 +532,16 @@ public: const vertex_descriptor v3 = source(he_ccw, pmesh()); return ( - CotangentValue::operator()(v0, v2, v1) / 2.0 + - CotangentValue::operator()(v0, v3, v1) / 2.0 ); - } + CotangentValue::operator()(v0, v2, v1) / 2.0 + + CotangentValue::operator()(v0, v3, v1) / 2.0 ); + } } }; // Single cotangent from -[Chao10] Simple Geometric Model for Elastic Deformation. template< -typename PolygonMesh, -typename CotangentValue = Cotangent_value_Meyer_impl > + typename PolygonMesh, + typename CotangentValue = Cotangent_value_Meyer_impl > struct Single_cotangent_weight_impl : CotangentValue { typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; @@ -551,9 +551,9 @@ struct Single_cotangent_weight_impl : CotangentValue { // 0 for border edges (which does not have an opposite angle). template double operator()( - halfedge_descriptor he, - PolygonMesh& pmesh, - const VertexPointMap& ppmap) { + halfedge_descriptor he, + PolygonMesh& pmesh, + const VertexPointMap& ppmap) { if (is_border(he, pmesh)) { return 0.0; } @@ -565,9 +565,9 @@ struct Single_cotangent_weight_impl : CotangentValue { }; template< -typename PolygonMesh, -typename VertexPointMap = typename boost::property_map::type, -typename CotangentValue = Cotangent_value_Meyer > + typename PolygonMesh, + typename VertexPointMap = typename boost::property_map::type, + typename CotangentValue = Cotangent_value_Meyer > class Single_cotangent_weight : CotangentValue { Single_cotangent_weight() @@ -575,9 +575,9 @@ class Single_cotangent_weight : CotangentValue { public: Single_cotangent_weight( - PolygonMesh& pmesh_, - VertexPointMap vpmap_) : - CotangentValue(pmesh_, vpmap_) + PolygonMesh& pmesh_, + VertexPointMap vpmap_) : + CotangentValue(pmesh_, vpmap_) { } PolygonMesh& pmesh() { @@ -609,9 +609,9 @@ public: }; template< -typename PolygonMesh, -typename VertexPointMap = typename boost::property_map::type, -typename CotangentValue = Cotangent_value_Meyer > + typename PolygonMesh, + typename VertexPointMap = typename boost::property_map::type, + typename CotangentValue = Cotangent_value_Meyer > class Cotangent_weight_with_triangle_area : CotangentValue { typedef PolygonMesh PM; @@ -626,9 +626,9 @@ class Cotangent_weight_with_triangle_area : CotangentValue { public: Cotangent_weight_with_triangle_area( - PolygonMesh& pmesh_, - VertexPointMap vpmap_) : - CotangentValue(pmesh_, vpmap_) + PolygonMesh& pmesh_, + VertexPointMap vpmap_) : + CotangentValue(pmesh_, vpmap_) { } PolygonMesh& pmesh() { @@ -656,7 +656,7 @@ public: const Point& v1_p = get(ppmap(), v1); const Point& v2_p = get(ppmap(), v2); const double area_t = to_double( - CGAL::sqrt(CGAL::squared_area(v0_p, v1_p, v2_p))); + CGAL::sqrt(CGAL::squared_area(v0_p, v1_p, v2_p))); return (CotangentValue::operator()(v0, v2, v1) / area_t); } else { @@ -673,8 +673,8 @@ public: const double area_t2 = to_double(CGAL::sqrt(CGAL::squared_area(v0_p, v1_p, v3_p))); return ( - CotangentValue::operator()(v0, v2, v1) / area_t1 + - CotangentValue::operator()(v0, v3, v1) / area_t2 ); + CotangentValue::operator()(v0, v2, v1) / area_t1 + + CotangentValue::operator()(v0, v3, v1) / area_t2 ); } return 0.0; } @@ -682,8 +682,8 @@ public: // Mean value calculator described in -[Floater04] Mean Value Coordinates- template< -typename PolygonMesh, -typename VertexPointMap = typename boost::property_map::type> + typename PolygonMesh, + typename VertexPointMap = typename boost::property_map::type> class Mean_value_weight { // Mean_value_weight() @@ -694,10 +694,10 @@ class Mean_value_weight { public: Mean_value_weight( - PolygonMesh& pmesh_, - VertexPointMap vpmap) : - pmesh_(pmesh_), - vpmap_(vpmap) + PolygonMesh& pmesh_, + VertexPointMap vpmap) : + pmesh_(pmesh_), + vpmap_(vpmap) { } PolygonMesh& pmesh() { @@ -738,17 +738,17 @@ public: const halfedge_descriptor he_ccw = prev(opposite(he, pmesh()), pmesh()); const vertex_descriptor v3 = source(he_ccw, pmesh()); return ( - half_tan_value_2(v1, v0, v2) / norm + - half_tan_value_2(v1, v0, v3) / norm); + half_tan_value_2(v1, v0, v2) / norm + + half_tan_value_2(v1, v0, v3) / norm); } } private: // Returns the tangent value of the half angle v0_v1_v2 / 2. double half_tan_value( - vertex_descriptor v0, - vertex_descriptor v1, - vertex_descriptor v2) { + vertex_descriptor v0, + vertex_descriptor v1, + vertex_descriptor v2) { const Vector vec0 = get(vpmap_, v1) - get(vpmap_, v2); const Vector vec1 = get(vpmap_, v2) - get(vpmap_, v0); @@ -766,9 +766,9 @@ private: // My deviation built on Meyer_02. double half_tan_value_2( - vertex_descriptor v0, - vertex_descriptor v1, - vertex_descriptor v2) { + vertex_descriptor v0, + vertex_descriptor v1, + vertex_descriptor v2) { const Vector a = get(vpmap_, v0) - get(vpmap_, v1); const Vector b = get(vpmap_, v2) - get(vpmap_, v1); @@ -788,9 +788,9 @@ private: }; template< -typename PolygonMesh, -typename PrimaryWeight = Cotangent_weight, -typename SecondaryWeight = Mean_value_weight > + typename PolygonMesh, + typename PrimaryWeight = Cotangent_weight, + typename SecondaryWeight = Mean_value_weight > class Hybrid_weight : public PrimaryWeight, SecondaryWeight { PrimaryWeight primary; @@ -801,8 +801,8 @@ class Hybrid_weight : public PrimaryWeight, SecondaryWeight { public: Hybrid_weight(PolygonMesh& pmesh_) : - primary(pmesh_), - secondary(pmesh_) + primary(pmesh_), + secondary(pmesh_) { } PolygonMesh& pmesh() { @@ -836,7 +836,7 @@ class Scale_dependent_weight_fairing { public: Scale_dependent_weight_fairing(PolygonMesh& pmesh_) : - pmesh_(pmesh_) + pmesh_(pmesh_) { } PolygonMesh& pmesh() { @@ -865,8 +865,8 @@ public: }; template< -typename PolygonMesh, -typename VertexPointMap = typename boost::property_map::type> + typename PolygonMesh, + typename VertexPointMap = typename boost::property_map::type> class Cotangent_weight_with_voronoi_area_fairing { typedef PolygonMesh PM; @@ -876,15 +876,15 @@ class Cotangent_weight_with_voronoi_area_fairing { public: Cotangent_weight_with_voronoi_area_fairing(PM& pmesh_) : - voronoi_functor(pmesh_, get(CGAL::vertex_point, pmesh_)), - cotangent_functor(pmesh_, get(CGAL::vertex_point, pmesh_)) + voronoi_functor(pmesh_, get(CGAL::vertex_point, pmesh_)), + cotangent_functor(pmesh_, get(CGAL::vertex_point, pmesh_)) { } Cotangent_weight_with_voronoi_area_fairing( - PM& pmesh_, - VPMap vpmap_) : - voronoi_functor(pmesh_, vpmap_), - cotangent_functor(pmesh_, vpmap_) + PM& pmesh_, + VPMap vpmap_) : + voronoi_functor(pmesh_, vpmap_), + cotangent_functor(pmesh_, vpmap_) { } PM& pmesh() { @@ -907,8 +907,8 @@ public: // Cotangent_value_Meyer_secure to avoid imprecisions from // the issue #4706 - https://github.com/CGAL/cgal/issues/4706. template< -typename PolygonMesh, -typename VertexPointMap = typename boost::property_map::type> + typename PolygonMesh, + typename VertexPointMap = typename boost::property_map::type> class Cotangent_weight_with_voronoi_area_fairing_secure { typedef PolygonMesh PM; @@ -918,15 +918,15 @@ class Cotangent_weight_with_voronoi_area_fairing_secure { public: Cotangent_weight_with_voronoi_area_fairing_secure(PM& pmesh_) : - voronoi_functor(pmesh_, get(CGAL::vertex_point, pmesh_)), - cotangent_functor(pmesh_, get(CGAL::vertex_point, pmesh_)) + voronoi_functor(pmesh_, get(CGAL::vertex_point, pmesh_)), + cotangent_functor(pmesh_, get(CGAL::vertex_point, pmesh_)) { } Cotangent_weight_with_voronoi_area_fairing_secure( - PM& pmesh_, - VPMap vpmap_) : - voronoi_functor(pmesh_, vpmap_), - cotangent_functor(pmesh_, vpmap_) + PM& pmesh_, + VPMap vpmap_) : + voronoi_functor(pmesh_, vpmap_), + cotangent_functor(pmesh_, vpmap_) { } PM& pmesh() { diff --git a/Weights/include/CGAL/Weights/internal/polygon_utils_2.h b/Weights/include/CGAL/Weights/internal/polygon_utils_2.h index b65ed49828c..c52388c7559 100644 --- a/Weights/include/CGAL/Weights/internal/polygon_utils_2.h +++ b/Weights/include/CGAL/Weights/internal/polygon_utils_2.h @@ -14,7 +14,12 @@ #ifndef CGAL_WEIGHTS_INTERNAL_POLYGON_UTILS_2_H #define CGAL_WEIGHTS_INTERNAL_POLYGON_UTILS_2_H -// STL includes. +#include +#include +#include +#include +#include + #include #include #include @@ -23,345 +28,328 @@ #include #include -// CGAL includes. -#include -#include -#include -#include -#include - namespace CGAL { namespace Weights { namespace internal { - enum class Edge_case { +enum class Edge_case { - EXTERIOR = 0, // exterior part of the polygon - BOUNDARY = 1, // boundary part of the polygon - INTERIOR = 2 // interior part of the polygon - }; + EXTERIOR = 0, // exterior part of the polygon + BOUNDARY = 1, // boundary part of the polygon + INTERIOR = 2 // interior part of the polygon +}; - // VertexRange type enum. - enum class Polygon_type { +// VertexRange type enum. +enum class Polygon_type +{ + CONCAVE = 0, // Concave polygon = non-convex polygon. + WEAKLY_CONVEX = 1, // This is a convex polygon with collinear vertices. + STRICTLY_CONVEX = 2 // This is a convex polygon without collinear vertices. +}; - // Concave polygon = non-convex polygon. - CONCAVE = 0, +// This function is taken from the Polygon_2_algorithms.h header. +// But it is updated to support property maps. +template +int which_side_in_slab_2(const Point_2& query, + const Point_2& low, const Point_2& high, + const Orientation_2& orientation_2, + const CompareX_2& compare_x_2) +{ + const Comparison_result low_x_comp_res = compare_x_2(query, low); + const Comparison_result high_x_comp_res = compare_x_2(query, high); - // This is a convex polygon with collinear vertices. - WEAKLY_CONVEX = 1, - - // This is a convex polygon without collinear vertices. - STRICTLY_CONVEX = 2 - }; - - // This function is taken from the Polygon_2_algorithms.h header. - // But it is updated to support property maps. - template< - class Point_2, - class Orientation_2, - class CompareX_2> - int which_side_in_slab_2( - const Point_2& query, const Point_2& low, const Point_2& high, - const Orientation_2& orientation_2, const CompareX_2& compare_x_2) { - - const auto low_x_comp_res = compare_x_2(query, low); - const auto high_x_comp_res = compare_x_2(query, high); - if (low_x_comp_res == CGAL::SMALLER) { - if (high_x_comp_res == CGAL::SMALLER) { - return -1; - } - } else { - switch (high_x_comp_res) { - case CGAL::LARGER: return 1; - case CGAL::SMALLER: break; - case CGAL::EQUAL: return (low_x_comp_res == CGAL::EQUAL) ? 0 : 1; - } + if (low_x_comp_res == CGAL::SMALLER) { + if (high_x_comp_res == CGAL::SMALLER) { + return -1; } - switch (orientation_2(low, query, high)) { - case CGAL::LEFT_TURN: return 1; - case CGAL::RIGHT_TURN: return -1; - default: return 0; + } else { + switch (high_x_comp_res) { + case CGAL::LARGER: return 1; + case CGAL::SMALLER: break; + case CGAL::EQUAL: return (low_x_comp_res == CGAL::EQUAL) ? 0 : 1; } } - // This function is taken from the Polygon_2_algorithms.h header. - // But it is updated to support property maps. - template< - typename VertexRange, - typename GeomTraits, - typename PointMap> - Edge_case bounded_side_2( - const VertexRange& polygon, const typename GeomTraits::Point_2& query, - const GeomTraits& traits, const PointMap point_map) { - - const auto first = polygon.begin(); - const auto last = polygon.end(); - - auto curr = first; - if (curr == last) { - return Edge_case::EXTERIOR; - } - - auto next = curr; ++next; - if (next == last) { - return Edge_case::EXTERIOR; - } - - const auto compare_x_2 = traits.compare_x_2_object(); - const auto compare_y_2 = traits.compare_y_2_object(); - const auto orientation_2 = traits.orientation_2_object(); - - bool is_inside = false; - auto curr_y_comp_res = compare_y_2(get(point_map, *curr), query); - - // Check if the segment (curr, next) intersects - // the ray { (t, query.y()) | t >= query.x() }. - do { - const auto& currp = get(point_map, *curr); - const auto& nextp = get(point_map, *next); - - auto next_y_comp_res = compare_y_2(nextp, query); - switch (curr_y_comp_res) { - case CGAL::SMALLER: - switch (next_y_comp_res) { - case CGAL::SMALLER: - break; - case CGAL::EQUAL: - switch (compare_x_2(query, nextp)) { - case CGAL::SMALLER: is_inside = !is_inside; break; - case CGAL::EQUAL: return Edge_case::BOUNDARY; - case CGAL::LARGER: break; - } - break; - case CGAL::LARGER: - switch (which_side_in_slab_2( - query, currp, nextp, orientation_2, compare_x_2)) { - case -1: is_inside = !is_inside; break; - case 0: return Edge_case::BOUNDARY; - } - break; - } - break; - case CGAL::EQUAL: - switch (next_y_comp_res) { - case CGAL::SMALLER: - switch (compare_x_2(query, currp)) { - case CGAL::SMALLER: is_inside = !is_inside; break; - case CGAL::EQUAL: return Edge_case::BOUNDARY; - case CGAL::LARGER: break; - } - break; - case CGAL::EQUAL: - switch (compare_x_2(query, currp)) { - case CGAL::SMALLER: - if (compare_x_2(query, nextp) != CGAL::SMALLER) { - return Edge_case::BOUNDARY; - } - break; - case CGAL::EQUAL: return Edge_case::BOUNDARY; - case CGAL::LARGER: - if (compare_x_2(query, nextp) != CGAL::LARGER) { - return Edge_case::BOUNDARY; - } - break; - } - break; - case CGAL::LARGER: - if (compare_x_2(query, currp) == CGAL::EQUAL) { - return Edge_case::BOUNDARY; - } - break; - } - break; - case CGAL::LARGER: - switch (next_y_comp_res) { - case CGAL::SMALLER: - switch (which_side_in_slab_2( - query, nextp, currp, orientation_2, compare_x_2)) { - case -1: is_inside = !is_inside; break; - case 0: return Edge_case::BOUNDARY; - } - break; - case CGAL::EQUAL: - if (compare_x_2(query, nextp) == CGAL::EQUAL) { - return Edge_case::BOUNDARY; - } - break; - case CGAL::LARGER: - break; - } - break; - } - - curr = next; - curr_y_comp_res = next_y_comp_res; - ++next; - if (next == last) { - next = first; - } - } while (curr != first); - return is_inside ? Edge_case::INTERIOR : Edge_case::EXTERIOR; + switch (orientation_2(low, query, high)) { + case CGAL::LEFT_TURN: return 1; + case CGAL::RIGHT_TURN: return -1; + default: return 0; } +} - // This function is taken from the Polygon_2_algorithms.h header. - // But it is updated to support property maps. - template< - typename VertexRange, - typename GeomTraits, - typename PointMap> - bool is_convex_2( - const VertexRange& polygon, const GeomTraits traits, const PointMap point_map) { +// This function is taken from the Polygon_2_algorithms.h header. +// But it is updated to support property maps. +template +Edge_case bounded_side_2(const VertexRange& polygon, + const typename GeomTraits::Point_2& query, + const GeomTraits& traits, + const PointMap point_map) +{ + const auto first = polygon.begin(); + const auto last = polygon.end(); - auto first = polygon.begin(); - const auto last = polygon.end(); + auto curr = first; + if (curr == last) + return Edge_case::EXTERIOR; - auto prev = first; - if (prev == last) { - return true; - } + auto next = curr; + ++next; + if (next == last) + return Edge_case::EXTERIOR; - auto curr = prev; ++curr; - if (curr == last) { - return true; - } + const auto compare_x_2 = traits.compare_x_2_object(); + const auto compare_y_2 = traits.compare_y_2_object(); + const auto orientation_2 = traits.orientation_2_object(); - auto next = curr; ++next; - if (next == last) { - return true; - } + bool is_inside = false; + auto curr_y_comp_res = compare_y_2(get(point_map, *curr), query); - const auto equal_2 = traits.equal_2_object(); - while (equal_2(get(point_map, *prev), get(point_map, *curr))) { - curr = next; ++next; - if (next == last) { - return true; - } - } + // Check if the segment (curr, next) intersects + // the ray { (t, query.y()) | t >= query.x() }. + do { + const auto& currp = get(point_map, *curr); + const auto& nextp = get(point_map, *next); - const auto less_xy_2 = traits.less_xy_2_object(); - const auto orientation_2 = traits.orientation_2_object(); - - bool has_clockwise_triplets = false; - bool has_counterclockwise_triplets = false; - bool order = less_xy_2( - get(point_map, *prev), get(point_map, *curr)); - int num_order_changes = 0; - - do { - switch_orient: - switch (orientation_2( - get(point_map, *prev), get(point_map, *curr), get(point_map, *next))) { - - case CGAL::CLOCKWISE: - has_clockwise_triplets = true; - break; - case CGAL::COUNTERCLOCKWISE: - has_counterclockwise_triplets = true; - break; - case CGAL::ZERO: { - if (equal_2( - get(point_map, *curr), - get(point_map, *next))) { - - if (next == first) { - first = curr; + auto next_y_comp_res = compare_y_2(nextp, query); + switch (curr_y_comp_res) { + case CGAL::SMALLER: + switch (next_y_comp_res) { + case CGAL::SMALLER: + break; + case CGAL::EQUAL: + switch (compare_x_2(query, nextp)) { + case CGAL::SMALLER: is_inside = !is_inside; break; + case CGAL::EQUAL: return Edge_case::BOUNDARY; + case CGAL::LARGER: break; } - ++next; - if (next == last) { - next = first; + break; + case CGAL::LARGER: + switch (which_side_in_slab_2( + query, currp, nextp, orientation_2, compare_x_2)) { + case -1: is_inside = !is_inside; break; + case 0: return Edge_case::BOUNDARY; } - goto switch_orient; - } - break; + break; } - } + break; + case CGAL::EQUAL: + switch (next_y_comp_res) { + case CGAL::SMALLER: + switch (compare_x_2(query, currp)) { + case CGAL::SMALLER: is_inside = !is_inside; break; + case CGAL::EQUAL: return Edge_case::BOUNDARY; + case CGAL::LARGER: break; + } + break; + case CGAL::EQUAL: + switch (compare_x_2(query, currp)) { + case CGAL::SMALLER: + if (compare_x_2(query, nextp) != CGAL::SMALLER) { + return Edge_case::BOUNDARY; + } + break; + case CGAL::EQUAL: return Edge_case::BOUNDARY; + case CGAL::LARGER: + if (compare_x_2(query, nextp) != CGAL::LARGER) { + return Edge_case::BOUNDARY; + } + break; + } + break; + case CGAL::LARGER: + if (compare_x_2(query, currp) == CGAL::EQUAL) { + return Edge_case::BOUNDARY; + } + break; + } + break; + case CGAL::LARGER: + switch (next_y_comp_res) { + case CGAL::SMALLER: + switch (which_side_in_slab_2( + query, nextp, currp, orientation_2, compare_x_2)) { + case -1: is_inside = !is_inside; break; + case 0: return Edge_case::BOUNDARY; + } + break; + case CGAL::EQUAL: + if (compare_x_2(query, nextp) == CGAL::EQUAL) { + return Edge_case::BOUNDARY; + } + break; + case CGAL::LARGER: + break; + } + break; + } - const bool new_order = less_xy_2( - get(point_map, *curr), get(point_map, *next)); + curr = next; + curr_y_comp_res = next_y_comp_res; + ++next; + if (next == last) { + next = first; + } + } while (curr != first); - if (order != new_order) { - num_order_changes++; - } + return is_inside ? Edge_case::INTERIOR : Edge_case::EXTERIOR; +} - if (num_order_changes > 2) { - return false; - } +// This function is taken from the Polygon_2_algorithms.h header. +// But it is updated to support property maps. +template +bool is_convex_2(const VertexRange& polygon, + const GeomTraits traits, + const PointMap point_map) +{ + auto first = polygon.begin(); + const auto last = polygon.end(); - if (has_clockwise_triplets && has_counterclockwise_triplets) { - return false; - } - - prev = curr; - curr = next; - ++next; - if (next == last) { - next = first; - } - order = new_order; - } while (prev != first); + auto prev = first; + if (prev == last) return true; - } - // This function is taken from the Polygon_2_algorithms.h header. - // But it is updated to support property maps. - template< - typename VertexRange, - typename GeomTraits, - typename PointMap> - bool is_simple_2( - const VertexRange& polygon, const GeomTraits traits, const PointMap point_map) { + auto curr = prev; + ++curr; + if (curr == last) + return true; - const auto first = polygon.begin(); - const auto last = polygon.end(); - if (first == last) { + auto next = curr; + ++next; + if (next == last) + return true; + + const auto equal_2 = traits.equal_2_object(); + while (equal_2(get(point_map, *prev), get(point_map, *curr))) { + curr = next; ++next; + if (next == last) return true; - } - - std::vector poly; - poly.reserve(polygon.size()); - for (const auto& vertex : polygon) { - poly.push_back(get(point_map, vertex)); - } - return CGAL::is_simple_2(poly.begin(), poly.end(), traits); } - template< - typename VertexRange, - typename GeomTraits, - typename PointMap> - Polygon_type polygon_type_2( - const VertexRange& polygon, const GeomTraits traits, const PointMap point_map) { + const auto less_xy_2 = traits.less_xy_2_object(); + const auto orientation_2 = traits.orientation_2_object(); - const auto collinear_2 = - traits.collinear_2_object(); - CGAL_precondition(polygon.size() >= 3); + bool has_clockwise_triplets = false; + bool has_counterclockwise_triplets = false; + bool order = less_xy_2(get(point_map, *prev), get(point_map, *curr)); + int num_order_changes = 0; - // First, test the polygon on convexity. - if (is_convex_2(polygon, traits, point_map)) { + do + { +switch_orient: + switch (orientation_2(get(point_map, *prev), get(point_map, *curr), get(point_map, *next))) + { + case CGAL::CLOCKWISE: + has_clockwise_triplets = true; + break; + case CGAL::COUNTERCLOCKWISE: + has_counterclockwise_triplets = true; + break; + case CGAL::ZERO: { + if (equal_2(get(point_map, *curr), + get(point_map, *next))) + { + if (next == first) + first = curr; - // Test all the consequent triplets of polygon vertices on collinearity. - // In case we find at least one, return WEAKLY_CONVEX polygon. - const std::size_t n = polygon.size(); - for (std::size_t i = 0; i < n; ++i) { - const auto& p1 = get(point_map, *(polygon.begin() + i)); + ++next; + if (next == last) + next = first; - const std::size_t im = (i + n - 1) % n; - const std::size_t ip = (i + 1) % n; - - const auto& p0 = get(point_map, *(polygon.begin() + im)); - const auto& p2 = get(point_map, *(polygon.begin() + ip)); - - if (collinear_2(p0, p1, p2)) { - return Polygon_type::WEAKLY_CONVEX; + goto switch_orient; } + break; } - // Otherwise, return STRICTLY_CONVEX polygon. - return Polygon_type::STRICTLY_CONVEX; } - // Otherwise, return CONCAVE polygon. - return Polygon_type::CONCAVE; + + const bool new_order = less_xy_2(get(point_map, *curr), get(point_map, *next)); + + if (order != new_order) + num_order_changes++; + + if (num_order_changes > 2) + return false; + + if (has_clockwise_triplets && has_counterclockwise_triplets) + return false; + + prev = curr; + curr = next; + ++next; + if (next == last) + next = first; + + order = new_order; + } while (prev != first); + + return true; +} + +// This function is taken from the Polygon_2_algorithms.h header. +// But it is updated to support property maps. +template +bool is_simple_2(const VertexRange& polygon, + const GeomTraits traits, + const PointMap point_map) +{ + const auto first = polygon.begin(); + const auto last = polygon.end(); + if (first == last) + return true; + + std::vector poly; + poly.reserve(polygon.size()); + for (const auto& vertex : polygon) + poly.push_back(get(point_map, vertex)); + + return CGAL::is_simple_2(poly.begin(), poly.end(), traits); +} + +template +Polygon_type polygon_type_2(const VertexRange& polygon, + const GeomTraits traits, + const PointMap point_map) +{ + auto collinear_2 = traits.collinear_2_object(); + CGAL_precondition(polygon.size() >= 3); + + // First, test the polygon on convexity. + if (is_convex_2(polygon, traits, point_map)) + { + // Test all the consequent triplets of polygon vertices on collinearity. + // In case we find at least one, return WEAKLY_CONVEX polygon. + const std::size_t n = polygon.size(); + for (std::size_t i = 0; i < n; ++i) + { + const auto& p1 = get(point_map, *(polygon.begin() + i)); + + const std::size_t im = (i + n - 1) % n; + const std::size_t ip = (i + 1) % n; + + const auto& p0 = get(point_map, *(polygon.begin() + im)); + const auto& p2 = get(point_map, *(polygon.begin() + ip)); + + if (collinear_2(p0, p1, p2)) + return Polygon_type::WEAKLY_CONVEX; + } + + // Otherwise, return STRICTLY_CONVEX polygon. + return Polygon_type::STRICTLY_CONVEX; } + // Otherwise, return CONCAVE polygon. + return Polygon_type::CONCAVE; +} + } // namespace internal } // namespace Weights } // namespace CGAL diff --git a/Weights/include/CGAL/Weights/internal/utils.h b/Weights/include/CGAL/Weights/internal/utils.h index 4e6ef42f96c..58eed2cd389 100644 --- a/Weights/include/CGAL/Weights/internal/utils.h +++ b/Weights/include/CGAL/Weights/internal/utils.h @@ -14,722 +14,650 @@ #ifndef CGAL_WEIGHTS_INTERNAL_UTILS_H #define CGAL_WEIGHTS_INTERNAL_UTILS_H -// STL includes. -#include -#include -#include -#include -#include -#include -#include -#include - -// Boost headers. -#include -#include - -// CGAL includes. -#include #include -#include +#include #include +#include #include -#include -#include +#include + +#include + +#include +#include +#include +#include +#include namespace CGAL { namespace Weights { namespace internal { - // Sqrt helpers. - template - class Default_sqrt { +// Sqrt helpers. +template +class Default_sqrt +{ +private: + using Traits = GeomTraits; + using FT = typename Traits::FT; - private: - using Traits = GeomTraits; - using FT = typename Traits::FT; - - public: - FT operator()(const FT value) const { - return static_cast( - CGAL::sqrt(CGAL::to_double(CGAL::abs(value)))); - } - }; - - BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_nested_type_Sqrt, Sqrt, false) - - // Case: do_not_use_default = false. - template::value> - class Get_sqrt { - - public: - using Traits = GeomTraits; - using Sqrt = Default_sqrt; - - static Sqrt sqrt_object(const Traits& ) { - return Sqrt(); - } - }; - - // Case: do_not_use_default = true. - template - class Get_sqrt { - - public: - using Traits = GeomTraits; - using Sqrt = typename Traits::Sqrt; - - static Sqrt sqrt_object(const Traits& traits) { - return traits.sqrt_object(); - } - }; - - // Normalize values. - template - void normalize(std::vector& values) { - - FT sum = FT(0); - for (const FT& value : values) { - sum += value; - } - - CGAL_assertion(sum != FT(0)); - if (sum == FT(0)) { - return; - } - - const FT inv_sum = FT(1) / sum; - for (FT& value : values) { - value *= inv_sum; - } +public: + FT operator()(const FT value) const + { + return static_cast(CGAL::sqrt(CGAL::to_double(CGAL::abs(value)))); } +}; - // Raises value to the power. - template - typename GeomTraits::FT power( - const GeomTraits&, - const typename GeomTraits::FT value, - const typename GeomTraits::FT p) { +BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_nested_type_Sqrt, Sqrt, false) - using FT = typename GeomTraits::FT; - const double base = CGAL::to_double(value); - const double exp = CGAL::to_double(p); - return static_cast(std::pow(base, exp)); +// Case: do_not_use_default = false. +template::value> +class Get_sqrt +{ +public: + using Traits = GeomTraits; + using Sqrt = Default_sqrt; + + static Sqrt sqrt_object(const Traits&) + { + return Sqrt(); } +}; - // Computes distance between two 2D points. - template - typename GeomTraits::FT distance_2( - const GeomTraits& traits, - const typename GeomTraits::Point_2& p, - const typename GeomTraits::Point_2& q) { +// Case: do_not_use_default = true. +template +class Get_sqrt +{ +public: + using Traits = GeomTraits; + using Sqrt = typename Traits::Sqrt; - using Get_sqrt = Get_sqrt; - const auto sqrt = Get_sqrt::sqrt_object(traits); - - const auto squared_distance_2 = - traits.compute_squared_distance_2_object(); - return sqrt(squared_distance_2(p, q)); + static Sqrt sqrt_object(const Traits& traits) + { + return traits.sqrt_object(); } - - // Computes length of a 2D vector. - template - typename GeomTraits::FT length_2( - const GeomTraits& traits, - const typename GeomTraits::Vector_2& v) { - - using Get_sqrt = Get_sqrt; - const auto sqrt = Get_sqrt::sqrt_object(traits); - - const auto squared_length_2 = - traits.compute_squared_length_2_object(); - return sqrt(squared_length_2(v)); - } - - // Normalizes a 2D vector. - template - void normalize_2( - const GeomTraits& traits, - typename GeomTraits::Vector_2& v) { - - using FT = typename GeomTraits::FT; - const FT length = length_2(traits, v); - CGAL_assertion(length != FT(0)); - if (length == FT(0)) { - return; - } - v /= length; - } - - // Computes cotanget between two 2D vectors. - template - typename GeomTraits::FT cotangent_2( - const GeomTraits& traits, - const typename GeomTraits::Point_2& p, - const typename GeomTraits::Point_2& q, - const typename GeomTraits::Point_2& r) { - - using FT = typename GeomTraits::FT; - const auto dot_product_2 = - traits.compute_scalar_product_2_object(); - const auto cross_product_2 = - traits.compute_determinant_2_object(); - const auto construct_vector_2 = - traits.construct_vector_2_object(); - - const auto v1 = construct_vector_2(q, r); - const auto v2 = construct_vector_2(q, p); - - const FT dot = dot_product_2(v1, v2); - const FT cross = cross_product_2(v1, v2); - - const FT length = CGAL::abs(cross); - // CGAL_assertion(length != FT(0)); not really necessary - if (length != FT(0)) { - return dot / length; - } else { - return FT(0); // undefined - } - } - - // Computes tanget between two 2D vectors. - template - typename GeomTraits::FT tangent_2( - const GeomTraits& traits, - const typename GeomTraits::Point_2& p, - const typename GeomTraits::Point_2& q, - const typename GeomTraits::Point_2& r) { - - using FT = typename GeomTraits::FT; - const auto dot_product_2 = - traits.compute_scalar_product_2_object(); - const auto cross_product_2 = - traits.compute_determinant_2_object(); - const auto construct_vector_2 = - traits.construct_vector_2_object(); - - const auto v1 = construct_vector_2(q, r); - const auto v2 = construct_vector_2(q, p); - - const FT dot = dot_product_2(v1, v2); - const FT cross = cross_product_2(v1, v2); - - const FT length = CGAL::abs(cross); - // CGAL_assertion(dot != FT(0)); not really necessary - if (dot != FT(0)) { - return length / dot; - } else { - return FT(0); // undefined - } - } - - // Computes distance between two 3D points. - template - typename GeomTraits::FT distance_3( - const GeomTraits& traits, - const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3& q) { - - using Get_sqrt = Get_sqrt; - const auto sqrt = Get_sqrt::sqrt_object(traits); - - const auto squared_distance_3 = - traits.compute_squared_distance_3_object(); - return sqrt(squared_distance_3(p, q)); - } - - // Computes length of a 3D vector. - template - typename GeomTraits::FT length_3( - const GeomTraits& traits, - const typename GeomTraits::Vector_3& v) { - - using Get_sqrt = Get_sqrt; - const auto sqrt = Get_sqrt::sqrt_object(traits); - - const auto squared_length_3 = - traits.compute_squared_length_3_object(); - return sqrt(squared_length_3(v)); - } - - // Normalizes a 3D vector. - template - void normalize_3( - const GeomTraits& traits, - typename GeomTraits::Vector_3& v) { - - using FT = typename GeomTraits::FT; - const FT length = length_3(traits, v); - CGAL_assertion(length != FT(0)); - if (length == FT(0)) { - return; - } - v /= length; - } - - // Computes cotanget between two 3D vectors. - template - typename GeomTraits::FT cotangent_3( - const GeomTraits& traits, - const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3& q, - const typename GeomTraits::Point_3& r) { - - using FT = typename GeomTraits::FT; - const auto dot_product_3 = - traits.compute_scalar_product_3_object(); - const auto cross_product_3 = - traits.construct_cross_product_vector_3_object(); - const auto construct_vector_3 = - traits.construct_vector_3_object(); - - const auto v1 = construct_vector_3(q, r); - const auto v2 = construct_vector_3(q, p); - - const FT dot = dot_product_3(v1, v2); - const auto cross = cross_product_3(v1, v2); - - const FT length = length_3(traits, cross); - // TODO: - // Not really necessary: since we handle case length = 0. Does this case happen? - // Yes, e.g. in Surface Parameterization tests. Does it affect the results? - // In current applications, not really. - // CGAL_assertion(length != FT(0)); - if (length != FT(0)) { - return dot / length; - } else { - return FT(0); // undefined - } - } - - // Computes tanget between two 3D vectors. - template - typename GeomTraits::FT tangent_3( - const GeomTraits& traits, - const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3& q, - const typename GeomTraits::Point_3& r) { - - using FT = typename GeomTraits::FT; - const auto dot_product_3 = - traits.compute_scalar_product_3_object(); - const auto cross_product_3 = - traits.construct_cross_product_vector_3_object(); - const auto construct_vector_3 = - traits.construct_vector_3_object(); - - const auto v1 = construct_vector_3(q, r); - const auto v2 = construct_vector_3(q, p); - - const FT dot = dot_product_3(v1, v2); - const auto cross = cross_product_3(v1, v2); - - const FT length = length_3(traits, cross); - // CGAL_assertion(dot != FT(0)); not really necessary - if (dot != FT(0)) { - return length / dot; - } else { - return FT(0); // undefined - } - } - - // Computes 3D angle between two vectors. - template - double angle_3( - const GeomTraits& traits, - const typename GeomTraits::Vector_3& v1, - const typename GeomTraits::Vector_3& v2) { - - const auto dot_product_3 = - traits.compute_scalar_product_3_object(); - const double dot = - CGAL::to_double(dot_product_3(v1, v2)); - - double angle_rad = 0.0; - if (dot < -1.0) { - angle_rad = std::acos(-1.0); - } else if (dot > 1.0) { - angle_rad = std::acos(+1.0); - } else { - angle_rad = std::acos(dot); - } - return angle_rad; - } - - // Rotates a 3D point around axis. - template - typename GeomTraits::Point_3 rotate_point_3( - const GeomTraits&, - const double angle_rad, - const typename GeomTraits::Vector_3& axis, - const typename GeomTraits::Point_3& query) { - - using FT = typename GeomTraits::FT; - using Point_3 = typename GeomTraits::Point_3; - - const FT c = static_cast(std::cos(angle_rad)); - const FT s = static_cast(std::sin(angle_rad)); - const FT C = FT(1) - c; - - const auto x = axis.x(); - const auto y = axis.y(); - const auto z = axis.z(); - - return Point_3( - (x * x * C + c) * query.x() + - (x * y * C - z * s) * query.y() + - (x * z * C + y * s) * query.z(), - (y * x * C + z * s) * query.x() + - (y * y * C + c) * query.y() + - (y * z * C - x * s) * query.z(), - (z * x * C - y * s) * query.x() + - (z * y * C + x * s) * query.y() + - (z * z * C + c) * query.z()); - } - - // Computes two 3D orthogonal base vectors wrt a given normal. - template - void orthogonal_bases_3( - const GeomTraits& traits, - const typename GeomTraits::Vector_3& normal, - typename GeomTraits::Vector_3& b1, - typename GeomTraits::Vector_3& b2) { - - using Vector_3 = typename GeomTraits::Vector_3; - const auto cross_product_3 = - traits.construct_cross_product_vector_3_object(); - - const auto nx = normal.x(); - const auto ny = normal.y(); - const auto nz = normal.z(); - - if (CGAL::abs(nz) >= CGAL::abs(ny)) { - b1 = Vector_3(nz, 0, -nx); - } else { - b1 = Vector_3(ny, -nx, 0); - } - b2 = cross_product_3(normal, b1); - - normalize_3(traits, b1); - normalize_3(traits, b2); - } - - // Converts a 3D point into a 2D point wrt to a given plane. - template - typename GeomTraits::Point_2 to_2d( - const GeomTraits& traits, - const typename GeomTraits::Vector_3& b1, - const typename GeomTraits::Vector_3& b2, - const typename GeomTraits::Point_3& origin, - const typename GeomTraits::Point_3& query) { - - using Point_2 = typename GeomTraits::Point_2; - const auto dot_product_3 = - traits.compute_scalar_product_3_object(); - const auto construct_vector_3 = - traits.construct_vector_3_object(); - - const auto v = construct_vector_3(origin, query); - const auto x = dot_product_3(b1, v); - const auto y = dot_product_3(b2, v); - return Point_2(x, y); - } - - // Flattening. - - // \cgalFigureBegin{flattening, flattening.svg} - // The non-planar configuration (top) is flattened to the planar configuration (bottom). - // \cgalFigureEnd - - // When computing weights for a query point \f$q\f$ with respect to its neighbors - // \f$p_0\f$, \f$p_1\f$, and \f$p_2\f$, the local configuration is a quadrilateral - // [\f$p_0\f$, \f$p_1\f$, \f$p_2\f$, \f$q\f$] or two connected triangles [\f$q\f$, \f$p_0\f$, \f$p_1\f$] - // and [\f$q\f$, \f$p_1\f$, \f$p_2\f$]. When working in 3D, these triangles are not - // necessarily coplanar, in other words, they do not belong to the same common plane. - // When they are not coplanar, they can be made coplanar through the process called *flattening* (see the Figure above), - // however the latter introduces a distortion because the weights are computed with respect to the - // flattened configuration rather than to the original non-flat configuration. - - // \subsection Weights_Examples_ProjectionTraits Computing 2D Weights in 3D - - // If you have a 2D polygon in 3D plane that is not an XY plane, you can still compute - // the 2D weights, however you need to provide a special projection traits class. - // The common plane that is used in this example is projectable to the XY plane. We first - // compute `Mean_value_weights_2` for a 3D polygon in this plane. We then also show how to use - // the projection traits to compute the \ref PkgWeightsRefWachspressWeights "2D Wachspress weight" - // for 3D points which are not strictly coplanar. - - // \cgalExample{Weights/projection_traits.cpp} - - // Example of flattening: - - // 3D configuration. - // const Point_3 p0(0, 1, 1); - // const Point_3 p1(2, 0, 1); - // const Point_3 p2(7, 1, 1); - // const Point_3 q0(3, 1, 1); - - // Choose a type of the weight: - // e.g. 0 - Wachspress (WP) weight. - // const FT wp = FT(0); - - // Compute WP weights for q1 which is not on the plane [p0, p1, p2]. - - // Point_3 q1(3, 1, 2); - // std::cout << "3D wachspress (WP, q1): "; - // std::cout << CGAL::Weights::three_point_family_weight(p0, p1, p2, q1, wp) << std::endl; - - // Converge q1 towards q0 that is we flatten the configuration. - // We also compare the result with the authalic weight. - - // std::cout << "Converge q1 to q0: " << std::endl; - // for (FT x = FT(0); x <= FT(1); x += step) { - // std::cout << "3D wachspress/authalic: "; - // q1 = Point_3(3, 1, FT(2) - x); - // std::cout << CGAL::Weights::three_point_family_weight(p0, p1, p2, q1, wp) << "/"; - // std::cout << CGAL::Weights::authalic_weight(p0, p1, p2, q1) << std::endl; - // } - - // Flattens an arbitrary quad into a planar quad. - template - void flatten( - const GeomTraits& traits, - const typename GeomTraits::Point_3& t, // prev neighbor/vertex/point - const typename GeomTraits::Point_3& r, // curr neighbor/vertex/point - const typename GeomTraits::Point_3& p, // next neighbor/vertex/point - const typename GeomTraits::Point_3& q, // query point - typename GeomTraits::Point_2& tf, - typename GeomTraits::Point_2& rf, - typename GeomTraits::Point_2& pf, - typename GeomTraits::Point_2& qf) { - - // std::cout << std::endl; - using Point_3 = typename GeomTraits::Point_3; - using Vector_3 = typename GeomTraits::Vector_3; - - const auto cross_product_3 = - traits.construct_cross_product_vector_3_object(); - const auto construct_vector_3 = - traits.construct_vector_3_object(); - const auto centroid_3 = - traits.construct_centroid_3_object(); - - // Compute centroid. - const auto center = centroid_3(t, r, p, q); - // std::cout << "centroid: " << center << std::endl; - - // Translate. - const Point_3 t1 = Point_3( - t.x() - center.x(), t.y() - center.y(), t.z() - center.z()); - const Point_3 r1 = Point_3( - r.x() - center.x(), r.y() - center.y(), r.z() - center.z()); - const Point_3 p1 = Point_3( - p.x() - center.x(), p.y() - center.y(), p.z() - center.z()); - const Point_3 q1 = Point_3( - q.x() - center.x(), q.y() - center.y(), q.z() - center.z()); - - // std::cout << "translated t1: " << t1 << std::endl; - // std::cout << "translated r1: " << r1 << std::endl; - // std::cout << "translated p1: " << p1 << std::endl; - // std::cout << "translated q1: " << q1 << std::endl; - - // Middle axis. - auto ax = construct_vector_3(q1, r1); - normalize_3(traits, ax); - - // Prev and next vectors. - auto v1 = construct_vector_3(q1, t1); - auto v2 = construct_vector_3(q1, p1); - - normalize_3(traits, v1); - normalize_3(traits, v2); - - // Two triangle normals. - auto n1 = cross_product_3(v1, ax); - auto n2 = cross_product_3(ax, v2); - - normalize_3(traits, n1); - normalize_3(traits, n2); - - // std::cout << "normal n1: " << n1 << std::endl; - // std::cout << "normal n2: " << n2 << std::endl; - - // Angle between two normals. - const double angle_rad = angle_3(traits, n1, n2); - // std::cout << "angle deg n1 <-> n2: " << angle_rad * 180.0 / CGAL_PI << std::endl; - - // Rotate p1 around ax so that it lands onto the plane [q1, t1, r1]. - const auto& t2 = t1; - const auto& r2 = r1; - const auto p2 = rotate_point_3(traits, angle_rad, ax, p1); - const auto& q2 = q1; - // std::cout << "rotated p2: " << p2 << std::endl; - - // Compute orthogonal base vectors. - Vector_3 b1, b2; - const auto& normal = n1; - orthogonal_bases_3(traits, normal, b1, b2); - - // const auto angle12 = angle_3(traits, b1, b2); - // std::cout << "angle deg b1 <-> b2: " << angle12 * 180.0 / CGAL_PI << std::endl; - - // Flatten a quad. - const auto& origin = q2; - tf = to_2d(traits, b1, b2, origin, t2); - rf = to_2d(traits, b1, b2, origin, r2); - pf = to_2d(traits, b1, b2, origin, p2); - qf = to_2d(traits, b1, b2, origin, q2); - - // std::cout << "flattened qf: " << qf << std::endl; - // std::cout << "flattened tf: " << tf << std::endl; - // std::cout << "flattened rf: " << rf << std::endl; - // std::cout << "flattened pf: " << pf << std::endl; - - // std::cout << "A1: " << area_2(traits, rf, qf, pf) << std::endl; - // std::cout << "A2: " << area_2(traits, pf, qf, rf) << std::endl; - // std::cout << "C: " << area_2(traits, tf, rf, pf) << std::endl; - // std::cout << "B: " << area_2(traits, pf, qf, tf) << std::endl; - } - - // Computes area of a 2D triangle. - template - typename GeomTraits::FT area_2( - const GeomTraits& traits, - const typename GeomTraits::Point_2& p, - const typename GeomTraits::Point_2& q, - const typename GeomTraits::Point_2& r) { - - const auto area_2 = traits.compute_area_2_object(); - return area_2(p, q, r); - } - - // Computes positive area of a 2D triangle. - template - typename GeomTraits::FT positive_area_2( - const GeomTraits& traits, - const typename GeomTraits::Point_2& p, - const typename GeomTraits::Point_2& q, - const typename GeomTraits::Point_2& r) { - - return CGAL::abs(area_2(traits, p, q, r)); - } - - // Computes area of a 3D triangle. - template - typename GeomTraits::FT area_3( - const GeomTraits& traits, - const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3& q, - const typename GeomTraits::Point_3& r) { - - using FT = typename GeomTraits::FT; - using Point_3 = typename GeomTraits::Point_3; - using Vector_3 = typename GeomTraits::Vector_3; - - const auto cross_product_3 = - traits.construct_cross_product_vector_3_object(); - const auto construct_vector_3 = - traits.construct_vector_3_object(); - const auto centroid_3 = - traits.construct_centroid_3_object(); - - // Compute centroid. - const auto center = centroid_3(p, q, r); - - // Translate. - const Point_3 a = Point_3( - p.x() - center.x(), p.y() - center.y(), p.z() - center.z()); - const Point_3 b = Point_3( - q.x() - center.x(), q.y() - center.y(), q.z() - center.z()); - const Point_3 c = Point_3( - r.x() - center.x(), r.y() - center.y(), r.z() - center.z()); - - // Prev and next vectors. - auto v1 = construct_vector_3(b, a); - auto v2 = construct_vector_3(b, c); - normalize_3(traits, v1); - normalize_3(traits, v2); - - // Compute normal. - auto normal = cross_product_3(v1, v2); - normalize_3(traits, normal); - - // Compute orthogonal base vectors. - Vector_3 b1, b2; - orthogonal_bases_3(traits, normal, b1, b2); - - // Compute area. - const auto& origin = b; - const auto pf = to_2d(traits, b1, b2, origin, a); - const auto qf = to_2d(traits, b1, b2, origin, b); - const auto rf = to_2d(traits, b1, b2, origin, c); - - const FT A = area_2(traits, pf, qf, rf); - return A; - } - - // Computes positive area of a 3D triangle. - template - typename GeomTraits::FT positive_area_3( - const GeomTraits& traits, - const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3& q, - const typename GeomTraits::Point_3& r) { - - using FT = typename GeomTraits::FT; - const auto construct_vector_3 = - traits.construct_vector_3_object(); - - const auto v1 = construct_vector_3(q, r); - const auto v2 = construct_vector_3(q, p); - - const auto cross_product_3 = - traits.construct_cross_product_vector_3_object(); - const auto cross = cross_product_3(v1, v2); - const FT half = FT(1) / FT(2); - const FT A = half * length_3(traits, cross); - return A; - } - - // Computes a clamped cotangent between two 3D vectors. - // In the old version of weights in PMP, it has been called secure. - // See Weights/internal/pmp_weights_deprecated.h for more information. - template - typename GeomTraits::FT cotangent_3_clamped( - const GeomTraits& traits, - const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3& q, - const typename GeomTraits::Point_3& r) { - - using FT = typename GeomTraits::FT; - using Get_sqrt = Get_sqrt; - const auto sqrt = Get_sqrt::sqrt_object(traits); - - const auto dot_product_3 = - traits.compute_scalar_product_3_object(); - const auto construct_vector_3 = - traits.construct_vector_3_object(); - - const auto v1 = construct_vector_3(q, r); - const auto v2 = construct_vector_3(q, p); - - const FT dot = dot_product_3(v1, v2); - const FT length_v1 = length_3(traits, v1); - const FT length_v2 = length_3(traits, v2); - - const FT lb = -FT(999) / FT(1000), ub = FT(999) / FT(1000); - FT cosine = dot / length_v1 / length_v2; - cosine = (cosine < lb) ? lb : cosine; - cosine = (cosine > ub) ? ub : cosine; - const FT sine = sqrt(FT(1) - cosine * cosine); - - CGAL_assertion(sine != FT(0)); - if (sine != FT(0)) { - return cosine / sine; - } +}; + +template +void normalize(std::vector& values) +{ + FT sum = FT(0); + for (const FT& value : values) + sum += value; + + CGAL_assertion(sum != FT(0)); + if (sum == FT(0)) + return; + + const FT inv_sum = FT(1) / sum; + for (FT& value : values) + value *= inv_sum; +} + +// Raises value to the power. +template +typename GeomTraits::FT power(const GeomTraits&, + const typename GeomTraits::FT value, + const typename GeomTraits::FT p) +{ + using FT = typename GeomTraits::FT; + + const double base = CGAL::to_double(value); + const double exp = CGAL::to_double(p); + + return static_cast(std::pow(base, exp)); +} + +// Computes distance between two 2D points. +template +typename GeomTraits::FT distance_2(const GeomTraits& traits, + const typename GeomTraits::Point_2& p, + const typename GeomTraits::Point_2& q) +{ + using Get_sqrt = Get_sqrt; + const auto sqrt = Get_sqrt::sqrt_object(traits); + + const auto squared_distance_2 = traits.compute_squared_distance_2_object(); + return sqrt(squared_distance_2(p, q)); +} + +// Computes length of a 2D vector. +template +typename GeomTraits::FT length_2(const GeomTraits& traits, + const typename GeomTraits::Vector_2& v) +{ + using Get_sqrt = Get_sqrt; + const auto sqrt = Get_sqrt::sqrt_object(traits); + + const auto squared_length_2 = traits.compute_squared_length_2_object(); + return sqrt(squared_length_2(v)); +} + +template +void normalize_2(const GeomTraits& traits, + typename GeomTraits::Vector_2& v) +{ + using FT = typename GeomTraits::FT; + const FT length = length_2(traits, v); + CGAL_assertion(length != FT(0)); + if (length == FT(0)) + return; + + v /= length; +} + +// Computes cotanget between two 2D vectors. +template +typename GeomTraits::FT cotangent_2(const GeomTraits& traits, + const typename GeomTraits::Point_2& p, + const typename GeomTraits::Point_2& q, + const typename GeomTraits::Point_2& r) +{ + using FT = typename GeomTraits::FT; + const auto dot_product_2 = traits.compute_scalar_product_2_object(); + const auto cross_product_2 = traits.compute_determinant_2_object(); + const auto construct_vector_2 = traits.construct_vector_2_object(); + + const auto v1 = construct_vector_2(q, r); + const auto v2 = construct_vector_2(q, p); + + const FT dot = dot_product_2(v1, v2); + const FT cross = cross_product_2(v1, v2); + + const FT length = CGAL::abs(cross); + // CGAL_assertion(length != FT(0)); not really necessary + if (length != FT(0)) + return dot / length; + else return FT(0); // undefined - } +} + +// Computes tanget between two 2D vectors. +template +typename GeomTraits::FT tangent_2(const GeomTraits& traits, + const typename GeomTraits::Point_2& p, + const typename GeomTraits::Point_2& q, + const typename GeomTraits::Point_2& r) +{ + using FT = typename GeomTraits::FT; + const auto dot_product_2 = traits.compute_scalar_product_2_object(); + const auto cross_product_2 = traits.compute_determinant_2_object(); + const auto construct_vector_2 = traits.construct_vector_2_object(); + + const auto v1 = construct_vector_2(q, r); + const auto v2 = construct_vector_2(q, p); + + const FT dot = dot_product_2(v1, v2); + const FT cross = cross_product_2(v1, v2); + + const FT length = CGAL::abs(cross); + // CGAL_assertion(dot != FT(0)); not really necessary + if (dot != FT(0)) + return length / dot; + else + return FT(0); // undefined +} + +// Computes distance between two 3D points. +template +typename GeomTraits::FT distance_3(const GeomTraits& traits, + const typename GeomTraits::Point_3& p, + const typename GeomTraits::Point_3& q) +{ + using Get_sqrt = Get_sqrt; + const auto sqrt = Get_sqrt::sqrt_object(traits); + + const auto squared_distance_3 = traits.compute_squared_distance_3_object(); + return sqrt(squared_distance_3(p, q)); +} + +template +typename GeomTraits::FT length_3(const GeomTraits& traits, + const typename GeomTraits::Vector_3& v) +{ + using Get_sqrt = Get_sqrt; + const auto sqrt = Get_sqrt::sqrt_object(traits); + + const auto squared_length_3 = traits.compute_squared_length_3_object(); + return sqrt(squared_length_3(v)); +} + +template +void normalize_3(const GeomTraits& traits, + typename GeomTraits::Vector_3& v) +{ + using FT = typename GeomTraits::FT; + + const FT length = length_3(traits, v); + CGAL_assertion(length != FT(0)); + if (length == FT(0)) + return; + + v /= length; +} + +template +typename GeomTraits::FT cotangent_3(const GeomTraits& traits, + const typename GeomTraits::Point_3& p, + const typename GeomTraits::Point_3& q, + const typename GeomTraits::Point_3& r) +{ + using FT = typename GeomTraits::FT; + const auto dot_product_3 = traits.compute_scalar_product_3_object(); + const auto cross_product_3 = traits.construct_cross_product_vector_3_object(); + const auto construct_vector_3 = traits.construct_vector_3_object(); + + const auto v1 = construct_vector_3(q, r); + const auto v2 = construct_vector_3(q, p); + + const FT dot = dot_product_3(v1, v2); + const auto cross = cross_product_3(v1, v2); + + const FT length = length_3(traits, cross); + // TODO: + // Not really necessary: since we handle case length = 0. Does this case happen? + // Yes, e.g. in Surface Parameterization tests. Does it affect the results? + // In current applications, not really. + // CGAL_assertion(length != FT(0)); + if (length != FT(0)) + return dot / length; + else + return FT(0); // undefined +} + +// Computes tanget between two 3D vectors. +template +typename GeomTraits::FT tangent_3(const GeomTraits& traits, + const typename GeomTraits::Point_3& p, + const typename GeomTraits::Point_3& q, + const typename GeomTraits::Point_3& r) +{ + using FT = typename GeomTraits::FT; + const auto dot_product_3 = traits.compute_scalar_product_3_object(); + const auto cross_product_3 = traits.construct_cross_product_vector_3_object(); + const auto construct_vector_3 = traits.construct_vector_3_object(); + + const auto v1 = construct_vector_3(q, r); + const auto v2 = construct_vector_3(q, p); + + const FT dot = dot_product_3(v1, v2); + const auto cross = cross_product_3(v1, v2); + + const FT length = length_3(traits, cross); + // CGAL_assertion(dot != FT(0)); not really necessary + if (dot != FT(0)) + return length / dot; + else + return FT(0); // undefined +} + +// Computes 3D angle between two vectors. +template +double angle_3(const GeomTraits& traits, + const typename GeomTraits::Vector_3& v1, + const typename GeomTraits::Vector_3& v2) +{ + const auto dot_product_3 = traits.compute_scalar_product_3_object(); + const double dot = CGAL::to_double(dot_product_3(v1, v2)); + + double angle_rad = 0.0; + if (dot < -1.0) + angle_rad = std::acos(-1.0); + else if (dot > 1.0) + angle_rad = std::acos(+1.0); + else + angle_rad = std::acos(dot); + + return angle_rad; +} + +// Rotates a 3D point around axis. +template +typename GeomTraits::Point_3 rotate_point_3(const GeomTraits&, + const double angle_rad, + const typename GeomTraits::Vector_3& axis, + const typename GeomTraits::Point_3& query) +{ + using FT = typename GeomTraits::FT; + using Point_3 = typename GeomTraits::Point_3; + + const FT c = static_cast(std::cos(angle_rad)); + const FT s = static_cast(std::sin(angle_rad)); + const FT C = FT(1) - c; + + const auto x = axis.x(); + const auto y = axis.y(); + const auto z = axis.z(); + + return Point_3( + (x * x * C + c) * query.x() + + (x * y * C - z * s) * query.y() + + (x * z * C + y * s) * query.z(), + (y * x * C + z * s) * query.x() + + (y * y * C + c) * query.y() + + (y * z * C - x * s) * query.z(), + (z * x * C - y * s) * query.x() + + (z * y * C + x * s) * query.y() + + (z * z * C + c) * query.z()); +} + +// Computes two 3D orthogonal base vectors wrt a given normal. +template +void orthogonal_bases_3(const GeomTraits& traits, + const typename GeomTraits::Vector_3& normal, + typename GeomTraits::Vector_3& b1, + typename GeomTraits::Vector_3& b2) +{ + using Vector_3 = typename GeomTraits::Vector_3; + const auto cross_product_3 = traits.construct_cross_product_vector_3_object(); + + const auto nx = normal.x(); + const auto ny = normal.y(); + const auto nz = normal.z(); + + if (CGAL::abs(nz) >= CGAL::abs(ny)) + b1 = Vector_3(nz, 0, -nx); + else + b1 = Vector_3(ny, -nx, 0); + + b2 = cross_product_3(normal, b1); + + normalize_3(traits, b1); + normalize_3(traits, b2); +} + +// Converts a 3D point into a 2D point wrt to a given plane. +template +typename GeomTraits::Point_2 to_2d(const GeomTraits& traits, + const typename GeomTraits::Vector_3& b1, + const typename GeomTraits::Vector_3& b2, + const typename GeomTraits::Point_3& origin, + const typename GeomTraits::Point_3& query) +{ + using Point_2 = typename GeomTraits::Point_2; + const auto dot_product_3 = traits.compute_scalar_product_3_object(); + const auto construct_vector_3 = traits.construct_vector_3_object(); + + const auto v = construct_vector_3(origin, query); + const auto x = dot_product_3(b1, v); + const auto y = dot_product_3(b2, v); + + return Point_2(x, y); +} + +// Flattening. + +// \cgalFigureBegin{flattening, flattening.svg} +// The non-planar configuration (top) is flattened to the planar configuration (bottom). +// \cgalFigureEnd + +// When computing weights for a query point \f$q\f$ with respect to its neighbors +// \f$p_0\f$, \f$p_1\f$, and \f$p_2\f$, the local configuration is a quadrilateral +// [\f$p_0\f$, \f$p_1\f$, \f$p_2\f$, \f$q\f$] or two connected triangles [\f$q\f$, \f$p_0\f$, \f$p_1\f$] +// and [\f$q\f$, \f$p_1\f$, \f$p_2\f$]. When working in 3D, these triangles are not +// necessarily coplanar, in other words, they do not belong to the same common plane. +// When they are not coplanar, they can be made coplanar through the process called *flattening* (see the Figure above), +// however the latter introduces a distortion because the weights are computed with respect to the +// flattened configuration rather than to the original non-flat configuration. + +// \subsection Weights_Examples_ProjectionTraits Computing 2D Weights in 3D + +// If you have a 2D polygon in 3D plane that is not an XY plane, you can still compute +// the 2D weights, however you need to provide a special projection traits class. +// The common plane that is used in this example is projectable to the XY plane. We first +// compute `Mean_value_weights_2` for a 3D polygon in this plane. We then also show how to use +// the projection traits to compute the \ref PkgWeightsRefWachspressWeights "2D Wachspress weight" +// for 3D points which are not strictly coplanar. + +// \cgalExample{Weights/projection_traits.cpp} + +// Example of flattening: + +// 3D configuration. +// const Point_3 p0(0, 1, 1); +// const Point_3 p1(2, 0, 1); +// const Point_3 p2(7, 1, 1); +// const Point_3 q0(3, 1, 1); + +// Choose a type of the weight: +// e.g. 0 - Wachspress (WP) weight. +// const FT wp = FT(0); + +// Compute WP weights for q1 which is not on the plane [p0, p1, p2]. + +// Point_3 q1(3, 1, 2); +// std::cout << "3D wachspress (WP, q1): "; +// std::cout << CGAL::Weights::three_point_family_weight(p0, p1, p2, q1, wp) << std::endl; + +// Converge q1 towards q0 that is we flatten the configuration. +// We also compare the result with the authalic weight. + +// std::cout << "Converge q1 to q0: " << std::endl; +// for (FT x = FT(0); x <= FT(1); x += step) { +// std::cout << "3D wachspress/authalic: "; +// q1 = Point_3(3, 1, FT(2) - x); +// std::cout << CGAL::Weights::three_point_family_weight(p0, p1, p2, q1, wp) << "/"; +// std::cout << CGAL::Weights::authalic_weight(p0, p1, p2, q1) << std::endl; +// } + +// Flattens an arbitrary quad into a planar quad. +template +void flatten(const GeomTraits& traits, + const typename GeomTraits::Point_3& t, // prev neighbor/vertex/point + const typename GeomTraits::Point_3& r, // curr neighbor/vertex/point + const typename GeomTraits::Point_3& p, // next neighbor/vertex/point + const typename GeomTraits::Point_3& q, // query point + typename GeomTraits::Point_2& tf, + typename GeomTraits::Point_2& rf, + typename GeomTraits::Point_2& pf, + typename GeomTraits::Point_2& qf) +{ + // std::cout << std::endl; + using Point_3 = typename GeomTraits::Point_3; + using Vector_3 = typename GeomTraits::Vector_3; + + const auto cross_product_3 = traits.construct_cross_product_vector_3_object(); + const auto construct_vector_3 = traits.construct_vector_3_object(); + const auto centroid_3 = traits.construct_centroid_3_object(); + + // Compute centroid. + const auto center = centroid_3(t, r, p, q); + // std::cout << "centroid: " << center << std::endl; + + // Translate. + const Point_3 t1 = Point_3(t.x() - center.x(), t.y() - center.y(), t.z() - center.z()); + const Point_3 r1 = Point_3(r.x() - center.x(), r.y() - center.y(), r.z() - center.z()); + const Point_3 p1 = Point_3(p.x() - center.x(), p.y() - center.y(), p.z() - center.z()); + const Point_3 q1 = Point_3(q.x() - center.x(), q.y() - center.y(), q.z() - center.z()); + + // std::cout << "translated t1: " << t1 << std::endl; + // std::cout << "translated r1: " << r1 << std::endl; + // std::cout << "translated p1: " << p1 << std::endl; + // std::cout << "translated q1: " << q1 << std::endl; + + // Middle axis. + auto ax = construct_vector_3(q1, r1); + normalize_3(traits, ax); + + // Prev and next vectors. + auto v1 = construct_vector_3(q1, t1); + auto v2 = construct_vector_3(q1, p1); + + normalize_3(traits, v1); + normalize_3(traits, v2); + + // Two triangle normals. + auto n1 = cross_product_3(v1, ax); + auto n2 = cross_product_3(ax, v2); + + normalize_3(traits, n1); + normalize_3(traits, n2); + + // std::cout << "normal n1: " << n1 << std::endl; + // std::cout << "normal n2: " << n2 << std::endl; + + // Angle between two normals. + const double angle_rad = angle_3(traits, n1, n2); + // std::cout << "angle deg n1 <-> n2: " << angle_rad * 180.0 / CGAL_PI << std::endl; + + // Rotate p1 around ax so that it lands onto the plane [q1, t1, r1]. + const auto& t2 = t1; + const auto& r2 = r1; + const auto p2 = rotate_point_3(traits, angle_rad, ax, p1); + const auto& q2 = q1; + // std::cout << "rotated p2: " << p2 << std::endl; + + // Compute orthogonal base vectors. + Vector_3 b1, b2; + const auto& normal = n1; + orthogonal_bases_3(traits, normal, b1, b2); + + // const auto angle12 = angle_3(traits, b1, b2); + // std::cout << "angle deg b1 <-> b2: " << angle12 * 180.0 / CGAL_PI << std::endl; + + // Flatten a quad. + const auto& origin = q2; + tf = to_2d(traits, b1, b2, origin, t2); + rf = to_2d(traits, b1, b2, origin, r2); + pf = to_2d(traits, b1, b2, origin, p2); + qf = to_2d(traits, b1, b2, origin, q2); + + // std::cout << "flattened qf: " << qf << std::endl; + // std::cout << "flattened tf: " << tf << std::endl; + // std::cout << "flattened rf: " << rf << std::endl; + // std::cout << "flattened pf: " << pf << std::endl; + + // std::cout << "A1: " << area_2(traits, rf, qf, pf) << std::endl; + // std::cout << "A2: " << area_2(traits, pf, qf, rf) << std::endl; + // std::cout << "C: " << area_2(traits, tf, rf, pf) << std::endl; + // std::cout << "B: " << area_2(traits, pf, qf, tf) << std::endl; +} + +// Computes area of a 2D triangle. +template +typename GeomTraits::FT area_2(const GeomTraits& traits, + const typename GeomTraits::Point_2& p, + const typename GeomTraits::Point_2& q, + const typename GeomTraits::Point_2& r) +{ + const auto area_2 = traits.compute_area_2_object(); + return area_2(p, q, r); +} + +// Computes positive area of a 2D triangle. +template +typename GeomTraits::FT positive_area_2(const GeomTraits& traits, + const typename GeomTraits::Point_2& p, + const typename GeomTraits::Point_2& q, + const typename GeomTraits::Point_2& r) +{ + return CGAL::abs(area_2(traits, p, q, r)); +} + +// Computes area of a 3D triangle. +template +typename GeomTraits::FT area_3(const GeomTraits& traits, + const typename GeomTraits::Point_3& p, + const typename GeomTraits::Point_3& q, + const typename GeomTraits::Point_3& r) +{ + using FT = typename GeomTraits::FT; + using Point_3 = typename GeomTraits::Point_3; + using Vector_3 = typename GeomTraits::Vector_3; + + const auto cross_product_3 = traits.construct_cross_product_vector_3_object(); + const auto construct_vector_3 = traits.construct_vector_3_object(); + const auto centroid_3 = traits.construct_centroid_3_object(); + + // Compute centroid. + const auto center = centroid_3(p, q, r); + + // Translate. + const Point_3 a = Point_3(p.x() - center.x(), p.y() - center.y(), p.z() - center.z()); + const Point_3 b = Point_3(q.x() - center.x(), q.y() - center.y(), q.z() - center.z()); + const Point_3 c = Point_3(r.x() - center.x(), r.y() - center.y(), r.z() - center.z()); + + // Prev and next vectors. + auto v1 = construct_vector_3(b, a); + auto v2 = construct_vector_3(b, c); + normalize_3(traits, v1); + normalize_3(traits, v2); + + // Compute normal. + auto normal = cross_product_3(v1, v2); + normalize_3(traits, normal); + + // Compute orthogonal base vectors. + Vector_3 b1, b2; + orthogonal_bases_3(traits, normal, b1, b2); + + // Compute area. + const auto& origin = b; + const auto pf = to_2d(traits, b1, b2, origin, a); + const auto qf = to_2d(traits, b1, b2, origin, b); + const auto rf = to_2d(traits, b1, b2, origin, c); + + const FT A = area_2(traits, pf, qf, rf); + return A; +} + +// Computes positive area of a 3D triangle. +template +typename GeomTraits::FT positive_area_3(const GeomTraits& traits, + const typename GeomTraits::Point_3& p, + const typename GeomTraits::Point_3& q, + const typename GeomTraits::Point_3& r) +{ + using FT = typename GeomTraits::FT; + + const auto construct_vector_3 = traits.construct_vector_3_object(); + const auto cross_product_3 = traits.construct_cross_product_vector_3_object(); + + const auto v1 = construct_vector_3(q, r); + const auto v2 = construct_vector_3(q, p); + + const auto cross = cross_product_3(v1, v2); + const FT half = FT(1) / FT(2); + const FT A = half * length_3(traits, cross); + return A; +} + +// Computes a clamped cotangent between two 3D vectors. +// In the old version of weights in PMP, it has been called secure. +// See Weights/internal/pmp_weights_deprecated.h for more information. +template +typename GeomTraits::FT cotangent_3_clamped(const GeomTraits& traits, + const typename GeomTraits::Point_3& p, + const typename GeomTraits::Point_3& q, + const typename GeomTraits::Point_3& r) +{ + using FT = typename GeomTraits::FT; + using Get_sqrt = Get_sqrt; + const auto sqrt = Get_sqrt::sqrt_object(traits); + + const auto dot_product_3 = traits.compute_scalar_product_3_object(); + const auto construct_vector_3 = traits.construct_vector_3_object(); + + const auto v1 = construct_vector_3(q, r); + const auto v2 = construct_vector_3(q, p); + + const FT dot = dot_product_3(v1, v2); + const FT length_v1 = length_3(traits, v1); + const FT length_v2 = length_3(traits, v2); + + const FT lb = -FT(999) / FT(1000), ub = FT(999) / FT(1000); + FT cosine = dot / length_v1 / length_v2; + cosine = (cosine < lb) ? lb : cosine; + cosine = (cosine > ub) ? ub : cosine; + const FT sine = sqrt(FT(1) - cosine * cosine); + + CGAL_assertion(sine != FT(0)); + if (sine != FT(0)) + return cosine / sine; + + return FT(0); // undefined +} } // namespace internal } // namespace Weights diff --git a/Weights/include/CGAL/Weights/inverse_distance_weights.h b/Weights/include/CGAL/Weights/inverse_distance_weights.h index 39dd22a189b..28fec763c5e 100644 --- a/Weights/include/CGAL/Weights/inverse_distance_weights.h +++ b/Weights/include/CGAL/Weights/inverse_distance_weights.h @@ -14,219 +14,215 @@ #ifndef CGAL_INVERSE_DISTANCE_WEIGHTS_H #define CGAL_INVERSE_DISTANCE_WEIGHTS_H -// Internal includes. #include namespace CGAL { namespace Weights { - /// \cond SKIP_IN_MANUAL - namespace inverse_distance_ns { +/// \cond SKIP_IN_MANUAL +namespace inverse_distance_ns { - template - FT weight(const FT d) { +template +FT weight(const FT d) +{ + FT w = FT(0); + CGAL_precondition(d != FT(0)); + if (d != FT(0)) + w = FT(1) / d; - FT w = FT(0); - CGAL_precondition(d != FT(0)); - if (d != FT(0)) { - w = FT(1) / d; - } - return w; - } - } - /// \endcond + return w; +} - #if defined(DOXYGEN_RUNNING) +} // namespace inverse_distance_ns - /*! +/// \endcond + +#if defined(DOXYGEN_RUNNING) + +/*! \ingroup PkgWeightsRefInverseDistanceWeights \brief computes the inverse distance weight in 2D using the points `p` and `q`, given a traits class `traits` with geometric objects, predicates, and constructions. */ - template - typename GeomTraits::FT inverse_distance_weight( +template +typename GeomTraits::FT inverse_distance_weight( const typename GeomTraits::Point_2&, const typename GeomTraits::Point_2& p, const typename GeomTraits::Point_2&, const typename GeomTraits::Point_2& q, const GeomTraits& traits) { } - /*! +/*! \ingroup PkgWeightsRefInverseDistanceWeights \brief computes the inverse distance weight in 3D using the points `p` and `q`, given a traits class `traits` with geometric objects, predicates, and constructions. */ - template - typename GeomTraits::FT inverse_distance_weight( +template +typename GeomTraits::FT inverse_distance_weight( const typename GeomTraits::Point_3&, const typename GeomTraits::Point_3& p, const typename GeomTraits::Point_3&, const typename GeomTraits::Point_3& q, const GeomTraits& traits) { } - /*! +/*! \ingroup PkgWeightsRefInverseDistanceWeights \brief computes the inverse distance weight in 2D using the points `p` and `q`, which are parameterized by a `Kernel` K. */ - template - typename K::FT inverse_distance_weight( +template +typename K::FT inverse_distance_weight( const CGAL::Point_2&, const CGAL::Point_2& p, const CGAL::Point_2&, const CGAL::Point_2& q) { } - /*! +/*! \ingroup PkgWeightsRefInverseDistanceWeights \brief computes the inverse distance weight in 3D using the points `p` and `q`, which are parameterized by a `Kernel` K. */ - template - typename K::FT inverse_distance_weight( +template +typename K::FT inverse_distance_weight( const CGAL::Point_3&, const CGAL::Point_3& p, const CGAL::Point_3&, const CGAL::Point_3& q) { } - /*! +/*! \ingroup PkgWeightsRefInverseDistanceWeights \brief computes the inverse distance weight in 2D using the points `p` and `q`, given a traits class `traits` with geometric objects, predicates, and constructions. */ - template - typename GeomTraits::FT inverse_distance_weight( +template +typename GeomTraits::FT inverse_distance_weight( const typename GeomTraits::Point_2& p, const typename GeomTraits::Point_2& q, const GeomTraits& traits) { } - /*! +/*! \ingroup PkgWeightsRefInverseDistanceWeights \brief computes the inverse distance weight in 3D using the points `p` and `q`, given a traits class `traits` with geometric objects, predicates, and constructions. */ - template - typename GeomTraits::FT inverse_distance_weight( +template +typename GeomTraits::FT inverse_distance_weight( const typename GeomTraits::Point_3& p, const typename GeomTraits::Point_3& q, const GeomTraits& traits) { } - /*! +/*! \ingroup PkgWeightsRefInverseDistanceWeights \brief computes the inverse distance weight in 2D using the points `p` and `q`, which are parameterized by a `Kernel` K. */ - template - typename K::FT inverse_distance_weight( +template +typename K::FT inverse_distance_weight( const CGAL::Point_2& p, const CGAL::Point_2& q) { } - /*! +/*! \ingroup PkgWeightsRefInverseDistanceWeights \brief computes the inverse distance weight in 3D using the points `p` and `q`, which are parameterized by a `Kernel` K. */ - template - typename K::FT inverse_distance_weight( +template +typename K::FT inverse_distance_weight( const CGAL::Point_3& p, const CGAL::Point_3& q) { } - #endif // DOXYGEN_RUNNING +#endif // DOXYGEN_RUNNING - /// \cond SKIP_IN_MANUAL - template - typename GeomTraits::FT inverse_distance_weight( - const typename GeomTraits::Point_2&, - const typename GeomTraits::Point_2& r, - const typename GeomTraits::Point_2&, - const typename GeomTraits::Point_2& q, - const GeomTraits& traits) { +/// \cond SKIP_IN_MANUAL +template +typename GeomTraits::FT inverse_distance_weight(const typename GeomTraits::Point_2&, + const typename GeomTraits::Point_2& r, + const typename GeomTraits::Point_2&, + const typename GeomTraits::Point_2& q, + const GeomTraits& traits) +{ + using FT = typename GeomTraits::FT; - using FT = typename GeomTraits::FT; - const FT d = internal::distance_2(traits, q, r); - return inverse_distance_ns::weight(d); - } + const FT d = internal::distance_2(traits, q, r); + return inverse_distance_ns::weight(d); +} - template - typename GeomTraits::FT inverse_distance_weight( - const CGAL::Point_2& t, - const CGAL::Point_2& r, - const CGAL::Point_2& p, - const CGAL::Point_2& q) { +template +typename GeomTraits::FT inverse_distance_weight(const CGAL::Point_2& t, + const CGAL::Point_2& r, + const CGAL::Point_2& p, + const CGAL::Point_2& q) +{ + const GeomTraits traits; + return inverse_distance_weight(t, r, p, q, traits); +} - const GeomTraits traits; - return inverse_distance_weight(t, r, p, q, traits); - } +template +typename GeomTraits::FT inverse_distance_weight(const typename GeomTraits::Point_2& p, + const typename GeomTraits::Point_2& q, + const GeomTraits& traits) +{ + typename GeomTraits::Point_2 stub; + return inverse_distance_weight(stub, p, stub, q, traits); +} - template - typename GeomTraits::FT inverse_distance_weight( - const typename GeomTraits::Point_2& p, - const typename GeomTraits::Point_2& q, - const GeomTraits& traits) { +template +typename GeomTraits::FT inverse_distance_weight(const CGAL::Point_2& p, + const CGAL::Point_2& q) +{ + CGAL::Point_2 stub; + return inverse_distance_weight(stub, p, stub, q); +} - typename GeomTraits::Point_2 stub; - return inverse_distance_weight(stub, p, stub, q, traits); - } +template +typename GeomTraits::FT inverse_distance_weight(const typename GeomTraits::Point_3&, + const typename GeomTraits::Point_3& r, + const typename GeomTraits::Point_3&, + const typename GeomTraits::Point_3& q, + const GeomTraits& traits) +{ + using FT = typename GeomTraits::FT; - template - typename GeomTraits::FT inverse_distance_weight( - const CGAL::Point_2& p, - const CGAL::Point_2& q) { + const FT d = internal::distance_3(traits, q, r); + return inverse_distance_ns::weight(d); +} - CGAL::Point_2 stub; - return inverse_distance_weight(stub, p, stub, q); - } +template +typename GeomTraits::FT inverse_distance_weight(const CGAL::Point_3& t, + const CGAL::Point_3& r, + const CGAL::Point_3& p, + const CGAL::Point_3& q) +{ + const GeomTraits traits; + return inverse_distance_weight(t, r, p, q, traits); +} - template - typename GeomTraits::FT inverse_distance_weight( - const typename GeomTraits::Point_3&, - const typename GeomTraits::Point_3& r, - const typename GeomTraits::Point_3&, - const typename GeomTraits::Point_3& q, - const GeomTraits& traits) { +template +typename GeomTraits::FT inverse_distance_weight(const typename GeomTraits::Point_3& p, + const typename GeomTraits::Point_3& q, + const GeomTraits& traits) +{ + typename GeomTraits::Point_3 stub; + return inverse_distance_weight(stub, p, stub, q, traits); +} - using FT = typename GeomTraits::FT; - const FT d = internal::distance_3(traits, q, r); - return inverse_distance_ns::weight(d); - } +template +typename GeomTraits::FT inverse_distance_weight(const CGAL::Point_3& p, + const CGAL::Point_3& q) +{ + CGAL::Point_3 stub; + return inverse_distance_weight(stub, p, stub, q); +} - template - typename GeomTraits::FT inverse_distance_weight( - const CGAL::Point_3& t, - const CGAL::Point_3& r, - const CGAL::Point_3& p, - const CGAL::Point_3& q) { - - const GeomTraits traits; - return inverse_distance_weight(t, r, p, q, traits); - } - - template - typename GeomTraits::FT inverse_distance_weight( - const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3& q, - const GeomTraits& traits) { - - typename GeomTraits::Point_3 stub; - return inverse_distance_weight(stub, p, stub, q, traits); - } - - template - typename GeomTraits::FT inverse_distance_weight( - const CGAL::Point_3& p, - const CGAL::Point_3& q) { - - CGAL::Point_3 stub; - return inverse_distance_weight(stub, p, stub, q); - } - /// \endcond +/// \endcond } // namespace Weights } // namespace CGAL diff --git a/Weights/include/CGAL/Weights/mean_value_weights.h b/Weights/include/CGAL/Weights/mean_value_weights.h index 814ba883608..810294355ac 100644 --- a/Weights/include/CGAL/Weights/mean_value_weights.h +++ b/Weights/include/CGAL/Weights/mean_value_weights.h @@ -14,498 +14,466 @@ #ifndef CGAL_MEAN_VALUE_WEIGHTS_H #define CGAL_MEAN_VALUE_WEIGHTS_H -// Internal includes. #include #include namespace CGAL { namespace Weights { - /// \cond SKIP_IN_MANUAL - namespace mean_value_ns { +/// \cond SKIP_IN_MANUAL +namespace mean_value_ns { - template - FT sign_of_weight(const FT A1, const FT A2, const FT B) { +template +FT sign_of_weight(const FT A1, const FT A2, const FT B) +{ + if (A1 > FT(0) && A2 > FT(0) && B <= FT(0)) + return +FT(1); - if (A1 > FT(0) && A2 > FT(0) && B <= FT(0)) { - return +FT(1); - } - if (A1 < FT(0) && A2 < FT(0) && B >= FT(0)) { - return -FT(1); - } - if (B > FT(0)) { - return +FT(1); - } - if (B < FT(0)) { - return -FT(1); - } - return FT(0); - } + if (A1 < FT(0) && A2 < FT(0) && B >= FT(0)) + return -FT(1); - template - typename GeomTraits::FT weight( - const GeomTraits& traits, - const typename GeomTraits::FT r1, - const typename GeomTraits::FT r2, - const typename GeomTraits::FT r3, - const typename GeomTraits::FT D1, - const typename GeomTraits::FT D2, - const typename GeomTraits::FT D, - const typename GeomTraits::FT sign) { + if (B > FT(0)) + return +FT(1); - using FT = typename GeomTraits::FT; - using Get_sqrt = internal::Get_sqrt; - const auto sqrt = Get_sqrt::sqrt_object(traits); + if (B < FT(0)) + return -FT(1); - const FT P1 = r1 * r2 + D1; - const FT P2 = r2 * r3 + D2; + return FT(0); +} - FT w = FT(0); - CGAL_precondition(P1 != FT(0) && P2 != FT(0)); - const FT prod = P1 * P2; - if (prod != FT(0)) { - const FT inv = FT(1) / prod; - w = FT(2) * (r1 * r3 - D) * inv; - CGAL_assertion(w >= FT(0)); - w = sqrt(w); - } - w *= FT(2); w *= sign; - return w; - } +template +typename GeomTraits::FT weight(const GeomTraits& traits, + const typename GeomTraits::FT r1, + const typename GeomTraits::FT r2, + const typename GeomTraits::FT r3, + const typename GeomTraits::FT D1, + const typename GeomTraits::FT D2, + const typename GeomTraits::FT D, + const typename GeomTraits::FT sign) +{ + using FT = typename GeomTraits::FT; + + using Get_sqrt = internal::Get_sqrt; + const auto sqrt = Get_sqrt::sqrt_object(traits); + + const FT P1 = r1 * r2 + D1; + const FT P2 = r2 * r3 + D2; + + FT w = FT(0); + CGAL_precondition(P1 != FT(0) && P2 != FT(0)); + const FT prod = P1 * P2; + if (prod != FT(0)) + { + const FT inv = FT(1) / prod; + w = FT(2) * (r1 * r3 - D) * inv; + CGAL_assertion(w >= FT(0)); + w = sqrt(w); } - /// \endcond - #if defined(DOXYGEN_RUNNING) + w *= FT(2); w *= sign; + return w; +} - /*! - \ingroup PkgWeightsRefMeanValueWeights +} // namespace mean_value_ns - \brief computes the mean value weight in 2D at `q` using the points `p0`, `p1`, - and `p2`, given a traits class `traits` with geometric objects, predicates, and constructions. - */ - template - typename GeomTraits::FT mean_value_weight( +/// \endcond + +#if defined(DOXYGEN_RUNNING) + +/*! + \ingroup PkgWeightsRefMeanValueWeights + + \brief computes the mean value weight in 2D at `q` using the points `p0`, `p1`, + and `p2`, given a traits class `traits` with geometric objects, predicates, and constructions. +*/ +template +typename GeomTraits::FT mean_value_weight( const typename GeomTraits::Point_2& p0, const typename GeomTraits::Point_2& p1, const typename GeomTraits::Point_2& p2, const typename GeomTraits::Point_2& q, const GeomTraits& traits) { } - /*! - \ingroup PkgWeightsRefMeanValueWeights +/*! + \ingroup PkgWeightsRefMeanValueWeights - \brief computes the mean value weight in 2D at `q` using the points `p0`, `p1`, - and `p2` which are parameterized by a `Kernel` K. - */ - template - typename K::FT mean_value_weight( + \brief computes the mean value weight in 2D at `q` using the points `p0`, `p1`, + and `p2` which are parameterized by a `Kernel` K. +*/ +template +typename K::FT mean_value_weight( const CGAL::Point_2& p0, const CGAL::Point_2& p1, const CGAL::Point_2& p2, const CGAL::Point_2& q) { } - #endif // DOXYGEN_RUNNING +#endif // DOXYGEN_RUNNING + +/// \cond SKIP_IN_MANUAL +template +typename GeomTraits::FT mean_value_weight(const typename GeomTraits::Point_2& t, + const typename GeomTraits::Point_2& r, + const typename GeomTraits::Point_2& p, + const typename GeomTraits::Point_2& q, + const GeomTraits& traits) +{ + using FT = typename GeomTraits::FT; + + const auto dot_product_2 = traits.compute_scalar_product_2_object(); + const auto construct_vector_2 = traits.construct_vector_2_object(); + + const auto v1 = construct_vector_2(q, t); + const auto v2 = construct_vector_2(q, r); + const auto v3 = construct_vector_2(q, p); + + const FT l1 = internal::length_2(traits, v1); + const FT l2 = internal::length_2(traits, v2); + const FT l3 = internal::length_2(traits, v3); + + const FT D1 = dot_product_2(v1, v2); + const FT D2 = dot_product_2(v2, v3); + const FT D = dot_product_2(v1, v3); + + const FT A1 = internal::area_2(traits, r, q, t); + const FT A2 = internal::area_2(traits, p, q, r); + const FT B = internal::area_2(traits, p, q, t); + + const FT sign = mean_value_ns::sign_of_weight(A1, A2, B); + return mean_value_ns::weight(traits, l1, l2, l3, D1, D2, D, sign); +} + +template +typename GeomTraits::FT mean_value_weight(const CGAL::Point_2& t, + const CGAL::Point_2& r, + const CGAL::Point_2& p, + const CGAL::Point_2& q) +{ + const GeomTraits traits; + return mean_value_weight(t, r, p, q, traits); +} + +namespace internal { + +template +typename GeomTraits::FT mean_value_weight(const typename GeomTraits::Point_3& t, + const typename GeomTraits::Point_3& r, + const typename GeomTraits::Point_3& p, + const typename GeomTraits::Point_3& q, + const GeomTraits& traits) +{ + using Point_2 = typename GeomTraits::Point_2; + Point_2 tf, rf, pf, qf; + internal::flatten(traits, + t, r, p, q, + tf, rf, pf, qf); + return CGAL::Weights::mean_value_weight(tf, rf, pf, qf, traits); +} + +template +typename GeomTraits::FT mean_value_weight(const CGAL::Point_3& t, + const CGAL::Point_3& r, + const CGAL::Point_3& p, + const CGAL::Point_3& q) +{ + const GeomTraits traits; + return mean_value_weight(t, r, p, q, traits); +} + +} // namespace internal + +/// \endcond + +/*! + \ingroup PkgWeightsRefBarycentricMeanValueWeights + + \brief 2D mean value weights for polygons. + + This class implements 2D mean value weights ( \cite cgal:bc:hf-mvcapp-06, + \cite cgal:bc:fhk-gcbcocp-06, \cite cgal:f-mvc-03 ) which can be computed + at any point inside and outside a simple polygon. + + Mean value weights are well-defined inside and outside a simple polygon and are + non-negative in the kernel of a star-shaped polygon. These weights are computed + analytically using the formulation from the `tangent_weight()`. + + \tparam VertexRange a model of `ConstRange` whose iterator type is `RandomAccessIterator` + \tparam GeomTraits a model of `AnalyticWeightTraits_2` + \tparam PointMap a model of `ReadablePropertyMap` whose key type is `VertexRange::value_type` and + value type is `Point_2`. The default is `CGAL::Identity_property_map`. + + \cgalModels `BarycentricWeights_2` +*/ +template > +class Mean_value_weights_2 +{ +public: + /// \name Types + /// @{ /// \cond SKIP_IN_MANUAL - template - typename GeomTraits::FT mean_value_weight( - const typename GeomTraits::Point_2& t, - const typename GeomTraits::Point_2& r, - const typename GeomTraits::Point_2& p, - const typename GeomTraits::Point_2& q, - const GeomTraits& traits) { - - using FT = typename GeomTraits::FT; - const auto dot_product_2 = - traits.compute_scalar_product_2_object(); - const auto construct_vector_2 = - traits.construct_vector_2_object(); - - const auto v1 = construct_vector_2(q, t); - const auto v2 = construct_vector_2(q, r); - const auto v3 = construct_vector_2(q, p); - - const FT l1 = internal::length_2(traits, v1); - const FT l2 = internal::length_2(traits, v2); - const FT l3 = internal::length_2(traits, v3); - - const FT D1 = dot_product_2(v1, v2); - const FT D2 = dot_product_2(v2, v3); - const FT D = dot_product_2(v1, v3); - - const FT A1 = internal::area_2(traits, r, q, t); - const FT A2 = internal::area_2(traits, p, q, r); - const FT B = internal::area_2(traits, p, q, t); - - const FT sign = mean_value_ns::sign_of_weight(A1, A2, B); - return mean_value_ns::weight( - traits, l1, l2, l3, D1, D2, D, sign); - } - - template - typename GeomTraits::FT mean_value_weight( - const CGAL::Point_2& t, - const CGAL::Point_2& r, - const CGAL::Point_2& p, - const CGAL::Point_2& q) { - - const GeomTraits traits; - return mean_value_weight(t, r, p, q, traits); - } - - namespace internal { - - template - typename GeomTraits::FT mean_value_weight( - const typename GeomTraits::Point_3& t, - const typename GeomTraits::Point_3& r, - const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3& q, - const GeomTraits& traits) { - - using Point_2 = typename GeomTraits::Point_2; - Point_2 tf, rf, pf, qf; - internal::flatten( - traits, - t, r, p, q, - tf, rf, pf, qf); - return CGAL::Weights:: - mean_value_weight(tf, rf, pf, qf, traits); - } - - template - typename GeomTraits::FT mean_value_weight( - const CGAL::Point_3& t, - const CGAL::Point_3& r, - const CGAL::Point_3& p, - const CGAL::Point_3& q) { - - const GeomTraits traits; - return mean_value_weight(t, r, p, q, traits); - } - - } // namespace internal + using Vertex_range = VertexRange; + using Geom_traits = GeomTraits; + using Point_map = PointMap; + using Vector_2 = typename GeomTraits::Vector_2; + using Area_2 = typename GeomTraits::Compute_area_2; + using Construct_vector_2 = typename GeomTraits::Construct_vector_2; + using Squared_length_2 = typename GeomTraits::Compute_squared_length_2; + using Scalar_product_2 = typename GeomTraits::Compute_scalar_product_2; + using Get_sqrt = internal::Get_sqrt; + using Sqrt = typename Get_sqrt::Sqrt; /// \endcond - /*! - \ingroup PkgWeightsRefBarycentricMeanValueWeights + /// Number type. + typedef typename GeomTraits::FT FT; - \brief 2D mean value weights for polygons. + /// Point type. + typedef typename GeomTraits::Point_2 Point_2; - This class implements 2D mean value weights ( \cite cgal:bc:hf-mvcapp-06, - \cite cgal:bc:fhk-gcbcocp-06, \cite cgal:f-mvc-03 ) which can be computed - at any point inside and outside a simple polygon. + /// @} - Mean value weights are well-defined inside and outside a simple polygon and are - non-negative in the kernel of a star-shaped polygon. These weights are computed - analytically using the formulation from the `tangent_weight()`. - - \tparam VertexRange - a model of `ConstRange` whose iterator type is `RandomAccessIterator` - - \tparam GeomTraits - a model of `AnalyticWeightTraits_2` - - \tparam PointMap - a model of `ReadablePropertyMap` whose key type is `VertexRange::value_type` and - value type is `Point_2`. The default is `CGAL::Identity_property_map`. - - \cgalModels `BarycentricWeights_2` - */ - template< - typename VertexRange, - typename GeomTraits, - typename PointMap = CGAL::Identity_property_map > - class Mean_value_weights_2 { - - public: - - /// \name Types - /// @{ - - /// \cond SKIP_IN_MANUAL - using Vertex_range = VertexRange; - using Geom_traits = GeomTraits; - using Point_map = PointMap; - - using Vector_2 = typename GeomTraits::Vector_2; - using Area_2 = typename GeomTraits::Compute_area_2; - using Construct_vector_2 = typename GeomTraits::Construct_vector_2; - using Squared_length_2 = typename GeomTraits::Compute_squared_length_2; - using Scalar_product_2 = typename GeomTraits::Compute_scalar_product_2; - using Get_sqrt = internal::Get_sqrt; - using Sqrt = typename Get_sqrt::Sqrt; - /// \endcond - - /// Number type. - typedef typename GeomTraits::FT FT; - - /// Point type. - typedef typename GeomTraits::Point_2 Point_2; - - /// @} - - /// \name Initialization - /// @{ - - /*! - \brief initializes all internal data structures. - - This class implements the behavior of mean value weights - for 2D query points inside simple polygons. - - \param polygon - an instance of `VertexRange` with the vertices of a simple polygon - - \param traits - a traits class with geometric objects, predicates, and constructions; - the default initialization is provided - - \param point_map - an instance of `PointMap` that maps a vertex from `polygon` to `Point_2`; - the default initialization is provided - - \pre polygon.size() >= 3 - \pre polygon is simple - */ - Mean_value_weights_2( - const VertexRange& polygon, - const GeomTraits traits = GeomTraits(), - const PointMap point_map = PointMap()) : - m_polygon(polygon), - m_traits(traits), - m_point_map(point_map), - m_area_2(m_traits.compute_area_2_object()), - m_construct_vector_2(m_traits.construct_vector_2_object()), - m_squared_length_2(m_traits.compute_squared_length_2_object()), - m_scalar_product_2(m_traits.compute_scalar_product_2_object()), - m_sqrt(Get_sqrt::sqrt_object(m_traits)) { - - CGAL_precondition( - polygon.size() >= 3); - CGAL_precondition( - internal::is_simple_2(polygon, traits, point_map)); - resize(); - } - - /// @} - - /// \name Access - /// @{ - - /*! - \brief computes 2D mean value weights. - - This function fills a destination range with 2D mean value weights computed at - the `query` point with respect to the vertices of the input polygon. - - The number of computed weights is equal to the number of polygon vertices. - - \tparam OutIterator - a model of `OutputIterator` whose value type is `FT` - - \param query - a query point - - \param w_begin - the beginning of the destination range with the computed weights - - \return an output iterator to the element in the destination range, - one past the last weight stored - */ - template - OutIterator operator()(const Point_2& query, OutIterator w_begin) { - const bool normalize = false; - return operator()(query, w_begin, normalize); - } - - /// @} - - /// \cond SKIP_IN_MANUAL - template - OutIterator operator()(const Point_2& query, OutIterator weights, const bool normalize) { - return optimal_weights(query, weights, normalize); - } - /// \endcond - - private: - - // Fields. - const VertexRange& m_polygon; - const GeomTraits m_traits; - const PointMap m_point_map; - - const Area_2 m_area_2; - const Construct_vector_2 m_construct_vector_2; - const Squared_length_2 m_squared_length_2; - const Scalar_product_2 m_scalar_product_2; - const Sqrt m_sqrt; - - std::vector s; - std::vector r; - std::vector A; - std::vector D; - std::vector t; - std::vector w; - - // Functions. - void resize() { - s.resize(m_polygon.size()); - r.resize(m_polygon.size()); - A.resize(m_polygon.size()); - D.resize(m_polygon.size()); - t.resize(m_polygon.size()); - w.resize(m_polygon.size()); - } - - template - OutputIterator optimal_weights( - const Point_2& query, OutputIterator weights, const bool normalize) { - - // Get the number of vertices in the polygon. - const std::size_t n = m_polygon.size(); - - // Compute vectors s following the pseudo-code in the Figure 10 from [1]. - for (std::size_t i = 0; i < n; ++i) { - const auto& pi = get(m_point_map, *(m_polygon.begin() + i)); - s[i] = m_construct_vector_2(query, pi); - } - - // Compute lengths r, areas A, and dot products D following the pseudo-code - // in the Figure 10 from [1]. Split the loop to make this computation faster. - const auto& p1 = get(m_point_map, *(m_polygon.begin() + 0)); - const auto& p2 = get(m_point_map, *(m_polygon.begin() + 1)); - - r[0] = m_sqrt(m_squared_length_2(s[0])); - A[0] = m_area_2(p1, p2, query); - D[0] = m_scalar_product_2(s[0], s[1]); - - for (std::size_t i = 1; i < n - 1; ++i) { - const auto& pi1 = get(m_point_map, *(m_polygon.begin() + (i + 0))); - const auto& pi2 = get(m_point_map, *(m_polygon.begin() + (i + 1))); - - r[i] = m_sqrt(m_squared_length_2(s[i])); - A[i] = m_area_2(pi1, pi2, query); - D[i] = m_scalar_product_2(s[i], s[i + 1]); - } - - const auto& pn = get(m_point_map, *(m_polygon.begin() + (n - 1))); - r[n - 1] = m_sqrt(m_squared_length_2(s[n - 1])); - A[n - 1] = m_area_2(pn, p1, query); - D[n - 1] = m_scalar_product_2(s[n - 1], s[0]); - - // Compute intermediate values t using the formulas from slide 19 here - // - http://www.inf.usi.ch/hormann/nsfworkshop/presentations/Hormann.pdf - for (std::size_t i = 0; i < n - 1; ++i) { - CGAL_assertion((r[i] * r[i + 1] + D[i]) != FT(0)); - t[i] = FT(2) * A[i] / (r[i] * r[i + 1] + D[i]); - } - - CGAL_assertion((r[n - 1] * r[0] + D[n - 1]) != FT(0)); - t[n - 1] = FT(2) * A[n - 1] / (r[n - 1] * r[0] + D[n - 1]); - - // Compute mean value weights using the same pseudo-code as before. - CGAL_assertion(r[0] != FT(0)); - w[0] = FT(2) * (t[n - 1] + t[0]) / r[0]; - - for (std::size_t i = 1; i < n - 1; ++i) { - CGAL_assertion(r[i] != FT(0)); - w[i] = FT(2) * (t[i - 1] + t[i]) / r[i]; - } - - CGAL_assertion(r[n - 1] != FT(0)); - w[n - 1] = FT(2) * (t[n - 2] + t[n - 1]) / r[n - 1]; - - // Normalize if necessary. - if (normalize) { - internal::normalize(w); - } - - // Return weights. - for (std::size_t i = 0; i < n; ++i) { - *(weights++) = w[i]; - } - return weights; - } - }; + /// \name Initialization + /// @{ /*! - \ingroup PkgWeightsRefBarycentricMeanValueWeights + \brief initializes all internal data structures. - \brief computes 2D mean value weights for polygons. + This class implements the behavior of mean value weights + for 2D query points inside simple polygons. - This function computes 2D mean value weights at a given `query` point - with respect to the vertices of a simple `polygon`, that is one - weight per vertex. The weights are stored in a destination range - beginning at `w_begin`. - - Internally, the class `Mean_value_weights_2` is used. If one wants to process - multiple query points, it is better to use that class. When using the free function, - internal memory is allocated for each query point, while when using the class, - it is allocated only once which is much more efficient. However, for a few query - points, it is easier to use this function. It can also be used when the processing - time is not a concern. - - \tparam PointRange - a model of `ConstRange` whose iterator type is `RandomAccessIterator` - and value type is `GeomTraits::Point_2` - - \tparam OutIterator - a model of `OutputIterator` whose value type is `GeomTraits::FT` - - \tparam GeomTraits - a model of `AnalyticWeightTraits_2` - - \param polygon - an instance of `PointRange` with 2D points which form a simple polygon - - \param query - a query point - - \param w_begin - the beginning of the destination range with the computed weights - - \param traits - a traits class with geometric objects, predicates, and constructions; - this parameter can be omitted if the traits class can be deduced from the point type - - \return an output iterator to the element in the destination range, - one past the last weight stored + \param polygon an instance of `VertexRange` with the vertices of a simple polygon + \param traits a traits class with geometric objects, predicates, and constructions; + the default initialization is provided + \param point_map an instance of `PointMap` that maps a vertex from `polygon` to `Point_2`; + the default initialization is provided \pre polygon.size() >= 3 \pre polygon is simple */ - template< - typename PointRange, - typename OutIterator, - typename GeomTraits> - OutIterator mean_value_weights_2( - const PointRange& polygon, const typename GeomTraits::Point_2& query, - OutIterator w_begin, const GeomTraits& traits) { - - Mean_value_weights_2 - mean_value(polygon, traits); - return mean_value(query, w_begin); + Mean_value_weights_2(const VertexRange& polygon, + const GeomTraits traits = GeomTraits(), + const PointMap point_map = PointMap()) + : m_polygon(polygon), + m_traits(traits), + m_point_map(point_map), + m_area_2(m_traits.compute_area_2_object()), + m_construct_vector_2(m_traits.construct_vector_2_object()), + m_squared_length_2(m_traits.compute_squared_length_2_object()), + m_scalar_product_2(m_traits.compute_scalar_product_2_object()), + m_sqrt(Get_sqrt::sqrt_object(m_traits)) + { + CGAL_precondition(polygon.size() >= 3); + CGAL_precondition(internal::is_simple_2(polygon, traits, point_map)); + resize(); } + /// @} + + /// \name Access + /// @{ + + /*! + \brief computes 2D mean value weights. + + This function fills a destination range with 2D mean value weights computed at + the `query` point with respect to the vertices of the input polygon. + + The number of computed weights is equal to the number of polygon vertices. + + \tparam OutIterator a model of `OutputIterator` whose value type is `FT` + + \param query a query point + \param w_begin the beginning of the destination range with the computed weights + + \return an output iterator to the element in the destination range, one past the last weight stored + */ + template + OutIterator operator()(const Point_2& query, OutIterator w_begin) + { + const bool normalize = false; + return operator()(query, w_begin, normalize); + } + + /// @} + /// \cond SKIP_IN_MANUAL - template< - typename PointRange, - typename OutIterator> - OutIterator mean_value_weights_2( - const PointRange& polygon, - const typename PointRange::value_type& query, - OutIterator w_begin) { - - using Point_2 = typename PointRange::value_type; - using GeomTraits = typename Kernel_traits::Kernel; - const GeomTraits traits; - return mean_value_weights_2( - polygon, query, w_begin, traits); + template + OutIterator operator()(const Point_2& query, + OutIterator weights, + const bool normalize) + { + return optimal_weights(query, weights, normalize); } + /// \endcond +private: + const VertexRange& m_polygon; + const GeomTraits m_traits; + const PointMap m_point_map; + + const Area_2 m_area_2; + const Construct_vector_2 m_construct_vector_2; + const Squared_length_2 m_squared_length_2; + const Scalar_product_2 m_scalar_product_2; + const Sqrt m_sqrt; + + std::vector s; + std::vector r; + std::vector A; + std::vector D; + std::vector t; + std::vector w; + + void resize() + { + s.resize(m_polygon.size()); + r.resize(m_polygon.size()); + A.resize(m_polygon.size()); + D.resize(m_polygon.size()); + t.resize(m_polygon.size()); + w.resize(m_polygon.size()); + } + + template + OutputIterator optimal_weights(const Point_2& query, + OutputIterator weights, + const bool normalize) + { + const std::size_t n = m_polygon.size(); + + // Compute vectors s following the pseudo-code in the Figure 10 from [1]. + for (std::size_t i = 0; i < n; ++i) + { + const auto& pi = get(m_point_map, *(m_polygon.begin() + i)); + s[i] = m_construct_vector_2(query, pi); + } + + // Compute lengths r, areas A, and dot products D following the pseudo-code + // in the Figure 10 from [1]. Split the loop to make this computation faster. + const auto& p1 = get(m_point_map, *(m_polygon.begin() + 0)); + const auto& p2 = get(m_point_map, *(m_polygon.begin() + 1)); + + r[0] = m_sqrt(m_squared_length_2(s[0])); + A[0] = m_area_2(p1, p2, query); + D[0] = m_scalar_product_2(s[0], s[1]); + + for (std::size_t i = 1; i < n - 1; ++i) + { + const auto& pi1 = get(m_point_map, *(m_polygon.begin() + (i + 0))); + const auto& pi2 = get(m_point_map, *(m_polygon.begin() + (i + 1))); + + r[i] = m_sqrt(m_squared_length_2(s[i])); + A[i] = m_area_2(pi1, pi2, query); + D[i] = m_scalar_product_2(s[i], s[i + 1]); + } + + const auto& pn = get(m_point_map, *(m_polygon.begin() + (n - 1))); + r[n - 1] = m_sqrt(m_squared_length_2(s[n - 1])); + A[n - 1] = m_area_2(pn, p1, query); + D[n - 1] = m_scalar_product_2(s[n - 1], s[0]); + + // Compute intermediate values t using the formulas from slide 19 here + // - http://www.inf.usi.ch/hormann/nsfworkshop/presentations/Hormann.pdf + for (std::size_t i = 0; i < n - 1; ++i) + { + CGAL_assertion((r[i] * r[i + 1] + D[i]) != FT(0)); + t[i] = FT(2) * A[i] / (r[i] * r[i + 1] + D[i]); + } + + CGAL_assertion((r[n - 1] * r[0] + D[n - 1]) != FT(0)); + t[n - 1] = FT(2) * A[n - 1] / (r[n - 1] * r[0] + D[n - 1]); + + // Compute mean value weights using the same pseudo-code as before. + CGAL_assertion(r[0] != FT(0)); + w[0] = FT(2) * (t[n - 1] + t[0]) / r[0]; + + for (std::size_t i = 1; i < n - 1; ++i) + { + CGAL_assertion(r[i] != FT(0)); + w[i] = FT(2) * (t[i - 1] + t[i]) / r[i]; + } + + CGAL_assertion(r[n - 1] != FT(0)); + w[n - 1] = FT(2) * (t[n - 2] + t[n - 1]) / r[n - 1]; + + // Normalize if necessary. + if (normalize) + internal::normalize(w); + + // Return weights. + for (std::size_t i = 0; i < n; ++i) + *(weights++) = w[i]; + + return weights; + } +}; + +/*! + \ingroup PkgWeightsRefBarycentricMeanValueWeights + + \brief computes 2D mean value weights for polygons. + + This function computes 2D mean value weights at a given `query` point + with respect to the vertices of a simple `polygon`, that is one + weight per vertex. The weights are stored in a destination range + beginning at `w_begin`. + + Internally, the class `Mean_value_weights_2` is used. If one wants to process + multiple query points, it is better to use that class. When using the free function, + internal memory is allocated for each query point, while when using the class, + it is allocated only once which is much more efficient. However, for a few query + points, it is easier to use this function. It can also be used when the processing + time is not a concern. + + \tparam PointRange a model of `ConstRange` whose iterator type is `RandomAccessIterator` + and value type is `GeomTraits::Point_2` + \tparam OutIterator a model of `OutputIterator` whose value type is `GeomTraits::FT` + \tparam GeomTraits a model of `AnalyticWeightTraits_2` + + \param polygon an instance of `PointRange` with 2D points which form a simple polygon + \param query a query point + \param w_begin the beginning of the destination range with the computed weights + \param traits a traits class with geometric objects, predicates, and constructions; + this parameter can be omitted if the traits class can be deduced from the point type + + \return an output iterator to the element in the destination range, + one past the last weight stored + + \pre polygon.size() >= 3 + \pre polygon is simple +*/ +template +OutIterator mean_value_weights_2(const PointRange& polygon, + const typename GeomTraits::Point_2& query, + OutIterator w_begin, + const GeomTraits& traits) +{ + Mean_value_weights_2 mean_value(polygon, traits); + return mean_value(query, w_begin); +} + +/// \cond SKIP_IN_MANUAL + +template +OutIterator mean_value_weights_2(const PointRange& polygon, + const typename PointRange::value_type& query, + OutIterator w_begin) +{ + using Point_2 = typename PointRange::value_type; + using GeomTraits = typename Kernel_traits::Kernel; + + const GeomTraits traits; + return mean_value_weights_2(polygon, query, w_begin, traits); +} + +/// \endcond + } // namespace Weights } // namespace CGAL diff --git a/Weights/include/CGAL/Weights/mixed_voronoi_region_weights.h b/Weights/include/CGAL/Weights/mixed_voronoi_region_weights.h index 579e8efda77..0dafc0f198c 100644 --- a/Weights/include/CGAL/Weights/mixed_voronoi_region_weights.h +++ b/Weights/include/CGAL/Weights/mixed_voronoi_region_weights.h @@ -14,157 +14,147 @@ #ifndef CGAL_MIXED_VORONOI_REGION_WEIGHTS_H #define CGAL_MIXED_VORONOI_REGION_WEIGHTS_H -// Internal includes. #include namespace CGAL { namespace Weights { - #if defined(DOXYGEN_RUNNING) +#if defined(DOXYGEN_RUNNING) - /*! - \ingroup PkgWeightsRefMixedVoronoiRegionWeights +/*! + \ingroup PkgWeightsRefMixedVoronoiRegionWeights - \brief computes the area of the mixed Voronoi cell in 2D using the points `p`, `q` - and `r`, given a traits class `traits` with geometric objects, predicates, and constructions. - */ - template - typename GeomTraits::FT mixed_voronoi_area( + \brief computes the area of the mixed Voronoi cell in 2D using the points `p`, `q` + and `r`, given a traits class `traits` with geometric objects, predicates, and constructions. +*/ +template +typename GeomTraits::FT mixed_voronoi_area( const typename GeomTraits::Point_2& p, const typename GeomTraits::Point_2& q, const typename GeomTraits::Point_2& r, const GeomTraits& traits) { } - /*! - \ingroup PkgWeightsRefMixedVoronoiRegionWeights +/*! + \ingroup PkgWeightsRefMixedVoronoiRegionWeights - \brief computes the area of the mixed Voronoi cell in 3D using the points `p`, `q` - and `r`, given a traits class `traits` with geometric objects, predicates, and constructions. - */ - template - typename GeomTraits::FT mixed_voronoi_area( + \brief computes the area of the mixed Voronoi cell in 3D using the points `p`, `q` + and `r`, given a traits class `traits` with geometric objects, predicates, and constructions. +*/ +template +typename GeomTraits::FT mixed_voronoi_area( const typename GeomTraits::Point_3& p, const typename GeomTraits::Point_3& q, const typename GeomTraits::Point_3& r, const GeomTraits& traits) { } - /*! - \ingroup PkgWeightsRefMixedVoronoiRegionWeights +/*! + \ingroup PkgWeightsRefMixedVoronoiRegionWeights - \brief computes the area of the mixed Voronoi cell in 2D using the points `p`, `q` - and `r` which are parameterized by a `Kernel` K. - */ - template - typename K::FT mixed_voronoi_area( + \brief computes the area of the mixed Voronoi cell in 2D using the points `p`, `q` + and `r` which are parameterized by a `Kernel` K. +*/ +template +typename K::FT mixed_voronoi_area( const CGAL::Point_2& p, const CGAL::Point_2& q, const CGAL::Point_2& r) { } - /*! - \ingroup PkgWeightsRefMixedVoronoiRegionWeights +/*! + \ingroup PkgWeightsRefMixedVoronoiRegionWeights - \brief computes the area of the mixed Voronoi cell in 3D using the points `p`, `q` - and `r` which are parameterized by a `Kernel` K. - */ - template - typename K::FT mixed_voronoi_area( + \brief computes the area of the mixed Voronoi cell in 3D using the points `p`, `q` + and `r` which are parameterized by a `Kernel` K. +*/ +template +typename K::FT mixed_voronoi_area( const CGAL::Point_3& p, const CGAL::Point_3& q, const CGAL::Point_3& r) { } - #endif // DOXYGEN_RUNNING +#endif // DOXYGEN_RUNNING - /// \cond SKIP_IN_MANUAL - template - typename GeomTraits::FT mixed_voronoi_area( - const typename GeomTraits::Point_2& p, - const typename GeomTraits::Point_2& q, - const typename GeomTraits::Point_2& r, - const GeomTraits& traits) { +/// \cond SKIP_IN_MANUAL +template +typename GeomTraits::FT mixed_voronoi_area(const typename GeomTraits::Point_2& p, + const typename GeomTraits::Point_2& q, + const typename GeomTraits::Point_2& r, + const GeomTraits& traits) +{ + using FT = typename GeomTraits::FT; + using Point_2 = typename GeomTraits::Point_2; - using FT = typename GeomTraits::FT; - using Point_2 = typename GeomTraits::Point_2; + const auto angle_2 = traits.angle_2_object(); + const auto midpoint_2 = traits.construct_midpoint_2_object(); + const auto circumcenter_2 = traits.construct_circumcenter_2_object(); - const auto angle_2 = - traits.angle_2_object(); - const auto a1 = angle_2(p, q, r); - const auto a2 = angle_2(q, r, p); - const auto a3 = angle_2(r, p, q); + const auto a1 = angle_2(p, q, r); + const auto a2 = angle_2(q, r, p); + const auto a3 = angle_2(r, p, q); - Point_2 center; - const auto midpoint_2 = - traits.construct_midpoint_2_object(); - if (a1 != CGAL::OBTUSE && a2 != CGAL::OBTUSE && a3 != CGAL::OBTUSE) { - const auto circumcenter_2 = - traits.construct_circumcenter_2_object(); - center = circumcenter_2(p, q, r); - } else { - center = midpoint_2(r, p); - } + Point_2 center; + if (a1 != CGAL::OBTUSE && a2 != CGAL::OBTUSE && a3 != CGAL::OBTUSE) + center = circumcenter_2(p, q, r); + else + center = midpoint_2(r, p); - const auto m1 = midpoint_2(q, r); - const auto m2 = midpoint_2(q, p); + const auto m1 = midpoint_2(q, r); + const auto m2 = midpoint_2(q, p); - const FT A1 = internal::positive_area_2(traits, q, m1, center); - const FT A2 = internal::positive_area_2(traits, q, center, m2); - return A1 + A2; - } + const FT A1 = internal::positive_area_2(traits, q, m1, center); + const FT A2 = internal::positive_area_2(traits, q, center, m2); + return A1 + A2; +} - template - typename GeomTraits::FT mixed_voronoi_area( - const CGAL::Point_2& p, - const CGAL::Point_2& q, - const CGAL::Point_2& r) { +template +typename GeomTraits::FT mixed_voronoi_area(const CGAL::Point_2& p, + const CGAL::Point_2& q, + const CGAL::Point_2& r) +{ + const GeomTraits traits; + return mixed_voronoi_area(p, q, r, traits); +} - const GeomTraits traits; - return mixed_voronoi_area(p, q, r, traits); - } +template +typename GeomTraits::FT mixed_voronoi_area(const typename GeomTraits::Point_3& p, + const typename GeomTraits::Point_3& q, + const typename GeomTraits::Point_3& r, + const GeomTraits& traits) +{ + using FT = typename GeomTraits::FT; + using Point_3 = typename GeomTraits::Point_3; - template - typename GeomTraits::FT mixed_voronoi_area( - const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3& q, - const typename GeomTraits::Point_3& r, - const GeomTraits& traits) { + const auto angle_3 = traits.angle_3_object(); + const auto midpoint_3 = traits.construct_midpoint_3_object(); + const auto circumcenter_3 = traits.construct_circumcenter_3_object(); - using FT = typename GeomTraits::FT; - using Point_3 = typename GeomTraits::Point_3; + const auto a1 = angle_3(p, q, r); + const auto a2 = angle_3(q, r, p); + const auto a3 = angle_3(r, p, q); - const auto angle_3 = - traits.angle_3_object(); - const auto a1 = angle_3(p, q, r); - const auto a2 = angle_3(q, r, p); - const auto a3 = angle_3(r, p, q); + Point_3 center; + if (a1 != CGAL::OBTUSE && a2 != CGAL::OBTUSE && a3 != CGAL::OBTUSE) + center = circumcenter_3(p, q, r); + else + center = midpoint_3(r, p); - Point_3 center; - const auto midpoint_3 = - traits.construct_midpoint_3_object(); - if (a1 != CGAL::OBTUSE && a2 != CGAL::OBTUSE && a3 != CGAL::OBTUSE) { - const auto circumcenter_3 = - traits.construct_circumcenter_3_object(); - center = circumcenter_3(p, q, r); - } else { - center = midpoint_3(r, p); - } + const auto m1 = midpoint_3(q, r); + const auto m2 = midpoint_3(q, p); - const auto m1 = midpoint_3(q, r); - const auto m2 = midpoint_3(q, p); + const FT A1 = internal::positive_area_3(traits, q, m1, center); + const FT A2 = internal::positive_area_3(traits, q, center, m2); + return A1 + A2; +} - const FT A1 = internal::positive_area_3(traits, q, m1, center); - const FT A2 = internal::positive_area_3(traits, q, center, m2); - return A1 + A2; - } +template +typename GeomTraits::FT mixed_voronoi_area(const CGAL::Point_3& p, + const CGAL::Point_3& q, + const CGAL::Point_3& r) +{ + const GeomTraits traits; + return mixed_voronoi_area(p, q, r, traits); +} - template - typename GeomTraits::FT mixed_voronoi_area( - const CGAL::Point_3& p, - const CGAL::Point_3& q, - const CGAL::Point_3& r) { - - const GeomTraits traits; - return mixed_voronoi_area(p, q, r, traits); - } - /// \endcond +/// \endcond } // namespace Weights } // namespace CGAL diff --git a/Weights/include/CGAL/Weights/shepard_weights.h b/Weights/include/CGAL/Weights/shepard_weights.h index 0a9fb5f8494..00e21883d21 100644 --- a/Weights/include/CGAL/Weights/shepard_weights.h +++ b/Weights/include/CGAL/Weights/shepard_weights.h @@ -14,46 +14,49 @@ #ifndef CGAL_SHEPARD_WEIGHTS_H #define CGAL_SHEPARD_WEIGHTS_H -// Internal includes. #include namespace CGAL { namespace Weights { - /// \cond SKIP_IN_MANUAL - namespace shepard_ns { +/// \cond SKIP_IN_MANUAL +namespace shepard_ns { - template - typename GeomTraits::FT weight( - const GeomTraits& traits, - const typename GeomTraits::FT d, - const typename GeomTraits::FT p) { +template +typename GeomTraits::FT weight(const GeomTraits& traits, + const typename GeomTraits::FT d, + const typename GeomTraits::FT p) +{ + using FT = typename GeomTraits::FT; - using FT = typename GeomTraits::FT; - FT w = FT(0); - CGAL_precondition(d != FT(0)); - if (d != FT(0)) { - FT denom = d; - if (p != FT(1)) { - denom = internal::power(traits, d, p); - } - w = FT(1) / denom; - } - return w; - } + FT w = FT(0); + CGAL_precondition(d != FT(0)); + if (d != FT(0)) + { + FT denom = d; + if (p != FT(1)) + denom = internal::power(traits, d, p); + + w = FT(1) / denom; } - /// \endcond - #if defined(DOXYGEN_RUNNING) + return w; +} - /*! - \ingroup PkgWeightsRefShepardWeights +} // namespace shepard_ns - \brief computes the Shepard weight in 2D using the points `p` and `q` and the power parameter `a`, - given a traits class `traits` with geometric objects, predicates, and constructions. - */ - template - typename GeomTraits::FT shepard_weight( +/// \endcond + +#if defined(DOXYGEN_RUNNING) + +/*! + \ingroup PkgWeightsRefShepardWeights + + \brief computes the Shepard weight in 2D using the points `p` and `q` and the power parameter `a`, + given a traits class `traits` with geometric objects, predicates, and constructions. +*/ +template +typename GeomTraits::FT shepard_weight( const typename GeomTraits::Point_2&, const typename GeomTraits::Point_2& p, const typename GeomTraits::Point_2&, @@ -61,14 +64,14 @@ namespace Weights { const typename GeomTraits::FT a, const GeomTraits& traits) { } - /*! - \ingroup PkgWeightsRefShepardWeights +/*! + \ingroup PkgWeightsRefShepardWeights - \brief computes the Shepard weight in 3D using the points `p` and `q` and the power parameter `a`, - given a traits class `traits` with geometric objects, predicates, and constructions. - */ - template - typename GeomTraits::FT shepard_weight( + \brief computes the Shepard weight in 3D using the points `p` and `q` and the power parameter `a`, + given a traits class `traits` with geometric objects, predicates, and constructions. +*/ +template +typename GeomTraits::FT shepard_weight( const typename GeomTraits::Point_3&, const typename GeomTraits::Point_3& p, const typename GeomTraits::Point_3&, @@ -76,189 +79,179 @@ namespace Weights { const typename GeomTraits::FT a, const GeomTraits& traits) { } - /*! - \ingroup PkgWeightsRefShepardWeights +/*! + \ingroup PkgWeightsRefShepardWeights - \brief computes the Shepard weight in 2D using the points `p` and `q`, - which are parameterized by a `Kernel` K, and the power parameter `a` which - can be omitted. - */ - template - typename K::FT shepard_weight( + \brief computes the Shepard weight in 2D using the points `p` and `q`, + which are parameterized by a `Kernel` K, and the power parameter `a` which + can be omitted. +*/ +template +typename K::FT shepard_weight( const CGAL::Point_2&, const CGAL::Point_2& p, const CGAL::Point_2&, const CGAL::Point_2& q, const typename K::FT a = typename K::FT(1)) { } - /*! - \ingroup PkgWeightsRefShepardWeights +/*! + \ingroup PkgWeightsRefShepardWeights - \brief computes the Shepard weight in 3D using the points `p` and `q`, - which are parameterized by a `Kernel` K, and the power parameter `a` which - can be omitted. - */ - template - typename K::FT shepard_weight( + \brief computes the Shepard weight in 3D using the points `p` and `q`, + which are parameterized by a `Kernel` K, and the power parameter `a` which + can be omitted. +*/ +template +typename K::FT shepard_weight( const CGAL::Point_3&, const CGAL::Point_3& p, const CGAL::Point_3&, const CGAL::Point_3& q, const typename K::FT a = typename K::FT(1)) { } - /*! - \ingroup PkgWeightsRefShepardWeights +/*! + \ingroup PkgWeightsRefShepardWeights - \brief computes the Shepard weight in 2D using the points `p` and `q` and the power parameter `a`, - given a traits class `traits` with geometric objects, predicates, and constructions. - */ - template - typename GeomTraits::FT shepard_weight( + \brief computes the Shepard weight in 2D using the points `p` and `q` and the power parameter `a`, + given a traits class `traits` with geometric objects, predicates, and constructions. +*/ +template +typename GeomTraits::FT shepard_weight( const typename GeomTraits::Point_2& p, const typename GeomTraits::Point_2& q, const typename GeomTraits::FT a, const GeomTraits& traits) { } - /*! - \ingroup PkgWeightsRefShepardWeights +/*! + \ingroup PkgWeightsRefShepardWeights - \brief computes the Shepard weight in 3D using the points `p` and `q` and the power parameter `a`, - given a traits class `traits` with geometric objects, predicates, and constructions. - */ - template - typename GeomTraits::FT shepard_weight( + \brief computes the Shepard weight in 3D using the points `p` and `q` and the power parameter `a`, + given a traits class `traits` with geometric objects, predicates, and constructions. +*/ +template +typename GeomTraits::FT shepard_weight( const typename GeomTraits::Point_3& p, const typename GeomTraits::Point_3& q, const typename GeomTraits::FT a, const GeomTraits& traits) { } - /*! - \ingroup PkgWeightsRefShepardWeights +/*! + \ingroup PkgWeightsRefShepardWeights - \brief computes the Shepard weight in 2D using the points `p` and `q`, - which are parameterized by a `Kernel` K, and the power parameter `a` which - can be omitted. - */ - template - typename K::FT shepard_weight( + \brief computes the Shepard weight in 2D using the points `p` and `q`, + which are parameterized by a `Kernel` K, and the power parameter `a` which + can be omitted. +*/ +template +typename K::FT shepard_weight( const CGAL::Point_2& p, const CGAL::Point_2& q, const typename K::FT a = typename K::FT(1)) { } - /*! - \ingroup PkgWeightsRefShepardWeights +/*! + \ingroup PkgWeightsRefShepardWeights - \brief computes the Shepard weight in 3D using the points `p` and `q`, - which are parameterized by a `Kernel` K, and the power parameter `a` which - can be omitted. - */ - template - typename K::FT shepard_weight( + \brief computes the Shepard weight in 3D using the points `p` and `q`, + which are parameterized by a `Kernel` K, and the power parameter `a` which + can be omitted. +*/ +template +typename K::FT shepard_weight( const CGAL::Point_3& p, const CGAL::Point_3& q, const typename K::FT a = typename K::FT(1)) { } - #endif // DOXYGEN_RUNNING +#endif // DOXYGEN_RUNNING - /// \cond SKIP_IN_MANUAL - template - typename GeomTraits::FT shepard_weight( - const typename GeomTraits::Point_2&, - const typename GeomTraits::Point_2& r, - const typename GeomTraits::Point_2&, - const typename GeomTraits::Point_2& q, - const typename GeomTraits::FT a, - const GeomTraits& traits) { +/// \cond SKIP_IN_MANUAL +template +typename GeomTraits::FT shepard_weight(const typename GeomTraits::Point_2&, + const typename GeomTraits::Point_2& r, + const typename GeomTraits::Point_2&, + const typename GeomTraits::Point_2& q, + const typename GeomTraits::FT a, + const GeomTraits& traits) +{ + using FT = typename GeomTraits::FT; - using FT = typename GeomTraits::FT; - const FT d = internal::distance_2(traits, q, r); - return shepard_ns::weight(traits, d, a); - } + const FT d = internal::distance_2(traits, q, r); + return shepard_ns::weight(traits, d, a); +} - template - typename GeomTraits::FT shepard_weight( - const CGAL::Point_2& t, - const CGAL::Point_2& r, - const CGAL::Point_2& p, - const CGAL::Point_2& q, - const typename GeomTraits::FT a = - typename GeomTraits::FT(1)) { +template +typename GeomTraits::FT shepard_weight(const CGAL::Point_2& t, + const CGAL::Point_2& r, + const CGAL::Point_2& p, + const CGAL::Point_2& q, + const typename GeomTraits::FT a = typename GeomTraits::FT(1)) +{ + const GeomTraits traits; + return shepard_weight(t, r, p, q, a, traits); +} - const GeomTraits traits; - return shepard_weight(t, r, p, q, a, traits); - } +template +typename GeomTraits::FT shepard_weight(const typename GeomTraits::Point_2& p, + const typename GeomTraits::Point_2& q, + const typename GeomTraits::FT a, + const GeomTraits& traits) +{ + typename GeomTraits::Point_2 stub; + return shepard_weight(stub, p, stub, q, a, traits); +} - template - typename GeomTraits::FT shepard_weight( - const typename GeomTraits::Point_2& p, - const typename GeomTraits::Point_2& q, - const typename GeomTraits::FT a, - const GeomTraits& traits) { +template +typename GeomTraits::FT shepard_weight(const CGAL::Point_2& p, + const CGAL::Point_2& q, + const typename GeomTraits::FT a = typename GeomTraits::FT(1)) +{ + CGAL::Point_2 stub; + return shepard_weight(stub, p, stub, q, a); +} - typename GeomTraits::Point_2 stub; - return shepard_weight(stub, p, stub, q, a, traits); - } +template +typename GeomTraits::FT shepard_weight(const typename GeomTraits::Point_3&, + const typename GeomTraits::Point_3& r, + const typename GeomTraits::Point_3&, + const typename GeomTraits::Point_3& q, + const typename GeomTraits::FT a, + const GeomTraits& traits) +{ + using FT = typename GeomTraits::FT; + const FT d = internal::distance_3(traits, q, r); + return shepard_ns::weight(traits, d, a); +} - template - typename GeomTraits::FT shepard_weight( - const CGAL::Point_2& p, - const CGAL::Point_2& q, - const typename GeomTraits::FT a = - typename GeomTraits::FT(1)) { +template +typename GeomTraits::FT shepard_weight(const CGAL::Point_3& t, + const CGAL::Point_3& r, + const CGAL::Point_3& p, + const CGAL::Point_3& q, + const typename GeomTraits::FT a = typename GeomTraits::FT(1)) +{ + const GeomTraits traits; + return shepard_weight(t, r, p, q, a, traits); +} - CGAL::Point_2 stub; - return shepard_weight(stub, p, stub, q, a); - } +template +typename GeomTraits::FT shepard_weight(const typename GeomTraits::Point_3& p, + const typename GeomTraits::Point_3& q, + const typename GeomTraits::FT a, + const GeomTraits& traits) +{ + typename GeomTraits::Point_3 stub; + return shepard_weight(stub, p, stub, q, a, traits); +} - template - typename GeomTraits::FT shepard_weight( - const typename GeomTraits::Point_3&, - const typename GeomTraits::Point_3& r, - const typename GeomTraits::Point_3&, - const typename GeomTraits::Point_3& q, - const typename GeomTraits::FT a, - const GeomTraits& traits) { +template +typename GeomTraits::FT shepard_weight(const CGAL::Point_3& p, + const CGAL::Point_3& q, + const typename GeomTraits::FT a = typename GeomTraits::FT(1)) +{ + CGAL::Point_3 stub; + return shepard_weight(stub, p, stub, q, a); +} - using FT = typename GeomTraits::FT; - const FT d = internal::distance_3(traits, q, r); - return shepard_ns::weight(traits, d, a); - } - - template - typename GeomTraits::FT shepard_weight( - const CGAL::Point_3& t, - const CGAL::Point_3& r, - const CGAL::Point_3& p, - const CGAL::Point_3& q, - const typename GeomTraits::FT a = - typename GeomTraits::FT(1)) { - - const GeomTraits traits; - return shepard_weight(t, r, p, q, a, traits); - } - - template - typename GeomTraits::FT shepard_weight( - const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3& q, - const typename GeomTraits::FT a, - const GeomTraits& traits) { - - typename GeomTraits::Point_3 stub; - return shepard_weight(stub, p, stub, q, a, traits); - } - - template - typename GeomTraits::FT shepard_weight( - const CGAL::Point_3& p, - const CGAL::Point_3& q, - const typename GeomTraits::FT a = - typename GeomTraits::FT(1)) { - - CGAL::Point_3 stub; - return shepard_weight(stub, p, stub, q, a); - } - /// \endcond +/// \endcond } // namespace Weights } // namespace CGAL diff --git a/Weights/include/CGAL/Weights/tangent_weights.h b/Weights/include/CGAL/Weights/tangent_weights.h index da4c87d0fdd..399878326f7 100644 --- a/Weights/include/CGAL/Weights/tangent_weights.h +++ b/Weights/include/CGAL/Weights/tangent_weights.h @@ -20,489 +20,469 @@ namespace CGAL { namespace Weights { - /// \cond SKIP_IN_MANUAL - namespace tangent_ns { +/// \cond SKIP_IN_MANUAL +namespace tangent_ns { - template - FT half_angle_tangent(const FT r, const FT d, const FT A, const FT D) { - - FT t = FT(0); - const FT P = r * d + D; - CGAL_precondition(P != FT(0)); - if (P != FT(0)) { - const FT inv = FT(2) / P; - t = A * inv; - } - return t; - } - - template - FT half_weight(const FT t, const FT r) { - - FT w = FT(0); - CGAL_precondition(r != FT(0)); - if (r != FT(0)) { - const FT inv = FT(2) / r; - w = t * inv; - } - return w; - } - - template - FT weight(const FT t1, const FT t2, const FT r) { - - FT w = FT(0); - CGAL_precondition(r != FT(0)); - if (r != FT(0)) { - const FT inv = FT(2) / r; - w = (t1 + t2) * inv; - } - return w; - } - - template - FT weight( - const FT d1, const FT r, const FT d2, - const FT A1, const FT A2, - const FT D1, const FT D2) { - - const FT P1 = d1 * r + D1; - const FT P2 = d2 * r + D2; - - FT w = FT(0); - CGAL_precondition(P1 != FT(0) && P2 != FT(0)); - if (P1 != FT(0) && P2 != FT(0)) { - const FT inv1 = FT(2) / P1; - const FT inv2 = FT(2) / P2; - const FT t1 = A1 * inv1; - const FT t2 = A2 * inv2; - w = weight(t1, t2, r); - } - return w; - } - - // This is positive case only. - // This version is based on the positive area. - // This version is more precise for all positive cases. - template - typename GeomTraits::FT tangent_weight_v1( - const typename GeomTraits::Point_3& t, - const typename GeomTraits::Point_3& r, - const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3& q, - const GeomTraits& traits) { - - using FT = typename GeomTraits::FT; - const auto dot_product_3 = - traits.compute_scalar_product_3_object(); - const auto construct_vector_3 = - traits.construct_vector_3_object(); - - const auto v1 = construct_vector_3(q, t); - const auto v2 = construct_vector_3(q, r); - const auto v3 = construct_vector_3(q, p); - - const FT l1 = internal::length_3(traits, v1); - const FT l2 = internal::length_3(traits, v2); - const FT l3 = internal::length_3(traits, v3); - - const FT A1 = internal::positive_area_3(traits, r, q, t); - const FT A2 = internal::positive_area_3(traits, p, q, r); - - const FT D1 = dot_product_3(v1, v2); - const FT D2 = dot_product_3(v2, v3); - - return weight(l1, l2, l3, A1, A2, D1, D2); - } - - // This version handles both positive and negative cases. - // However, it is less precise. - template - typename GeomTraits::FT tangent_weight_v2( - const typename GeomTraits::Point_3& t, - const typename GeomTraits::Point_3& r, - const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3& q, - const GeomTraits& traits) { - - using FT = typename GeomTraits::FT; - const auto construct_vector_3 = - traits.construct_vector_3_object(); - - auto v1 = construct_vector_3(q, t); - auto v2 = construct_vector_3(q, r); - auto v3 = construct_vector_3(q, p); - - const FT l2 = internal::length_3(traits, v2); - - internal::normalize_3(traits, v1); - internal::normalize_3(traits, v2); - internal::normalize_3(traits, v3); - - const double ha_rad_1 = internal::angle_3(traits, v1, v2) / 2.0; - const double ha_rad_2 = internal::angle_3(traits, v2, v3) / 2.0; - const FT t1 = static_cast(std::tan(ha_rad_1)); - const FT t2 = static_cast(std::tan(ha_rad_2)); - - return weight(t1, t2, l2); - } - } - /// \endcond - - /*! - \ingroup PkgWeightsRefTangentWeights - - \brief computes the tangent of the half angle. - - This function computes the tangent of the half angle using the precomputed - distance, area, and dot product values. The returned value is - \f$\frac{2\textbf{A}}{\textbf{d}\textbf{l} + \textbf{D}}\f$. - - \tparam FT - a model of `FieldNumberType` - - \param d - the distance value - - \param l - the distance value - - \param A - the area value - - \param D - the dot product value - - \pre (d * l + D) != 0 - - \sa `half_tangent_weight()` - */ - template - FT tangent_half_angle(const FT d, const FT l, const FT A, const FT D) { - return tangent_ns::half_angle_tangent(d, l, A, D); +template +FT half_angle_tangent(const FT r, const FT d, const FT A, const FT D) +{ + FT t = FT(0); + const FT P = r * d + D; + CGAL_precondition(P != FT(0)); + if (P != FT(0)) + { + const FT inv = FT(2) / P; + t = A * inv; } - /*! - \ingroup PkgWeightsRefTangentWeights + return t; +} - \brief computes the half value of the tangent weight. - - This function constructs the half of the tangent weight using the precomputed - half angle tangent and distance values. The returned value is - \f$\frac{2\textbf{tan05}}{\textbf{d}}\f$. - - \tparam FT - a model of `FieldNumberType` - - \param tan05 - the half angle tangent value - - \param d - the distance value - - \pre d != 0 - - \sa `tangent_half_angle()` - \sa `tangent_weight()` - */ - template - FT half_tangent_weight(const FT tan05, const FT d) { - return tangent_ns::half_weight(tan05, d); +template +FT half_weight(const FT t, const FT r) +{ + FT w = FT(0); + CGAL_precondition(r != FT(0)); + if (r != FT(0)) + { + const FT inv = FT(2) / r; + w = t * inv; } - /*! - \ingroup PkgWeightsRefTangentWeights + return w; +} - \brief computes the half value of the tangent weight. - - This function constructs the half of the tangent weight using the precomputed - distance, area, and dot product values. The returned value is - \f$\frac{2\textbf{t}}{\textbf{d}}\f$ where - \f$\textbf{t} = \frac{2\textbf{A}}{\textbf{d}\textbf{l} + \textbf{D}}\f$. - - \tparam FT - a model of `FieldNumberType` - - \param d - the distance value - - \param l - the distance value - - \param A - the area value - - \param D - the dot product value - - \pre (d * l + D) != 0 && d != 0 - - \sa `tangent_weight()` - */ - template - FT half_tangent_weight(const FT d, const FT l, const FT A, const FT D) { - const FT tan05 = tangent_half_angle(d, l, A, D); - return half_tangent_weight(tan05, d); +template +FT weight(const FT t1, const FT t2, const FT r) +{ + FT w = FT(0); + CGAL_precondition(r != FT(0)); + if (r != FT(0)) + { + const FT inv = FT(2) / r; + w = (t1 + t2) * inv; } - #if defined(DOXYGEN_RUNNING) + return w; +} - /*! - \ingroup PkgWeightsRefTangentWeights +template +FT weight(const FT d1, const FT r, const FT d2, + const FT A1, const FT A2, + const FT D1, const FT D2) +{ + const FT P1 = d1 * r + D1; + const FT P2 = d2 * r + D2; - \brief computes the tangent weight in 2D at `q` using the points `p0`, `p1`, - and `p2`, given a traits class `traits` with geometric objects, predicates, and constructions. - */ - template - typename GeomTraits::FT tangent_weight( + FT w = FT(0); + CGAL_precondition(P1 != FT(0) && P2 != FT(0)); + if (P1 != FT(0) && P2 != FT(0)) + { + const FT inv1 = FT(2) / P1; + const FT inv2 = FT(2) / P2; + const FT t1 = A1 * inv1; + const FT t2 = A2 * inv2; + w = weight(t1, t2, r); + } + + return w; +} + +// This is positive case only. +// This version is based on the positive area. +// This version is more precise for all positive cases. +template +typename GeomTraits::FT tangent_weight_v1(const typename GeomTraits::Point_3& t, + const typename GeomTraits::Point_3& r, + const typename GeomTraits::Point_3& p, + const typename GeomTraits::Point_3& q, + const GeomTraits& traits) +{ + using FT = typename GeomTraits::FT; + + const auto dot_product_3 = traits.compute_scalar_product_3_object(); + const auto construct_vector_3 = traits.construct_vector_3_object(); + + const auto v1 = construct_vector_3(q, t); + const auto v2 = construct_vector_3(q, r); + const auto v3 = construct_vector_3(q, p); + + const FT l1 = internal::length_3(traits, v1); + const FT l2 = internal::length_3(traits, v2); + const FT l3 = internal::length_3(traits, v3); + + const FT A1 = internal::positive_area_3(traits, r, q, t); + const FT A2 = internal::positive_area_3(traits, p, q, r); + + const FT D1 = dot_product_3(v1, v2); + const FT D2 = dot_product_3(v2, v3); + + return weight(l1, l2, l3, A1, A2, D1, D2); +} + +// This version handles both positive and negative cases. +// However, it is less precise. +template +typename GeomTraits::FT tangent_weight_v2(const typename GeomTraits::Point_3& t, + const typename GeomTraits::Point_3& r, + const typename GeomTraits::Point_3& p, + const typename GeomTraits::Point_3& q, + const GeomTraits& traits) +{ + using FT = typename GeomTraits::FT; + + const auto construct_vector_3 = traits.construct_vector_3_object(); + + auto v1 = construct_vector_3(q, t); + auto v2 = construct_vector_3(q, r); + auto v3 = construct_vector_3(q, p); + + const FT l2 = internal::length_3(traits, v2); + + internal::normalize_3(traits, v1); + internal::normalize_3(traits, v2); + internal::normalize_3(traits, v3); + + const double ha_rad_1 = internal::angle_3(traits, v1, v2) / 2.0; + const double ha_rad_2 = internal::angle_3(traits, v2, v3) / 2.0; + const FT t1 = static_cast(std::tan(ha_rad_1)); + const FT t2 = static_cast(std::tan(ha_rad_2)); + + return weight(t1, t2, l2); +} + +} // namespace tangent_ns + +/// \endcond + +/*! + \ingroup PkgWeightsRefTangentWeights + + \brief computes the tangent of the half angle. + + This function computes the tangent of the half angle using the precomputed + distance, area, and dot product values. The returned value is + \f$\frac{2\textbf{A}}{\textbf{d}\textbf{l} + \textbf{D}}\f$. + + \tparam FT a model of `FieldNumberType` + + \param d the distance value + \param l the distance value + \param A the area value + \param D the dot product value + + \pre (d * l + D) != 0 + + \sa `half_tangent_weight()` +*/ +template +FT tangent_half_angle(const FT d, const FT l, const FT A, const FT D) +{ + return tangent_ns::half_angle_tangent(d, l, A, D); +} + +/*! + \ingroup PkgWeightsRefTangentWeights + + \brief computes the half value of the tangent weight. + + This function constructs the half of the tangent weight using the precomputed + half angle tangent and distance values. The returned value is + \f$\frac{2\textbf{tan05}}{\textbf{d}}\f$. + + \tparam FT a model of `FieldNumberType` + + \param tan05 the half angle tangent value + \param d the distance value + + \pre d != 0 + + \sa `tangent_half_angle()` + \sa `tangent_weight()` +*/ +template +FT half_tangent_weight(const FT tan05, const FT d) +{ + return tangent_ns::half_weight(tan05, d); +} + +/*! + \ingroup PkgWeightsRefTangentWeights + + \brief computes the half value of the tangent weight. + + This function constructs the half of the tangent weight using the precomputed + distance, area, and dot product values. The returned value is + \f$\frac{2\textbf{t}}{\textbf{d}}\f$ where + \f$\textbf{t} = \frac{2\textbf{A}}{\textbf{d}\textbf{l} + \textbf{D}}\f$. + + \tparam FT a model of `FieldNumberType` + + \param d the distance value + \param l the distance value + \param A the area value + \param D the dot product value + + \pre (d * l + D) != 0 && d != 0 + + \sa `tangent_weight()` +*/ +template +FT half_tangent_weight(const FT d, const FT l, const FT A, const FT D) +{ + const FT tan05 = tangent_half_angle(d, l, A, D); + return half_tangent_weight(tan05, d); +} + +#if defined(DOXYGEN_RUNNING) + +/*! + \ingroup PkgWeightsRefTangentWeights + + \brief computes the tangent weight in 2D at `q` using the points `p0`, `p1`, + and `p2`, given a traits class `traits` with geometric objects, predicates, and constructions. +*/ +template +typename GeomTraits::FT tangent_weight( const typename GeomTraits::Point_2& p0, const typename GeomTraits::Point_2& p1, const typename GeomTraits::Point_2& p2, const typename GeomTraits::Point_2& q, const GeomTraits& traits) { } - /*! - \ingroup PkgWeightsRefTangentWeights +/*! + \ingroup PkgWeightsRefTangentWeights - \brief computes the tangent weight in 3D at `q` using the points `p0`, `p1`, - and `p2`, given a traits class `traits` with geometric objects, predicates, and constructions. - */ - template - typename GeomTraits::FT tangent_weight( + \brief computes the tangent weight in 3D at `q` using the points `p0`, `p1`, + and `p2`, given a traits class `traits` with geometric objects, predicates, and constructions. +*/ +template +typename GeomTraits::FT tangent_weight( const typename GeomTraits::Point_3& p0, const typename GeomTraits::Point_3& p1, const typename GeomTraits::Point_3& p2, const typename GeomTraits::Point_3& q, const GeomTraits& traits) { } - /*! - \ingroup PkgWeightsRefTangentWeights +/*! + \ingroup PkgWeightsRefTangentWeights - \brief computes the tangent weight in 2D at `q` using the points `p0`, `p1`, - and `p2` which are parameterized by a `Kernel` K. - */ - template - typename K::FT tangent_weight( + \brief computes the tangent weight in 2D at `q` using the points `p0`, `p1`, + and `p2` which are parameterized by a `Kernel` K. +*/ +template +typename K::FT tangent_weight( const CGAL::Point_2& p0, const CGAL::Point_2& p1, const CGAL::Point_2& p2, const CGAL::Point_2& q) { } - /*! - \ingroup PkgWeightsRefTangentWeights +/*! + \ingroup PkgWeightsRefTangentWeights - \brief computes the tangent weight in 3D at `q` using the points `p0`, `p1`, - and `p2` which are parameterized by a `Kernel` K. - */ - template - typename K::FT tangent_weight( + \brief computes the tangent weight in 3D at `q` using the points `p0`, `p1`, + and `p2` which are parameterized by a `Kernel` K. +*/ +template +typename K::FT tangent_weight( const CGAL::Point_3& p0, const CGAL::Point_3& p1, const CGAL::Point_3& p2, const CGAL::Point_3& q) { } - #endif // DOXYGEN_RUNNING +#endif // DOXYGEN_RUNNING - /// \cond SKIP_IN_MANUAL - template - typename GeomTraits::FT tangent_weight( - const typename GeomTraits::Point_2& t, - const typename GeomTraits::Point_2& r, - const typename GeomTraits::Point_2& p, - const typename GeomTraits::Point_2& q, - const GeomTraits& traits) { +/// \cond SKIP_IN_MANUAL +template +typename GeomTraits::FT tangent_weight(const typename GeomTraits::Point_2& t, + const typename GeomTraits::Point_2& r, + const typename GeomTraits::Point_2& p, + const typename GeomTraits::Point_2& q, + const GeomTraits& traits) +{ + using FT = typename GeomTraits::FT; + const auto dot_product_2 = traits.compute_scalar_product_2_object(); + const auto construct_vector_2 = traits.construct_vector_2_object(); - using FT = typename GeomTraits::FT; - const auto dot_product_2 = - traits.compute_scalar_product_2_object(); - const auto construct_vector_2 = - traits.construct_vector_2_object(); + const auto v1 = construct_vector_2(q, t); + const auto v2 = construct_vector_2(q, r); + const auto v3 = construct_vector_2(q, p); - const auto v1 = construct_vector_2(q, t); - const auto v2 = construct_vector_2(q, r); - const auto v3 = construct_vector_2(q, p); + const FT l1 = internal::length_2(traits, v1); + const FT l2 = internal::length_2(traits, v2); + const FT l3 = internal::length_2(traits, v3); - const FT l1 = internal::length_2(traits, v1); - const FT l2 = internal::length_2(traits, v2); - const FT l3 = internal::length_2(traits, v3); + const FT A1 = internal::area_2(traits, r, q, t); + const FT A2 = internal::area_2(traits, p, q, r); - const FT A1 = internal::area_2(traits, r, q, t); - const FT A2 = internal::area_2(traits, p, q, r); + const FT D1 = dot_product_2(v1, v2); + const FT D2 = dot_product_2(v2, v3); - const FT D1 = dot_product_2(v1, v2); - const FT D2 = dot_product_2(v2, v3); + return tangent_ns::weight(l1, l2, l3, A1, A2, D1, D2); +} - return tangent_ns::weight( - l1, l2, l3, A1, A2, D1, D2); +template +typename GeomTraits::FT tangent_weight(const CGAL::Point_2& t, + const CGAL::Point_2& r, + const CGAL::Point_2& p, + const CGAL::Point_2& q) +{ + const GeomTraits traits; + return tangent_weight(t, r, p, q, traits); +} + +template +typename GeomTraits::FT tangent_weight(const typename GeomTraits::Point_3& t, + const typename GeomTraits::Point_3& r, + const typename GeomTraits::Point_3& p, + const typename GeomTraits::Point_3& q, + const GeomTraits& traits) +{ + // return tangent_ns::tangent_weight_v1(t, r, p, q, traits); + return tangent_ns::tangent_weight_v2(t, r, p, q, traits); +} + +template +typename GeomTraits::FT tangent_weight(const CGAL::Point_3& t, + const CGAL::Point_3& r, + const CGAL::Point_3& p, + const CGAL::Point_3& q) +{ + const GeomTraits traits; + return tangent_weight(t, r, p, q, traits); +} + +// Undocumented tangent weight class. +// Its constructor takes a polygon mesh and a vertex to point map +// and its operator() is defined based on the halfedge_descriptor only. +// This version is currently used in: +// Surface_mesh_parameterizer -> Iterative_authalic_parameterizer_3.h +template::type> +class Edge_tangent_weight +{ + using GeomTraits = typename CGAL::Kernel_traits::value_type>::type; + using FT = typename GeomTraits::FT; + + const PolygonMesh& m_pmesh; + const VertexPointMap m_pmap; + const GeomTraits m_traits; + +public: + using vertex_descriptor = typename boost::graph_traits::vertex_descriptor; + using halfedge_descriptor = typename boost::graph_traits::halfedge_descriptor; + + Edge_tangent_weight(const PolygonMesh& pmesh, const VertexPointMap pmap) + : m_pmesh(pmesh), m_pmap(pmap), m_traits() + { } + + FT operator()(const halfedge_descriptor he) const + { + FT weight = FT(0); + if (is_border_edge(he, m_pmesh)) + { + const auto h1 = next(he, m_pmesh); + + const auto v0 = target(he, m_pmesh); + const auto v1 = source(he, m_pmesh); + const auto v2 = target(h1, m_pmesh); + + const auto& p0 = get(m_pmap, v0); + const auto& p1 = get(m_pmap, v1); + const auto& p2 = get(m_pmap, v2); + + weight = internal::tangent_3(m_traits, p0, p2, p1); + } + else + { + const auto h1 = next(he, m_pmesh); + const auto h2 = prev(opposite(he, m_pmesh), m_pmesh); + + const auto v0 = target(he, m_pmesh); + const auto v1 = source(he, m_pmesh); + const auto v2 = target(h1, m_pmesh); + const auto v3 = source(h2, m_pmesh); + + const auto& p0 = get(m_pmap, v0); + const auto& p1 = get(m_pmap, v1); + const auto& p2 = get(m_pmap, v2); + const auto& p3 = get(m_pmap, v3); + + weight = tangent_weight(p2, p1, p3, p0) / FT(2); + } + return weight; } +}; +// Undocumented tangent weight class. +// Its constructor takes three points either in 2D or 3D. +// This version is currently used in: +// Surface_mesh_parameterizer -> MVC_post_processor_3.h +// Surface_mesh_parameterizer -> Orbifold_Tutte_parameterizer_3.h +template +class Tangent_weight { + FT m_d_r, m_d_p, m_w_base; + +public: template - typename GeomTraits::FT tangent_weight( - const CGAL::Point_2& t, - const CGAL::Point_2& r, - const CGAL::Point_2& p, - const CGAL::Point_2& q) { - + Tangent_weight(const CGAL::Point_2& p, + const CGAL::Point_2& q, + const CGAL::Point_2& r) + { const GeomTraits traits; - return tangent_weight(t, r, p, q, traits); + + const auto scalar_product_2 = traits.compute_scalar_product_2_object(); + const auto construct_vector_2 = traits.construct_vector_2_object(); + + m_d_r = internal::distance_2(traits, q, r); + CGAL_assertion(m_d_r != FT(0)); // two points are identical! + m_d_p = internal::distance_2(traits, q, p); + CGAL_assertion(m_d_p != FT(0)); // two points are identical! + + const auto v1 = construct_vector_2(q, r); + const auto v2 = construct_vector_2(q, p); + + const auto A = internal::positive_area_2(traits, p, q, r); + CGAL_assertion(A != FT(0)); // three points are identical! + const auto S = scalar_product_2(v1, v2); + m_w_base = -tangent_half_angle(m_d_r, m_d_p, A, S); } template - typename GeomTraits::FT tangent_weight( - const typename GeomTraits::Point_3& t, - const typename GeomTraits::Point_3& r, - const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3& q, - const GeomTraits& traits) { - - // return tangent_ns::tangent_weight_v1(t, r, p, q, traits); - return tangent_ns::tangent_weight_v2(t, r, p, q, traits); - } - - template - typename GeomTraits::FT tangent_weight( - const CGAL::Point_3& t, - const CGAL::Point_3& r, - const CGAL::Point_3& p, - const CGAL::Point_3& q) { - + Tangent_weight(const CGAL::Point_3& p, + const CGAL::Point_3& q, + const CGAL::Point_3& r) + { const GeomTraits traits; - return tangent_weight(t, r, p, q, traits); + const auto scalar_product_3 = traits.compute_scalar_product_3_object(); + const auto construct_vector_3 = traits.construct_vector_3_object(); + + m_d_r = internal::distance_3(traits, q, r); + CGAL_assertion(m_d_r != FT(0)); // two points are identical! + m_d_p = internal::distance_3(traits, q, p); + CGAL_assertion(m_d_p != FT(0)); // two points are identical! + + const auto v1 = construct_vector_3(q, r); + const auto v2 = construct_vector_3(q, p); + + const auto A = internal::positive_area_3(traits, p, q, r); + CGAL_assertion(A != FT(0)); // three points are identical! + const auto S = scalar_product_3(v1, v2); + m_w_base = -tangent_half_angle(m_d_r, m_d_p, A, S); } - // Undocumented tangent weight class. - // Its constructor takes a polygon mesh and a vertex to point map - // and its operator() is defined based on the halfedge_descriptor only. - // This version is currently used in: - // Surface_mesh_parameterizer -> Iterative_authalic_parameterizer_3.h - template< - typename PolygonMesh, - typename VertexPointMap = typename boost::property_map::type> - class Edge_tangent_weight { + FT get_w_r() const + { + return half_tangent_weight(m_w_base, m_d_r) / FT(2); + } - using GeomTraits = typename CGAL::Kernel_traits< - typename boost::property_traits::value_type>::type; - using FT = typename GeomTraits::FT; + FT get_w_p() const + { + return half_tangent_weight(m_w_base, m_d_p) / FT(2); + } +}; - const PolygonMesh& m_pmesh; - const VertexPointMap m_pmap; - const GeomTraits m_traits; - - public: - using vertex_descriptor = typename boost::graph_traits::vertex_descriptor; - using halfedge_descriptor = typename boost::graph_traits::halfedge_descriptor; - - Edge_tangent_weight(const PolygonMesh& pmesh, const VertexPointMap pmap) : - m_pmesh(pmesh), m_pmap(pmap), m_traits() { } - - FT operator()(const halfedge_descriptor he) const { - - FT weight = FT(0); - if (is_border_edge(he, m_pmesh)) { - const auto h1 = next(he, m_pmesh); - - const auto v0 = target(he, m_pmesh); - const auto v1 = source(he, m_pmesh); - const auto v2 = target(h1, m_pmesh); - - const auto& p0 = get(m_pmap, v0); - const auto& p1 = get(m_pmap, v1); - const auto& p2 = get(m_pmap, v2); - - weight = internal::tangent_3(m_traits, p0, p2, p1); - - } else { - const auto h1 = next(he, m_pmesh); - const auto h2 = prev(opposite(he, m_pmesh), m_pmesh); - - const auto v0 = target(he, m_pmesh); - const auto v1 = source(he, m_pmesh); - const auto v2 = target(h1, m_pmesh); - const auto v3 = source(h2, m_pmesh); - - const auto& p0 = get(m_pmap, v0); - const auto& p1 = get(m_pmap, v1); - const auto& p2 = get(m_pmap, v2); - const auto& p3 = get(m_pmap, v3); - - weight = tangent_weight(p2, p1, p3, p0) / FT(2); - } - return weight; - } - }; - - // Undocumented tangent weight class. - // Its constructor takes three points either in 2D or 3D. - // This version is currently used in: - // Surface_mesh_parameterizer -> MVC_post_processor_3.h - // Surface_mesh_parameterizer -> Orbifold_Tutte_parameterizer_3.h - template - class Tangent_weight { - FT m_d_r, m_d_p, m_w_base; - - public: - template - Tangent_weight( - const CGAL::Point_2& p, - const CGAL::Point_2& q, - const CGAL::Point_2& r) { - - const GeomTraits traits; - const auto scalar_product_2 = - traits.compute_scalar_product_2_object(); - const auto construct_vector_2 = - traits.construct_vector_2_object(); - - m_d_r = internal::distance_2(traits, q, r); - CGAL_assertion(m_d_r != FT(0)); // two points are identical! - m_d_p = internal::distance_2(traits, q, p); - CGAL_assertion(m_d_p != FT(0)); // two points are identical! - - const auto v1 = construct_vector_2(q, r); - const auto v2 = construct_vector_2(q, p); - - const auto A = internal::positive_area_2(traits, p, q, r); - CGAL_assertion(A != FT(0)); // three points are identical! - const auto S = scalar_product_2(v1, v2); - m_w_base = -tangent_half_angle(m_d_r, m_d_p, A, S); - } - - template - Tangent_weight( - const CGAL::Point_3& p, - const CGAL::Point_3& q, - const CGAL::Point_3& r) { - - const GeomTraits traits; - const auto scalar_product_3 = - traits.compute_scalar_product_3_object(); - const auto construct_vector_3 = - traits.construct_vector_3_object(); - - m_d_r = internal::distance_3(traits, q, r); - CGAL_assertion(m_d_r != FT(0)); // two points are identical! - m_d_p = internal::distance_3(traits, q, p); - CGAL_assertion(m_d_p != FT(0)); // two points are identical! - - const auto v1 = construct_vector_3(q, r); - const auto v2 = construct_vector_3(q, p); - - const auto A = internal::positive_area_3(traits, p, q, r); - CGAL_assertion(A != FT(0)); // three points are identical! - const auto S = scalar_product_3(v1, v2); - m_w_base = -tangent_half_angle(m_d_r, m_d_p, A, S); - } - - FT get_w_r() const { - return half_tangent_weight(m_w_base, m_d_r) / FT(2); - } - - FT get_w_p() const { - return half_tangent_weight(m_w_base, m_d_p) / FT(2); - } - }; - - /// \endcond +/// \endcond } // namespace Weights } // namespace CGAL diff --git a/Weights/include/CGAL/Weights/three_point_family_weights.h b/Weights/include/CGAL/Weights/three_point_family_weights.h index eca32f1b281..ce7b0d978a0 100644 --- a/Weights/include/CGAL/Weights/three_point_family_weights.h +++ b/Weights/include/CGAL/Weights/three_point_family_weights.h @@ -14,58 +14,62 @@ #ifndef CGAL_THREE_POINT_FAMILY_WEIGHTS_H #define CGAL_THREE_POINT_FAMILY_WEIGHTS_H -// Internal includes. #include namespace CGAL { namespace Weights { - /// \cond SKIP_IN_MANUAL - namespace three_point_family_ns { +/// \cond SKIP_IN_MANUAL +namespace three_point_family_ns { - template - typename GeomTraits::FT weight( - const GeomTraits& traits, - const typename GeomTraits::FT d1, - const typename GeomTraits::FT d2, - const typename GeomTraits::FT d3, - const typename GeomTraits::FT A1, - const typename GeomTraits::FT A2, - const typename GeomTraits::FT B, - const typename GeomTraits::FT p) { +template +typename GeomTraits::FT weight(const GeomTraits& traits, + const typename GeomTraits::FT d1, + const typename GeomTraits::FT d2, + const typename GeomTraits::FT d3, + const typename GeomTraits::FT A1, + const typename GeomTraits::FT A2, + const typename GeomTraits::FT B, + const typename GeomTraits::FT p) +{ + using FT = typename GeomTraits::FT; - using FT = typename GeomTraits::FT; - FT w = FT(0); - CGAL_precondition(A1 != FT(0) && A2 != FT(0)); - const FT prod = A1 * A2; - if (prod != FT(0)) { - const FT inv = FT(1) / prod; - FT r1 = d1; - FT r2 = d2; - FT r3 = d3; - if (p != FT(1)) { - r1 = internal::power(traits, d1, p); - r2 = internal::power(traits, d2, p); - r3 = internal::power(traits, d3, p); - } - w = (r3 * A1 - r2 * B + r1 * A2) * inv; - } - return w; + FT w = FT(0); + CGAL_precondition(A1 != FT(0) && A2 != FT(0)); + const FT prod = A1 * A2; + if (prod != FT(0)) + { + const FT inv = FT(1) / prod; + FT r1 = d1; + FT r2 = d2; + FT r3 = d3; + if (p != FT(1)) + { + r1 = internal::power(traits, d1, p); + r2 = internal::power(traits, d2, p); + r3 = internal::power(traits, d3, p); } + w = (r3 * A1 - r2 * B + r1 * A2) * inv; } - /// \endcond - #if defined(DOXYGEN_RUNNING) + return w; +} - /*! - \ingroup PkgWeightsRefThreePointFamilyWeights +} // namespace three_point_family_ns - \brief computes the three-point family weight in 2D at `q` using the points `p0`, `p1`, - and `p2` and the power parameter `a`, given a traits class `traits` with geometric objects, - predicates, and constructions. - */ - template - typename GeomTraits::FT three_point_family_weight( +/// \endcond + +#if defined(DOXYGEN_RUNNING) + +/*! + \ingroup PkgWeightsRefThreePointFamilyWeights + + \brief computes the three-point family weight in 2D at `q` using the points `p0`, `p1`, + and `p2` and the power parameter `a`, given a traits class `traits` with geometric objects, + predicates, and constructions. +*/ +template +typename GeomTraits::FT three_point_family_weight( const typename GeomTraits::Point_2& p0, const typename GeomTraits::Point_2& p1, const typename GeomTraits::Point_2& p2, @@ -73,96 +77,89 @@ namespace Weights { const typename GeomTraits::FT a, const GeomTraits& traits) { } - /*! - \ingroup PkgWeightsRefThreePointFamilyWeights +/*! + \ingroup PkgWeightsRefThreePointFamilyWeights - \brief computes the three-point family weight in 2D at `q` using the points `p0`, `p1`, - and `p2` which are parameterized by a `Kernel` K, and the power parameter `a` which - can be omitted. - */ - template - typename K::FT three_point_family_weight( + \brief computes the three-point family weight in 2D at `q` using the points `p0`, `p1`, + and `p2` which are parameterized by a `Kernel` K, and the power parameter `a` which + can be omitted. +*/ +template +typename K::FT three_point_family_weight( const CGAL::Point_2& p0, const CGAL::Point_2& p1, const CGAL::Point_2& p2, const CGAL::Point_2& q, const typename K::FT a = typename K::FT(1)) { } - #endif // DOXYGEN_RUNNING +#endif // DOXYGEN_RUNNING - /// \cond SKIP_IN_MANUAL - template - typename GeomTraits::FT three_point_family_weight( - const typename GeomTraits::Point_2& t, - const typename GeomTraits::Point_2& r, - const typename GeomTraits::Point_2& p, - const typename GeomTraits::Point_2& q, - const typename GeomTraits::FT a, - const GeomTraits& traits) { +/// \cond SKIP_IN_MANUAL +template +typename GeomTraits::FT three_point_family_weight(const typename GeomTraits::Point_2& t, + const typename GeomTraits::Point_2& r, + const typename GeomTraits::Point_2& p, + const typename GeomTraits::Point_2& q, + const typename GeomTraits::FT a, + const GeomTraits& traits) +{ + using FT = typename GeomTraits::FT; - using FT = typename GeomTraits::FT; - const FT d1 = internal::distance_2(traits, q, t); - const FT d2 = internal::distance_2(traits, q, r); - const FT d3 = internal::distance_2(traits, q, p); + const FT d1 = internal::distance_2(traits, q, t); + const FT d2 = internal::distance_2(traits, q, r); + const FT d3 = internal::distance_2(traits, q, p); - const FT A1 = internal::area_2(traits, r, q, t); - const FT A2 = internal::area_2(traits, p, q, r); - const FT B = internal::area_2(traits, p, q, t); + const FT A1 = internal::area_2(traits, r, q, t); + const FT A2 = internal::area_2(traits, p, q, r); + const FT B = internal::area_2(traits, p, q, t); - return three_point_family_ns::weight( - traits, d1, d2, d3, A1, A2, B, a); - } + return three_point_family_ns::weight(traits, d1, d2, d3, A1, A2, B, a); +} - template - typename GeomTraits::FT three_point_family_weight( - const CGAL::Point_2& t, - const CGAL::Point_2& r, - const CGAL::Point_2& p, - const CGAL::Point_2& q, - const typename GeomTraits::FT a = - typename GeomTraits::FT(1)) { +template +typename GeomTraits::FT three_point_family_weight(const CGAL::Point_2& t, + const CGAL::Point_2& r, + const CGAL::Point_2& p, + const CGAL::Point_2& q, + const typename GeomTraits::FT a = typename GeomTraits::FT(1)) +{ + const GeomTraits traits; + return three_point_family_weight(t, r, p, q, a, traits); +} - const GeomTraits traits; - return three_point_family_weight(t, r, p, q, a, traits); - } +namespace internal { - namespace internal { +template +typename GeomTraits::FT three_point_family_weight(const typename GeomTraits::Point_3& t, + const typename GeomTraits::Point_3& r, + const typename GeomTraits::Point_3& p, + const typename GeomTraits::Point_3& q, + const typename GeomTraits::FT a, + const GeomTraits& traits) +{ + using Point_2 = typename GeomTraits::Point_2; - template - typename GeomTraits::FT three_point_family_weight( - const typename GeomTraits::Point_3& t, - const typename GeomTraits::Point_3& r, - const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3& q, - const typename GeomTraits::FT a, - const GeomTraits& traits) { + Point_2 tf, rf, pf, qf; + internal::flatten(traits, + t, r, p, q, + tf, rf, pf, qf); + return CGAL::Weights::three_point_family_weight(tf, rf, pf, qf, a, traits); +} - using Point_2 = typename GeomTraits::Point_2; - Point_2 tf, rf, pf, qf; - internal::flatten( - traits, - t, r, p, q, - tf, rf, pf, qf); - return CGAL::Weights:: - three_point_family_weight(tf, rf, pf, qf, a, traits); - } +template +typename GeomTraits::FT three_point_family_weight(const CGAL::Point_3& t, + const CGAL::Point_3& r, + const CGAL::Point_3& p, + const CGAL::Point_3& q, + const typename GeomTraits::FT a = typename GeomTraits::FT(1)) +{ + const GeomTraits traits; + return three_point_family_weight(t, r, p, q, a, traits); +} - template - typename GeomTraits::FT three_point_family_weight( - const CGAL::Point_3& t, - const CGAL::Point_3& r, - const CGAL::Point_3& p, - const CGAL::Point_3& q, - const typename GeomTraits::FT a = - typename GeomTraits::FT(1)) { +} // namespace internal - const GeomTraits traits; - return three_point_family_weight(t, r, p, q, a, traits); - } - - } // namespace internal - - /// \endcond +/// \endcond } // namespace Weights } // namespace CGAL diff --git a/Weights/include/CGAL/Weights/triangular_region_weights.h b/Weights/include/CGAL/Weights/triangular_region_weights.h index d0605d8e1bf..bb94af1a332 100644 --- a/Weights/include/CGAL/Weights/triangular_region_weights.h +++ b/Weights/include/CGAL/Weights/triangular_region_weights.h @@ -14,107 +14,103 @@ #ifndef CGAL_TRIANGULAR_REGION_WEIGHTS_H #define CGAL_TRIANGULAR_REGION_WEIGHTS_H -// Internal includes. #include namespace CGAL { namespace Weights { - #if defined(DOXYGEN_RUNNING) +#if defined(DOXYGEN_RUNNING) - /*! - \ingroup PkgWeightsRefTriangularRegionWeights +/*! + \ingroup PkgWeightsRefTriangularRegionWeights - \brief computes the area of the triangular cell in 2D using the points `p`, `q` - and `r`, given a traits class `traits` with geometric objects, predicates, and constructions. - */ - template - typename GeomTraits::FT triangular_area( + \brief computes the area of the triangular cell in 2D using the points `p`, `q` + and `r`, given a traits class `traits` with geometric objects, predicates, and constructions. +*/ +template +typename GeomTraits::FT triangular_area( const typename GeomTraits::Point_2& p, const typename GeomTraits::Point_2& q, const typename GeomTraits::Point_2& r, const GeomTraits& traits) { } - /*! - \ingroup PkgWeightsRefTriangularRegionWeights +/*! + \ingroup PkgWeightsRefTriangularRegionWeights - \brief computes the area of the triangular cell in 3D using the points `p`, `q` - and `r`, given a traits class `traits` with geometric objects, predicates, and constructions. - */ - template - typename GeomTraits::FT triangular_area( + \brief computes the area of the triangular cell in 3D using the points `p`, `q` + and `r`, given a traits class `traits` with geometric objects, predicates, and constructions. +*/ +template +typename GeomTraits::FT triangular_area( const typename GeomTraits::Point_3& p, const typename GeomTraits::Point_3& q, const typename GeomTraits::Point_3& r, const GeomTraits& traits) { } - /*! - \ingroup PkgWeightsRefTriangularRegionWeights +/*! + \ingroup PkgWeightsRefTriangularRegionWeights - \brief computes the area of the triangular cell in 2D using the points `p`, `q` - and `r` which are parameterized by a `Kernel` K. - */ - template - typename K::FT triangular_area( + \brief computes the area of the triangular cell in 2D using the points `p`, `q` + and `r` which are parameterized by a `Kernel` K. +*/ +template +typename K::FT triangular_area( const CGAL::Point_2& p, const CGAL::Point_2& q, const CGAL::Point_2& r) { } - /*! - \ingroup PkgWeightsRefTriangularRegionWeights +/*! + \ingroup PkgWeightsRefTriangularRegionWeights - \brief computes the area of the triangular cell in 3D using the points `p`, `q` - and `r` which are parameterized by a `Kernel` K. - */ - template - typename K::FT triangular_area( + \brief computes the area of the triangular cell in 3D using the points `p`, `q` + and `r` which are parameterized by a `Kernel` K. +*/ +template +typename K::FT triangular_area( const CGAL::Point_3& p, const CGAL::Point_3& q, const CGAL::Point_3& r) { } - #endif // DOXYGEN_RUNNING +#endif // DOXYGEN_RUNNING - /// \cond SKIP_IN_MANUAL - template - typename GeomTraits::FT triangular_area( - const typename GeomTraits::Point_2& p, - const typename GeomTraits::Point_2& q, - const typename GeomTraits::Point_2& r, - const GeomTraits& traits) { +/// \cond SKIP_IN_MANUAL +template +typename GeomTraits::FT triangular_area(const typename GeomTraits::Point_2& p, + const typename GeomTraits::Point_2& q, + const typename GeomTraits::Point_2& r, + const GeomTraits& traits) +{ + return internal::positive_area_2(traits, p, q, r); +} - return internal::positive_area_2(traits, p, q, r); - } +template +typename GeomTraits::FT triangular_area(const CGAL::Point_2& p, + const CGAL::Point_2& q, + const CGAL::Point_2& r) +{ + const GeomTraits traits; + return triangular_area(p, q, r, traits); +} - template - typename GeomTraits::FT triangular_area( - const CGAL::Point_2& p, - const CGAL::Point_2& q, - const CGAL::Point_2& r) { +template +typename GeomTraits::FT triangular_area(const typename GeomTraits::Point_3& p, + const typename GeomTraits::Point_3& q, + const typename GeomTraits::Point_3& r, + const GeomTraits& traits) +{ + return internal::positive_area_3(traits, p, q, r); +} - const GeomTraits traits; - return triangular_area(p, q, r, traits); - } +template +typename GeomTraits::FT triangular_area(const CGAL::Point_3& p, + const CGAL::Point_3& q, + const CGAL::Point_3& r) +{ + const GeomTraits traits; + return triangular_area(p, q, r, traits); +} - template - typename GeomTraits::FT triangular_area( - const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3& q, - const typename GeomTraits::Point_3& r, - const GeomTraits& traits) { - - return internal::positive_area_3(traits, p, q, r); - } - - template - typename GeomTraits::FT triangular_area( - const CGAL::Point_3& p, - const CGAL::Point_3& q, - const CGAL::Point_3& r) { - - const GeomTraits traits; - return triangular_area(p, q, r, traits); - } - /// \endcond +/// \endcond } // namespace Weights } // namespace CGAL diff --git a/Weights/include/CGAL/Weights/uniform_region_weights.h b/Weights/include/CGAL/Weights/uniform_region_weights.h index 9d78a58b6b5..f028c700903 100644 --- a/Weights/include/CGAL/Weights/uniform_region_weights.h +++ b/Weights/include/CGAL/Weights/uniform_region_weights.h @@ -20,103 +20,100 @@ namespace CGAL { namespace Weights { - #if defined(DOXYGEN_RUNNING) +#if defined(DOXYGEN_RUNNING) - /*! - \ingroup PkgWeightsRefUniformRegionWeights +/*! + \ingroup PkgWeightsRefUniformRegionWeights - \brief this function always returns 1, given three points in 2D and a traits class - with geometric objects, predicates, and constructions. - */ - template - typename GeomTraits::FT uniform_area( + \brief this function always returns 1, given three points in 2D and a traits class + with geometric objects, predicates, and constructions. +*/ +template +typename GeomTraits::FT uniform_area( const typename GeomTraits::Point_2&, const typename GeomTraits::Point_2&, const typename GeomTraits::Point_2&, const GeomTraits&) { } - /*! - \ingroup PkgWeightsRefUniformRegionWeights +/*! + \ingroup PkgWeightsRefUniformRegionWeights - \brief this function always returns 1, given three points in 3D and a traits class - with geometric objects, predicates, and constructions. - */ - template - typename GeomTraits::FT uniform_area( + \brief this function always returns 1, given three points in 3D and a traits class + with geometric objects, predicates, and constructions. +*/ +template +typename GeomTraits::FT uniform_area( const typename GeomTraits::Point_3&, const typename GeomTraits::Point_3&, const typename GeomTraits::Point_3&, const GeomTraits&) { } - /*! - \ingroup PkgWeightsRefUniformRegionWeights +/*! + \ingroup PkgWeightsRefUniformRegionWeights - \brief this function always returns 1, given three points in 2D which are - parameterized by a `Kernel` K. - */ - template - typename K::FT uniform_area( + \brief this function always returns 1, given three points in 2D which are + parameterized by a `Kernel` K. +*/ +template +typename K::FT uniform_area( const CGAL::Point_2&, const CGAL::Point_2&, const CGAL::Point_2&) { } - /*! - \ingroup PkgWeightsRefUniformRegionWeights +/*! + \ingroup PkgWeightsRefUniformRegionWeights - \brief this function always returns 1, given three points in 3D which are - parameterized by a `Kernel` K. - */ - template - typename K::FT uniform_area( + \brief this function always returns 1, given three points in 3D which are + parameterized by a `Kernel` K. +*/ +template +typename K::FT uniform_area( const CGAL::Point_3&, const CGAL::Point_3&, const CGAL::Point_3&) { } - #endif // DOXYGEN_RUNNING +#endif // DOXYGEN_RUNNING - /// \cond SKIP_IN_MANUAL - template - typename GeomTraits::FT uniform_area( - const typename GeomTraits::Point_2&, - const typename GeomTraits::Point_2&, - const typename GeomTraits::Point_2&, - const GeomTraits&) { +/// \cond SKIP_IN_MANUAL +template +typename GeomTraits::FT uniform_area(const typename GeomTraits::Point_2&, + const typename GeomTraits::Point_2&, + const typename GeomTraits::Point_2&, + const GeomTraits&) +{ + using FT = typename GeomTraits::FT; + return FT(1); +} - using FT = typename GeomTraits::FT; - return FT(1); - } +template +typename GeomTraits::FT uniform_area(const CGAL::Point_2& p, + const CGAL::Point_2& q, + const CGAL::Point_2& r) +{ + const GeomTraits traits; + return uniform_area(p, q, r, traits); +} - template - typename GeomTraits::FT uniform_area( - const CGAL::Point_2& p, - const CGAL::Point_2& q, - const CGAL::Point_2& r) { +template +typename GeomTraits::FT uniform_area(const typename GeomTraits::Point_3&, + const typename GeomTraits::Point_3&, + const typename GeomTraits::Point_3&, + const GeomTraits&) +{ + using FT = typename GeomTraits::FT; + return FT(1); +} - const GeomTraits traits; - return uniform_area(p, q, r, traits); - } +template +typename GeomTraits::FT uniform_area(const CGAL::Point_3& p, + const CGAL::Point_3& q, + const CGAL::Point_3& r) +{ + const GeomTraits traits; + return uniform_area(p, q, r, traits); +} - template - typename GeomTraits::FT uniform_area( - const typename GeomTraits::Point_3&, - const typename GeomTraits::Point_3&, - const typename GeomTraits::Point_3&, - const GeomTraits&) { - - using FT = typename GeomTraits::FT; - return FT(1); - } - - template - typename GeomTraits::FT uniform_area( - const CGAL::Point_3& p, - const CGAL::Point_3& q, - const CGAL::Point_3& r) { - - const GeomTraits traits; - return uniform_area(p, q, r, traits); - } - /// \endcond +/// \endcond } // namespace Weights } // namespace CGAL diff --git a/Weights/include/CGAL/Weights/uniform_weights.h b/Weights/include/CGAL/Weights/uniform_weights.h index 9ce8d49d360..439e0e74075 100644 --- a/Weights/include/CGAL/Weights/uniform_weights.h +++ b/Weights/include/CGAL/Weights/uniform_weights.h @@ -20,128 +20,128 @@ namespace CGAL { namespace Weights { - #if defined(DOXYGEN_RUNNING) +#if defined(DOXYGEN_RUNNING) - /*! +/*! \ingroup PkgWeightsRefUniformWeights \brief this function always returns 1, given four points in 2D and a traits class with geometric objects, predicates, and constructions. */ - template - typename GeomTraits::FT uniform_weight( +template +typename GeomTraits::FT uniform_weight( const typename GeomTraits::Point_2&, const typename GeomTraits::Point_2&, const typename GeomTraits::Point_2&, const typename GeomTraits::Point_2&, const GeomTraits&) { } - /*! +/*! \ingroup PkgWeightsRefUniformWeights \brief this function always returns 1, given four points in 3D and a traits class with geometric objects, predicates, and constructions. */ - template - typename GeomTraits::FT uniform_weight( +template +typename GeomTraits::FT uniform_weight( const typename GeomTraits::Point_3&, const typename GeomTraits::Point_3&, const typename GeomTraits::Point_3&, const typename GeomTraits::Point_3&, const GeomTraits&) { } - /*! +/*! \ingroup PkgWeightsRefUniformWeights \brief this function always returns 1, given four points in 2D which are parameterized by a `Kernel` K. */ - template - typename K::FT uniform_weight( +template +typename K::FT uniform_weight( const CGAL::Point_2&, const CGAL::Point_2&, const CGAL::Point_2&, const CGAL::Point_2&) { } - /*! +/*! \ingroup PkgWeightsRefUniformWeights \brief this function always returns 1, given four points in 3D which are parameterized by a `Kernel` K. */ - template - typename K::FT uniform_weight( +template +typename K::FT uniform_weight( const CGAL::Point_3&, const CGAL::Point_3&, const CGAL::Point_3&, const CGAL::Point_3&) { } - #endif // DOXYGEN_RUNNING +#endif // DOXYGEN_RUNNING - /// \cond SKIP_IN_MANUAL - template - typename GeomTraits::FT uniform_weight( +/// \cond SKIP_IN_MANUAL +template +typename GeomTraits::FT uniform_weight( const typename GeomTraits::Point_2&, const typename GeomTraits::Point_2&, const typename GeomTraits::Point_2&, const typename GeomTraits::Point_2&, const GeomTraits&) { - using FT = typename GeomTraits::FT; - return FT(1); - } + using FT = typename GeomTraits::FT; + return FT(1); +} - template - typename GeomTraits::FT uniform_weight( +template +typename GeomTraits::FT uniform_weight( const CGAL::Point_2& q, const CGAL::Point_2& t, const CGAL::Point_2& r, const CGAL::Point_2& p) { - const GeomTraits traits; - return uniform_weight(q, t, r, p, traits); - } + const GeomTraits traits; + return uniform_weight(q, t, r, p, traits); +} - template - typename GeomTraits::FT uniform_weight( +template +typename GeomTraits::FT uniform_weight( const typename GeomTraits::Point_3&, const typename GeomTraits::Point_3&, const typename GeomTraits::Point_3&, const typename GeomTraits::Point_3&, const GeomTraits&) { - using FT = typename GeomTraits::FT; - return FT(1); - } + using FT = typename GeomTraits::FT; + return FT(1); +} - template - typename GeomTraits::FT uniform_weight( +template +typename GeomTraits::FT uniform_weight( const CGAL::Point_3& q, const CGAL::Point_3& t, const CGAL::Point_3& r, const CGAL::Point_3& p) { - const GeomTraits traits; - return uniform_weight(q, t, r, p, traits); - } + const GeomTraits traits; + return uniform_weight(q, t, r, p, traits); +} - // Undocumented uniform weight class taking as input a polygon mesh. - // It is currently used in: - // Polygon_mesh_processing -> triangulate_hole_Polyhedron_3_test.cpp - // Polygon_mesh_processing -> triangulate_hole_Polyhedron_3_no_delaunay_test.cpp - // Polyhedron demo -> Fairing_plugin.cpp - // Polyhedron demo -> Hole_filling_plugin.cpp - template - class Uniform_weight { +// Undocumented uniform weight class taking as input a polygon mesh. +// It is currently used in: +// Polygon_mesh_processing -> triangulate_hole_Polyhedron_3_test.cpp +// Polygon_mesh_processing -> triangulate_hole_Polyhedron_3_no_delaunay_test.cpp +// Polyhedron demo -> Fairing_plugin.cpp +// Polyhedron demo -> Hole_filling_plugin.cpp +template +class Uniform_weight +{ +public: + using vertex_descriptor = typename boost::graph_traits::vertex_descriptor; + using halfedge_descriptor = typename boost::graph_traits::halfedge_descriptor; + double w_i(vertex_descriptor) { return 1.; } + double w_ij(halfedge_descriptor) { return 1.; } +}; - public: - using vertex_descriptor = typename boost::graph_traits::vertex_descriptor; - using halfedge_descriptor = typename boost::graph_traits::halfedge_descriptor; - double w_i(vertex_descriptor) { return 1; } - double w_ij(halfedge_descriptor) { return 1; } - }; - - /// \endcond +/// \endcond } // namespace Weights } // namespace CGAL diff --git a/Weights/include/CGAL/Weights/utils.h b/Weights/include/CGAL/Weights/utils.h index 5636e00f296..d28dfe877ba 100644 --- a/Weights/include/CGAL/Weights/utils.h +++ b/Weights/include/CGAL/Weights/utils.h @@ -20,187 +20,168 @@ namespace CGAL { namespace Weights { - /// \cond SKIP_IN_MANUAL - template - typename GeomTraits::FT tangent( - const typename GeomTraits::Point_2& p, - const typename GeomTraits::Point_2& q, - const typename GeomTraits::Point_2& r, - const GeomTraits& traits) { +/// \cond SKIP_IN_MANUAL +template +typename GeomTraits::FT tangent(const typename GeomTraits::Point_2& p, + const typename GeomTraits::Point_2& q, + const typename GeomTraits::Point_2& r, + const GeomTraits& traits) +{ + return internal::tangent_2(traits, p, q, r); +} - return internal::tangent_2(traits, p, q, r); - } +template +typename GeomTraits::FT tangent(const CGAL::Point_2& p, + const CGAL::Point_2& q, + const CGAL::Point_2& r) +{ + const GeomTraits traits; + return tangent(p, q, r, traits); +} - template - typename GeomTraits::FT tangent( - const CGAL::Point_2& p, - const CGAL::Point_2& q, - const CGAL::Point_2& r) { +template +typename GeomTraits::FT tangent(const typename GeomTraits::Point_3& p, + const typename GeomTraits::Point_3& q, + const typename GeomTraits::Point_3& r, + const GeomTraits& traits) +{ + return internal::tangent_3(traits, p, q, r); +} - const GeomTraits traits; - return tangent(p, q, r, traits); - } +template +typename GeomTraits::FT tangent(const CGAL::Point_3& p, + const CGAL::Point_3& q, + const CGAL::Point_3& r) +{ + const GeomTraits traits; + return tangent(p, q, r, traits); +} - template - typename GeomTraits::FT tangent( - const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3& q, - const typename GeomTraits::Point_3& r, - const GeomTraits& traits) { +template +typename GeomTraits::FT cotangent(const typename GeomTraits::Point_2& p, + const typename GeomTraits::Point_2& q, + const typename GeomTraits::Point_2& r, + const GeomTraits& traits) +{ + return internal::cotangent_2(traits, p, q, r); +} - return internal::tangent_3(traits, p, q, r); - } +template +typename GeomTraits::FT cotangent(const CGAL::Point_2& p, + const CGAL::Point_2& q, + const CGAL::Point_2& r) +{ + const GeomTraits traits; + return cotangent(p, q, r, traits); +} - template - typename GeomTraits::FT tangent( - const CGAL::Point_3& p, - const CGAL::Point_3& q, - const CGAL::Point_3& r) { +template +typename GeomTraits::FT cotangent(const typename GeomTraits::Point_3& p, + const typename GeomTraits::Point_3& q, + const typename GeomTraits::Point_3& r, + const GeomTraits& traits) +{ + return internal::cotangent_3(traits, p, q, r); +} - const GeomTraits traits; - return tangent(p, q, r, traits); - } +template +typename GeomTraits::FT cotangent(const CGAL::Point_3& p, + const CGAL::Point_3& q, + const CGAL::Point_3& r) +{ + const GeomTraits traits; + return cotangent(p, q, r, traits); +} - template - typename GeomTraits::FT cotangent( - const typename GeomTraits::Point_2& p, - const typename GeomTraits::Point_2& q, - const typename GeomTraits::Point_2& r, - const GeomTraits& traits) { +/// \endcond - return internal::cotangent_2(traits, p, q, r); - } +/// \cond SKIP_IN_MANUAL +// These are free functions to be used when building weights from parts rather +// than using the predefined weight functions. In principle, they can be removed. +// They are here to have unified interface within the Weights package and its +// construction weight system. +template +typename GeomTraits::FT squared_distance(const CGAL::Point_2& p, + const CGAL::Point_2& q) +{ + const GeomTraits traits; + const auto squared_distance_2 = traits.compute_squared_distance_2_object(); + return squared_distance_2(p, q); +} - template - typename GeomTraits::FT cotangent( - const CGAL::Point_2& p, - const CGAL::Point_2& q, - const CGAL::Point_2& r) { +template +typename GeomTraits::FT squared_distance(const CGAL::Point_3& p, + const CGAL::Point_3& q) +{ + const GeomTraits traits; + const auto squared_distance_3 = traits.compute_squared_distance_3_object(); + return squared_distance_3(p, q); +} - const GeomTraits traits; - return cotangent(p, q, r, traits); - } +template +typename GeomTraits::FT distance(const CGAL::Point_2& p, + const CGAL::Point_2& q) +{ + const GeomTraits traits; + return internal::distance_2(traits, p, q); +} - template - typename GeomTraits::FT cotangent( - const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3& q, - const typename GeomTraits::Point_3& r, - const GeomTraits& traits) { +template +typename GeomTraits::FT distance(const CGAL::Point_3& p, + const CGAL::Point_3& q) +{ + const GeomTraits traits; + return internal::distance_3(traits, p, q); +} - return internal::cotangent_3(traits, p, q, r); - } +template +typename GeomTraits::FT area(const CGAL::Point_2& p, + const CGAL::Point_2& q, + const CGAL::Point_2& r) +{ + const GeomTraits traits; + return internal::area_2(traits, p, q, r); +} - template - typename GeomTraits::FT cotangent( - const CGAL::Point_3& p, - const CGAL::Point_3& q, - const CGAL::Point_3& r) { +template +typename GeomTraits::FT area(const CGAL::Point_3& p, + const CGAL::Point_3& q, + const CGAL::Point_3& r) +{ + const GeomTraits traits; + return internal::positive_area_3(traits, p, q, r); +} - const GeomTraits traits; - return cotangent(p, q, r, traits); - } - /// \endcond +template +typename GeomTraits::FT scalar_product(const CGAL::Point_2& p, + const CGAL::Point_2& q, + const CGAL::Point_2& r) +{ + const GeomTraits traits; - /// \cond SKIP_IN_MANUAL - // These are free functions to be used when building weights from parts rather - // than using the predefined weight functions. In principle, they can be removed. - // They are here to have unified interface within the Weights package and its - // construction weight system. - template - typename GeomTraits::FT squared_distance( - const CGAL::Point_2& p, - const CGAL::Point_2& q) { + const auto scalar_product_2 = traits.compute_scalar_product_2_object(); + const auto construct_vector_2 = traits.construct_vector_2_object(); - const GeomTraits traits; - const auto squared_distance_2 = - traits.compute_squared_distance_2_object(); - return squared_distance_2(p, q); - } + const auto v1 = construct_vector_2(q, r); + const auto v2 = construct_vector_2(q, p); + return scalar_product_2(v1, v2); +} - template - typename GeomTraits::FT squared_distance( - const CGAL::Point_3& p, - const CGAL::Point_3& q) { +template +typename GeomTraits::FT scalar_product(const CGAL::Point_3& p, + const CGAL::Point_3& q, + const CGAL::Point_3& r) +{ + const GeomTraits traits; + const auto scalar_product_3 = traits.compute_scalar_product_3_object(); + const auto construct_vector_3 = traits.construct_vector_3_object(); - const GeomTraits traits; - const auto squared_distance_3 = - traits.compute_squared_distance_3_object(); - return squared_distance_3(p, q); - } + const auto v1 = construct_vector_3(q, r); + const auto v2 = construct_vector_3(q, p); + return scalar_product_3(v1, v2); +} - template - typename GeomTraits::FT distance( - const CGAL::Point_2& p, - const CGAL::Point_2& q) { - - const GeomTraits traits; - return internal::distance_2(traits, p, q); - } - - template - typename GeomTraits::FT distance( - const CGAL::Point_3& p, - const CGAL::Point_3& q) { - - const GeomTraits traits; - return internal::distance_3(traits, p, q); - } - - template - typename GeomTraits::FT area( - const CGAL::Point_2& p, - const CGAL::Point_2& q, - const CGAL::Point_2& r) { - - const GeomTraits traits; - return internal::area_2(traits, p, q, r); - } - - template - typename GeomTraits::FT area( - const CGAL::Point_3& p, - const CGAL::Point_3& q, - const CGAL::Point_3& r) { - - const GeomTraits traits; - return internal::positive_area_3(traits, p, q, r); - } - - template - typename GeomTraits::FT scalar_product( - const CGAL::Point_2& p, - const CGAL::Point_2& q, - const CGAL::Point_2& r) { - - const GeomTraits traits; - const auto scalar_product_2 = - traits.compute_scalar_product_2_object(); - const auto construct_vector_2 = - traits.construct_vector_2_object(); - - const auto v1 = construct_vector_2(q, r); - const auto v2 = construct_vector_2(q, p); - return scalar_product_2(v1, v2); - } - - template - typename GeomTraits::FT scalar_product( - const CGAL::Point_3& p, - const CGAL::Point_3& q, - const CGAL::Point_3& r) { - - const GeomTraits traits; - const auto scalar_product_3 = - traits.compute_scalar_product_3_object(); - const auto construct_vector_3 = - traits.construct_vector_3_object(); - - const auto v1 = construct_vector_3(q, r); - const auto v2 = construct_vector_3(q, p); - return scalar_product_3(v1, v2); - } - /// \endcond +/// \endcond } // namespace Weights } // namespace CGAL diff --git a/Weights/include/CGAL/Weights/voronoi_region_weights.h b/Weights/include/CGAL/Weights/voronoi_region_weights.h index 569c26a6870..8497c8aad57 100644 --- a/Weights/include/CGAL/Weights/voronoi_region_weights.h +++ b/Weights/include/CGAL/Weights/voronoi_region_weights.h @@ -14,131 +14,125 @@ #ifndef CGAL_VORONOI_REGION_WEIGHTS_H #define CGAL_VORONOI_REGION_WEIGHTS_H -// Internal includes. #include namespace CGAL { namespace Weights { - #if defined(DOXYGEN_RUNNING) +#if defined(DOXYGEN_RUNNING) - /*! - \ingroup PkgWeightsRefVoronoiRegionWeights +/*! + \ingroup PkgWeightsRefVoronoiRegionWeights - \brief computes the area of the Voronoi cell in 2D using the points `p`, `q` - and `r`, given a traits class `traits` with geometric objects, predicates, and constructions. - */ - template - typename GeomTraits::FT voronoi_area( + \brief computes the area of the Voronoi cell in 2D using the points `p`, `q` + and `r`, given a traits class `traits` with geometric objects, predicates, and constructions. +*/ +template +typename GeomTraits::FT voronoi_area( const typename GeomTraits::Point_2& p, const typename GeomTraits::Point_2& q, const typename GeomTraits::Point_2& r, const GeomTraits& traits) { } - /*! - \ingroup PkgWeightsRefVoronoiRegionWeights +/*! + \ingroup PkgWeightsRefVoronoiRegionWeights - \brief computes the area of the Voronoi cell in 3D using the points `p`, `q` - and `r`, given a traits class `traits` with geometric objects, predicates, and constructions. - */ - template - typename GeomTraits::FT voronoi_area( + \brief computes the area of the Voronoi cell in 3D using the points `p`, `q` + and `r`, given a traits class `traits` with geometric objects, predicates, and constructions. +*/ +template +typename GeomTraits::FT voronoi_area( const typename GeomTraits::Point_3& p, const typename GeomTraits::Point_3& q, const typename GeomTraits::Point_3& r, const GeomTraits& traits) { } - /*! - \ingroup PkgWeightsRefVoronoiRegionWeights +/*! + \ingroup PkgWeightsRefVoronoiRegionWeights - \brief computes the area of the Voronoi cell in 2D using the points `p`, `q` - and `r` which are parameterized by a `Kernel` K. - */ - template - typename K::FT voronoi_area( + \brief computes the area of the Voronoi cell in 2D using the points `p`, `q` + and `r` which are parameterized by a `Kernel` K. +*/ +template +typename K::FT voronoi_area( const CGAL::Point_2& p, const CGAL::Point_2& q, const CGAL::Point_2& r) { } - /*! - \ingroup PkgWeightsRefVoronoiRegionWeights +/*! + \ingroup PkgWeightsRefVoronoiRegionWeights - \brief computes the area of the Voronoi cell in 3D using the points `p`, `q` - and `r` which are parameterized by a `Kernel` K. - */ - template - typename K::FT voronoi_area( - const CGAL::Point_3& p, + \brief computes the area of the Voronoi cell in 3D using the points `p`, `q` + and `r` which are parameterized by a `Kernel` K. +*/ +template +typename K::FT voronoi_area( + const CGAL::Point_3& p, const CGAL::Point_3& q, const CGAL::Point_3& r) { } - #endif // DOXYGEN_RUNNING +#endif // DOXYGEN_RUNNING - /// \cond SKIP_IN_MANUAL - template - typename GeomTraits::FT voronoi_area( - const typename GeomTraits::Point_2& p, - const typename GeomTraits::Point_2& q, - const typename GeomTraits::Point_2& r, - const GeomTraits& traits) { +/// \cond SKIP_IN_MANUAL +template +typename GeomTraits::FT voronoi_area(const typename GeomTraits::Point_2& p, + const typename GeomTraits::Point_2& q, + const typename GeomTraits::Point_2& r, + const GeomTraits& traits) +{ + using FT = typename GeomTraits::FT; - using FT = typename GeomTraits::FT; - const auto circumcenter_2 = - traits.construct_circumcenter_2_object(); - const auto midpoint_2 = - traits.construct_midpoint_2_object(); + const auto circumcenter_2 = traits.construct_circumcenter_2_object(); + const auto midpoint_2 = traits.construct_midpoint_2_object(); - const auto center = circumcenter_2(p, q, r); - const auto m1 = midpoint_2(q, r); - const auto m2 = midpoint_2(q, p); + const auto center = circumcenter_2(p, q, r); + const auto m1 = midpoint_2(q, r); + const auto m2 = midpoint_2(q, p); - const FT A1 = internal::positive_area_2(traits, q, m1, center); - const FT A2 = internal::positive_area_2(traits, q, center, m2); - return A1 + A2; - } + const FT A1 = internal::positive_area_2(traits, q, m1, center); + const FT A2 = internal::positive_area_2(traits, q, center, m2); + return A1 + A2; +} - template - typename GeomTraits::FT voronoi_area( - const CGAL::Point_2& p, - const CGAL::Point_2& q, - const CGAL::Point_2& r) { +template +typename GeomTraits::FT voronoi_area(const CGAL::Point_2& p, + const CGAL::Point_2& q, + const CGAL::Point_2& r) +{ + const GeomTraits traits; + return voronoi_area(p, q, r, traits); +} - const GeomTraits traits; - return voronoi_area(p, q, r, traits); - } +template +typename GeomTraits::FT voronoi_area(const typename GeomTraits::Point_3& p, + const typename GeomTraits::Point_3& q, + const typename GeomTraits::Point_3& r, + const GeomTraits& traits) +{ + using FT = typename GeomTraits::FT; - template - typename GeomTraits::FT voronoi_area( - const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3& q, - const typename GeomTraits::Point_3& r, - const GeomTraits& traits) { + const auto circumcenter_3 = traits.construct_circumcenter_3_object(); + const auto midpoint_3 = traits.construct_midpoint_3_object(); - using FT = typename GeomTraits::FT; - const auto circumcenter_3 = - traits.construct_circumcenter_3_object(); - const auto midpoint_3 = - traits.construct_midpoint_3_object(); + const auto center = circumcenter_3(p, q, r); + const auto m1 = midpoint_3(q, r); + const auto m2 = midpoint_3(q, p); - const auto center = circumcenter_3(p, q, r); - const auto m1 = midpoint_3(q, r); - const auto m2 = midpoint_3(q, p); + const FT A1 = internal::positive_area_3(traits, q, m1, center); + const FT A2 = internal::positive_area_3(traits, q, center, m2); + return A1 + A2; +} - const FT A1 = internal::positive_area_3(traits, q, m1, center); - const FT A2 = internal::positive_area_3(traits, q, center, m2); - return A1 + A2; - } +template +typename GeomTraits::FT voronoi_area(const CGAL::Point_3& p, + const CGAL::Point_3& q, + const CGAL::Point_3& r) +{ + const GeomTraits traits; + return voronoi_area(p, q, r, traits); +} - template - typename GeomTraits::FT voronoi_area( - const CGAL::Point_3& p, - const CGAL::Point_3& q, - const CGAL::Point_3& r) { - - const GeomTraits traits; - return voronoi_area(p, q, r, traits); - } - /// \endcond +/// \endcond } // namespace Weights } // namespace CGAL diff --git a/Weights/include/CGAL/Weights/wachspress_weights.h b/Weights/include/CGAL/Weights/wachspress_weights.h index 34299c24a52..00d843d18d1 100644 --- a/Weights/include/CGAL/Weights/wachspress_weights.h +++ b/Weights/include/CGAL/Weights/wachspress_weights.h @@ -21,402 +21,377 @@ namespace CGAL { namespace Weights { - /// \cond SKIP_IN_MANUAL - namespace wachspress_ns { +/// \cond SKIP_IN_MANUAL +namespace wachspress_ns { - template - FT weight(const FT A1, const FT A2, const FT C) { - - FT w = FT(0); - CGAL_precondition(A1 != FT(0) && A2 != FT(0)); - const FT prod = A1 * A2; - if (prod != FT(0)) { - const FT inv = FT(1) / prod; - w = C * inv; - } - return w; - } +template +FT weight(const FT A1, const FT A2, const FT C) +{ + FT w = FT(0); + CGAL_precondition(A1 != FT(0) && A2 != FT(0)); + const FT prod = A1 * A2; + if (prod != FT(0)) + { + const FT inv = FT(1) / prod; + w = C * inv; } - /// \endcond + return w; +} - #if defined(DOXYGEN_RUNNING) +} // wachspress_ns - /*! - \ingroup PkgWeightsRefWachspressWeights +/// \endcond - \brief computes the Wachspress weight in 2D at `q` using the points `p0`, `p1`, - and `p2`, given a traits class `traits` with geometric objects, predicates, and constructions. - */ - template - typename GeomTraits::FT wachspress_weight( +#if defined(DOXYGEN_RUNNING) + +/*! + \ingroup PkgWeightsRefWachspressWeights + + \brief computes the Wachspress weight in 2D at `q` using the points `p0`, `p1`, + and `p2`, given a traits class `traits` with geometric objects, predicates, and constructions. +*/ +template +typename GeomTraits::FT wachspress_weight( const typename GeomTraits::Point_2& p0, const typename GeomTraits::Point_2& p1, const typename GeomTraits::Point_2& p2, const typename GeomTraits::Point_2& q, const GeomTraits& traits) { } - /*! - \ingroup PkgWeightsRefWachspressWeights +/*! + \ingroup PkgWeightsRefWachspressWeights - \brief computes the Wachspress weight in 2D at `q` using the points `p0`, `p1`, - and `p2` which are parameterized by a `Kernel` K. - */ - template - typename K::FT wachspress_weight( + \brief computes the Wachspress weight in 2D at `q` using the points `p0`, `p1`, + and `p2` which are parameterized by a `Kernel` K. +*/ +template +typename K::FT wachspress_weight( const CGAL::Point_2& p0, const CGAL::Point_2& p1, const CGAL::Point_2& p2, const CGAL::Point_2& q) { } - #endif // DOXYGEN_RUNNING +#endif // DOXYGEN_RUNNING + +/// \cond SKIP_IN_MANUAL +template +typename GeomTraits::FT wachspress_weight(const typename GeomTraits::Point_2& t, + const typename GeomTraits::Point_2& r, + const typename GeomTraits::Point_2& p, + const typename GeomTraits::Point_2& q, + const GeomTraits& traits) +{ + using FT = typename GeomTraits::FT; + const FT A1 = internal::area_2(traits, r, q, t); + const FT A2 = internal::area_2(traits, p, q, r); + const FT C = internal::area_2(traits, t, r, p); + return wachspress_ns::weight(A1, A2, C); +} + +template +typename GeomTraits::FT wachspress_weight(const CGAL::Point_2& t, + const CGAL::Point_2& r, + const CGAL::Point_2& p, + const CGAL::Point_2& q) +{ + const GeomTraits traits; + return wachspress_weight(t, r, p, q, traits); +} + +namespace internal { + +template +typename GeomTraits::FT wachspress_weight(const typename GeomTraits::Point_3& t, + const typename GeomTraits::Point_3& r, + const typename GeomTraits::Point_3& p, + const typename GeomTraits::Point_3& q, + const GeomTraits& traits) +{ + using Point_2 = typename GeomTraits::Point_2; + + Point_2 tf, rf, pf, qf; + internal::flatten(traits, + t, r, p, q, + tf, rf, pf, qf); + return CGAL::Weights::wachspress_weight(tf, rf, pf, qf, traits); +} + +template +typename GeomTraits::FT wachspress_weight(const CGAL::Point_3& t, + const CGAL::Point_3& r, + const CGAL::Point_3& p, + const CGAL::Point_3& q) +{ + const GeomTraits traits; + return wachspress_weight(t, r, p, q, traits); +} + +} // namespace internal + +/// \endcond + +/*! + \ingroup PkgWeightsRefBarycentricWachspressWeights + + \brief 2D Wachspress weights for polygons. + + This class implements 2D Wachspress weights ( \cite cgal:bc:fhk-gcbcocp-06, + \cite cgal:bc:mlbd-gbcip-02, \cite cgal:bc:w-rfeb-75 ) which can be computed + at any point inside a strictly convex polygon. + + Wachspress weights are well-defined and non-negative inside a strictly convex polygon. + The weights are computed analytically using the formulation from the `wachspress_weight()`. + + \tparam VertexRange a model of `ConstRange` whose iterator type is `RandomAccessIterator` + \tparam GeomTraits a model of `AnalyticWeightTraits_2` + \tparam PointMap a model of `ReadablePropertyMap` whose key type is `VertexRange::value_type` and + value type is `Point_2`. The default is `CGAL::Identity_property_map`. + + \cgalModels `BarycentricWeights_2` +*/ +template > +class Wachspress_weights_2 +{ +public: + + /// \name Types + /// @{ /// \cond SKIP_IN_MANUAL - template - typename GeomTraits::FT wachspress_weight( - const typename GeomTraits::Point_2& t, - const typename GeomTraits::Point_2& r, - const typename GeomTraits::Point_2& p, - const typename GeomTraits::Point_2& q, - const GeomTraits& traits) { - using FT = typename GeomTraits::FT; - const FT A1 = internal::area_2(traits, r, q, t); - const FT A2 = internal::area_2(traits, p, q, r); - const FT C = internal::area_2(traits, t, r, p); - return wachspress_ns::weight(A1, A2, C); - } + using Vertex_range = VertexRange; + using Geom_traits = GeomTraits; + using Point_map = PointMap; - template - typename GeomTraits::FT wachspress_weight( - const CGAL::Point_2& t, - const CGAL::Point_2& r, - const CGAL::Point_2& p, - const CGAL::Point_2& q) { - - const GeomTraits traits; - return wachspress_weight(t, r, p, q, traits); - } - - namespace internal { - - template - typename GeomTraits::FT wachspress_weight( - const typename GeomTraits::Point_3& t, - const typename GeomTraits::Point_3& r, - const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3& q, - const GeomTraits& traits) { - - using Point_2 = typename GeomTraits::Point_2; - Point_2 tf, rf, pf, qf; - internal::flatten( - traits, - t, r, p, q, - tf, rf, pf, qf); - return CGAL::Weights:: - wachspress_weight(tf, rf, pf, qf, traits); - } - - template - typename GeomTraits::FT wachspress_weight( - const CGAL::Point_3& t, - const CGAL::Point_3& r, - const CGAL::Point_3& p, - const CGAL::Point_3& q) { - - const GeomTraits traits; - return wachspress_weight(t, r, p, q, traits); - } - - } // namespace internal + using Area_2 = typename GeomTraits::Compute_area_2; /// \endcond - /*! - \ingroup PkgWeightsRefBarycentricWachspressWeights + /// Number type. + typedef typename GeomTraits::FT FT; - \brief 2D Wachspress weights for polygons. + /// Point type. + typedef typename GeomTraits::Point_2 Point_2; - This class implements 2D Wachspress weights ( \cite cgal:bc:fhk-gcbcocp-06, - \cite cgal:bc:mlbd-gbcip-02, \cite cgal:bc:w-rfeb-75 ) which can be computed - at any point inside a strictly convex polygon. + /// @} - Wachspress weights are well-defined and non-negative inside a strictly convex polygon. - The weights are computed analytically using the formulation from the `wachspress_weight()`. - - \tparam VertexRange - a model of `ConstRange` whose iterator type is `RandomAccessIterator` - - \tparam GeomTraits - a model of `AnalyticWeightTraits_2` - - \tparam PointMap - a model of `ReadablePropertyMap` whose key type is `VertexRange::value_type` and - value type is `Point_2`. The default is `CGAL::Identity_property_map`. - - \cgalModels `BarycentricWeights_2` - */ - template< - typename VertexRange, - typename GeomTraits, - typename PointMap = CGAL::Identity_property_map > - class Wachspress_weights_2 { - - public: - - /// \name Types - /// @{ - - /// \cond SKIP_IN_MANUAL - using Vertex_range = VertexRange; - using Geom_traits = GeomTraits; - using Point_map = PointMap; - - using Area_2 = typename GeomTraits::Compute_area_2; - /// \endcond - - /// Number type. - typedef typename GeomTraits::FT FT; - - /// Point type. - typedef typename GeomTraits::Point_2 Point_2; - - /// @} - - /// \name Initialization - /// @{ - - /*! - \brief initializes all internal data structures. - - This class implements the behavior of Wachspress weights - for 2D query points inside strictly convex polygons. - - \param polygon - an instance of `VertexRange` with the vertices of a strictly convex polygon - - \param traits - a traits class with geometric objects, predicates, and constructions; - the default initialization is provided - - \param point_map - an instance of `PointMap` that maps a vertex from `polygon` to `Point_2`; - the default initialization is provided - - \pre polygon.size() >= 3 - \pre polygon is simple - \pre polygon is strictly convex - */ - Wachspress_weights_2( - const VertexRange& polygon, - const GeomTraits traits = GeomTraits(), - const PointMap point_map = PointMap()) : - m_polygon(polygon), - m_traits(traits), - m_point_map(point_map), - m_area_2(m_traits.compute_area_2_object()) { - - CGAL_precondition( - polygon.size() >= 3); - CGAL_precondition( - internal::is_simple_2(polygon, traits, point_map)); - CGAL_precondition( - internal::polygon_type_2(polygon, traits, point_map) == - internal::Polygon_type::STRICTLY_CONVEX); - resize(); - } - - /// @} - - /// \name Access - /// @{ - - /*! - \brief computes 2D Wachspress weights. - - This function fills a destination range with 2D Wachspress weights computed - at the `query` point with respect to the vertices of the input polygon. - - The number of computed weights is equal to the number of polygon vertices. - - \tparam OutIterator - a model of `OutputIterator` whose value type is `FT` - - \param query - a query point - - \param w_begin - the beginning of the destination range with the computed weights - - \return an output iterator to the element in the destination range, - one past the last weight stored - */ - template - OutIterator operator()(const Point_2& query, OutIterator w_begin) { - const bool normalize = false; - return operator()(query, w_begin, normalize); - } - - /// @} - - /// \cond SKIP_IN_MANUAL - template - OutIterator operator()(const Point_2& query, OutIterator w_begin, const bool normalize) { - return optimal_weights(query, w_begin, normalize); - } - /// \endcond - - private: - - // Fields. - const VertexRange& m_polygon; - const GeomTraits m_traits; - const PointMap m_point_map; - - const Area_2 m_area_2; - - std::vector A; - std::vector C; - std::vector w; - - // Functions. - void resize() { - A.resize(m_polygon.size()); - C.resize(m_polygon.size()); - w.resize(m_polygon.size()); - } - - template - OutputIterator optimal_weights( - const Point_2& query, OutputIterator weights, const bool normalize) { - - // Get the number of vertices in the polygon. - const std::size_t n = m_polygon.size(); - - // Compute areas A and C following the area notation from [1]. - // Split the loop to make this computation faster. - const auto& p1 = get(m_point_map, *(m_polygon.begin() + 0)); - const auto& p2 = get(m_point_map, *(m_polygon.begin() + 1)); - const auto& pn = get(m_point_map, *(m_polygon.begin() + (n - 1))); - - A[0] = m_area_2(p1, p2, query); - C[0] = m_area_2(pn, p1, p2); - - for (std::size_t i = 1; i < n - 1; ++i) { - const auto& pi0 = get(m_point_map, *(m_polygon.begin() + (i - 1))); - const auto& pi1 = get(m_point_map, *(m_polygon.begin() + (i + 0))); - const auto& pi2 = get(m_point_map, *(m_polygon.begin() + (i + 1))); - - A[i] = m_area_2(pi1, pi2, query); - C[i] = m_area_2(pi0, pi1, pi2); - } - - const auto& pm = get(m_point_map, *(m_polygon.begin() + (n - 2))); - A[n - 1] = m_area_2(pn, p1, query); - C[n - 1] = m_area_2(pm, pn, p1); - - // Compute unnormalized weights following the formula (28) from [1]. - CGAL_assertion(A[n - 1] != FT(0) && A[0] != FT(0)); - w[0] = C[0] / (A[n - 1] * A[0]); - - for (std::size_t i = 1; i < n - 1; ++i) { - CGAL_assertion(A[i - 1] != FT(0) && A[i] != FT(0)); - w[i] = C[i] / (A[i - 1] * A[i]); - } - - CGAL_assertion(A[n - 2] != FT(0) && A[n - 1] != FT(0)); - w[n - 1] = C[n - 1] / (A[n - 2] * A[n - 1]); - - // Normalize if necessary. - if (normalize) { - internal::normalize(w); - } - - // Return weights. - for (std::size_t i = 0; i < n; ++i) { - *(weights++) = w[i]; - } - return weights; - } - }; + /// \name Initialization + /// @{ /*! - \ingroup PkgWeightsRefBarycentricWachspressWeights + \brief initializes all internal data structures. - \brief computes 2D Wachspress weights for polygons. + This class implements the behavior of Wachspress weights + for 2D query points inside strictly convex polygons. - This function computes 2D Wachspress weights at a given `query` point - with respect to the vertices of a strictly convex `polygon`, that is one - weight per vertex. The weights are stored in a destination range - beginning at `w_begin`. - - Internally, the class `Wachspress_weights_2` is used. If one wants to process - multiple query points, it is better to use that class. When using the free function, - internal memory is allocated for each query point, while when using the class, - it is allocated only once which is much more efficient. However, for a few query - points, it is easier to use this function. It can also be used when the processing - time is not a concern. - - \tparam PointRange - a model of `ConstRange` whose iterator type is `RandomAccessIterator` - and value type is `GeomTraits::Point_2` - - \tparam OutIterator - a model of `OutputIterator` whose value type is `GeomTraits::FT` - - \tparam GeomTraits - a model of `AnalyticWeightTraits_2` - - \param polygon - an instance of `PointRange` with 2D points which form a strictly convex polygon - - \param query - a query point - - \param w_begin - the beginning of the destination range with the computed weights - - \param traits - a traits class with geometric objects, predicates, and constructions; - this parameter can be omitted if the traits class can be deduced from the point type - - \return an output iterator to the element in the destination range, - one past the last weight stored + \param polygon an instance of `VertexRange` with the vertices of a strictly convex polygon + \param traits a traits class with geometric objects, predicates, and constructions; + the default initialization is provided + \param point_map an instance of `PointMap` that maps a vertex from `polygon` to `Point_2`; + the default initialization is provided \pre polygon.size() >= 3 \pre polygon is simple \pre polygon is strictly convex */ - template< - typename PointRange, - typename OutIterator, - typename GeomTraits> - OutIterator wachspress_weights_2( - const PointRange& polygon, const typename GeomTraits::Point_2& query, - OutIterator w_begin, const GeomTraits& traits) { - - Wachspress_weights_2 - wachspress(polygon, traits); - return wachspress(query, w_begin); + Wachspress_weights_2(const VertexRange& polygon, + const GeomTraits traits = GeomTraits(), + const PointMap point_map = PointMap()) + : m_polygon(polygon), + m_traits(traits), + m_point_map(point_map), + m_area_2(m_traits.compute_area_2_object()) + { + CGAL_precondition(polygon.size() >= 3); + CGAL_precondition(internal::is_simple_2(polygon, traits, point_map)); + CGAL_precondition(internal::polygon_type_2(polygon, traits, point_map) == + internal::Polygon_type::STRICTLY_CONVEX); + resize(); } + /// @} + + /// \name Access + /// @{ + + /*! + \brief computes 2D Wachspress weights. + + This function fills a destination range with 2D Wachspress weights computed + at the `query` point with respect to the vertices of the input polygon. + + The number of computed weights is equal to the number of polygon vertices. + + \tparam OutIterator a model of `OutputIterator` whose value type is `FT` + + \param query a query point + \param w_begin the beginning of the destination range with the computed weights + + \return an output iterator to the element in the destination range, + one past the last weight stored + */ + template + OutIterator operator()(const Point_2& query, + OutIterator w_begin) + { + const bool normalize = false; + return operator()(query, w_begin, normalize); + } + + /// @} + /// \cond SKIP_IN_MANUAL - template< - typename PointRange, - typename OutIterator> - OutIterator wachspress_weights_2( - const PointRange& polygon, - const typename PointRange::value_type& query, - OutIterator w_begin) { - using Point_2 = typename PointRange::value_type; - using GeomTraits = typename Kernel_traits::Kernel; - const GeomTraits traits; - return wachspress_weights_2( - polygon, query, w_begin, traits); + template + OutIterator operator()(const Point_2& query, + OutIterator w_begin, + const bool normalize) + { + return optimal_weights(query, w_begin, normalize); } + /// \endcond +private: + const VertexRange& m_polygon; + const GeomTraits m_traits; + const PointMap m_point_map; + + const Area_2 m_area_2; + + std::vector A; + std::vector C; + std::vector w; + + void resize() + { + A.resize(m_polygon.size()); + C.resize(m_polygon.size()); + w.resize(m_polygon.size()); + } + + template + OutputIterator optimal_weights(const Point_2& query, + OutputIterator weights, + const bool normalize) + { + + // Get the number of vertices in the polygon. + const std::size_t n = m_polygon.size(); + + // Compute areas A and C following the area notation from [1]. + // Split the loop to make this computation faster. + const auto& p1 = get(m_point_map, *(m_polygon.begin() + 0)); + const auto& p2 = get(m_point_map, *(m_polygon.begin() + 1)); + const auto& pn = get(m_point_map, *(m_polygon.begin() + (n - 1))); + + A[0] = m_area_2(p1, p2, query); + C[0] = m_area_2(pn, p1, p2); + + for (std::size_t i = 1; i < n - 1; ++i) + { + const auto& pi0 = get(m_point_map, *(m_polygon.begin() + (i - 1))); + const auto& pi1 = get(m_point_map, *(m_polygon.begin() + (i + 0))); + const auto& pi2 = get(m_point_map, *(m_polygon.begin() + (i + 1))); + + A[i] = m_area_2(pi1, pi2, query); + C[i] = m_area_2(pi0, pi1, pi2); + } + + const auto& pm = get(m_point_map, *(m_polygon.begin() + (n - 2))); + A[n - 1] = m_area_2(pn, p1, query); + C[n - 1] = m_area_2(pm, pn, p1); + + // Compute unnormalized weights following the formula (28) from [1]. + CGAL_assertion(A[n - 1] != FT(0) && A[0] != FT(0)); + w[0] = C[0] / (A[n - 1] * A[0]); + + for (std::size_t i = 1; i < n - 1; ++i) + { + CGAL_assertion(A[i - 1] != FT(0) && A[i] != FT(0)); + w[i] = C[i] / (A[i - 1] * A[i]); + } + + CGAL_assertion(A[n - 2] != FT(0) && A[n - 1] != FT(0)); + w[n - 1] = C[n - 1] / (A[n - 2] * A[n - 1]); + + // Normalize if necessary. + if (normalize) + internal::normalize(w); + + // Return weights. + for (std::size_t i = 0; i < n; ++i) + *(weights++) = w[i]; + + return weights; + } +}; + +/*! + \ingroup PkgWeightsRefBarycentricWachspressWeights + + \brief computes 2D Wachspress weights for polygons. + + This function computes 2D Wachspress weights at a given `query` point + with respect to the vertices of a strictly convex `polygon`, that is one + weight per vertex. The weights are stored in a destination range + beginning at `w_begin`. + + Internally, the class `Wachspress_weights_2` is used. If one wants to process + multiple query points, it is better to use that class. When using the free function, + internal memory is allocated for each query point, while when using the class, + it is allocated only once which is much more efficient. However, for a few query + points, it is easier to use this function. It can also be used when the processing + time is not a concern. + + \tparam PointRange a model of `ConstRange` whose iterator type is `RandomAccessIterator` + and value type is `GeomTraits::Point_2` + \tparam OutIterator a model of `OutputIterator` whose value type is `GeomTraits::FT` + \tparam GeomTraits a model of `AnalyticWeightTraits_2` + + \param polygon an instance of `PointRange` with 2D points which form a strictly convex polygon + \param query a query point + \param w_begin the beginning of the destination range with the computed weights + \param traits a traits class with geometric objects, predicates, and constructions; + this parameter can be omitted if the traits class can be deduced from the point type + + \return an output iterator to the element in the destination range, one past the last weight stored + + \pre polygon.size() >= 3 + \pre polygon is simple + \pre polygon is strictly convex +*/ +template +OutIterator wachspress_weights_2(const PointRange& polygon, + const typename GeomTraits::Point_2& query, + OutIterator w_begin, + const GeomTraits& traits) +{ + Wachspress_weights_2 wachspress(polygon, traits); + return wachspress(query, w_begin); +} + +/// \cond SKIP_IN_MANUAL + +template +OutIterator wachspress_weights_2(const PointRange& polygon, + const typename PointRange::value_type& query, + OutIterator w_begin) +{ + using Point_2 = typename PointRange::value_type; + using GeomTraits = typename Kernel_traits::Kernel; + + const GeomTraits traits; + return wachspress_weights_2(polygon, query, w_begin, traits); +} + +/// \endcond + } // namespace Weights } // namespace CGAL From e0e0c4d54bdee2e566e992ddba886dab2d74774f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 17 Oct 2022 16:25:36 +0200 Subject: [PATCH 02/35] Remove old doc (new one to be re-added directly on the functions) --- .../include/CGAL/Weights/authalic_weights.h | 62 --------- .../CGAL/Weights/barycentric_region_weights.h | 57 --------- .../include/CGAL/Weights/cotangent_weights.h | 61 --------- .../CGAL/Weights/discrete_harmonic_weights.h | 34 ----- .../CGAL/Weights/inverse_distance_weights.h | 107 ---------------- .../include/CGAL/Weights/mean_value_weights.h | 34 ----- .../Weights/mixed_voronoi_region_weights.h | 54 -------- .../include/CGAL/Weights/shepard_weights.h | 119 ------------------ .../include/CGAL/Weights/tangent_weights.h | 58 --------- .../CGAL/Weights/three_point_family_weights.h | 38 ------ .../CGAL/Weights/triangular_region_weights.h | 54 -------- .../CGAL/Weights/uniform_region_weights.h | 55 -------- .../include/CGAL/Weights/uniform_weights.h | 59 --------- Weights/include/CGAL/Weights/utils.h | 1 - .../CGAL/Weights/voronoi_region_weights.h | 54 -------- .../include/CGAL/Weights/wachspress_weights.h | 34 ----- 16 files changed, 881 deletions(-) diff --git a/Weights/include/CGAL/Weights/authalic_weights.h b/Weights/include/CGAL/Weights/authalic_weights.h index 25d38e60f26..447c58f1bea 100644 --- a/Weights/include/CGAL/Weights/authalic_weights.h +++ b/Weights/include/CGAL/Weights/authalic_weights.h @@ -76,66 +76,6 @@ FT half_authalic_weight(const FT cot, const FT d2) return authalic_ns::half_weight(cot, d2); } -#if defined(DOXYGEN_RUNNING) - -/*! - \ingroup PkgWeightsRefAuthalicWeights - - \brief computes the authalic weight in 2D at `q` using the points `p0`, `p1`, - and `p2`, given a traits class `traits` with geometric objects, predicates, and constructions. -*/ -template -typename GeomTraits::FT authalic_weight( - const typename GeomTraits::Point_2& p0, - const typename GeomTraits::Point_2& p1, - const typename GeomTraits::Point_2& p2, - const typename GeomTraits::Point_2& q, - const GeomTraits& traits) { } - -/*! - \ingroup PkgWeightsRefAuthalicWeights - - \brief computes the authalic weight in 3D at `q` using the points `p0`, `p1`, - and `p2`, given a traits class `traits` with geometric objects, predicates, and constructions. -*/ -template -typename GeomTraits::FT authalic_weight( - const typename GeomTraits::Point_3& p0, - const typename GeomTraits::Point_3& p1, - const typename GeomTraits::Point_3& p2, - const typename GeomTraits::Point_3& q, - const GeomTraits& traits) { } - -/*! - \ingroup PkgWeightsRefAuthalicWeights - - \brief computes the authalic weight in 2D at `q` using the points `p0`, `p1`, - and `p2` which are parameterized by a `Kernel` K. -*/ -template -typename K::FT authalic_weight( - const CGAL::Point_2& p0, - const CGAL::Point_2& p1, - const CGAL::Point_2& p2, - const CGAL::Point_2& q) { } - -/*! - \ingroup PkgWeightsRefAuthalicWeights - - \brief computes the authalic weight in 3D at `q` using the points `p0`, `p1`, - and `p2` which are parameterized by a `Kernel` K. -*/ -template -typename K::FT authalic_weight( - const CGAL::Point_3& p0, - const CGAL::Point_3& p1, - const CGAL::Point_3& p2, - const CGAL::Point_3& q) { } - -#endif // DOXYGEN_RUNNING - -/// \cond SKIP_IN_MANUAL -// Overloads! template typename GeomTraits::FT authalic_weight(const typename GeomTraits::Point_2& t, const typename GeomTraits::Point_2& r, @@ -192,8 +132,6 @@ typename GeomTraits::FT authalic_weight(const CGAL::Point_3& t, return authalic_weight(t, r, p, q, traits); } -/// \endcond - } // namespace Weights } // namespace CGAL diff --git a/Weights/include/CGAL/Weights/barycentric_region_weights.h b/Weights/include/CGAL/Weights/barycentric_region_weights.h index c095bd8c520..4b8d5692bf5 100644 --- a/Weights/include/CGAL/Weights/barycentric_region_weights.h +++ b/Weights/include/CGAL/Weights/barycentric_region_weights.h @@ -19,61 +19,6 @@ namespace CGAL { namespace Weights { -#if defined(DOXYGEN_RUNNING) - -/*! - \ingroup PkgWeightsRefBarycentricRegionWeights - - \brief computes the area of the barycentric cell in 2D using the points `p`, `q` - and `r`, given a traits class `traits` with geometric objects, predicates, and constructions. -*/ -template -typename GeomTraits::FT barycentric_area( - const typename GeomTraits::Point_2& p, - const typename GeomTraits::Point_2& q, - const typename GeomTraits::Point_2& r, - const GeomTraits& traits) { } - -/*! - \ingroup PkgWeightsRefBarycentricRegionWeights - - \brief computes the area of the barycentric cell in 3D using the points `p`, `q` - and `r`, given a traits class `traits` with geometric objects, predicates, and constructions. -*/ -template -typename GeomTraits::FT barycentric_area( - const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3& q, - const typename GeomTraits::Point_3& r, - const GeomTraits& traits) { } - -/*! - \ingroup PkgWeightsRefBarycentricRegionWeights - - \brief computes the area of the barycentric cell in 2D using the points `p`, `q` - and `r` which are parameterized by a `Kernel` K. -*/ -template -typename K::FT barycentric_area( - const CGAL::Point_2& p, - const CGAL::Point_2& q, - const CGAL::Point_2& r) { } - -/*! - \ingroup PkgWeightsRefBarycentricRegionWeights - - \brief computes the area of the barycentric cell in 3D using the points `p`, `q` - and `r` which are parameterized by a `Kernel` K. -*/ -template -typename K::FT barycentric_area( - const CGAL::Point_3& p, - const CGAL::Point_3& q, - const CGAL::Point_3& r) { } - -#endif // DOXYGEN_RUNNING - -/// \cond SKIP_IN_MANUAL template typename GeomTraits::FT barycentric_area(const typename GeomTraits::Point_2& p, const typename GeomTraits::Point_2& q, @@ -132,8 +77,6 @@ typename GeomTraits::FT barycentric_area(const CGAL::Point_3& p, return barycentric_area(p, q, r, traits); } -/// \endcond - } // namespace Weights } // namespace CGAL diff --git a/Weights/include/CGAL/Weights/cotangent_weights.h b/Weights/include/CGAL/Weights/cotangent_weights.h index 5b8a5617fa7..b4096632442 100644 --- a/Weights/include/CGAL/Weights/cotangent_weights.h +++ b/Weights/include/CGAL/Weights/cotangent_weights.h @@ -59,65 +59,6 @@ FT half_cotangent_weight(const FT cot) return cotangent_ns::half_weight(cot); } -#if defined(DOXYGEN_RUNNING) - -/*! - \ingroup PkgWeightsRefCotangentWeights - - \brief computes the cotangent weight in 2D at `q` using the points `p0`, `p1`, - and `p2`, given a traits class `traits` with geometric objects, predicates, and constructions. -*/ -template -typename GeomTraits::FT cotangent_weight( - const typename GeomTraits::Point_2& p0, - const typename GeomTraits::Point_2& p1, - const typename GeomTraits::Point_2& p2, - const typename GeomTraits::Point_2& q, - const GeomTraits& traits) { } - -/*! - \ingroup PkgWeightsRefCotangentWeights - - \brief computes the cotangent weight in 3D at `q` using the points `p0`, `p1`, - and `p2`, given a traits class `traits` with geometric objects, predicates, and constructions. -*/ -template -typename GeomTraits::FT cotangent_weight( - const typename GeomTraits::Point_3& p0, - const typename GeomTraits::Point_3& p1, - const typename GeomTraits::Point_3& p2, - const typename GeomTraits::Point_3& q, - const GeomTraits& traits) { } - -/*! - \ingroup PkgWeightsRefCotangentWeights - - \brief computes the cotangent weight in 2D at `q` using the points `p0`, `p1`, - and `p2` which are parameterized by a `Kernel` K. -*/ -template -typename K::FT cotangent_weight( - const CGAL::Point_2& p0, - const CGAL::Point_2& p1, - const CGAL::Point_2& p2, - const CGAL::Point_2& q) { } - -/*! - \ingroup PkgWeightsRefCotangentWeights - - \brief computes the cotangent weight in 3D at `q` using the points `p0`, `p1`, - and `p2` which are parameterized by a `Kernel` K. -*/ -template -typename K::FT cotangent_weight( - const CGAL::Point_3& p0, - const CGAL::Point_3& p1, - const CGAL::Point_3& p2, - const CGAL::Point_3& q) { } - -#endif // DOXYGEN_RUNNING - -/// \cond SKIP_IN_MANUAL template typename GeomTraits::FT cotangent_weight(const typename GeomTraits::Point_2& t, const typename GeomTraits::Point_2& r, @@ -512,8 +453,6 @@ private: } }; -/// \endcond - } // namespace Weights } // namespace CGAL diff --git a/Weights/include/CGAL/Weights/discrete_harmonic_weights.h b/Weights/include/CGAL/Weights/discrete_harmonic_weights.h index 170b73a67b3..5f836d0a2bc 100644 --- a/Weights/include/CGAL/Weights/discrete_harmonic_weights.h +++ b/Weights/include/CGAL/Weights/discrete_harmonic_weights.h @@ -42,40 +42,6 @@ FT weight(const FT r1, const FT r2, const FT r3, } // namespace discrete_harmonic_ns -/// \endcond - -#if defined(DOXYGEN_RUNNING) - -/*! - \ingroup PkgWeightsRefDiscreteHarmonicWeights - - \brief computes the discrete harmonic weight in 2D at `q` using the points `p0`, `p1`, - and `p2`, given a traits class `traits` with geometric objects, predicates, and constructions. -*/ -template -typename GeomTraits::FT discrete_harmonic_weight( - const typename GeomTraits::Point_2& p0, - const typename GeomTraits::Point_2& p1, - const typename GeomTraits::Point_2& p2, - const typename GeomTraits::Point_2& q, - const GeomTraits& traits) { } - -/*! - \ingroup PkgWeightsRefDiscreteHarmonicWeights - - \brief computes the discrete harmonic weight in 2D at `q` using the points `p0`, `p1`, - and `p2` which are parameterized by a `Kernel` K. -*/ -template -typename K::FT discrete_harmonic_weight( - const CGAL::Point_2& p0, - const CGAL::Point_2& p1, - const CGAL::Point_2& p2, - const CGAL::Point_2& q) { } - -#endif // DOXYGEN_RUNNING - -/// \cond SKIP_IN_MANUAL template typename GeomTraits::FT discrete_harmonic_weight(const typename GeomTraits::Point_2& t, const typename GeomTraits::Point_2& r, diff --git a/Weights/include/CGAL/Weights/inverse_distance_weights.h b/Weights/include/CGAL/Weights/inverse_distance_weights.h index 28fec763c5e..a6774ad509a 100644 --- a/Weights/include/CGAL/Weights/inverse_distance_weights.h +++ b/Weights/include/CGAL/Weights/inverse_distance_weights.h @@ -35,113 +35,6 @@ FT weight(const FT d) } // namespace inverse_distance_ns -/// \endcond - -#if defined(DOXYGEN_RUNNING) - -/*! - \ingroup PkgWeightsRefInverseDistanceWeights - - \brief computes the inverse distance weight in 2D using the points `p` and `q`, - given a traits class `traits` with geometric objects, predicates, and constructions. - */ -template -typename GeomTraits::FT inverse_distance_weight( - const typename GeomTraits::Point_2&, - const typename GeomTraits::Point_2& p, - const typename GeomTraits::Point_2&, - const typename GeomTraits::Point_2& q, - const GeomTraits& traits) { } - -/*! - \ingroup PkgWeightsRefInverseDistanceWeights - - \brief computes the inverse distance weight in 3D using the points `p` and `q`, - given a traits class `traits` with geometric objects, predicates, and constructions. - */ -template -typename GeomTraits::FT inverse_distance_weight( - const typename GeomTraits::Point_3&, - const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3&, - const typename GeomTraits::Point_3& q, - const GeomTraits& traits) { } - -/*! - \ingroup PkgWeightsRefInverseDistanceWeights - - \brief computes the inverse distance weight in 2D using the points `p` and `q`, - which are parameterized by a `Kernel` K. - */ -template -typename K::FT inverse_distance_weight( - const CGAL::Point_2&, - const CGAL::Point_2& p, - const CGAL::Point_2&, - const CGAL::Point_2& q) { } - -/*! - \ingroup PkgWeightsRefInverseDistanceWeights - - \brief computes the inverse distance weight in 3D using the points `p` and `q`, - which are parameterized by a `Kernel` K. - */ -template -typename K::FT inverse_distance_weight( - const CGAL::Point_3&, - const CGAL::Point_3& p, - const CGAL::Point_3&, - const CGAL::Point_3& q) { } - -/*! - \ingroup PkgWeightsRefInverseDistanceWeights - - \brief computes the inverse distance weight in 2D using the points `p` and `q`, - given a traits class `traits` with geometric objects, predicates, and constructions. - */ -template -typename GeomTraits::FT inverse_distance_weight( - const typename GeomTraits::Point_2& p, - const typename GeomTraits::Point_2& q, - const GeomTraits& traits) { } - -/*! - \ingroup PkgWeightsRefInverseDistanceWeights - - \brief computes the inverse distance weight in 3D using the points `p` and `q`, - given a traits class `traits` with geometric objects, predicates, and constructions. - */ -template -typename GeomTraits::FT inverse_distance_weight( - const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3& q, - const GeomTraits& traits) { } - -/*! - \ingroup PkgWeightsRefInverseDistanceWeights - - \brief computes the inverse distance weight in 2D using the points `p` and `q`, - which are parameterized by a `Kernel` K. - */ -template -typename K::FT inverse_distance_weight( - const CGAL::Point_2& p, - const CGAL::Point_2& q) { } - -/*! - \ingroup PkgWeightsRefInverseDistanceWeights - - \brief computes the inverse distance weight in 3D using the points `p` and `q`, - which are parameterized by a `Kernel` K. - */ -template -typename K::FT inverse_distance_weight( - const CGAL::Point_3& p, - const CGAL::Point_3& q) { } - -#endif // DOXYGEN_RUNNING - -/// \cond SKIP_IN_MANUAL template typename GeomTraits::FT inverse_distance_weight(const typename GeomTraits::Point_2&, const typename GeomTraits::Point_2& r, diff --git a/Weights/include/CGAL/Weights/mean_value_weights.h b/Weights/include/CGAL/Weights/mean_value_weights.h index 810294355ac..0e688e72226 100644 --- a/Weights/include/CGAL/Weights/mean_value_weights.h +++ b/Weights/include/CGAL/Weights/mean_value_weights.h @@ -76,40 +76,6 @@ typename GeomTraits::FT weight(const GeomTraits& traits, } // namespace mean_value_ns -/// \endcond - -#if defined(DOXYGEN_RUNNING) - -/*! - \ingroup PkgWeightsRefMeanValueWeights - - \brief computes the mean value weight in 2D at `q` using the points `p0`, `p1`, - and `p2`, given a traits class `traits` with geometric objects, predicates, and constructions. -*/ -template -typename GeomTraits::FT mean_value_weight( - const typename GeomTraits::Point_2& p0, - const typename GeomTraits::Point_2& p1, - const typename GeomTraits::Point_2& p2, - const typename GeomTraits::Point_2& q, - const GeomTraits& traits) { } - -/*! - \ingroup PkgWeightsRefMeanValueWeights - - \brief computes the mean value weight in 2D at `q` using the points `p0`, `p1`, - and `p2` which are parameterized by a `Kernel` K. -*/ -template -typename K::FT mean_value_weight( - const CGAL::Point_2& p0, - const CGAL::Point_2& p1, - const CGAL::Point_2& p2, - const CGAL::Point_2& q) { } - -#endif // DOXYGEN_RUNNING - -/// \cond SKIP_IN_MANUAL template typename GeomTraits::FT mean_value_weight(const typename GeomTraits::Point_2& t, const typename GeomTraits::Point_2& r, diff --git a/Weights/include/CGAL/Weights/mixed_voronoi_region_weights.h b/Weights/include/CGAL/Weights/mixed_voronoi_region_weights.h index 0dafc0f198c..4eea980e123 100644 --- a/Weights/include/CGAL/Weights/mixed_voronoi_region_weights.h +++ b/Weights/include/CGAL/Weights/mixed_voronoi_region_weights.h @@ -19,60 +19,6 @@ namespace CGAL { namespace Weights { -#if defined(DOXYGEN_RUNNING) - -/*! - \ingroup PkgWeightsRefMixedVoronoiRegionWeights - - \brief computes the area of the mixed Voronoi cell in 2D using the points `p`, `q` - and `r`, given a traits class `traits` with geometric objects, predicates, and constructions. -*/ -template -typename GeomTraits::FT mixed_voronoi_area( - const typename GeomTraits::Point_2& p, - const typename GeomTraits::Point_2& q, - const typename GeomTraits::Point_2& r, - const GeomTraits& traits) { } - -/*! - \ingroup PkgWeightsRefMixedVoronoiRegionWeights - - \brief computes the area of the mixed Voronoi cell in 3D using the points `p`, `q` - and `r`, given a traits class `traits` with geometric objects, predicates, and constructions. -*/ -template -typename GeomTraits::FT mixed_voronoi_area( - const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3& q, - const typename GeomTraits::Point_3& r, - const GeomTraits& traits) { } - -/*! - \ingroup PkgWeightsRefMixedVoronoiRegionWeights - - \brief computes the area of the mixed Voronoi cell in 2D using the points `p`, `q` - and `r` which are parameterized by a `Kernel` K. -*/ -template -typename K::FT mixed_voronoi_area( - const CGAL::Point_2& p, - const CGAL::Point_2& q, - const CGAL::Point_2& r) { } - -/*! - \ingroup PkgWeightsRefMixedVoronoiRegionWeights - - \brief computes the area of the mixed Voronoi cell in 3D using the points `p`, `q` - and `r` which are parameterized by a `Kernel` K. -*/ -template -typename K::FT mixed_voronoi_area( - const CGAL::Point_3& p, - const CGAL::Point_3& q, - const CGAL::Point_3& r) { } - -#endif // DOXYGEN_RUNNING - /// \cond SKIP_IN_MANUAL template typename GeomTraits::FT mixed_voronoi_area(const typename GeomTraits::Point_2& p, diff --git a/Weights/include/CGAL/Weights/shepard_weights.h b/Weights/include/CGAL/Weights/shepard_weights.h index 00e21883d21..7fbc2e7a6e5 100644 --- a/Weights/include/CGAL/Weights/shepard_weights.h +++ b/Weights/include/CGAL/Weights/shepard_weights.h @@ -45,125 +45,6 @@ typename GeomTraits::FT weight(const GeomTraits& traits, } // namespace shepard_ns -/// \endcond - -#if defined(DOXYGEN_RUNNING) - -/*! - \ingroup PkgWeightsRefShepardWeights - - \brief computes the Shepard weight in 2D using the points `p` and `q` and the power parameter `a`, - given a traits class `traits` with geometric objects, predicates, and constructions. -*/ -template -typename GeomTraits::FT shepard_weight( - const typename GeomTraits::Point_2&, - const typename GeomTraits::Point_2& p, - const typename GeomTraits::Point_2&, - const typename GeomTraits::Point_2& q, - const typename GeomTraits::FT a, - const GeomTraits& traits) { } - -/*! - \ingroup PkgWeightsRefShepardWeights - - \brief computes the Shepard weight in 3D using the points `p` and `q` and the power parameter `a`, - given a traits class `traits` with geometric objects, predicates, and constructions. -*/ -template -typename GeomTraits::FT shepard_weight( - const typename GeomTraits::Point_3&, - const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3&, - const typename GeomTraits::Point_3& q, - const typename GeomTraits::FT a, - const GeomTraits& traits) { } - -/*! - \ingroup PkgWeightsRefShepardWeights - - \brief computes the Shepard weight in 2D using the points `p` and `q`, - which are parameterized by a `Kernel` K, and the power parameter `a` which - can be omitted. -*/ -template -typename K::FT shepard_weight( - const CGAL::Point_2&, - const CGAL::Point_2& p, - const CGAL::Point_2&, - const CGAL::Point_2& q, - const typename K::FT a = typename K::FT(1)) { } - -/*! - \ingroup PkgWeightsRefShepardWeights - - \brief computes the Shepard weight in 3D using the points `p` and `q`, - which are parameterized by a `Kernel` K, and the power parameter `a` which - can be omitted. -*/ -template -typename K::FT shepard_weight( - const CGAL::Point_3&, - const CGAL::Point_3& p, - const CGAL::Point_3&, - const CGAL::Point_3& q, - const typename K::FT a = typename K::FT(1)) { } - -/*! - \ingroup PkgWeightsRefShepardWeights - - \brief computes the Shepard weight in 2D using the points `p` and `q` and the power parameter `a`, - given a traits class `traits` with geometric objects, predicates, and constructions. -*/ -template -typename GeomTraits::FT shepard_weight( - const typename GeomTraits::Point_2& p, - const typename GeomTraits::Point_2& q, - const typename GeomTraits::FT a, - const GeomTraits& traits) { } - -/*! - \ingroup PkgWeightsRefShepardWeights - - \brief computes the Shepard weight in 3D using the points `p` and `q` and the power parameter `a`, - given a traits class `traits` with geometric objects, predicates, and constructions. -*/ -template -typename GeomTraits::FT shepard_weight( - const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3& q, - const typename GeomTraits::FT a, - const GeomTraits& traits) { } - -/*! - \ingroup PkgWeightsRefShepardWeights - - \brief computes the Shepard weight in 2D using the points `p` and `q`, - which are parameterized by a `Kernel` K, and the power parameter `a` which - can be omitted. -*/ -template -typename K::FT shepard_weight( - const CGAL::Point_2& p, - const CGAL::Point_2& q, - const typename K::FT a = typename K::FT(1)) { } - -/*! - \ingroup PkgWeightsRefShepardWeights - - \brief computes the Shepard weight in 3D using the points `p` and `q`, - which are parameterized by a `Kernel` K, and the power parameter `a` which - can be omitted. -*/ -template -typename K::FT shepard_weight( - const CGAL::Point_3& p, - const CGAL::Point_3& q, - const typename K::FT a = typename K::FT(1)) { } - -#endif // DOXYGEN_RUNNING - -/// \cond SKIP_IN_MANUAL template typename GeomTraits::FT shepard_weight(const typename GeomTraits::Point_2&, const typename GeomTraits::Point_2& r, diff --git a/Weights/include/CGAL/Weights/tangent_weights.h b/Weights/include/CGAL/Weights/tangent_weights.h index 399878326f7..f4f6e5c623f 100644 --- a/Weights/include/CGAL/Weights/tangent_weights.h +++ b/Weights/include/CGAL/Weights/tangent_weights.h @@ -234,64 +234,6 @@ FT half_tangent_weight(const FT d, const FT l, const FT A, const FT D) return half_tangent_weight(tan05, d); } -#if defined(DOXYGEN_RUNNING) - -/*! - \ingroup PkgWeightsRefTangentWeights - - \brief computes the tangent weight in 2D at `q` using the points `p0`, `p1`, - and `p2`, given a traits class `traits` with geometric objects, predicates, and constructions. -*/ -template -typename GeomTraits::FT tangent_weight( - const typename GeomTraits::Point_2& p0, - const typename GeomTraits::Point_2& p1, - const typename GeomTraits::Point_2& p2, - const typename GeomTraits::Point_2& q, - const GeomTraits& traits) { } - -/*! - \ingroup PkgWeightsRefTangentWeights - - \brief computes the tangent weight in 3D at `q` using the points `p0`, `p1`, - and `p2`, given a traits class `traits` with geometric objects, predicates, and constructions. -*/ -template -typename GeomTraits::FT tangent_weight( - const typename GeomTraits::Point_3& p0, - const typename GeomTraits::Point_3& p1, - const typename GeomTraits::Point_3& p2, - const typename GeomTraits::Point_3& q, - const GeomTraits& traits) { } - -/*! - \ingroup PkgWeightsRefTangentWeights - - \brief computes the tangent weight in 2D at `q` using the points `p0`, `p1`, - and `p2` which are parameterized by a `Kernel` K. -*/ -template -typename K::FT tangent_weight( - const CGAL::Point_2& p0, - const CGAL::Point_2& p1, - const CGAL::Point_2& p2, - const CGAL::Point_2& q) { } - -/*! - \ingroup PkgWeightsRefTangentWeights - - \brief computes the tangent weight in 3D at `q` using the points `p0`, `p1`, - and `p2` which are parameterized by a `Kernel` K. -*/ -template -typename K::FT tangent_weight( - const CGAL::Point_3& p0, - const CGAL::Point_3& p1, - const CGAL::Point_3& p2, - const CGAL::Point_3& q) { } - -#endif // DOXYGEN_RUNNING - /// \cond SKIP_IN_MANUAL template typename GeomTraits::FT tangent_weight(const typename GeomTraits::Point_2& t, diff --git a/Weights/include/CGAL/Weights/three_point_family_weights.h b/Weights/include/CGAL/Weights/three_point_family_weights.h index ce7b0d978a0..44743f8497e 100644 --- a/Weights/include/CGAL/Weights/three_point_family_weights.h +++ b/Weights/include/CGAL/Weights/three_point_family_weights.h @@ -57,44 +57,6 @@ typename GeomTraits::FT weight(const GeomTraits& traits, } // namespace three_point_family_ns -/// \endcond - -#if defined(DOXYGEN_RUNNING) - -/*! - \ingroup PkgWeightsRefThreePointFamilyWeights - - \brief computes the three-point family weight in 2D at `q` using the points `p0`, `p1`, - and `p2` and the power parameter `a`, given a traits class `traits` with geometric objects, - predicates, and constructions. -*/ -template -typename GeomTraits::FT three_point_family_weight( - const typename GeomTraits::Point_2& p0, - const typename GeomTraits::Point_2& p1, - const typename GeomTraits::Point_2& p2, - const typename GeomTraits::Point_2& q, - const typename GeomTraits::FT a, - const GeomTraits& traits) { } - -/*! - \ingroup PkgWeightsRefThreePointFamilyWeights - - \brief computes the three-point family weight in 2D at `q` using the points `p0`, `p1`, - and `p2` which are parameterized by a `Kernel` K, and the power parameter `a` which - can be omitted. -*/ -template -typename K::FT three_point_family_weight( - const CGAL::Point_2& p0, - const CGAL::Point_2& p1, - const CGAL::Point_2& p2, - const CGAL::Point_2& q, - const typename K::FT a = typename K::FT(1)) { } - -#endif // DOXYGEN_RUNNING - -/// \cond SKIP_IN_MANUAL template typename GeomTraits::FT three_point_family_weight(const typename GeomTraits::Point_2& t, const typename GeomTraits::Point_2& r, diff --git a/Weights/include/CGAL/Weights/triangular_region_weights.h b/Weights/include/CGAL/Weights/triangular_region_weights.h index bb94af1a332..6975bb38349 100644 --- a/Weights/include/CGAL/Weights/triangular_region_weights.h +++ b/Weights/include/CGAL/Weights/triangular_region_weights.h @@ -19,60 +19,6 @@ namespace CGAL { namespace Weights { -#if defined(DOXYGEN_RUNNING) - -/*! - \ingroup PkgWeightsRefTriangularRegionWeights - - \brief computes the area of the triangular cell in 2D using the points `p`, `q` - and `r`, given a traits class `traits` with geometric objects, predicates, and constructions. -*/ -template -typename GeomTraits::FT triangular_area( - const typename GeomTraits::Point_2& p, - const typename GeomTraits::Point_2& q, - const typename GeomTraits::Point_2& r, - const GeomTraits& traits) { } - -/*! - \ingroup PkgWeightsRefTriangularRegionWeights - - \brief computes the area of the triangular cell in 3D using the points `p`, `q` - and `r`, given a traits class `traits` with geometric objects, predicates, and constructions. -*/ -template -typename GeomTraits::FT triangular_area( - const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3& q, - const typename GeomTraits::Point_3& r, - const GeomTraits& traits) { } - -/*! - \ingroup PkgWeightsRefTriangularRegionWeights - - \brief computes the area of the triangular cell in 2D using the points `p`, `q` - and `r` which are parameterized by a `Kernel` K. -*/ -template -typename K::FT triangular_area( - const CGAL::Point_2& p, - const CGAL::Point_2& q, - const CGAL::Point_2& r) { } - -/*! - \ingroup PkgWeightsRefTriangularRegionWeights - - \brief computes the area of the triangular cell in 3D using the points `p`, `q` - and `r` which are parameterized by a `Kernel` K. -*/ -template -typename K::FT triangular_area( - const CGAL::Point_3& p, - const CGAL::Point_3& q, - const CGAL::Point_3& r) { } - -#endif // DOXYGEN_RUNNING - /// \cond SKIP_IN_MANUAL template typename GeomTraits::FT triangular_area(const typename GeomTraits::Point_2& p, diff --git a/Weights/include/CGAL/Weights/uniform_region_weights.h b/Weights/include/CGAL/Weights/uniform_region_weights.h index f028c700903..fd5d41179a1 100644 --- a/Weights/include/CGAL/Weights/uniform_region_weights.h +++ b/Weights/include/CGAL/Weights/uniform_region_weights.h @@ -14,66 +14,11 @@ #ifndef CGAL_UNIFORM_REGION_WEIGHTS_H #define CGAL_UNIFORM_REGION_WEIGHTS_H -// Internal includes. #include namespace CGAL { namespace Weights { -#if defined(DOXYGEN_RUNNING) - -/*! - \ingroup PkgWeightsRefUniformRegionWeights - - \brief this function always returns 1, given three points in 2D and a traits class - with geometric objects, predicates, and constructions. -*/ -template -typename GeomTraits::FT uniform_area( - const typename GeomTraits::Point_2&, - const typename GeomTraits::Point_2&, - const typename GeomTraits::Point_2&, - const GeomTraits&) { } - -/*! - \ingroup PkgWeightsRefUniformRegionWeights - - \brief this function always returns 1, given three points in 3D and a traits class - with geometric objects, predicates, and constructions. -*/ -template -typename GeomTraits::FT uniform_area( - const typename GeomTraits::Point_3&, - const typename GeomTraits::Point_3&, - const typename GeomTraits::Point_3&, - const GeomTraits&) { } - -/*! - \ingroup PkgWeightsRefUniformRegionWeights - - \brief this function always returns 1, given three points in 2D which are - parameterized by a `Kernel` K. -*/ -template -typename K::FT uniform_area( - const CGAL::Point_2&, - const CGAL::Point_2&, - const CGAL::Point_2&) { } - -/*! - \ingroup PkgWeightsRefUniformRegionWeights - - \brief this function always returns 1, given three points in 3D which are - parameterized by a `Kernel` K. -*/ -template -typename K::FT uniform_area( - const CGAL::Point_3&, - const CGAL::Point_3&, - const CGAL::Point_3&) { } - -#endif // DOXYGEN_RUNNING - /// \cond SKIP_IN_MANUAL template typename GeomTraits::FT uniform_area(const typename GeomTraits::Point_2&, diff --git a/Weights/include/CGAL/Weights/uniform_weights.h b/Weights/include/CGAL/Weights/uniform_weights.h index 439e0e74075..dd96ca4a9f5 100644 --- a/Weights/include/CGAL/Weights/uniform_weights.h +++ b/Weights/include/CGAL/Weights/uniform_weights.h @@ -14,70 +14,11 @@ #ifndef CGAL_UNIFORM_WEIGHTS_H #define CGAL_UNIFORM_WEIGHTS_H -// Internal includes. #include namespace CGAL { namespace Weights { -#if defined(DOXYGEN_RUNNING) - -/*! - \ingroup PkgWeightsRefUniformWeights - - \brief this function always returns 1, given four points in 2D and a traits class - with geometric objects, predicates, and constructions. - */ -template -typename GeomTraits::FT uniform_weight( - const typename GeomTraits::Point_2&, - const typename GeomTraits::Point_2&, - const typename GeomTraits::Point_2&, - const typename GeomTraits::Point_2&, - const GeomTraits&) { } - -/*! - \ingroup PkgWeightsRefUniformWeights - - \brief this function always returns 1, given four points in 3D and a traits class - with geometric objects, predicates, and constructions. - */ -template -typename GeomTraits::FT uniform_weight( - const typename GeomTraits::Point_3&, - const typename GeomTraits::Point_3&, - const typename GeomTraits::Point_3&, - const typename GeomTraits::Point_3&, - const GeomTraits&) { } - -/*! - \ingroup PkgWeightsRefUniformWeights - - \brief this function always returns 1, given four points in 2D which are - parameterized by a `Kernel` K. - */ -template -typename K::FT uniform_weight( - const CGAL::Point_2&, - const CGAL::Point_2&, - const CGAL::Point_2&, - const CGAL::Point_2&) { } - -/*! - \ingroup PkgWeightsRefUniformWeights - - \brief this function always returns 1, given four points in 3D which are - parameterized by a `Kernel` K. - */ -template -typename K::FT uniform_weight( - const CGAL::Point_3&, - const CGAL::Point_3&, - const CGAL::Point_3&, - const CGAL::Point_3&) { } - -#endif // DOXYGEN_RUNNING - /// \cond SKIP_IN_MANUAL template typename GeomTraits::FT uniform_weight( diff --git a/Weights/include/CGAL/Weights/utils.h b/Weights/include/CGAL/Weights/utils.h index d28dfe877ba..6c72a4e27c8 100644 --- a/Weights/include/CGAL/Weights/utils.h +++ b/Weights/include/CGAL/Weights/utils.h @@ -14,7 +14,6 @@ #ifndef CGAL_WEIGHTS_UTILS_H #define CGAL_WEIGHTS_UTILS_H -// Internal includes. #include namespace CGAL { diff --git a/Weights/include/CGAL/Weights/voronoi_region_weights.h b/Weights/include/CGAL/Weights/voronoi_region_weights.h index 8497c8aad57..729ae98e8a8 100644 --- a/Weights/include/CGAL/Weights/voronoi_region_weights.h +++ b/Weights/include/CGAL/Weights/voronoi_region_weights.h @@ -19,60 +19,6 @@ namespace CGAL { namespace Weights { -#if defined(DOXYGEN_RUNNING) - -/*! - \ingroup PkgWeightsRefVoronoiRegionWeights - - \brief computes the area of the Voronoi cell in 2D using the points `p`, `q` - and `r`, given a traits class `traits` with geometric objects, predicates, and constructions. -*/ -template -typename GeomTraits::FT voronoi_area( - const typename GeomTraits::Point_2& p, - const typename GeomTraits::Point_2& q, - const typename GeomTraits::Point_2& r, - const GeomTraits& traits) { } - -/*! - \ingroup PkgWeightsRefVoronoiRegionWeights - - \brief computes the area of the Voronoi cell in 3D using the points `p`, `q` - and `r`, given a traits class `traits` with geometric objects, predicates, and constructions. -*/ -template -typename GeomTraits::FT voronoi_area( - const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3& q, - const typename GeomTraits::Point_3& r, - const GeomTraits& traits) { } - -/*! - \ingroup PkgWeightsRefVoronoiRegionWeights - - \brief computes the area of the Voronoi cell in 2D using the points `p`, `q` - and `r` which are parameterized by a `Kernel` K. -*/ -template -typename K::FT voronoi_area( - const CGAL::Point_2& p, - const CGAL::Point_2& q, - const CGAL::Point_2& r) { } - -/*! - \ingroup PkgWeightsRefVoronoiRegionWeights - - \brief computes the area of the Voronoi cell in 3D using the points `p`, `q` - and `r` which are parameterized by a `Kernel` K. -*/ -template -typename K::FT voronoi_area( - const CGAL::Point_3& p, - const CGAL::Point_3& q, - const CGAL::Point_3& r) { } - -#endif // DOXYGEN_RUNNING - /// \cond SKIP_IN_MANUAL template typename GeomTraits::FT voronoi_area(const typename GeomTraits::Point_2& p, diff --git a/Weights/include/CGAL/Weights/wachspress_weights.h b/Weights/include/CGAL/Weights/wachspress_weights.h index 00d843d18d1..c695cfbea4a 100644 --- a/Weights/include/CGAL/Weights/wachspress_weights.h +++ b/Weights/include/CGAL/Weights/wachspress_weights.h @@ -40,40 +40,6 @@ FT weight(const FT A1, const FT A2, const FT C) } // wachspress_ns -/// \endcond - -#if defined(DOXYGEN_RUNNING) - -/*! - \ingroup PkgWeightsRefWachspressWeights - - \brief computes the Wachspress weight in 2D at `q` using the points `p0`, `p1`, - and `p2`, given a traits class `traits` with geometric objects, predicates, and constructions. -*/ -template -typename GeomTraits::FT wachspress_weight( - const typename GeomTraits::Point_2& p0, - const typename GeomTraits::Point_2& p1, - const typename GeomTraits::Point_2& p2, - const typename GeomTraits::Point_2& q, - const GeomTraits& traits) { } - -/*! - \ingroup PkgWeightsRefWachspressWeights - - \brief computes the Wachspress weight in 2D at `q` using the points `p0`, `p1`, - and `p2` which are parameterized by a `Kernel` K. -*/ -template -typename K::FT wachspress_weight( - const CGAL::Point_2& p0, - const CGAL::Point_2& p1, - const CGAL::Point_2& p2, - const CGAL::Point_2& q) { } - -#endif // DOXYGEN_RUNNING - -/// \cond SKIP_IN_MANUAL template typename GeomTraits::FT wachspress_weight(const typename GeomTraits::Point_2& t, const typename GeomTraits::Point_2& r, From d20475f3222d1411c9914586e342af7434d057e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 17 Oct 2022 16:29:32 +0200 Subject: [PATCH 03/35] Add missing includes in Weights --- Weights/include/CGAL/Weights/authalic_weights.h | 6 +++++- Weights/include/CGAL/Weights/barycentric_region_weights.h | 5 ++++- Weights/include/CGAL/Weights/cotangent_weights.h | 8 +++++++- Weights/include/CGAL/Weights/discrete_harmonic_weights.h | 6 ++++++ Weights/include/CGAL/Weights/inverse_distance_weights.h | 3 +++ Weights/include/CGAL/Weights/mean_value_weights.h | 8 ++++++++ .../include/CGAL/Weights/mixed_voronoi_region_weights.h | 3 +++ Weights/include/CGAL/Weights/shepard_weights.h | 4 ++++ Weights/include/CGAL/Weights/tangent_weights.h | 8 ++++++-- Weights/include/CGAL/Weights/three_point_family_weights.h | 3 +++ Weights/include/CGAL/Weights/triangular_region_weights.h | 3 +++ Weights/include/CGAL/Weights/uniform_region_weights.h | 3 ++- Weights/include/CGAL/Weights/uniform_weights.h | 5 ++++- Weights/include/CGAL/Weights/voronoi_region_weights.h | 3 +++ Weights/include/CGAL/Weights/wachspress_weights.h | 8 +++++++- 15 files changed, 68 insertions(+), 8 deletions(-) diff --git a/Weights/include/CGAL/Weights/authalic_weights.h b/Weights/include/CGAL/Weights/authalic_weights.h index 447c58f1bea..316fb62289b 100644 --- a/Weights/include/CGAL/Weights/authalic_weights.h +++ b/Weights/include/CGAL/Weights/authalic_weights.h @@ -14,12 +14,16 @@ #ifndef CGAL_AUTHALIC_WEIGHTS_H #define CGAL_AUTHALIC_WEIGHTS_H -#include +#include + +#include +#include namespace CGAL { namespace Weights { /// \cond SKIP_IN_MANUAL + namespace authalic_ns { template diff --git a/Weights/include/CGAL/Weights/barycentric_region_weights.h b/Weights/include/CGAL/Weights/barycentric_region_weights.h index 4b8d5692bf5..f044887186d 100644 --- a/Weights/include/CGAL/Weights/barycentric_region_weights.h +++ b/Weights/include/CGAL/Weights/barycentric_region_weights.h @@ -14,7 +14,10 @@ #ifndef CGAL_BARYCENTRIC_REGION_WEIGHTS_H #define CGAL_BARYCENTRIC_REGION_WEIGHTS_H -#include +#include + +#include +#include namespace CGAL { namespace Weights { diff --git a/Weights/include/CGAL/Weights/cotangent_weights.h b/Weights/include/CGAL/Weights/cotangent_weights.h index b4096632442..65a5908a51e 100644 --- a/Weights/include/CGAL/Weights/cotangent_weights.h +++ b/Weights/include/CGAL/Weights/cotangent_weights.h @@ -14,7 +14,13 @@ #ifndef CGAL_COTANGENT_WEIGHTS_H #define CGAL_COTANGENT_WEIGHTS_H -#include +#include + +#include +#include +#include +#include +#include namespace CGAL { namespace Weights { diff --git a/Weights/include/CGAL/Weights/discrete_harmonic_weights.h b/Weights/include/CGAL/Weights/discrete_harmonic_weights.h index 5f836d0a2bc..865525dbb5f 100644 --- a/Weights/include/CGAL/Weights/discrete_harmonic_weights.h +++ b/Weights/include/CGAL/Weights/discrete_harmonic_weights.h @@ -17,6 +17,12 @@ #include #include +#include +#include +#include + +#include + namespace CGAL { namespace Weights { diff --git a/Weights/include/CGAL/Weights/inverse_distance_weights.h b/Weights/include/CGAL/Weights/inverse_distance_weights.h index a6774ad509a..9d0927c21ee 100644 --- a/Weights/include/CGAL/Weights/inverse_distance_weights.h +++ b/Weights/include/CGAL/Weights/inverse_distance_weights.h @@ -16,6 +16,9 @@ #include +#include +#include + namespace CGAL { namespace Weights { diff --git a/Weights/include/CGAL/Weights/mean_value_weights.h b/Weights/include/CGAL/Weights/mean_value_weights.h index 0e688e72226..33291d74fa7 100644 --- a/Weights/include/CGAL/Weights/mean_value_weights.h +++ b/Weights/include/CGAL/Weights/mean_value_weights.h @@ -17,10 +17,18 @@ #include #include +#include +#include +#include +#include + +#include + namespace CGAL { namespace Weights { /// \cond SKIP_IN_MANUAL + namespace mean_value_ns { template diff --git a/Weights/include/CGAL/Weights/mixed_voronoi_region_weights.h b/Weights/include/CGAL/Weights/mixed_voronoi_region_weights.h index 4eea980e123..6808512751f 100644 --- a/Weights/include/CGAL/Weights/mixed_voronoi_region_weights.h +++ b/Weights/include/CGAL/Weights/mixed_voronoi_region_weights.h @@ -16,6 +16,9 @@ #include +#include +#include + namespace CGAL { namespace Weights { diff --git a/Weights/include/CGAL/Weights/shepard_weights.h b/Weights/include/CGAL/Weights/shepard_weights.h index 7fbc2e7a6e5..2cfbc76b862 100644 --- a/Weights/include/CGAL/Weights/shepard_weights.h +++ b/Weights/include/CGAL/Weights/shepard_weights.h @@ -16,10 +16,14 @@ #include +#include +#include + namespace CGAL { namespace Weights { /// \cond SKIP_IN_MANUAL + namespace shepard_ns { template diff --git a/Weights/include/CGAL/Weights/tangent_weights.h b/Weights/include/CGAL/Weights/tangent_weights.h index f4f6e5c623f..46599707e14 100644 --- a/Weights/include/CGAL/Weights/tangent_weights.h +++ b/Weights/include/CGAL/Weights/tangent_weights.h @@ -14,8 +14,12 @@ #ifndef CGAL_TANGENT_WEIGHTS_H #define CGAL_TANGENT_WEIGHTS_H -// Internal includes. -#include +#include + +#include +#include + +#include namespace CGAL { namespace Weights { diff --git a/Weights/include/CGAL/Weights/three_point_family_weights.h b/Weights/include/CGAL/Weights/three_point_family_weights.h index 44743f8497e..6f2b5f7925f 100644 --- a/Weights/include/CGAL/Weights/three_point_family_weights.h +++ b/Weights/include/CGAL/Weights/three_point_family_weights.h @@ -16,6 +16,9 @@ #include +#include +#include + namespace CGAL { namespace Weights { diff --git a/Weights/include/CGAL/Weights/triangular_region_weights.h b/Weights/include/CGAL/Weights/triangular_region_weights.h index 6975bb38349..9e0f7d2facd 100644 --- a/Weights/include/CGAL/Weights/triangular_region_weights.h +++ b/Weights/include/CGAL/Weights/triangular_region_weights.h @@ -16,6 +16,9 @@ #include +#include +#include + namespace CGAL { namespace Weights { diff --git a/Weights/include/CGAL/Weights/uniform_region_weights.h b/Weights/include/CGAL/Weights/uniform_region_weights.h index fd5d41179a1..a7035fcccdd 100644 --- a/Weights/include/CGAL/Weights/uniform_region_weights.h +++ b/Weights/include/CGAL/Weights/uniform_region_weights.h @@ -14,7 +14,8 @@ #ifndef CGAL_UNIFORM_REGION_WEIGHTS_H #define CGAL_UNIFORM_REGION_WEIGHTS_H -#include +#include +#include namespace CGAL { namespace Weights { diff --git a/Weights/include/CGAL/Weights/uniform_weights.h b/Weights/include/CGAL/Weights/uniform_weights.h index dd96ca4a9f5..be69470d143 100644 --- a/Weights/include/CGAL/Weights/uniform_weights.h +++ b/Weights/include/CGAL/Weights/uniform_weights.h @@ -14,7 +14,10 @@ #ifndef CGAL_UNIFORM_WEIGHTS_H #define CGAL_UNIFORM_WEIGHTS_H -#include +#include +#include + +#include namespace CGAL { namespace Weights { diff --git a/Weights/include/CGAL/Weights/voronoi_region_weights.h b/Weights/include/CGAL/Weights/voronoi_region_weights.h index 729ae98e8a8..5d8f748f26e 100644 --- a/Weights/include/CGAL/Weights/voronoi_region_weights.h +++ b/Weights/include/CGAL/Weights/voronoi_region_weights.h @@ -16,6 +16,9 @@ #include +#include +#include + namespace CGAL { namespace Weights { diff --git a/Weights/include/CGAL/Weights/wachspress_weights.h b/Weights/include/CGAL/Weights/wachspress_weights.h index c695cfbea4a..58face6b47a 100644 --- a/Weights/include/CGAL/Weights/wachspress_weights.h +++ b/Weights/include/CGAL/Weights/wachspress_weights.h @@ -14,14 +14,20 @@ #ifndef CGAL_WACHSPRESS_WEIGHTS_H #define CGAL_WACHSPRESS_WEIGHTS_H -// Internal includes. #include #include +#include +#include +#include + +#include + namespace CGAL { namespace Weights { /// \cond SKIP_IN_MANUAL + namespace wachspress_ns { template From 9a438b26c421092100a23b8fac8f4ec9cbe66776 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 17 Oct 2022 16:48:56 +0200 Subject: [PATCH 04/35] Use fewer 'auto's --- .../include/CGAL/Weights/authalic_weights.h | 4 +- .../CGAL/Weights/barycentric_region_weights.h | 22 ++- .../include/CGAL/Weights/cotangent_weights.h | 75 ++++---- .../CGAL/Weights/discrete_harmonic_weights.h | 2 +- .../CGAL/Weights/internal/polygon_utils_2.h | 12 +- Weights/include/CGAL/Weights/internal/utils.h | 182 ++++++++++-------- .../include/CGAL/Weights/mean_value_weights.h | 13 +- .../Weights/mixed_voronoi_region_weights.h | 32 +-- .../include/CGAL/Weights/tangent_weights.h | 81 ++++---- Weights/include/CGAL/Weights/utils.h | 27 +-- .../CGAL/Weights/voronoi_region_weights.h | 22 ++- 11 files changed, 255 insertions(+), 217 deletions(-) diff --git a/Weights/include/CGAL/Weights/authalic_weights.h b/Weights/include/CGAL/Weights/authalic_weights.h index 316fb62289b..6700bdbb6ad 100644 --- a/Weights/include/CGAL/Weights/authalic_weights.h +++ b/Weights/include/CGAL/Weights/authalic_weights.h @@ -89,7 +89,7 @@ typename GeomTraits::FT authalic_weight(const typename GeomTraits::Point_2& t, { using FT = typename GeomTraits::FT; - const auto squared_distance_2 = traits.compute_squared_distance_2_object(); + auto squared_distance_2 = traits.compute_squared_distance_2_object(); const FT cot_gamma = internal::cotangent_2(traits, t, r, q); const FT cot_beta = internal::cotangent_2(traits, q, r, p); @@ -117,7 +117,7 @@ typename GeomTraits::FT authalic_weight(const typename GeomTraits::Point_3& t, { using FT = typename GeomTraits::FT; - const auto squared_distance_3 = traits.compute_squared_distance_3_object(); + auto squared_distance_3 = traits.compute_squared_distance_3_object(); const FT cot_gamma = internal::cotangent_3(traits, t, r, q); const FT cot_beta = internal::cotangent_3(traits, q, r, p); diff --git a/Weights/include/CGAL/Weights/barycentric_region_weights.h b/Weights/include/CGAL/Weights/barycentric_region_weights.h index f044887186d..fe95dedd107 100644 --- a/Weights/include/CGAL/Weights/barycentric_region_weights.h +++ b/Weights/include/CGAL/Weights/barycentric_region_weights.h @@ -29,13 +29,14 @@ typename GeomTraits::FT barycentric_area(const typename GeomTraits::Point_2& p, const GeomTraits& traits) { using FT = typename GeomTraits::FT; + using Point_2 = typename GeomTraits::Point_2; - const auto midpoint_2 = traits.construct_midpoint_2_object(); - const auto centroid_2 = traits.construct_centroid_2_object(); + auto midpoint_2 = traits.construct_midpoint_2_object(); + auto centroid_2 = traits.construct_centroid_2_object(); - const auto center = centroid_2(p, q, r); - const auto m1 = midpoint_2(q, r); - const auto m2 = midpoint_2(q, p); + const Point_2 center = centroid_2(p, q, r); + const Point_2 m1 = midpoint_2(q, r); + const Point_2 m2 = midpoint_2(q, p); const FT A1 = internal::positive_area_2(traits, q, m1, center); const FT A2 = internal::positive_area_2(traits, q, center, m2); @@ -58,13 +59,14 @@ typename GeomTraits::FT barycentric_area(const typename GeomTraits::Point_3& p, const GeomTraits& traits) { using FT = typename GeomTraits::FT; + using Point_3 = typename GeomTraits::Point_3; - const auto midpoint_3 = traits.construct_midpoint_3_object(); - const auto centroid_3 = traits.construct_centroid_3_object(); + auto midpoint_3 = traits.construct_midpoint_3_object(); + auto centroid_3 = traits.construct_centroid_3_object(); - const auto center = centroid_3(p, q, r); - const auto m1 = midpoint_3(q, r); - const auto m2 = midpoint_3(q, p); + const Point_3 center = centroid_3(p, q, r); + const Point_3 m1 = midpoint_3(q, r); + const Point_3 m2 = midpoint_3(q, p); const FT A1 = internal::positive_area_3(traits, q, m1, center); const FT A2 = internal::positive_area_3(traits, q, center, m2); diff --git a/Weights/include/CGAL/Weights/cotangent_weights.h b/Weights/include/CGAL/Weights/cotangent_weights.h index 65a5908a51e..be6b1b7876d 100644 --- a/Weights/include/CGAL/Weights/cotangent_weights.h +++ b/Weights/include/CGAL/Weights/cotangent_weights.h @@ -146,11 +146,11 @@ public: FT weight = FT(0); if (is_border_edge(he, m_pmesh)) { - const auto h1 = next(he, m_pmesh); + const halfedge_descriptor h1 = next(he, m_pmesh); - const auto v0 = target(he, m_pmesh); - const auto v1 = source(he, m_pmesh); - const auto v2 = target(h1, m_pmesh); + const vertex_descriptor v0 = target(he, m_pmesh); + const vertex_descriptor v1 = source(he, m_pmesh); + const vertex_descriptor v2 = target(h1, m_pmesh); const auto& p0 = get(m_pmap, v0); const auto& p1 = get(m_pmap, v1); @@ -161,13 +161,13 @@ public: } else { - const auto h1 = next(he, m_pmesh); - const auto h2 = prev(opposite(he, m_pmesh), m_pmesh); + const halfedge_descriptor h1 = next(he, m_pmesh); + const halfedge_descriptor h2 = prev(opposite(he, m_pmesh), m_pmesh); - const auto v0 = target(he, m_pmesh); - const auto v1 = source(he, m_pmesh); - const auto v2 = target(h1, m_pmesh); - const auto v3 = source(h2, m_pmesh); + const vertex_descriptor v0 = target(he, m_pmesh); + const vertex_descriptor v1 = source(he, m_pmesh); + const vertex_descriptor v2 = target(h1, m_pmesh); + const vertex_descriptor v3 = source(h2, m_pmesh); const auto& p0 = get(m_pmap, v0); const auto& p1 = get(m_pmap, v1); @@ -249,8 +249,8 @@ public: GeomTraits traits; - const auto v0 = target(he, pmesh); - const auto v1 = source(he, pmesh); + const vertex_descriptor v0 = target(he, pmesh); + const vertex_descriptor v1 = source(he, pmesh); const auto& p0 = get(pmap, v0); const auto& p1 = get(pmap, v1); @@ -258,12 +258,12 @@ public: FT weight = FT(0); if (is_border_edge(he, pmesh)) { - const auto he_cw = opposite(next(he, pmesh), pmesh); + const halfedge_descriptor he_cw = opposite(next(he, pmesh), pmesh); auto v2 = source(he_cw, pmesh); if (is_border_edge(he_cw, pmesh)) { - const auto he_ccw = prev(opposite(he, pmesh), pmesh); + const halfedge_descriptor he_ccw = prev(opposite(he, pmesh), pmesh); v2 = source(he_ccw, pmesh); const auto& p2 = get(pmap, v2); @@ -289,10 +289,10 @@ public: } else { - const auto he_cw = opposite(next(he, pmesh), pmesh); - const auto v2 = source(he_cw, pmesh); - const auto he_ccw = prev(opposite(he, pmesh), pmesh); - const auto v3 = source(he_ccw, pmesh); + const halfedge_descriptor he_cw = opposite(next(he, pmesh), pmesh); + const vertex_descriptor v2 = source(he_cw, pmesh); + const halfedge_descriptor he_ccw = prev(opposite(he, pmesh), pmesh); + const vertex_descriptor v3 = source(he_ccw, pmesh); const auto& p2 = get(pmap, v2); const auto& p3 = get(pmap, v3); @@ -331,6 +331,7 @@ class Secure_cotangent_weight_with_voronoi_area { using GeomTraits = typename CGAL::Kernel_traits::value_type>::type; using FT = typename GeomTraits::FT; + using Vector_3 = typename GeomTraits::Vector_3; const PolygonMesh& m_pmesh; const VertexPointMap m_pmap; @@ -359,8 +360,8 @@ private: FT cotangent_clamped(const halfedge_descriptor he) const { - const auto v0 = target(he, m_pmesh); - const auto v1 = source(he, m_pmesh); + const vertex_descriptor v0 = target(he, m_pmesh); + const vertex_descriptor v1 = source(he, m_pmesh); const auto& p0 = get(m_pmap, v0); const auto& p1 = get(m_pmap, v1); @@ -368,12 +369,12 @@ private: FT weight = FT(0); if (is_border_edge(he, m_pmesh)) { - const auto he_cw = opposite(next(he, m_pmesh), m_pmesh); - auto v2 = source(he_cw, m_pmesh); + const halfedge_descriptor he_cw = opposite(next(he, m_pmesh), m_pmesh); + vertex_descriptor v2 = source(he_cw, m_pmesh); if (is_border_edge(he_cw, m_pmesh)) { - const auto he_ccw = prev(opposite(he, m_pmesh), m_pmesh); + const halfedge_descriptor he_ccw = prev(opposite(he, m_pmesh), m_pmesh); v2 = source(he_ccw, m_pmesh); const auto& p2 = get(m_pmap, v2); @@ -387,10 +388,10 @@ private: } else { - const auto he_cw = opposite(next(he, m_pmesh), m_pmesh); - const auto v2 = source(he_cw, m_pmesh); - const auto he_ccw = prev(opposite(he, m_pmesh), m_pmesh); - const auto v3 = source(he_ccw, m_pmesh); + const halfedge_descriptor he_cw = opposite(next(he, m_pmesh), m_pmesh); + const vertex_descriptor v2 = source(he_cw, m_pmesh); + const halfedge_descriptor he_ccw = prev(opposite(he, m_pmesh), m_pmesh); + const vertex_descriptor v3 = source(he_ccw, m_pmesh); const auto& p2 = get(m_pmap, v2); const auto& p3 = get(m_pmap, v3); @@ -405,27 +406,27 @@ private: FT voronoi(const vertex_descriptor v0) const { - const auto squared_length_3 = m_traits.compute_squared_length_3_object(); - const auto construct_vector_3 = m_traits.construct_vector_3_object(); + auto squared_length_3 = m_traits.compute_squared_length_3_object(); + auto vector_3 = m_traits.construct_vector_3_object(); FT voronoi_area = FT(0); CGAL_assertion(CGAL::is_triangle_mesh(m_pmesh)); - for (const auto& he : halfedges_around_target(halfedge(v0, m_pmesh), m_pmesh)) + for (const halfedge_descriptor& he : halfedges_around_target(halfedge(v0, m_pmesh), m_pmesh)) { CGAL_assertion(v0 == target(he, m_pmesh)); if (is_border(he, m_pmesh)) continue; - const auto v1 = source(he, m_pmesh); - const auto v2 = target(next(he, m_pmesh), m_pmesh); + const vertex_descriptor v1 = source(he, m_pmesh); + const vertex_descriptor v2 = target(next(he, m_pmesh), m_pmesh); const auto& p0 = get(m_pmap, v0); const auto& p1 = get(m_pmap, v1); const auto& p2 = get(m_pmap, v2); - const auto angle0 = CGAL::angle(p1, p0, p2); - const auto angle1 = CGAL::angle(p2, p1, p0); - const auto angle2 = CGAL::angle(p0, p2, p1); + const Angle angle0 = CGAL::angle(p1, p0, p2); + const Angle angle1 = CGAL::angle(p2, p1, p0); + const Angle angle2 = CGAL::angle(p0, p2, p1); const bool obtuse = (angle0 == CGAL::OBTUSE) || (angle1 == CGAL::OBTUSE) || @@ -436,8 +437,8 @@ private: const FT cot_p1 = internal::cotangent_3(m_traits, p2, p1, p0); const FT cot_p2 = internal::cotangent_3(m_traits, p0, p2, p1); - const auto v1 = construct_vector_3(p0, p1); - const auto v2 = construct_vector_3(p0, p2); + const Vector_3 v1 = vector_3(p0, p1); + const Vector_3 v2 = vector_3(p0, p2); const FT t1 = cot_p1 * squared_length_3(v2); const FT t2 = cot_p2 * squared_length_3(v1); diff --git a/Weights/include/CGAL/Weights/discrete_harmonic_weights.h b/Weights/include/CGAL/Weights/discrete_harmonic_weights.h index 865525dbb5f..ea0b89a923b 100644 --- a/Weights/include/CGAL/Weights/discrete_harmonic_weights.h +++ b/Weights/include/CGAL/Weights/discrete_harmonic_weights.h @@ -57,7 +57,7 @@ typename GeomTraits::FT discrete_harmonic_weight(const typename GeomTraits::Poin { using FT = typename GeomTraits::FT; - const auto squared_distance_2 = traits.compute_squared_distance_2_object(); + auto squared_distance_2 = traits.compute_squared_distance_2_object(); const FT d1 = squared_distance_2(q, t); const FT d2 = squared_distance_2(q, r); diff --git a/Weights/include/CGAL/Weights/internal/polygon_utils_2.h b/Weights/include/CGAL/Weights/internal/polygon_utils_2.h index c52388c7559..f2933317972 100644 --- a/Weights/include/CGAL/Weights/internal/polygon_utils_2.h +++ b/Weights/include/CGAL/Weights/internal/polygon_utils_2.h @@ -101,9 +101,9 @@ Edge_case bounded_side_2(const VertexRange& polygon, if (next == last) return Edge_case::EXTERIOR; - const auto compare_x_2 = traits.compare_x_2_object(); - const auto compare_y_2 = traits.compare_y_2_object(); - const auto orientation_2 = traits.orientation_2_object(); + auto compare_x_2 = traits.compare_x_2_object(); + auto compare_y_2 = traits.compare_y_2_object(); + auto orientation_2 = traits.orientation_2_object(); bool is_inside = false; auto curr_y_comp_res = compare_y_2(get(point_map, *curr), query); @@ -224,15 +224,15 @@ bool is_convex_2(const VertexRange& polygon, if (next == last) return true; - const auto equal_2 = traits.equal_2_object(); + auto equal_2 = traits.equal_2_object(); while (equal_2(get(point_map, *prev), get(point_map, *curr))) { curr = next; ++next; if (next == last) return true; } - const auto less_xy_2 = traits.less_xy_2_object(); - const auto orientation_2 = traits.orientation_2_object(); + auto less_xy_2 = traits.less_xy_2_object(); + auto orientation_2 = traits.orientation_2_object(); bool has_clockwise_triplets = false; bool has_counterclockwise_triplets = false; diff --git a/Weights/include/CGAL/Weights/internal/utils.h b/Weights/include/CGAL/Weights/internal/utils.h index 58eed2cd389..640ef28e789 100644 --- a/Weights/include/CGAL/Weights/internal/utils.h +++ b/Weights/include/CGAL/Weights/internal/utils.h @@ -116,9 +116,9 @@ typename GeomTraits::FT distance_2(const GeomTraits& traits, const typename GeomTraits::Point_2& q) { using Get_sqrt = Get_sqrt; - const auto sqrt = Get_sqrt::sqrt_object(traits); + auto sqrt = Get_sqrt::sqrt_object(traits); - const auto squared_distance_2 = traits.compute_squared_distance_2_object(); + auto squared_distance_2 = traits.compute_squared_distance_2_object(); return sqrt(squared_distance_2(p, q)); } @@ -128,9 +128,9 @@ typename GeomTraits::FT length_2(const GeomTraits& traits, const typename GeomTraits::Vector_2& v) { using Get_sqrt = Get_sqrt; - const auto sqrt = Get_sqrt::sqrt_object(traits); + auto sqrt = Get_sqrt::sqrt_object(traits); - const auto squared_length_2 = traits.compute_squared_length_2_object(); + auto squared_length_2 = traits.compute_squared_length_2_object(); return sqrt(squared_length_2(v)); } @@ -155,12 +155,14 @@ typename GeomTraits::FT cotangent_2(const GeomTraits& traits, const typename GeomTraits::Point_2& r) { using FT = typename GeomTraits::FT; - const auto dot_product_2 = traits.compute_scalar_product_2_object(); - const auto cross_product_2 = traits.compute_determinant_2_object(); - const auto construct_vector_2 = traits.construct_vector_2_object(); + using Vector_2 = typename GeomTraits::Vector_2; - const auto v1 = construct_vector_2(q, r); - const auto v2 = construct_vector_2(q, p); + auto dot_product_2 = traits.compute_scalar_product_2_object(); + auto cross_product_2 = traits.compute_determinant_2_object(); + auto construct_vector_2 = traits.construct_vector_2_object(); + + const Vector_2 v1 = construct_vector_2(q, r); + const Vector_2 v2 = construct_vector_2(q, p); const FT dot = dot_product_2(v1, v2); const FT cross = cross_product_2(v1, v2); @@ -181,12 +183,14 @@ typename GeomTraits::FT tangent_2(const GeomTraits& traits, const typename GeomTraits::Point_2& r) { using FT = typename GeomTraits::FT; - const auto dot_product_2 = traits.compute_scalar_product_2_object(); - const auto cross_product_2 = traits.compute_determinant_2_object(); - const auto construct_vector_2 = traits.construct_vector_2_object(); + using Vector_2 = typename GeomTraits::Vector_2; - const auto v1 = construct_vector_2(q, r); - const auto v2 = construct_vector_2(q, p); + auto dot_product_2 = traits.compute_scalar_product_2_object(); + auto cross_product_2 = traits.compute_determinant_2_object(); + auto construct_vector_2 = traits.construct_vector_2_object(); + + const Vector_2 v1 = construct_vector_2(q, r); + const Vector_2 v2 = construct_vector_2(q, p); const FT dot = dot_product_2(v1, v2); const FT cross = cross_product_2(v1, v2); @@ -206,9 +210,9 @@ typename GeomTraits::FT distance_3(const GeomTraits& traits, const typename GeomTraits::Point_3& q) { using Get_sqrt = Get_sqrt; - const auto sqrt = Get_sqrt::sqrt_object(traits); + auto sqrt = Get_sqrt::sqrt_object(traits); - const auto squared_distance_3 = traits.compute_squared_distance_3_object(); + auto squared_distance_3 = traits.compute_squared_distance_3_object(); return sqrt(squared_distance_3(p, q)); } @@ -217,9 +221,9 @@ typename GeomTraits::FT length_3(const GeomTraits& traits, const typename GeomTraits::Vector_3& v) { using Get_sqrt = Get_sqrt; - const auto sqrt = Get_sqrt::sqrt_object(traits); + auto sqrt = Get_sqrt::sqrt_object(traits); - const auto squared_length_3 = traits.compute_squared_length_3_object(); + auto squared_length_3 = traits.compute_squared_length_3_object(); return sqrt(squared_length_3(v)); } @@ -244,15 +248,17 @@ typename GeomTraits::FT cotangent_3(const GeomTraits& traits, const typename GeomTraits::Point_3& r) { using FT = typename GeomTraits::FT; - const auto dot_product_3 = traits.compute_scalar_product_3_object(); - const auto cross_product_3 = traits.construct_cross_product_vector_3_object(); - const auto construct_vector_3 = traits.construct_vector_3_object(); + using Vector_3 = typename GeomTraits::Vector_3; - const auto v1 = construct_vector_3(q, r); - const auto v2 = construct_vector_3(q, p); + auto dot_product_3 = traits.compute_scalar_product_3_object(); + auto cross_product_3 = traits.construct_cross_product_vector_3_object(); + auto vector_3 = traits.construct_vector_3_object(); + + const Vector_3 v1 = vector_3(q, r); + const Vector_3 v2 = vector_3(q, p); const FT dot = dot_product_3(v1, v2); - const auto cross = cross_product_3(v1, v2); + auto cross = cross_product_3(v1, v2); const FT length = length_3(traits, cross); // TODO: @@ -274,15 +280,17 @@ typename GeomTraits::FT tangent_3(const GeomTraits& traits, const typename GeomTraits::Point_3& r) { using FT = typename GeomTraits::FT; - const auto dot_product_3 = traits.compute_scalar_product_3_object(); - const auto cross_product_3 = traits.construct_cross_product_vector_3_object(); - const auto construct_vector_3 = traits.construct_vector_3_object(); + using Vector_3 = typename GeomTraits::Vector_3; - const auto v1 = construct_vector_3(q, r); - const auto v2 = construct_vector_3(q, p); + auto dot_product_3 = traits.compute_scalar_product_3_object(); + auto cross_product_3 = traits.construct_cross_product_vector_3_object(); + auto vector_3 = traits.construct_vector_3_object(); + + const Vector_3 v1 = vector_3(q, r); + const Vector_3 v2 = vector_3(q, p); const FT dot = dot_product_3(v1, v2); - const auto cross = cross_product_3(v1, v2); + auto cross = cross_product_3(v1, v2); const FT length = length_3(traits, cross); // CGAL_assertion(dot != FT(0)); not really necessary @@ -298,7 +306,7 @@ double angle_3(const GeomTraits& traits, const typename GeomTraits::Vector_3& v1, const typename GeomTraits::Vector_3& v2) { - const auto dot_product_3 = traits.compute_scalar_product_3_object(); + auto dot_product_3 = traits.compute_scalar_product_3_object(); const double dot = CGAL::to_double(dot_product_3(v1, v2)); double angle_rad = 0.0; @@ -326,9 +334,9 @@ typename GeomTraits::Point_3 rotate_point_3(const GeomTraits&, const FT s = static_cast(std::sin(angle_rad)); const FT C = FT(1) - c; - const auto x = axis.x(); - const auto y = axis.y(); - const auto z = axis.z(); + const FT x = axis.x(); + const FT y = axis.y(); + const FT z = axis.z(); return Point_3( (x * x * C + c) * query.x() + @@ -349,12 +357,14 @@ void orthogonal_bases_3(const GeomTraits& traits, typename GeomTraits::Vector_3& b1, typename GeomTraits::Vector_3& b2) { + using FT = typename GeomTraits::FT; using Vector_3 = typename GeomTraits::Vector_3; - const auto cross_product_3 = traits.construct_cross_product_vector_3_object(); - const auto nx = normal.x(); - const auto ny = normal.y(); - const auto nz = normal.z(); + auto cross_product_3 = traits.construct_cross_product_vector_3_object(); + + const FT nx = normal.x(); + const FT ny = normal.y(); + const FT nz = normal.z(); if (CGAL::abs(nz) >= CGAL::abs(ny)) b1 = Vector_3(nz, 0, -nx); @@ -375,15 +385,19 @@ typename GeomTraits::Point_2 to_2d(const GeomTraits& traits, const typename GeomTraits::Point_3& origin, const typename GeomTraits::Point_3& query) { + using FT = typename GeomTraits::FT; using Point_2 = typename GeomTraits::Point_2; - const auto dot_product_3 = traits.compute_scalar_product_3_object(); - const auto construct_vector_3 = traits.construct_vector_3_object(); + using Vector_3 = typename GeomTraits::Vector_3; - const auto v = construct_vector_3(origin, query); - const auto x = dot_product_3(b1, v); - const auto y = dot_product_3(b2, v); + auto point_2 = traits.construct_point_2_object(); + auto dot_product_3 = traits.compute_scalar_product_3_object(); + auto vector_3 = traits.construct_vector_3_object(); - return Point_2(x, y); + const Vector_3 v = vector_3(origin, query); + const FT x = dot_product_3(b1, v); + const FT y = dot_product_3(b2, v); + + return point_2(x, y); } // Flattening. @@ -457,12 +471,12 @@ void flatten(const GeomTraits& traits, using Point_3 = typename GeomTraits::Point_3; using Vector_3 = typename GeomTraits::Vector_3; - const auto cross_product_3 = traits.construct_cross_product_vector_3_object(); - const auto construct_vector_3 = traits.construct_vector_3_object(); - const auto centroid_3 = traits.construct_centroid_3_object(); + auto cross_product_3 = traits.construct_cross_product_vector_3_object(); + auto vector_3 = traits.construct_vector_3_object(); + auto centroid_3 = traits.construct_centroid_3_object(); // Compute centroid. - const auto center = centroid_3(t, r, p, q); + const Point_3 center = centroid_3(t, r, p, q); // std::cout << "centroid: " << center << std::endl; // Translate. @@ -477,19 +491,19 @@ void flatten(const GeomTraits& traits, // std::cout << "translated q1: " << q1 << std::endl; // Middle axis. - auto ax = construct_vector_3(q1, r1); + Vector_3 ax = vector_3(q1, r1); normalize_3(traits, ax); // Prev and next vectors. - auto v1 = construct_vector_3(q1, t1); - auto v2 = construct_vector_3(q1, p1); + Vector_3 v1 = vector_3(q1, t1); + Vector_3 v2 = vector_3(q1, p1); normalize_3(traits, v1); normalize_3(traits, v2); // Two triangle normals. - auto n1 = cross_product_3(v1, ax); - auto n2 = cross_product_3(ax, v2); + Vector_3 n1 = cross_product_3(v1, ax); + Vector_3 n2 = cross_product_3(ax, v2); normalize_3(traits, n1); normalize_3(traits, n2); @@ -502,22 +516,22 @@ void flatten(const GeomTraits& traits, // std::cout << "angle deg n1 <-> n2: " << angle_rad * 180.0 / CGAL_PI << std::endl; // Rotate p1 around ax so that it lands onto the plane [q1, t1, r1]. - const auto& t2 = t1; - const auto& r2 = r1; - const auto p2 = rotate_point_3(traits, angle_rad, ax, p1); - const auto& q2 = q1; + const Point_3& t2 = t1; + const Point_3& r2 = r1; + const Point_3 p2 = rotate_point_3(traits, angle_rad, ax, p1); + const Point_3& q2 = q1; // std::cout << "rotated p2: " << p2 << std::endl; // Compute orthogonal base vectors. Vector_3 b1, b2; - const auto& normal = n1; + const Vector_3& normal = n1; orthogonal_bases_3(traits, normal, b1, b2); - // const auto angle12 = angle_3(traits, b1, b2); + // const Angle angle12 = angle_3(traits, b1, b2); // std::cout << "angle deg b1 <-> b2: " << angle12 * 180.0 / CGAL_PI << std::endl; // Flatten a quad. - const auto& origin = q2; + const Point_3& origin = q2; tf = to_2d(traits, b1, b2, origin, t2); rf = to_2d(traits, b1, b2, origin, r2); pf = to_2d(traits, b1, b2, origin, p2); @@ -541,7 +555,7 @@ typename GeomTraits::FT area_2(const GeomTraits& traits, const typename GeomTraits::Point_2& q, const typename GeomTraits::Point_2& r) { - const auto area_2 = traits.compute_area_2_object(); + auto area_2 = traits.compute_area_2_object(); return area_2(p, q, r); } @@ -563,15 +577,16 @@ typename GeomTraits::FT area_3(const GeomTraits& traits, const typename GeomTraits::Point_3& r) { using FT = typename GeomTraits::FT; + using Point_2 = typename GeomTraits::Point_2; using Point_3 = typename GeomTraits::Point_3; using Vector_3 = typename GeomTraits::Vector_3; - const auto cross_product_3 = traits.construct_cross_product_vector_3_object(); - const auto construct_vector_3 = traits.construct_vector_3_object(); - const auto centroid_3 = traits.construct_centroid_3_object(); + auto cross_product_3 = traits.construct_cross_product_vector_3_object(); + auto vector_3 = traits.construct_vector_3_object(); + auto centroid_3 = traits.construct_centroid_3_object(); // Compute centroid. - const auto center = centroid_3(p, q, r); + const Point_3 center = centroid_3(p, q, r); // Translate. const Point_3 a = Point_3(p.x() - center.x(), p.y() - center.y(), p.z() - center.z()); @@ -579,13 +594,13 @@ typename GeomTraits::FT area_3(const GeomTraits& traits, const Point_3 c = Point_3(r.x() - center.x(), r.y() - center.y(), r.z() - center.z()); // Prev and next vectors. - auto v1 = construct_vector_3(b, a); - auto v2 = construct_vector_3(b, c); + Vector_3 v1 = vector_3(b, a); + Vector_3 v2 = vector_3(b, c); normalize_3(traits, v1); normalize_3(traits, v2); // Compute normal. - auto normal = cross_product_3(v1, v2); + Vector_3 normal = cross_product_3(v1, v2); normalize_3(traits, normal); // Compute orthogonal base vectors. @@ -593,10 +608,10 @@ typename GeomTraits::FT area_3(const GeomTraits& traits, orthogonal_bases_3(traits, normal, b1, b2); // Compute area. - const auto& origin = b; - const auto pf = to_2d(traits, b1, b2, origin, a); - const auto qf = to_2d(traits, b1, b2, origin, b); - const auto rf = to_2d(traits, b1, b2, origin, c); + const Point_3& origin = b; + const Point_2 pf = to_2d(traits, b1, b2, origin, a); + const Point_2 qf = to_2d(traits, b1, b2, origin, b); + const Point_2 rf = to_2d(traits, b1, b2, origin, c); const FT A = area_2(traits, pf, qf, rf); return A; @@ -610,14 +625,15 @@ typename GeomTraits::FT positive_area_3(const GeomTraits& traits, const typename GeomTraits::Point_3& r) { using FT = typename GeomTraits::FT; + using Vector_3 = typename GeomTraits::Vector_3; - const auto construct_vector_3 = traits.construct_vector_3_object(); - const auto cross_product_3 = traits.construct_cross_product_vector_3_object(); + auto vector_3 = traits.construct_vector_3_object(); + auto cross_product_3 = traits.construct_cross_product_vector_3_object(); - const auto v1 = construct_vector_3(q, r); - const auto v2 = construct_vector_3(q, p); + const Vector_3 v1 = vector_3(q, r); + const Vector_3 v2 = vector_3(q, p); - const auto cross = cross_product_3(v1, v2); + Vector_3 cross = cross_product_3(v1, v2); const FT half = FT(1) / FT(2); const FT A = half * length_3(traits, cross); return A; @@ -633,14 +649,16 @@ typename GeomTraits::FT cotangent_3_clamped(const GeomTraits& traits, const typename GeomTraits::Point_3& r) { using FT = typename GeomTraits::FT; + using Vector_3 = typename GeomTraits::Vector_3; + using Get_sqrt = Get_sqrt; - const auto sqrt = Get_sqrt::sqrt_object(traits); + auto sqrt = Get_sqrt::sqrt_object(traits); - const auto dot_product_3 = traits.compute_scalar_product_3_object(); - const auto construct_vector_3 = traits.construct_vector_3_object(); + auto dot_product_3 = traits.compute_scalar_product_3_object(); + auto vector_3 = traits.construct_vector_3_object(); - const auto v1 = construct_vector_3(q, r); - const auto v2 = construct_vector_3(q, p); + const Vector_3 v1 = vector_3(q, r); + const Vector_3 v2 = vector_3(q, p); const FT dot = dot_product_3(v1, v2); const FT length_v1 = length_3(traits, v1); diff --git a/Weights/include/CGAL/Weights/mean_value_weights.h b/Weights/include/CGAL/Weights/mean_value_weights.h index 33291d74fa7..c08ccef1c51 100644 --- a/Weights/include/CGAL/Weights/mean_value_weights.h +++ b/Weights/include/CGAL/Weights/mean_value_weights.h @@ -62,7 +62,7 @@ typename GeomTraits::FT weight(const GeomTraits& traits, using FT = typename GeomTraits::FT; using Get_sqrt = internal::Get_sqrt; - const auto sqrt = Get_sqrt::sqrt_object(traits); + auto sqrt = Get_sqrt::sqrt_object(traits); const FT P1 = r1 * r2 + D1; const FT P2 = r2 * r3 + D2; @@ -92,13 +92,14 @@ typename GeomTraits::FT mean_value_weight(const typename GeomTraits::Point_2& t, const GeomTraits& traits) { using FT = typename GeomTraits::FT; + using Vector_2 = typename GeomTraits::Vector_2; - const auto dot_product_2 = traits.compute_scalar_product_2_object(); - const auto construct_vector_2 = traits.construct_vector_2_object(); + auto dot_product_2 = traits.compute_scalar_product_2_object(); + auto construct_vector_2 = traits.construct_vector_2_object(); - const auto v1 = construct_vector_2(q, t); - const auto v2 = construct_vector_2(q, r); - const auto v3 = construct_vector_2(q, p); + const Vector_2 v1 = construct_vector_2(q, t); + const Vector_2 v2 = construct_vector_2(q, r); + const Vector_2 v3 = construct_vector_2(q, p); const FT l1 = internal::length_2(traits, v1); const FT l2 = internal::length_2(traits, v2); diff --git a/Weights/include/CGAL/Weights/mixed_voronoi_region_weights.h b/Weights/include/CGAL/Weights/mixed_voronoi_region_weights.h index 6808512751f..1e5ab27327c 100644 --- a/Weights/include/CGAL/Weights/mixed_voronoi_region_weights.h +++ b/Weights/include/CGAL/Weights/mixed_voronoi_region_weights.h @@ -32,13 +32,13 @@ typename GeomTraits::FT mixed_voronoi_area(const typename GeomTraits::Point_2& p using FT = typename GeomTraits::FT; using Point_2 = typename GeomTraits::Point_2; - const auto angle_2 = traits.angle_2_object(); - const auto midpoint_2 = traits.construct_midpoint_2_object(); - const auto circumcenter_2 = traits.construct_circumcenter_2_object(); + auto angle_2 = traits.angle_2_object(); + auto midpoint_2 = traits.construct_midpoint_2_object(); + auto circumcenter_2 = traits.construct_circumcenter_2_object(); - const auto a1 = angle_2(p, q, r); - const auto a2 = angle_2(q, r, p); - const auto a3 = angle_2(r, p, q); + const Angle a1 = angle_2(p, q, r); + const Angle a2 = angle_2(q, r, p); + const Angle a3 = angle_2(r, p, q); Point_2 center; if (a1 != CGAL::OBTUSE && a2 != CGAL::OBTUSE && a3 != CGAL::OBTUSE) @@ -46,8 +46,8 @@ typename GeomTraits::FT mixed_voronoi_area(const typename GeomTraits::Point_2& p else center = midpoint_2(r, p); - const auto m1 = midpoint_2(q, r); - const auto m2 = midpoint_2(q, p); + const Point_2 m1 = midpoint_2(q, r); + const Point_2 m2 = midpoint_2(q, p); const FT A1 = internal::positive_area_2(traits, q, m1, center); const FT A2 = internal::positive_area_2(traits, q, center, m2); @@ -72,13 +72,13 @@ typename GeomTraits::FT mixed_voronoi_area(const typename GeomTraits::Point_3& p using FT = typename GeomTraits::FT; using Point_3 = typename GeomTraits::Point_3; - const auto angle_3 = traits.angle_3_object(); - const auto midpoint_3 = traits.construct_midpoint_3_object(); - const auto circumcenter_3 = traits.construct_circumcenter_3_object(); + auto angle_3 = traits.angle_3_object(); + auto midpoint_3 = traits.construct_midpoint_3_object(); + auto circumcenter_3 = traits.construct_circumcenter_3_object(); - const auto a1 = angle_3(p, q, r); - const auto a2 = angle_3(q, r, p); - const auto a3 = angle_3(r, p, q); + const Angle a1 = angle_3(p, q, r); + const Angle a2 = angle_3(q, r, p); + const Angle a3 = angle_3(r, p, q); Point_3 center; if (a1 != CGAL::OBTUSE && a2 != CGAL::OBTUSE && a3 != CGAL::OBTUSE) @@ -86,8 +86,8 @@ typename GeomTraits::FT mixed_voronoi_area(const typename GeomTraits::Point_3& p else center = midpoint_3(r, p); - const auto m1 = midpoint_3(q, r); - const auto m2 = midpoint_3(q, p); + const Point_3 m1 = midpoint_3(q, r); + const Point_3 m2 = midpoint_3(q, p); const FT A1 = internal::positive_area_3(traits, q, m1, center); const FT A2 = internal::positive_area_3(traits, q, center, m2); diff --git a/Weights/include/CGAL/Weights/tangent_weights.h b/Weights/include/CGAL/Weights/tangent_weights.h index 46599707e14..9986d115bcd 100644 --- a/Weights/include/CGAL/Weights/tangent_weights.h +++ b/Weights/include/CGAL/Weights/tangent_weights.h @@ -103,13 +103,14 @@ typename GeomTraits::FT tangent_weight_v1(const typename GeomTraits::Point_3& t, const GeomTraits& traits) { using FT = typename GeomTraits::FT; + using Vector_3 = typename GeomTraits::Vector_3; - const auto dot_product_3 = traits.compute_scalar_product_3_object(); - const auto construct_vector_3 = traits.construct_vector_3_object(); + auto dot_product_3 = traits.compute_scalar_product_3_object(); + auto construct_vector_3 = traits.construct_vector_3_object(); - const auto v1 = construct_vector_3(q, t); - const auto v2 = construct_vector_3(q, r); - const auto v3 = construct_vector_3(q, p); + const Vector_3 v1 = construct_vector_3(q, t); + const Vector_3 v2 = construct_vector_3(q, r); + const Vector_3 v3 = construct_vector_3(q, p); const FT l1 = internal::length_3(traits, v1); const FT l2 = internal::length_3(traits, v2); @@ -134,12 +135,13 @@ typename GeomTraits::FT tangent_weight_v2(const typename GeomTraits::Point_3& t, const GeomTraits& traits) { using FT = typename GeomTraits::FT; + using Vector_3 = typename GeomTraits::Vector_3; - const auto construct_vector_3 = traits.construct_vector_3_object(); + auto construct_vector_3 = traits.construct_vector_3_object(); - auto v1 = construct_vector_3(q, t); - auto v2 = construct_vector_3(q, r); - auto v3 = construct_vector_3(q, p); + Vector_3 v1 = construct_vector_3(q, t); + Vector_3 v2 = construct_vector_3(q, r); + Vector_3 v3 = construct_vector_3(q, p); const FT l2 = internal::length_3(traits, v2); @@ -247,12 +249,14 @@ typename GeomTraits::FT tangent_weight(const typename GeomTraits::Point_2& t, const GeomTraits& traits) { using FT = typename GeomTraits::FT; - const auto dot_product_2 = traits.compute_scalar_product_2_object(); - const auto construct_vector_2 = traits.construct_vector_2_object(); + using Vector_2 = typename GeomTraits::Vector_2; - const auto v1 = construct_vector_2(q, t); - const auto v2 = construct_vector_2(q, r); - const auto v3 = construct_vector_2(q, p); + auto dot_product_2 = traits.compute_scalar_product_2_object(); + auto construct_vector_2 = traits.construct_vector_2_object(); + + const Vector_2 v1 = construct_vector_2(q, t); + const Vector_2 v2 = construct_vector_2(q, r); + const Vector_2 v3 = construct_vector_2(q, p); const FT l1 = internal::length_2(traits, v1); const FT l2 = internal::length_2(traits, v2); @@ -327,11 +331,11 @@ public: FT weight = FT(0); if (is_border_edge(he, m_pmesh)) { - const auto h1 = next(he, m_pmesh); + const halfedge_descriptor h1 = next(he, m_pmesh); - const auto v0 = target(he, m_pmesh); - const auto v1 = source(he, m_pmesh); - const auto v2 = target(h1, m_pmesh); + const vertex_descriptor v0 = target(he, m_pmesh); + const vertex_descriptor v1 = source(he, m_pmesh); + const vertex_descriptor v2 = target(h1, m_pmesh); const auto& p0 = get(m_pmap, v0); const auto& p1 = get(m_pmap, v1); @@ -341,13 +345,13 @@ public: } else { - const auto h1 = next(he, m_pmesh); - const auto h2 = prev(opposite(he, m_pmesh), m_pmesh); + const halfedge_descriptor h1 = next(he, m_pmesh); + const halfedge_descriptor h2 = prev(opposite(he, m_pmesh), m_pmesh); - const auto v0 = target(he, m_pmesh); - const auto v1 = source(he, m_pmesh); - const auto v2 = target(h1, m_pmesh); - const auto v3 = source(h2, m_pmesh); + const vertex_descriptor v0 = target(he, m_pmesh); + const vertex_descriptor v1 = source(he, m_pmesh); + const vertex_descriptor v2 = target(h1, m_pmesh); + const vertex_descriptor v3 = source(h2, m_pmesh); const auto& p0 = get(m_pmap, v0); const auto& p1 = get(m_pmap, v1); @@ -375,22 +379,24 @@ public: const CGAL::Point_2& q, const CGAL::Point_2& r) { + using Vector_2 = typename GeomTraits::Vector_2; + const GeomTraits traits; - const auto scalar_product_2 = traits.compute_scalar_product_2_object(); - const auto construct_vector_2 = traits.construct_vector_2_object(); + auto scalar_product_2 = traits.compute_scalar_product_2_object(); + auto construct_vector_2 = traits.construct_vector_2_object(); m_d_r = internal::distance_2(traits, q, r); CGAL_assertion(m_d_r != FT(0)); // two points are identical! m_d_p = internal::distance_2(traits, q, p); CGAL_assertion(m_d_p != FT(0)); // two points are identical! - const auto v1 = construct_vector_2(q, r); - const auto v2 = construct_vector_2(q, p); + const Vector_2 v1 = construct_vector_2(q, r); + const Vector_2 v2 = construct_vector_2(q, p); - const auto A = internal::positive_area_2(traits, p, q, r); + const FT A = internal::positive_area_2(traits, p, q, r); CGAL_assertion(A != FT(0)); // three points are identical! - const auto S = scalar_product_2(v1, v2); + const FT S = scalar_product_2(v1, v2); m_w_base = -tangent_half_angle(m_d_r, m_d_p, A, S); } @@ -399,21 +405,24 @@ public: const CGAL::Point_3& q, const CGAL::Point_3& r) { + using Vector_3 = typename GeomTraits::Vector_3; + const GeomTraits traits; - const auto scalar_product_3 = traits.compute_scalar_product_3_object(); - const auto construct_vector_3 = traits.construct_vector_3_object(); + + auto scalar_product_3 = traits.compute_scalar_product_3_object(); + auto construct_vector_3 = traits.construct_vector_3_object(); m_d_r = internal::distance_3(traits, q, r); CGAL_assertion(m_d_r != FT(0)); // two points are identical! m_d_p = internal::distance_3(traits, q, p); CGAL_assertion(m_d_p != FT(0)); // two points are identical! - const auto v1 = construct_vector_3(q, r); - const auto v2 = construct_vector_3(q, p); + const Vector_3 v1 = construct_vector_3(q, r); + const Vector_3 v2 = construct_vector_3(q, p); - const auto A = internal::positive_area_3(traits, p, q, r); + const FT A = internal::positive_area_3(traits, p, q, r); CGAL_assertion(A != FT(0)); // three points are identical! - const auto S = scalar_product_3(v1, v2); + const FT S = scalar_product_3(v1, v2); m_w_base = -tangent_half_angle(m_d_r, m_d_p, A, S); } diff --git a/Weights/include/CGAL/Weights/utils.h b/Weights/include/CGAL/Weights/utils.h index 6c72a4e27c8..fe4f5705afd 100644 --- a/Weights/include/CGAL/Weights/utils.h +++ b/Weights/include/CGAL/Weights/utils.h @@ -104,7 +104,7 @@ typename GeomTraits::FT squared_distance(const CGAL::Point_2& p, const CGAL::Point_2& q) { const GeomTraits traits; - const auto squared_distance_2 = traits.compute_squared_distance_2_object(); + auto squared_distance_2 = traits.compute_squared_distance_2_object(); return squared_distance_2(p, q); } @@ -113,7 +113,7 @@ typename GeomTraits::FT squared_distance(const CGAL::Point_3& p, const CGAL::Point_3& q) { const GeomTraits traits; - const auto squared_distance_3 = traits.compute_squared_distance_3_object(); + auto squared_distance_3 = traits.compute_squared_distance_3_object(); return squared_distance_3(p, q); } @@ -156,13 +156,15 @@ typename GeomTraits::FT scalar_product(const CGAL::Point_2& p, const CGAL::Point_2& q, const CGAL::Point_2& r) { + using Vector_2 = typename GeomTraits::Vector_2; + const GeomTraits traits; - const auto scalar_product_2 = traits.compute_scalar_product_2_object(); - const auto construct_vector_2 = traits.construct_vector_2_object(); + auto scalar_product_2 = traits.compute_scalar_product_2_object(); + auto construct_vector_2 = traits.construct_vector_2_object(); - const auto v1 = construct_vector_2(q, r); - const auto v2 = construct_vector_2(q, p); + const Vector_2 v1 = construct_vector_2(q, r); + const Vector_2 v2 = construct_vector_2(q, p); return scalar_product_2(v1, v2); } @@ -171,12 +173,15 @@ typename GeomTraits::FT scalar_product(const CGAL::Point_3& p, const CGAL::Point_3& q, const CGAL::Point_3& r) { - const GeomTraits traits; - const auto scalar_product_3 = traits.compute_scalar_product_3_object(); - const auto construct_vector_3 = traits.construct_vector_3_object(); + using Vector_3 = typename GeomTraits::Vector_3; - const auto v1 = construct_vector_3(q, r); - const auto v2 = construct_vector_3(q, p); + const GeomTraits traits; + + auto scalar_product_3 = traits.compute_scalar_product_3_object(); + auto vector_3 = traits.construct_vector_3_object(); + + const Vector_3 v1 = vector_3(q, r); + const Vector_3 v2 = vector_3(q, p); return scalar_product_3(v1, v2); } diff --git a/Weights/include/CGAL/Weights/voronoi_region_weights.h b/Weights/include/CGAL/Weights/voronoi_region_weights.h index 5d8f748f26e..61880e73ff8 100644 --- a/Weights/include/CGAL/Weights/voronoi_region_weights.h +++ b/Weights/include/CGAL/Weights/voronoi_region_weights.h @@ -30,13 +30,14 @@ typename GeomTraits::FT voronoi_area(const typename GeomTraits::Point_2& p, const GeomTraits& traits) { using FT = typename GeomTraits::FT; + using Point_2 = typename GeomTraits::Point_2; - const auto circumcenter_2 = traits.construct_circumcenter_2_object(); - const auto midpoint_2 = traits.construct_midpoint_2_object(); + auto circumcenter_2 = traits.construct_circumcenter_2_object(); + auto midpoint_2 = traits.construct_midpoint_2_object(); - const auto center = circumcenter_2(p, q, r); - const auto m1 = midpoint_2(q, r); - const auto m2 = midpoint_2(q, p); + const Point_2 center = circumcenter_2(p, q, r); + const Point_2 m1 = midpoint_2(q, r); + const Point_2 m2 = midpoint_2(q, p); const FT A1 = internal::positive_area_2(traits, q, m1, center); const FT A2 = internal::positive_area_2(traits, q, center, m2); @@ -59,13 +60,14 @@ typename GeomTraits::FT voronoi_area(const typename GeomTraits::Point_3& p, const GeomTraits& traits) { using FT = typename GeomTraits::FT; + using Point_3 = typename GeomTraits::Point_3; - const auto circumcenter_3 = traits.construct_circumcenter_3_object(); - const auto midpoint_3 = traits.construct_midpoint_3_object(); + auto circumcenter_3 = traits.construct_circumcenter_3_object(); + auto midpoint_3 = traits.construct_midpoint_3_object(); - const auto center = circumcenter_3(p, q, r); - const auto m1 = midpoint_3(q, r); - const auto m2 = midpoint_3(q, p); + const Point_3 center = circumcenter_3(p, q, r); + const Point_3 m1 = midpoint_3(q, r); + const Point_3 m2 = midpoint_3(q, p); const FT A1 = internal::positive_area_3(traits, q, m1, center); const FT A2 = internal::positive_area_3(traits, q, center, m2); From 85132eea04c7c8c6994b0b7b8821f4f56c134e51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 17 Oct 2022 17:02:29 +0200 Subject: [PATCH 05/35] More re-indentation --- .../Weights/internal/pmp_weights_deprecated.h | 744 ++++++++---------- 1 file changed, 329 insertions(+), 415 deletions(-) diff --git a/Weights/include/CGAL/Weights/internal/pmp_weights_deprecated.h b/Weights/include/CGAL/Weights/internal/pmp_weights_deprecated.h index 942ad0dc8d5..fb44deac937 100644 --- a/Weights/include/CGAL/Weights/internal/pmp_weights_deprecated.h +++ b/Weights/include/CGAL/Weights/internal/pmp_weights_deprecated.h @@ -41,19 +41,18 @@ namespace deprecated { // (i.e. for v0, v1, v2 and v2, v1, v0 the returned cot weights can be slightly different). // This one provides stable results. template -struct Cotangent_value_Meyer_impl { - +struct Cotangent_value_Meyer_impl +{ typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; template - double operator()( - vertex_descriptor v0, - vertex_descriptor v1, - vertex_descriptor v2, - const VertexPointMap& ppmap) { - + double operator()(vertex_descriptor v0, + vertex_descriptor v1, + vertex_descriptor v2, + const VertexPointMap& ppmap) + { typedef typename Kernel_traits< - typename boost::property_traits::value_type >::Kernel::Vector_3 Vector; + typename boost::property_traits::value_type >::Kernel::Vector_3 Vector; const Vector a = get(ppmap, v0) - get(ppmap, v1); const Vector b = get(ppmap, v2) - get(ppmap, v1); @@ -66,28 +65,27 @@ struct Cotangent_value_Meyer_impl { // double divider = CGAL::sqrt(dot_aa * dot_bb - dot_ab * dot_ab); const Vector cross_ab = CGAL::cross_product(a, b); - const double divider = CGAL::to_double( - CGAL::approximate_sqrt(cross_ab * cross_ab)); + const double divider = CGAL::to_double(CGAL::approximate_sqrt(cross_ab * cross_ab)); - if (divider == 0.0 /* || divider != divider */) { + if (divider == 0.0 /* || divider != divider */) + { CGAL::collinear(get(ppmap, v0), get(ppmap, v1), get(ppmap, v2)) ? - CGAL_warning_msg(false, "Infinite Cotangent value with the degenerate triangle!") : - CGAL_warning_msg(false, "Infinite Cotangent value due to the floating point arithmetic!"); + CGAL_warning_msg(false, "Infinite Cotangent value with the degenerate triangle!") : + CGAL_warning_msg(false, "Infinite Cotangent value due to the floating point arithmetic!"); - return dot_ab > 0.0 ? - (std::numeric_limits::max)() : - -(std::numeric_limits::max)(); + return dot_ab > 0.0 ? (std::numeric_limits::max)() : + -(std::numeric_limits::max)(); } + return dot_ab / divider; } }; // Same as above but with a different API. -template< - typename PolygonMesh, - typename VertexPointMap = typename boost::property_map::type> -class Cotangent_value_Meyer { - +template::type> +class Cotangent_value_Meyer +{ protected: typedef VertexPointMap Point_property_map; typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; @@ -98,36 +96,27 @@ protected: Point_property_map ppmap_; public: - Cotangent_value_Meyer( - PolygonMesh& pmesh_, - VertexPointMap vpmap_) : - pmesh_(pmesh_), - ppmap_(vpmap_) + Cotangent_value_Meyer(PolygonMesh& pmesh_, + VertexPointMap vpmap_) + : pmesh_(pmesh_), ppmap_(vpmap_) { } - PolygonMesh& pmesh() { - return pmesh_; - } - - Point_property_map& ppmap() { - return ppmap_; - } - - double operator()( - vertex_descriptor v0, - vertex_descriptor v1, - vertex_descriptor v2) { + PolygonMesh& pmesh() { return pmesh_; } + Point_property_map& ppmap() { return ppmap_; } + double operator()(vertex_descriptor v0, + vertex_descriptor v1, + vertex_descriptor v2) + { return Cotangent_value_Meyer_impl()(v0, v1, v2, ppmap()); } }; // Imported from skeletonization. -template< - typename PolygonMesh, - typename VertexPointMap = typename boost::property_map::type> -class Cotangent_value_Meyer_secure { - +template::type> +class Cotangent_value_Meyer_secure +{ typedef VertexPointMap Point_property_map; typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; typedef typename boost::property_traits::value_type Point; @@ -137,26 +126,18 @@ class Cotangent_value_Meyer_secure { Point_property_map ppmap_; public: - Cotangent_value_Meyer_secure( - PolygonMesh& pmesh_, - VertexPointMap vpmap_) : - pmesh_(pmesh_), - ppmap_(vpmap_) + Cotangent_value_Meyer_secure(PolygonMesh& pmesh_, + VertexPointMap vpmap_) + : pmesh_(pmesh_), ppmap_(vpmap_) { } - PolygonMesh& pmesh() { - return pmesh_; - } - - Point_property_map& ppmap() { - return ppmap_; - } - - double operator()( - vertex_descriptor v0, - vertex_descriptor v1, - vertex_descriptor v2) { + PolygonMesh& pmesh() { return pmesh_; } + Point_property_map& ppmap() { return ppmap_; } + double operator()(vertex_descriptor v0, + vertex_descriptor v1, + vertex_descriptor v2) + { const Vector a = get(ppmap(), v0) - get(ppmap(), v1); const Vector b = get(ppmap(), v2) - get(ppmap(), v1); @@ -174,37 +155,28 @@ public: // Returns the cotangent value of the half angle [v0, v1, v2] by clamping between // [1, 89] degrees as suggested by -[Friedel] Unconstrained Spherical Parameterization-. -template< - typename PolygonMesh, - typename VertexPointMap = typename boost::property_map::type, - typename CotangentValue = Cotangent_value_Meyer > -class Cotangent_value_clamped : CotangentValue { - - Cotangent_value_clamped() - { } +template::type, +typename CotangentValue = Cotangent_value_Meyer > +class Cotangent_value_clamped : CotangentValue +{ + Cotangent_value_clamped() { } public: - Cotangent_value_clamped( - PolygonMesh& pmesh_, - VertexPointMap vpmap_) : - CotangentValue(pmesh_, vpmap_) + Cotangent_value_clamped(PolygonMesh& pmesh_, + VertexPointMap vpmap_) + : CotangentValue(pmesh_, vpmap_) { } - PolygonMesh& pmesh() { - return CotangentValue::pmesh(); - } - - VertexPointMap& ppmap() { - return CotangentValue::ppmap(); - } + PolygonMesh& pmesh() { return CotangentValue::pmesh(); } + VertexPointMap& ppmap() { return CotangentValue::ppmap(); } typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - double operator()( - vertex_descriptor v0, - vertex_descriptor v1, - vertex_descriptor v2) { - + double operator()(vertex_descriptor v0, + vertex_descriptor v1, + vertex_descriptor v2) + { const double cot_1 = 57.289962; const double cot_89 = 0.017455; const double value = CotangentValue::operator()(v0, v1, v2); @@ -212,37 +184,28 @@ public: } }; -template< - typename PolygonMesh, - typename VertexPointMap = typename boost::property_map::type, - typename CotangentValue = Cotangent_value_Meyer > -class Cotangent_value_clamped_2 : CotangentValue { - - Cotangent_value_clamped_2() - { } +template::type, +typename CotangentValue = Cotangent_value_Meyer > +class Cotangent_value_clamped_2 : CotangentValue +{ + Cotangent_value_clamped_2() { } public: - Cotangent_value_clamped_2( - PolygonMesh& pmesh_, - VertexPointMap vpmap_) : - CotangentValue(pmesh_, vpmap_) + Cotangent_value_clamped_2(PolygonMesh& pmesh_, + VertexPointMap vpmap_) + : CotangentValue(pmesh_, vpmap_) { } - PolygonMesh& pmesh() { - return CotangentValue::pmesh(); - } - - VertexPointMap& ppmap() { - return CotangentValue::ppmap(); - } + PolygonMesh& pmesh() { return CotangentValue::pmesh(); } + VertexPointMap& ppmap() { return CotangentValue::ppmap(); } typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - double operator()( - vertex_descriptor v0, - vertex_descriptor v1, - vertex_descriptor v2) { - + double operator()(vertex_descriptor v0, + vertex_descriptor v1, + vertex_descriptor v2) + { const double cot_5 = 5.671282; const double cot_175 = -cot_5; const double value = CotangentValue::operator()(v0, v1, v2); @@ -250,80 +213,66 @@ public: } }; -template< - typename PolygonMesh, - typename CotangentValue = Cotangent_value_Meyer_impl > -struct Cotangent_value_minimum_zero_impl : CotangentValue { - +template > +struct Cotangent_value_minimum_zero_impl + : CotangentValue +{ typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; template - double operator()( - vertex_descriptor v0, - vertex_descriptor v1, - vertex_descriptor v2, - const VertexPointMap ppmap) { - + double operator()(vertex_descriptor v0, + vertex_descriptor v1, + vertex_descriptor v2, + const VertexPointMap ppmap) + { const double value = CotangentValue::operator()(v0, v1, v2, ppmap); return (std::max)(0.0, value); } }; -template< - typename PolygonMesh, - typename VertexPointMap = typename boost::property_map::type, - typename CotangentValue = Cotangent_value_Meyer > -class Cotangent_value_minimum_zero : CotangentValue { - +template::type, +typename CotangentValue = Cotangent_value_Meyer > +class Cotangent_value_minimum_zero : CotangentValue +{ Cotangent_value_minimum_zero() { } public: - Cotangent_value_minimum_zero( - PolygonMesh& pmesh_, - VertexPointMap vpmap_) : - CotangentValue(pmesh_, vpmap_) + Cotangent_value_minimum_zero(PolygonMesh& pmesh_, + VertexPointMap vpmap_) + : CotangentValue(pmesh_, vpmap_) { } - PolygonMesh& pmesh() { - return CotangentValue::pmesh(); - } - - VertexPointMap& ppmap() { - return CotangentValue::ppmap(); - } + PolygonMesh& pmesh() { return CotangentValue::pmesh(); } + VertexPointMap& ppmap() { return CotangentValue::ppmap(); } typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - double operator()( - vertex_descriptor v0, - vertex_descriptor v1, - vertex_descriptor v2) { + double operator()(vertex_descriptor v0, + vertex_descriptor v1, + vertex_descriptor v2) + { const double value = CotangentValue::operator()(v0, v1, v2); return (std::max)(0.0, value); } }; -template< - typename PolygonMesh, - typename VertexPointMap = typename boost::property_map::type, - typename CotangentValue = Cotangent_value_Meyer > -class Voronoi_area : CotangentValue { - +template::type, + typename CotangentValue = Cotangent_value_Meyer > +class Voronoi_area + : CotangentValue +{ public: - Voronoi_area( - PolygonMesh& pmesh_, - VertexPointMap vpmap_) : - CotangentValue(pmesh_, vpmap_) + Voronoi_area(PolygonMesh& pmesh_, + VertexPointMap vpmap_) + : CotangentValue(pmesh_, vpmap_) { } - PolygonMesh& pmesh() { - return CotangentValue::pmesh(); - } - - VertexPointMap& ppmap() { - return CotangentValue::ppmap(); - } + PolygonMesh& pmesh() { return CotangentValue::pmesh(); } + VertexPointMap& ppmap() { return CotangentValue::ppmap(); } typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; typedef typename boost::graph_traits::in_edge_iterator in_edge_iterator; @@ -333,13 +282,13 @@ public: typedef typename boost::property_traits::value_type Point; typedef typename Kernel_traits::Kernel::Vector_3 Vector; - double operator()(vertex_descriptor v0) { - + double operator()(vertex_descriptor v0) + { // return 1.0; double voronoi_area = 0.0; for (const halfedge_descriptor he : - halfedges_around_target(halfedge(v0, pmesh()), pmesh())) { - + halfedges_around_target(halfedge(v0, pmesh()), pmesh())) + { if (is_border(he, pmesh()) ) { continue; } CGAL_assertion(CGAL::is_triangle_mesh(pmesh())); @@ -356,12 +305,12 @@ public: const CGAL::Angle angle1 = CGAL::angle(v_op_p, v1_p, v0_p); const CGAL::Angle angle_op = CGAL::angle(v0_p, v_op_p, v1_p); - bool obtuse = - (angle0 == CGAL::OBTUSE) || - (angle1 == CGAL::OBTUSE) || - (angle_op == CGAL::OBTUSE); + bool obtuse = (angle0 == CGAL::OBTUSE) || + (angle1 == CGAL::OBTUSE) || + (angle_op == CGAL::OBTUSE); - if (!obtuse) { + if (!obtuse) + { const double cot_v1 = CotangentValue::operator()(v_op, v1, v0); const double cot_v_op = CotangentValue::operator()(v0, v_op, v1); @@ -369,18 +318,18 @@ public: const double term2 = cot_v_op * to_double((v1_p - v0_p).squared_length()); voronoi_area += (1.0 / 8.0) * (term1 + term2); - } else { - const double area_t = to_double( - CGAL::approximate_sqrt( - CGAL::squared_area(v0_p, v1_p, v_op_p))); + } + else + { + const double area_t = to_double(CGAL::approximate_sqrt(CGAL::squared_area(v0_p, v1_p, v_op_p))); - if (angle0 == CGAL::OBTUSE) { + if (angle0 == CGAL::OBTUSE) voronoi_area += area_t / 2.0; - } else { + else voronoi_area += area_t / 4.0; - } } } + CGAL_warning_msg(voronoi_area != 0.0, "Zero Voronoi area!"); return voronoi_area; } @@ -388,118 +337,103 @@ public: // Returns the cotangent value of the half angle [v0, v1, v2] by dividing the triangle area // as suggested by -[Mullen08] Spectral Conformal Parameterization-. -template< - typename PolygonMesh, - typename VertexPointMap = typename boost::property_map::type, - typename CotangentValue = Cotangent_value_Meyer > -class Cotangent_value_area_weighted : CotangentValue { - - Cotangent_value_area_weighted() - { } +template::type, + typename CotangentValue = Cotangent_value_Meyer > +class Cotangent_value_area_weighted + : CotangentValue +{ + Cotangent_value_area_weighted() { } public: - Cotangent_value_area_weighted( - PolygonMesh& pmesh_, - VertexPointMap vpmap_) : + Cotangent_value_area_weighted(PolygonMesh& pmesh_, + VertexPointMap vpmap_) : CotangentValue(pmesh_, vpmap_) { } - PolygonMesh& pmesh() { - return CotangentValue::pmesh(); - } - - VertexPointMap& ppmap() { - return CotangentValue::ppmap(); - } + PolygonMesh& pmesh() { return CotangentValue::pmesh(); } + VertexPointMap& ppmap() { return CotangentValue::ppmap(); } typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - double operator()( - vertex_descriptor v0, - vertex_descriptor v1, - vertex_descriptor v2) { - + double operator()(vertex_descriptor v0, + vertex_descriptor v1, + vertex_descriptor v2) + { return CotangentValue::operator()(v0, v1, v2) / - CGAL::sqrt(CGAL::squared_area( - get(this->ppmap(), v0), - get(this->ppmap(), v1), - get(this->ppmap(), v2))); + CGAL::sqrt(CGAL::squared_area(get(this->ppmap(), v0), + get(this->ppmap(), v1), + get(this->ppmap(), v2))); } }; // Cotangent weight calculator: // Cotangent_value: as suggested by -[Sorkine07] ARAP Surface Modeling-. // Cotangent_value_area_weighted: as suggested by -[Mullen08] Spectral Conformal Parameterization-. -template< - typename PolygonMesh, - typename CotangentValue = Cotangent_value_minimum_zero_impl > -struct Cotangent_weight_impl : CotangentValue { - +template > +struct Cotangent_weight_impl + : CotangentValue +{ typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; // Returns the cotangent weight of the specified halfedge_descriptor. // Edge orientation is trivial. template - double operator()( - halfedge_descriptor he, - PolygonMesh& pmesh, - const VertexPointMap& ppmap) { - + double operator()(halfedge_descriptor he, + PolygonMesh& pmesh, + const VertexPointMap& ppmap) + { const vertex_descriptor v0 = target(he, pmesh); const vertex_descriptor v1 = source(he, pmesh); // Only one triangle for border edges. - if (is_border_edge(he, pmesh)) { - + if (is_border_edge(he, pmesh)) + { const halfedge_descriptor he_cw = opposite(next(he, pmesh), pmesh); vertex_descriptor v2 = source(he_cw, pmesh); - if (is_border_edge(he_cw, pmesh)) { + if (is_border_edge(he_cw, pmesh)) + { const halfedge_descriptor he_ccw = prev(opposite(he, pmesh), pmesh); v2 = source(he_ccw, pmesh); } - return (CotangentValue::operator()(v0, v2, v1, ppmap) / 2.0); - } else { + return (CotangentValue::operator()(v0, v2, v1, ppmap) / 2.0); + } + else + { const halfedge_descriptor he_cw = opposite(next(he, pmesh), pmesh); const vertex_descriptor v2 = source(he_cw, pmesh); const halfedge_descriptor he_ccw = prev(opposite(he, pmesh), pmesh); const vertex_descriptor v3 = source(he_ccw, pmesh); - return ( - CotangentValue::operator()(v0, v2, v1, ppmap) / 2.0 + - CotangentValue::operator()(v0, v3, v1, ppmap) / 2.0 ); + return (CotangentValue::operator()(v0, v2, v1, ppmap) / 2.0 + + CotangentValue::operator()(v0, v3, v1, ppmap) / 2.0 ); } } }; -template< - typename PolygonMesh, - typename VertexPointMap = typename boost::property_map::type, - typename CotangentValue = Cotangent_value_minimum_zero > -class Cotangent_weight : CotangentValue { - - Cotangent_weight() - { } +template::type, + typename CotangentValue = Cotangent_value_minimum_zero > +class Cotangent_weight + : CotangentValue +{ + Cotangent_weight() { } public: - Cotangent_weight( - PolygonMesh& pmesh_, - VertexPointMap vpmap_) : - CotangentValue(pmesh_, vpmap_) + Cotangent_weight(PolygonMesh& pmesh_, + VertexPointMap vpmap_) + : CotangentValue(pmesh_, vpmap_) { } - Cotangent_weight(PolygonMesh& pmesh_) : - CotangentValue(pmesh_, get(CGAL::vertex_point, pmesh_)) + Cotangent_weight(PolygonMesh& pmesh_) + : CotangentValue(pmesh_, get(CGAL::vertex_point, pmesh_)) { } - PolygonMesh& pmesh() { - return CotangentValue::pmesh(); - } - - VertexPointMap& ppmap() { - return CotangentValue::ppmap(); - } + PolygonMesh& pmesh() { return CotangentValue::pmesh(); } + VertexPointMap& ppmap() { return CotangentValue::ppmap(); } typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; @@ -510,52 +444,55 @@ public: // Returns the cotangent weight of the specified halfedge_descriptor. // Edge orientation is trivial. - double operator()(halfedge_descriptor he) { + double operator()(halfedge_descriptor he) + { const vertex_descriptor v0 = target(he, pmesh()); const vertex_descriptor v1 = source(he, pmesh()); // Only one triangle for border edges. - if (is_border_edge(he, pmesh())) { - + if (is_border_edge(he, pmesh())) + { const halfedge_descriptor he_cw = opposite(next(he, pmesh()), pmesh()); vertex_descriptor v2 = source(he_cw, pmesh()); - if (is_border_edge(he_cw, pmesh())) { + if (is_border_edge(he_cw, pmesh())) + { const halfedge_descriptor he_ccw = prev(opposite(he, pmesh()), pmesh()); v2 = source(he_ccw, pmesh()); } - return (CotangentValue::operator()(v0, v2, v1) / 2.0); - } else { + return (CotangentValue::operator()(v0, v2, v1) / 2.0); + } + else + { const halfedge_descriptor he_cw = opposite(next(he, pmesh()), pmesh()); const vertex_descriptor v2 = source(he_cw, pmesh()); const halfedge_descriptor he_ccw = prev(opposite(he, pmesh()), pmesh()); const vertex_descriptor v3 = source(he_ccw, pmesh()); - return ( - CotangentValue::operator()(v0, v2, v1) / 2.0 + - CotangentValue::operator()(v0, v3, v1) / 2.0 ); + return (CotangentValue::operator()(v0, v2, v1) / 2.0 + + CotangentValue::operator()(v0, v3, v1) / 2.0 ); } } }; // Single cotangent from -[Chao10] Simple Geometric Model for Elastic Deformation. -template< - typename PolygonMesh, - typename CotangentValue = Cotangent_value_Meyer_impl > -struct Single_cotangent_weight_impl : CotangentValue { - +template > +struct Single_cotangent_weight_impl + : CotangentValue +{ typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; // Returns the cotangent of the opposite angle of the edge // 0 for border edges (which does not have an opposite angle). template - double operator()( - halfedge_descriptor he, - PolygonMesh& pmesh, - const VertexPointMap& ppmap) { - - if (is_border(he, pmesh)) { return 0.0; } + double operator()(halfedge_descriptor he, + PolygonMesh& pmesh, + const VertexPointMap& ppmap) + { + if (is_border(he, pmesh)) + return 0.0; const vertex_descriptor v0 = target(he, pmesh); const vertex_descriptor v1 = source(he, pmesh); @@ -564,29 +501,22 @@ struct Single_cotangent_weight_impl : CotangentValue { } }; -template< - typename PolygonMesh, - typename VertexPointMap = typename boost::property_map::type, - typename CotangentValue = Cotangent_value_Meyer > -class Single_cotangent_weight : CotangentValue { - - Single_cotangent_weight() - { } +template::type, + typename CotangentValue = Cotangent_value_Meyer > +class Single_cotangent_weight + : CotangentValue +{ + Single_cotangent_weight() { } public: - Single_cotangent_weight( - PolygonMesh& pmesh_, - VertexPointMap vpmap_) : - CotangentValue(pmesh_, vpmap_) + Single_cotangent_weight(PolygonMesh& pmesh_, + VertexPointMap vpmap_) + : CotangentValue(pmesh_, vpmap_) { } - PolygonMesh& pmesh() { - return CotangentValue::pmesh(); - } - - VertexPointMap& ppmap() { - return CotangentValue::ppmap(); - } + PolygonMesh& pmesh() { return CotangentValue::pmesh(); } + VertexPointMap& ppmap() { return CotangentValue::ppmap(); } typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; @@ -597,9 +527,10 @@ public: // Returns the cotangent of the opposite angle of the edge // 0 for border edges (which does not have an opposite angle). - double operator()(halfedge_descriptor he) { - - if (is_border(he, pmesh())) { return 0.0; } + double operator()(halfedge_descriptor he) + { + if (is_border(he, pmesh())) + return 0.0; const vertex_descriptor v0 = target(he, pmesh()); const vertex_descriptor v1 = source(he, pmesh()); @@ -608,12 +539,12 @@ public: } }; -template< - typename PolygonMesh, - typename VertexPointMap = typename boost::property_map::type, - typename CotangentValue = Cotangent_value_Meyer > -class Cotangent_weight_with_triangle_area : CotangentValue { - +template::type, + typename CotangentValue = Cotangent_value_Meyer > +class Cotangent_weight_with_triangle_area + : CotangentValue +{ typedef PolygonMesh PM; typedef VertexPointMap VPMap; typedef typename boost::property_traits::value_type Point; @@ -621,33 +552,29 @@ class Cotangent_weight_with_triangle_area : CotangentValue { typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - Cotangent_weight_with_triangle_area() - { } + Cotangent_weight_with_triangle_area() { } public: - Cotangent_weight_with_triangle_area( - PolygonMesh& pmesh_, - VertexPointMap vpmap_) : - CotangentValue(pmesh_, vpmap_) + Cotangent_weight_with_triangle_area(PolygonMesh& pmesh_, + VertexPointMap vpmap_) + : CotangentValue(pmesh_, vpmap_) { } - PolygonMesh& pmesh() { - return CotangentValue::pmesh(); - } + PolygonMesh& pmesh() { return CotangentValue::pmesh(); } + VertexPointMap& ppmap() { return CotangentValue::ppmap(); } - VertexPointMap& ppmap() { - return CotangentValue::ppmap(); - } - - double operator()(halfedge_descriptor he) { + double operator()(halfedge_descriptor he) + { const vertex_descriptor v0 = target(he, pmesh()); const vertex_descriptor v1 = source(he, pmesh()); // Only one triangle for border edges. - if (is_border_edge(he, pmesh())) { + if (is_border_edge(he, pmesh())) + { const halfedge_descriptor he_cw = opposite(next(he, pmesh()), pmesh()); vertex_descriptor v2 = source(he_cw, pmesh()); - if (is_border_edge(he_cw, pmesh())) { + if (is_border_edge(he_cw, pmesh())) + { const halfedge_descriptor he_ccw = prev(opposite(he, pmesh()), pmesh()); v2 = source(he_ccw, pmesh()); } @@ -655,11 +582,11 @@ public: const Point& v0_p = get(ppmap(), v0); const Point& v1_p = get(ppmap(), v1); const Point& v2_p = get(ppmap(), v2); - const double area_t = to_double( - CGAL::sqrt(CGAL::squared_area(v0_p, v1_p, v2_p))); + const double area_t = to_double(CGAL::sqrt(CGAL::squared_area(v0_p, v1_p, v2_p))); return (CotangentValue::operator()(v0, v2, v1) / area_t); - - } else { + } + else + { const halfedge_descriptor he_cw = opposite(next(he, pmesh()), pmesh()); const vertex_descriptor v2 = source(he_cw, pmesh()); const halfedge_descriptor he_ccw = prev(opposite(he, pmesh()), pmesh()); @@ -672,37 +599,31 @@ public: const double area_t1 = to_double(CGAL::sqrt(CGAL::squared_area(v0_p, v1_p, v2_p))); const double area_t2 = to_double(CGAL::sqrt(CGAL::squared_area(v0_p, v1_p, v3_p))); - return ( - CotangentValue::operator()(v0, v2, v1) / area_t1 + - CotangentValue::operator()(v0, v3, v1) / area_t2 ); + return (CotangentValue::operator()(v0, v2, v1) / area_t1 + + CotangentValue::operator()(v0, v3, v1) / area_t2 ); } + return 0.0; } }; // Mean value calculator described in -[Floater04] Mean Value Coordinates- -template< - typename PolygonMesh, - typename VertexPointMap = typename boost::property_map::type> -class Mean_value_weight { - - // Mean_value_weight() - // {} +template::type> +class Mean_value_weight +{ + // Mean_value_weight() {} PolygonMesh& pmesh_; VertexPointMap vpmap_; public: - Mean_value_weight( - PolygonMesh& pmesh_, - VertexPointMap vpmap) : - pmesh_(pmesh_), - vpmap_(vpmap) + Mean_value_weight(PolygonMesh& pmesh_, + VertexPointMap vpmap) + : pmesh_(pmesh_), vpmap_(vpmap) { } - PolygonMesh& pmesh() { - return pmesh_; - } + PolygonMesh& pmesh() { return pmesh_; } typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; @@ -714,42 +635,43 @@ public: // Returns the mean-value coordinate of the specified halfedge_descriptor. // Returns different value for different edge orientation (which is a normal // behavior according to the formula). - double operator()(halfedge_descriptor he) { - + double operator()(halfedge_descriptor he) + { const vertex_descriptor v0 = target(he, pmesh()); const vertex_descriptor v1 = source(he, pmesh()); const Vector vec = get(vpmap_, v0) - get(vpmap_, v1); const double norm = CGAL::sqrt(vec.squared_length()); // Only one triangle for border edges. - if (is_border_edge(he, pmesh())) { - + if (is_border_edge(he, pmesh())) + { const halfedge_descriptor he_cw = opposite(next(he, pmesh()), pmesh()); vertex_descriptor v2 = source(he_cw, pmesh()); - if (is_border_edge(he_cw, pmesh())) { + if (is_border_edge(he_cw, pmesh())) + { const halfedge_descriptor he_ccw = prev(opposite(he, pmesh()), pmesh()); v2 = source(he_ccw, pmesh()); } - return (half_tan_value_2(v1, v0, v2) / norm); - } else { + return (half_tan_value_2(v1, v0, v2) / norm); + } + else + { const halfedge_descriptor he_cw = opposite(next(he, pmesh()), pmesh()); const vertex_descriptor v2 = source(he_cw, pmesh()); const halfedge_descriptor he_ccw = prev(opposite(he, pmesh()), pmesh()); const vertex_descriptor v3 = source(he_ccw, pmesh()); - return ( - half_tan_value_2(v1, v0, v2) / norm + - half_tan_value_2(v1, v0, v3) / norm); + return (half_tan_value_2(v1, v0, v2) / norm + + half_tan_value_2(v1, v0, v3) / norm); } } private: // Returns the tangent value of the half angle v0_v1_v2 / 2. - double half_tan_value( - vertex_descriptor v0, - vertex_descriptor v1, - vertex_descriptor v2) { - + double half_tan_value(vertex_descriptor v0, + vertex_descriptor v1, + vertex_descriptor v2) + { const Vector vec0 = get(vpmap_, v1) - get(vpmap_, v2); const Vector vec1 = get(vpmap_, v2) - get(vpmap_, v0); const Vector vec2 = get(vpmap_, v0) - get(vpmap_, v1); @@ -765,11 +687,10 @@ private: } // My deviation built on Meyer_02. - double half_tan_value_2( - vertex_descriptor v0, - vertex_descriptor v1, - vertex_descriptor v2) { - + double half_tan_value_2(vertex_descriptor v0, + vertex_descriptor v1, + vertex_descriptor v2) + { const Vector a = get(vpmap_, v0) - get(vpmap_, v1); const Vector b = get(vpmap_, v2) - get(vpmap_, v1); const double dot_ab = a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; @@ -787,32 +708,28 @@ private: } }; -template< - typename PolygonMesh, - typename PrimaryWeight = Cotangent_weight, - typename SecondaryWeight = Mean_value_weight > -class Hybrid_weight : public PrimaryWeight, SecondaryWeight { - +template, + typename SecondaryWeight = Mean_value_weight > +class Hybrid_weight + : public PrimaryWeight, SecondaryWeight +{ PrimaryWeight primary; SecondaryWeight secondary; - Hybrid_weight() - { } + Hybrid_weight() { } public: - Hybrid_weight(PolygonMesh& pmesh_) : - primary(pmesh_), - secondary(pmesh_) + Hybrid_weight(PolygonMesh& pmesh_) + : primary(pmesh_), secondary(pmesh_) { } - PolygonMesh& pmesh() { - return primary.pmesh(); - } + PolygonMesh& pmesh() { return primary.pmesh(); } typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - double operator()(halfedge_descriptor he) { - + double operator()(halfedge_descriptor he) + { const double weight = primary(he); // if (weight < 0.0) { std::cout << "Negative weight!" << std::endl; } return (weight >= 0.0) ? weight : secondary(he); @@ -821,27 +738,25 @@ public: // Trivial uniform weights (created for test purposes). template -class Uniform_weight { +class Uniform_weight +{ public: typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - double operator()(halfedge_descriptor /* e */) - { return 1.0; } + double operator()(halfedge_descriptor /* e */) { return 1.0; } }; template -class Scale_dependent_weight_fairing { - +class Scale_dependent_weight_fairing +{ PolygonMesh& pmesh_; public: - Scale_dependent_weight_fairing(PolygonMesh& pmesh_) : - pmesh_(pmesh_) + Scale_dependent_weight_fairing(PolygonMesh& pmesh_) + : pmesh_(pmesh_) { } - PolygonMesh& pmesh() { - return pmesh_; - } + PolygonMesh& pmesh() { return pmesh_; } typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; @@ -852,53 +767,53 @@ public: double w_i(vertex_descriptor /* v_i */) { return 1.0; } - double w_ij(halfedge_descriptor he) { - + double w_ij(halfedge_descriptor he) + { const Vector v = target(he, pmesh())->point() - source(he, pmesh())->point(); const double divider = CGAL::sqrt(v.squared_length()); - if (divider == 0.0) { + if (divider == 0.0) + { CGAL_warning_msg(false, "Scale dependent weight - zero length edge."); return (std::numeric_limits::max)(); } + return 1.0 / divider; } }; -template< - typename PolygonMesh, - typename VertexPointMap = typename boost::property_map::type> -class Cotangent_weight_with_voronoi_area_fairing { - +template::type> +class Cotangent_weight_with_voronoi_area_fairing +{ typedef PolygonMesh PM; typedef VertexPointMap VPMap; Voronoi_area voronoi_functor; Cotangent_weight > cotangent_functor; public: - Cotangent_weight_with_voronoi_area_fairing(PM& pmesh_) : - voronoi_functor(pmesh_, get(CGAL::vertex_point, pmesh_)), - cotangent_functor(pmesh_, get(CGAL::vertex_point, pmesh_)) + Cotangent_weight_with_voronoi_area_fairing(PM& pmesh_) + : voronoi_functor(pmesh_, get(CGAL::vertex_point, pmesh_)), + cotangent_functor(pmesh_, get(CGAL::vertex_point, pmesh_)) { } - Cotangent_weight_with_voronoi_area_fairing( - PM& pmesh_, - VPMap vpmap_) : - voronoi_functor(pmesh_, vpmap_), - cotangent_functor(pmesh_, vpmap_) + Cotangent_weight_with_voronoi_area_fairing(PM& pmesh_, + VPMap vpmap_) + : voronoi_functor(pmesh_, vpmap_), + cotangent_functor(pmesh_, vpmap_) { } - PM& pmesh() { - return voronoi_functor.pmesh(); - } + PM& pmesh() { return voronoi_functor.pmesh(); } typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - double w_i(vertex_descriptor v_i) { + double w_i(vertex_descriptor v_i) + { return 0.5 / voronoi_functor(v_i); } - double w_ij(halfedge_descriptor he) { + double w_ij(halfedge_descriptor he) + { return cotangent_functor(he) * 2.0; } }; @@ -906,54 +821,51 @@ public: // Cotangent_value_Meyer has been changed to the version: // Cotangent_value_Meyer_secure to avoid imprecisions from // the issue #4706 - https://github.com/CGAL/cgal/issues/4706. -template< - typename PolygonMesh, - typename VertexPointMap = typename boost::property_map::type> -class Cotangent_weight_with_voronoi_area_fairing_secure { - +template::type> +class Cotangent_weight_with_voronoi_area_fairing_secure +{ typedef PolygonMesh PM; typedef VertexPointMap VPMap; Voronoi_area voronoi_functor; Cotangent_weight > cotangent_functor; public: - Cotangent_weight_with_voronoi_area_fairing_secure(PM& pmesh_) : - voronoi_functor(pmesh_, get(CGAL::vertex_point, pmesh_)), - cotangent_functor(pmesh_, get(CGAL::vertex_point, pmesh_)) + Cotangent_weight_with_voronoi_area_fairing_secure(PM& pmesh_) + : voronoi_functor(pmesh_, get(CGAL::vertex_point, pmesh_)), + cotangent_functor(pmesh_, get(CGAL::vertex_point, pmesh_)) { } - Cotangent_weight_with_voronoi_area_fairing_secure( - PM& pmesh_, - VPMap vpmap_) : - voronoi_functor(pmesh_, vpmap_), - cotangent_functor(pmesh_, vpmap_) + Cotangent_weight_with_voronoi_area_fairing_secure(PM& pmesh_, + VPMap vpmap_) + : voronoi_functor(pmesh_, vpmap_), + cotangent_functor(pmesh_, vpmap_) { } - PM& pmesh() { - return voronoi_functor.pmesh(); - } + PM& pmesh() { return voronoi_functor.pmesh(); } typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - double w_i(vertex_descriptor v_i) { + double w_i(vertex_descriptor v_i) + { return 0.5 / voronoi_functor(v_i); } - double w_ij(halfedge_descriptor he) { + double w_ij(halfedge_descriptor he) + { return cotangent_functor(he) * 2.0; } }; template -class Uniform_weight_fairing { - +class Uniform_weight_fairing +{ public: typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - Uniform_weight_fairing(PolygonMesh&) - { } + Uniform_weight_fairing(PolygonMesh&) { } double w_ij(halfedge_descriptor /* e */) { return 1.0; } double w_i(vertex_descriptor /* v_i */) { return 1.0; } @@ -965,4 +877,6 @@ public: } // namespace Weights } // namespace CGAL +#endif // CGAL_NO_DEPRECATED_CODE + #endif // CGAL_WEIGHTS_PMP_DEPRECATED_H From 72163bc009692b082e359a8b127980b943d5280a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 17 Oct 2022 17:54:01 +0200 Subject: [PATCH 06/35] Simply weight computations and use documentation variable names --- .../include/CGAL/Weights/authalic_weights.h | 18 ++--- .../CGAL/Weights/discrete_harmonic_weights.h | 11 ++- Weights/include/CGAL/Weights/internal/utils.h | 14 ++-- .../CGAL/Weights/inverse_distance_weights.h | 4 +- .../include/CGAL/Weights/mean_value_weights.h | 4 +- .../include/CGAL/Weights/shepard_weights.h | 12 +--- .../include/CGAL/Weights/tangent_weights.h | 69 +++++++------------ .../CGAL/Weights/three_point_family_weights.h | 36 +++------- 8 files changed, 60 insertions(+), 108 deletions(-) diff --git a/Weights/include/CGAL/Weights/authalic_weights.h b/Weights/include/CGAL/Weights/authalic_weights.h index 6700bdbb6ad..0e9b18782ad 100644 --- a/Weights/include/CGAL/Weights/authalic_weights.h +++ b/Weights/include/CGAL/Weights/authalic_weights.h @@ -30,11 +30,10 @@ template FT half_weight(const FT cot, const FT r2) { FT w = FT(0); - CGAL_precondition(r2 != FT(0)); - if (r2 != FT(0)) { - const FT inv = FT(2) / r2; - w = cot * inv; - } + CGAL_precondition(!is_zero(r2)); + if (!is_zero(r2)) + w = FT(2) * cot / r2; + return w; } @@ -42,12 +41,9 @@ template FT weight(const FT cot_gamma, const FT cot_beta, const FT r2) { FT w = FT(0); - CGAL_precondition(r2 != FT(0)); - if (r2 != FT(0)) - { - const FT inv = FT(2) / r2; - w = (cot_gamma + cot_beta) * inv; - } + CGAL_precondition(!is_zero(r2)); + if (!is_zero(r2)) + w = FT(2) * (cot_gamma + cot_beta) / r2; return w; } diff --git a/Weights/include/CGAL/Weights/discrete_harmonic_weights.h b/Weights/include/CGAL/Weights/discrete_harmonic_weights.h index ea0b89a923b..514b25eb488 100644 --- a/Weights/include/CGAL/Weights/discrete_harmonic_weights.h +++ b/Weights/include/CGAL/Weights/discrete_harmonic_weights.h @@ -31,17 +31,14 @@ namespace Weights { namespace discrete_harmonic_ns { template -FT weight(const FT r1, const FT r2, const FT r3, +FT weight(const FT d1, const FT d2, const FT d, const FT A1, const FT A2, const FT B) { FT w = FT(0); - CGAL_precondition(A1 != FT(0) && A2 != FT(0)); + CGAL_precondition(!is_zero(A1) && !is_zero(A2)); const FT prod = A1 * A2; - if (prod != FT(0)) - { - const FT inv = FT(1) / prod; - w = (r3 * A1 - r2 * B + r1 * A2) * inv; - } + if (!is_zero(prod)) + w = (d2 * A1 - d * B + d1 * A2) / prod; return w; } diff --git a/Weights/include/CGAL/Weights/internal/utils.h b/Weights/include/CGAL/Weights/internal/utils.h index 640ef28e789..8a0d58341d1 100644 --- a/Weights/include/CGAL/Weights/internal/utils.h +++ b/Weights/include/CGAL/Weights/internal/utils.h @@ -86,8 +86,8 @@ void normalize(std::vector& values) for (const FT& value : values) sum += value; - CGAL_assertion(sum != FT(0)); - if (sum == FT(0)) + CGAL_assertion(!is_zero(sum)); + if (is_zero(sum)) return; const FT inv_sum = FT(1) / sum; @@ -95,14 +95,10 @@ void normalize(std::vector& values) value *= inv_sum; } -// Raises value to the power. -template -typename GeomTraits::FT power(const GeomTraits&, - const typename GeomTraits::FT value, - const typename GeomTraits::FT p) +template +FT power(const FT value, + const FT p) { - using FT = typename GeomTraits::FT; - const double base = CGAL::to_double(value); const double exp = CGAL::to_double(p); diff --git a/Weights/include/CGAL/Weights/inverse_distance_weights.h b/Weights/include/CGAL/Weights/inverse_distance_weights.h index 9d0927c21ee..332d18f9c4a 100644 --- a/Weights/include/CGAL/Weights/inverse_distance_weights.h +++ b/Weights/include/CGAL/Weights/inverse_distance_weights.h @@ -29,8 +29,8 @@ template FT weight(const FT d) { FT w = FT(0); - CGAL_precondition(d != FT(0)); - if (d != FT(0)) + CGAL_precondition(!is_zero(d)); + if (!is_zero(d)) w = FT(1) / d; return w; diff --git a/Weights/include/CGAL/Weights/mean_value_weights.h b/Weights/include/CGAL/Weights/mean_value_weights.h index c08ccef1c51..3271db9cbb0 100644 --- a/Weights/include/CGAL/Weights/mean_value_weights.h +++ b/Weights/include/CGAL/Weights/mean_value_weights.h @@ -68,9 +68,9 @@ typename GeomTraits::FT weight(const GeomTraits& traits, const FT P2 = r2 * r3 + D2; FT w = FT(0); - CGAL_precondition(P1 != FT(0) && P2 != FT(0)); + CGAL_precondition(!is_zero(P1) && !is_zero(P2)); const FT prod = P1 * P2; - if (prod != FT(0)) + if (!is_zero(prod)) { const FT inv = FT(1) / prod; w = FT(2) * (r1 * r3 - D) * inv; diff --git a/Weights/include/CGAL/Weights/shepard_weights.h b/Weights/include/CGAL/Weights/shepard_weights.h index 2cfbc76b862..8c12d55687d 100644 --- a/Weights/include/CGAL/Weights/shepard_weights.h +++ b/Weights/include/CGAL/Weights/shepard_weights.h @@ -34,15 +34,9 @@ typename GeomTraits::FT weight(const GeomTraits& traits, using FT = typename GeomTraits::FT; FT w = FT(0); - CGAL_precondition(d != FT(0)); - if (d != FT(0)) - { - FT denom = d; - if (p != FT(1)) - denom = internal::power(traits, d, p); - - w = FT(1) / denom; - } + CGAL_precondition(is_positive(d)); + if(is_positive(d)) + w = internal::power(d, -p); return w; } diff --git a/Weights/include/CGAL/Weights/tangent_weights.h b/Weights/include/CGAL/Weights/tangent_weights.h index 9986d115bcd..4c4260314fd 100644 --- a/Weights/include/CGAL/Weights/tangent_weights.h +++ b/Weights/include/CGAL/Weights/tangent_weights.h @@ -25,33 +25,16 @@ namespace CGAL { namespace Weights { /// \cond SKIP_IN_MANUAL + namespace tangent_ns { -template -FT half_angle_tangent(const FT r, const FT d, const FT A, const FT D) -{ - FT t = FT(0); - const FT P = r * d + D; - CGAL_precondition(P != FT(0)); - if (P != FT(0)) - { - const FT inv = FT(2) / P; - t = A * inv; - } - - return t; -} - template FT half_weight(const FT t, const FT r) { FT w = FT(0); - CGAL_precondition(r != FT(0)); - if (r != FT(0)) - { - const FT inv = FT(2) / r; - w = t * inv; - } + CGAL_precondition(!is_zero(r)); + if (!is_zero(r)) + w = FT(2) * t / r; return w; } @@ -62,33 +45,27 @@ FT weight(const FT t1, const FT t2, const FT r) FT w = FT(0); CGAL_precondition(r != FT(0)); if (r != FT(0)) - { - const FT inv = FT(2) / r; - w = (t1 + t2) * inv; - } + w = FT(2) * (t1 + t2) / r; return w; } template -FT weight(const FT d1, const FT r, const FT d2, +FT weight(const FT d1, const FT d, const FT d2, const FT A1, const FT A2, const FT D1, const FT D2) { - const FT P1 = d1 * r + D1; - const FT P2 = d2 * r + D2; + const FT P1 = d1 * d + D1; + const FT P2 = d2 * d + D2; FT w = FT(0); - CGAL_precondition(P1 != FT(0) && P2 != FT(0)); - if (P1 != FT(0) && P2 != FT(0)) + CGAL_precondition(!is_zero(P1) && !is_zero(P2)); + if (!is_zero(P1) && !is_zero(P2)) { - const FT inv1 = FT(2) / P1; - const FT inv2 = FT(2) / P2; - const FT t1 = A1 * inv1; - const FT t2 = A2 * inv2; - w = weight(t1, t2, r); + const FT t1 = FT(2) * A1 / P1; + const FT t2 = FT(2) * A2 / P2; + w = weight(t1, t2, d); } - return w; } @@ -168,23 +145,29 @@ typename GeomTraits::FT tangent_weight_v2(const typename GeomTraits::Point_3& t, This function computes the tangent of the half angle using the precomputed distance, area, and dot product values. The returned value is - \f$\frac{2\textbf{A}}{\textbf{d}\textbf{l} + \textbf{D}}\f$. + \f$\frac{2\textbf{A}}{\textbf{d}\textbf{d_1} + \textbf{D_1}}\f$. \tparam FT a model of `FieldNumberType` - \param d the distance value - \param l the distance value + \param d1 the first distance value + \param d2 the second distance value \param A the area value \param D the dot product value - \pre (d * l + D) != 0 + \pre (d1 * d2 + D) != 0 \sa `half_tangent_weight()` */ template -FT tangent_half_angle(const FT d, const FT l, const FT A, const FT D) +FT tangent_half_angle(const FT d1, const FT d2, const FT A, const FT D) { - return tangent_ns::half_angle_tangent(d, l, A, D); + FT t = FT(0); + const FT P = d1 * d2 + D; + CGAL_precondition(!is_zero(P)); + if (!is_zero(P)) + t = FT(2) * A / P; + + return t; } /*! @@ -237,7 +220,7 @@ template FT half_tangent_weight(const FT d, const FT l, const FT A, const FT D) { const FT tan05 = tangent_half_angle(d, l, A, D); - return half_tangent_weight(tan05, d); + return tangent_ns::half_weight(tan05, d); } /// \cond SKIP_IN_MANUAL diff --git a/Weights/include/CGAL/Weights/three_point_family_weights.h b/Weights/include/CGAL/Weights/three_point_family_weights.h index 6f2b5f7925f..f5b08ce9c48 100644 --- a/Weights/include/CGAL/Weights/three_point_family_weights.h +++ b/Weights/include/CGAL/Weights/three_point_family_weights.h @@ -25,36 +25,22 @@ namespace Weights { /// \cond SKIP_IN_MANUAL namespace three_point_family_ns { -template -typename GeomTraits::FT weight(const GeomTraits& traits, - const typename GeomTraits::FT d1, - const typename GeomTraits::FT d2, - const typename GeomTraits::FT d3, - const typename GeomTraits::FT A1, - const typename GeomTraits::FT A2, - const typename GeomTraits::FT B, - const typename GeomTraits::FT p) +template +FT weight(const FT d1, const FT d2, const FT d, + const FT A1, const FT A2, const FT B, + const FT p) { - using FT = typename GeomTraits::FT; - FT w = FT(0); - CGAL_precondition(A1 != FT(0) && A2 != FT(0)); + CGAL_precondition(!is_zero(A1) && !is_zero(A2)); const FT prod = A1 * A2; - if (prod != FT(0)) + if (!is_zero(prod)) { - const FT inv = FT(1) / prod; - FT r1 = d1; - FT r2 = d2; - FT r3 = d3; - if (p != FT(1)) - { - r1 = internal::power(traits, d1, p); - r2 = internal::power(traits, d2, p); - r3 = internal::power(traits, d3, p); - } - w = (r3 * A1 - r2 * B + r1 * A2) * inv; - } + const FT r1 = internal::power(d1, p); + const FT r2 = internal::power(d2, p); + const FT r = internal::power(d , p); + w = (r2 * A1 - r * B + r1 * A2) / prod; + } return w; } From 15de97faf1981888f1eb76d6a3deec97b2d44b8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 17 Oct 2022 21:40:05 +0200 Subject: [PATCH 07/35] Re-organize internal functions and use usual APIs --- Weights/include/CGAL/Weights/internal/utils.h | 314 ++++-------------- Weights/include/CGAL/Weights/utils.h | 293 +++++++++------- 2 files changed, 250 insertions(+), 357 deletions(-) diff --git a/Weights/include/CGAL/Weights/internal/utils.h b/Weights/include/CGAL/Weights/internal/utils.h index 8a0d58341d1..2c01c4e1e30 100644 --- a/Weights/include/CGAL/Weights/internal/utils.h +++ b/Weights/include/CGAL/Weights/internal/utils.h @@ -105,11 +105,12 @@ FT power(const FT value, return static_cast(std::pow(base, exp)); } -// Computes distance between two 2D points. +// 2D ============================================================================================== + template -typename GeomTraits::FT distance_2(const GeomTraits& traits, - const typename GeomTraits::Point_2& p, - const typename GeomTraits::Point_2& q) +typename GeomTraits::FT distance_2(const typename GeomTraits::Point_2& p, + const typename GeomTraits::Point_2& q, + const GeomTraits& traits) { using Get_sqrt = Get_sqrt; auto sqrt = Get_sqrt::sqrt_object(traits); @@ -118,10 +119,9 @@ typename GeomTraits::FT distance_2(const GeomTraits& traits, return sqrt(squared_distance_2(p, q)); } -// Computes length of a 2D vector. template -typename GeomTraits::FT length_2(const GeomTraits& traits, - const typename GeomTraits::Vector_2& v) +typename GeomTraits::FT length_2(const typename GeomTraits::Vector_2& v, + const GeomTraits& traits) { using Get_sqrt = Get_sqrt; auto sqrt = Get_sqrt::sqrt_object(traits); @@ -131,8 +131,8 @@ typename GeomTraits::FT length_2(const GeomTraits& traits, } template -void normalize_2(const GeomTraits& traits, - typename GeomTraits::Vector_2& v) +void normalize_2(typename GeomTraits::Vector_2& v, + const GeomTraits& traits) { using FT = typename GeomTraits::FT; const FT length = length_2(traits, v); @@ -143,78 +143,24 @@ void normalize_2(const GeomTraits& traits, v /= length; } -// Computes cotanget between two 2D vectors. +// 3D ============================================================================================== + template -typename GeomTraits::FT cotangent_2(const GeomTraits& traits, - const typename GeomTraits::Point_2& p, - const typename GeomTraits::Point_2& q, - const typename GeomTraits::Point_2& r) +typename GeomTraits::FT distance_3(const typename GeomTraits::Point_3& p, + const typename GeomTraits::Point_3& q, + const GeomTraits& traits) { - using FT = typename GeomTraits::FT; - using Vector_2 = typename GeomTraits::Vector_2; + auto squared_distance_3 = traits.compute_squared_distance_3_object(); - auto dot_product_2 = traits.compute_scalar_product_2_object(); - auto cross_product_2 = traits.compute_determinant_2_object(); - auto construct_vector_2 = traits.construct_vector_2_object(); - - const Vector_2 v1 = construct_vector_2(q, r); - const Vector_2 v2 = construct_vector_2(q, p); - - const FT dot = dot_product_2(v1, v2); - const FT cross = cross_product_2(v1, v2); - - const FT length = CGAL::abs(cross); - // CGAL_assertion(length != FT(0)); not really necessary - if (length != FT(0)) - return dot / length; - else - return FT(0); // undefined -} - -// Computes tanget between two 2D vectors. -template -typename GeomTraits::FT tangent_2(const GeomTraits& traits, - const typename GeomTraits::Point_2& p, - const typename GeomTraits::Point_2& q, - const typename GeomTraits::Point_2& r) -{ - using FT = typename GeomTraits::FT; - using Vector_2 = typename GeomTraits::Vector_2; - - auto dot_product_2 = traits.compute_scalar_product_2_object(); - auto cross_product_2 = traits.compute_determinant_2_object(); - auto construct_vector_2 = traits.construct_vector_2_object(); - - const Vector_2 v1 = construct_vector_2(q, r); - const Vector_2 v2 = construct_vector_2(q, p); - - const FT dot = dot_product_2(v1, v2); - const FT cross = cross_product_2(v1, v2); - - const FT length = CGAL::abs(cross); - // CGAL_assertion(dot != FT(0)); not really necessary - if (dot != FT(0)) - return length / dot; - else - return FT(0); // undefined -} - -// Computes distance between two 3D points. -template -typename GeomTraits::FT distance_3(const GeomTraits& traits, - const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3& q) -{ using Get_sqrt = Get_sqrt; auto sqrt = Get_sqrt::sqrt_object(traits); - auto squared_distance_3 = traits.compute_squared_distance_3_object(); return sqrt(squared_distance_3(p, q)); } template -typename GeomTraits::FT length_3(const GeomTraits& traits, - const typename GeomTraits::Vector_3& v) +typename GeomTraits::FT length_3(const typename GeomTraits::Vector_3& v, + const GeomTraits& traits) { using Get_sqrt = Get_sqrt; auto sqrt = Get_sqrt::sqrt_object(traits); @@ -224,8 +170,8 @@ typename GeomTraits::FT length_3(const GeomTraits& traits, } template -void normalize_3(const GeomTraits& traits, - typename GeomTraits::Vector_3& v) +void normalize_3(typename GeomTraits::Vector_3& v, + const GeomTraits& traits) { using FT = typename GeomTraits::FT; @@ -238,71 +184,12 @@ void normalize_3(const GeomTraits& traits, } template -typename GeomTraits::FT cotangent_3(const GeomTraits& traits, - const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3& q, - const typename GeomTraits::Point_3& r) -{ - using FT = typename GeomTraits::FT; - using Vector_3 = typename GeomTraits::Vector_3; - - auto dot_product_3 = traits.compute_scalar_product_3_object(); - auto cross_product_3 = traits.construct_cross_product_vector_3_object(); - auto vector_3 = traits.construct_vector_3_object(); - - const Vector_3 v1 = vector_3(q, r); - const Vector_3 v2 = vector_3(q, p); - - const FT dot = dot_product_3(v1, v2); - auto cross = cross_product_3(v1, v2); - - const FT length = length_3(traits, cross); - // TODO: - // Not really necessary: since we handle case length = 0. Does this case happen? - // Yes, e.g. in Surface Parameterization tests. Does it affect the results? - // In current applications, not really. - // CGAL_assertion(length != FT(0)); - if (length != FT(0)) - return dot / length; - else - return FT(0); // undefined -} - -// Computes tanget between two 3D vectors. -template -typename GeomTraits::FT tangent_3(const GeomTraits& traits, - const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3& q, - const typename GeomTraits::Point_3& r) -{ - using FT = typename GeomTraits::FT; - using Vector_3 = typename GeomTraits::Vector_3; - - auto dot_product_3 = traits.compute_scalar_product_3_object(); - auto cross_product_3 = traits.construct_cross_product_vector_3_object(); - auto vector_3 = traits.construct_vector_3_object(); - - const Vector_3 v1 = vector_3(q, r); - const Vector_3 v2 = vector_3(q, p); - - const FT dot = dot_product_3(v1, v2); - auto cross = cross_product_3(v1, v2); - - const FT length = length_3(traits, cross); - // CGAL_assertion(dot != FT(0)); not really necessary - if (dot != FT(0)) - return length / dot; - else - return FT(0); // undefined -} - -// Computes 3D angle between two vectors. -template -double angle_3(const GeomTraits& traits, - const typename GeomTraits::Vector_3& v1, - const typename GeomTraits::Vector_3& v2) +double angle_3(const typename GeomTraits::Vector_3& v1, + const typename GeomTraits::Vector_3& v2, + const GeomTraits& traits) { auto dot_product_3 = traits.compute_scalar_product_3_object(); + const double dot = CGAL::to_double(dot_product_3(v1, v2)); double angle_rad = 0.0; @@ -318,10 +205,10 @@ double angle_3(const GeomTraits& traits, // Rotates a 3D point around axis. template -typename GeomTraits::Point_3 rotate_point_3(const GeomTraits&, - const double angle_rad, +typename GeomTraits::Point_3 rotate_point_3(const double angle_rad, const typename GeomTraits::Vector_3& axis, - const typename GeomTraits::Point_3& query) + const typename GeomTraits::Point_3& query, + const GeomTraits& traits) { using FT = typename GeomTraits::FT; using Point_3 = typename GeomTraits::Point_3; @@ -348,10 +235,10 @@ typename GeomTraits::Point_3 rotate_point_3(const GeomTraits&, // Computes two 3D orthogonal base vectors wrt a given normal. template -void orthogonal_bases_3(const GeomTraits& traits, - const typename GeomTraits::Vector_3& normal, +void orthogonal_bases_3(const typename GeomTraits::Vector_3& normal, typename GeomTraits::Vector_3& b1, - typename GeomTraits::Vector_3& b2) + typename GeomTraits::Vector_3& b2, + const GeomTraits& traits) { using FT = typename GeomTraits::FT; using Vector_3 = typename GeomTraits::Vector_3; @@ -369,17 +256,17 @@ void orthogonal_bases_3(const GeomTraits& traits, b2 = cross_product_3(normal, b1); - normalize_3(traits, b1); - normalize_3(traits, b2); + normalize_3(b1, traits); + normalize_3(b2, traits); } // Converts a 3D point into a 2D point wrt to a given plane. template -typename GeomTraits::Point_2 to_2d(const GeomTraits& traits, - const typename GeomTraits::Vector_3& b1, +typename GeomTraits::Point_2 to_2d(const typename GeomTraits::Vector_3& b1, const typename GeomTraits::Vector_3& b2, const typename GeomTraits::Point_3& origin, - const typename GeomTraits::Point_3& query) + const typename GeomTraits::Point_3& query, + const GeomTraits& traits) { using FT = typename GeomTraits::FT; using Point_2 = typename GeomTraits::Point_2; @@ -453,15 +340,15 @@ typename GeomTraits::Point_2 to_2d(const GeomTraits& traits, // Flattens an arbitrary quad into a planar quad. template -void flatten(const GeomTraits& traits, - const typename GeomTraits::Point_3& t, // prev neighbor/vertex/point +void flatten(const typename GeomTraits::Point_3& t, // prev neighbor/vertex/point const typename GeomTraits::Point_3& r, // curr neighbor/vertex/point const typename GeomTraits::Point_3& p, // next neighbor/vertex/point const typename GeomTraits::Point_3& q, // query point typename GeomTraits::Point_2& tf, typename GeomTraits::Point_2& rf, typename GeomTraits::Point_2& pf, - typename GeomTraits::Point_2& qf) + typename GeomTraits::Point_2& qf, + const GeomTraits& traits) { // std::cout << std::endl; using Point_3 = typename GeomTraits::Point_3; @@ -488,89 +375,76 @@ void flatten(const GeomTraits& traits, // Middle axis. Vector_3 ax = vector_3(q1, r1); - normalize_3(traits, ax); + normalize_3(ax, traits); // Prev and next vectors. Vector_3 v1 = vector_3(q1, t1); Vector_3 v2 = vector_3(q1, p1); - normalize_3(traits, v1); - normalize_3(traits, v2); + normalize_3(v1, traits); + normalize_3(v2, traits); // Two triangle normals. Vector_3 n1 = cross_product_3(v1, ax); Vector_3 n2 = cross_product_3(ax, v2); - normalize_3(traits, n1); - normalize_3(traits, n2); + normalize_3(n1, traits); + normalize_3(n2, traits); // std::cout << "normal n1: " << n1 << std::endl; // std::cout << "normal n2: " << n2 << std::endl; // Angle between two normals. - const double angle_rad = angle_3(traits, n1, n2); + const double angle_rad = angle_3(n1, n2, traits); // std::cout << "angle deg n1 <-> n2: " << angle_rad * 180.0 / CGAL_PI << std::endl; // Rotate p1 around ax so that it lands onto the plane [q1, t1, r1]. const Point_3& t2 = t1; const Point_3& r2 = r1; - const Point_3 p2 = rotate_point_3(traits, angle_rad, ax, p1); + const Point_3 p2 = rotate_point_3(angle_rad, ax, p1, traits); const Point_3& q2 = q1; // std::cout << "rotated p2: " << p2 << std::endl; // Compute orthogonal base vectors. Vector_3 b1, b2; const Vector_3& normal = n1; - orthogonal_bases_3(traits, normal, b1, b2); + orthogonal_bases_3(normal, b1, b2, traits); - // const Angle angle12 = angle_3(traits, b1, b2); + // const Angle angle12 = angle_3(b1, b2, traits); // std::cout << "angle deg b1 <-> b2: " << angle12 * 180.0 / CGAL_PI << std::endl; // Flatten a quad. const Point_3& origin = q2; - tf = to_2d(traits, b1, b2, origin, t2); - rf = to_2d(traits, b1, b2, origin, r2); - pf = to_2d(traits, b1, b2, origin, p2); - qf = to_2d(traits, b1, b2, origin, q2); + tf = to_2d(b1, b2, origin, t2, traits); + rf = to_2d(b1, b2, origin, r2, traits); + pf = to_2d(b1, b2, origin, p2, traits); + qf = to_2d(b1, b2, origin, q2, traits); // std::cout << "flattened qf: " << qf << std::endl; // std::cout << "flattened tf: " << tf << std::endl; // std::cout << "flattened rf: " << rf << std::endl; // std::cout << "flattened pf: " << pf << std::endl; - // std::cout << "A1: " << area_2(traits, rf, qf, pf) << std::endl; - // std::cout << "A2: " << area_2(traits, pf, qf, rf) << std::endl; - // std::cout << "C: " << area_2(traits, tf, rf, pf) << std::endl; - // std::cout << "B: " << area_2(traits, pf, qf, tf) << std::endl; + // std::cout << "A1: " << area_2(rf, qf, pf, traits) << std::endl; + // std::cout << "A2: " << area_2(pf, qf, rf, traits) << std::endl; + // std::cout << "C: " << area_2(tf, rf, pf, traits) << std::endl; + // std::cout << "B: " << area_2(pf, qf, tf, traits) << std::endl; } -// Computes area of a 2D triangle. template -typename GeomTraits::FT area_2(const GeomTraits& traits, - const typename GeomTraits::Point_2& p, - const typename GeomTraits::Point_2& q, - const typename GeomTraits::Point_2& r) -{ - auto area_2 = traits.compute_area_2_object(); - return area_2(p, q, r); -} - -// Computes positive area of a 2D triangle. -template -typename GeomTraits::FT positive_area_2(const GeomTraits& traits, - const typename GeomTraits::Point_2& p, +typename GeomTraits::FT positive_area_2(const typename GeomTraits::Point_2& p, const typename GeomTraits::Point_2& q, - const typename GeomTraits::Point_2& r) + const typename GeomTraits::Point_2& r, + const GeomTraits& traits) { return CGAL::abs(area_2(traits, p, q, r)); } -// Computes area of a 3D triangle. template -typename GeomTraits::FT area_3(const GeomTraits& traits, - const typename GeomTraits::Point_3& p, +typename GeomTraits::FT area_3(const typename GeomTraits::Point_3& p, const typename GeomTraits::Point_3& q, - const typename GeomTraits::Point_3& r) + const typename GeomTraits::Point_3& r, + const GeomTraits& traits) { using FT = typename GeomTraits::FT; using Point_2 = typename GeomTraits::Point_2; @@ -592,22 +466,22 @@ typename GeomTraits::FT area_3(const GeomTraits& traits, // Prev and next vectors. Vector_3 v1 = vector_3(b, a); Vector_3 v2 = vector_3(b, c); - normalize_3(traits, v1); - normalize_3(traits, v2); + normalize_3(v1, traits); + normalize_3(v2, traits); // Compute normal. Vector_3 normal = cross_product_3(v1, v2); - normalize_3(traits, normal); + normalize_3(normal, traits); // Compute orthogonal base vectors. Vector_3 b1, b2; - orthogonal_bases_3(traits, normal, b1, b2); + orthogonal_bases_3(normal, b1, b2, traits); // Compute area. const Point_3& origin = b; - const Point_2 pf = to_2d(traits, b1, b2, origin, a); - const Point_2 qf = to_2d(traits, b1, b2, origin, b); - const Point_2 rf = to_2d(traits, b1, b2, origin, c); + const Point_2 pf = to_2d(b1, b2, origin, a, traits); + const Point_2 qf = to_2d(b1, b2, origin, b, traits); + const Point_2 rf = to_2d(b1, b2, origin, c, traits); const FT A = area_2(traits, pf, qf, rf); return A; @@ -615,62 +489,18 @@ typename GeomTraits::FT area_3(const GeomTraits& traits, // Computes positive area of a 3D triangle. template -typename GeomTraits::FT positive_area_3(const GeomTraits& traits, - const typename GeomTraits::Point_3& p, +typename GeomTraits::FT positive_area_3(const typename GeomTraits::Point_3& p, const typename GeomTraits::Point_3& q, - const typename GeomTraits::Point_3& r) + const typename GeomTraits::Point_3& r, + const GeomTraits& traits) { using FT = typename GeomTraits::FT; - using Vector_3 = typename GeomTraits::Vector_3; - - auto vector_3 = traits.construct_vector_3_object(); - auto cross_product_3 = traits.construct_cross_product_vector_3_object(); - - const Vector_3 v1 = vector_3(q, r); - const Vector_3 v2 = vector_3(q, p); - - Vector_3 cross = cross_product_3(v1, v2); - const FT half = FT(1) / FT(2); - const FT A = half * length_3(traits, cross); - return A; -} - -// Computes a clamped cotangent between two 3D vectors. -// In the old version of weights in PMP, it has been called secure. -// See Weights/internal/pmp_weights_deprecated.h for more information. -template -typename GeomTraits::FT cotangent_3_clamped(const GeomTraits& traits, - const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3& q, - const typename GeomTraits::Point_3& r) -{ - using FT = typename GeomTraits::FT; - using Vector_3 = typename GeomTraits::Vector_3; - using Get_sqrt = Get_sqrt; auto sqrt = Get_sqrt::sqrt_object(traits); - auto dot_product_3 = traits.compute_scalar_product_3_object(); - auto vector_3 = traits.construct_vector_3_object(); + auto squared_area_3 = traits.compute_squared_area_3_object(); - const Vector_3 v1 = vector_3(q, r); - const Vector_3 v2 = vector_3(q, p); - - const FT dot = dot_product_3(v1, v2); - const FT length_v1 = length_3(traits, v1); - const FT length_v2 = length_3(traits, v2); - - const FT lb = -FT(999) / FT(1000), ub = FT(999) / FT(1000); - FT cosine = dot / length_v1 / length_v2; - cosine = (cosine < lb) ? lb : cosine; - cosine = (cosine > ub) ? ub : cosine; - const FT sine = sqrt(FT(1) - cosine * cosine); - - CGAL_assertion(sine != FT(0)); - if (sine != FT(0)) - return cosine / sine; - - return FT(0); // undefined + return sqrt(squared_area_3(p, q, r)); } } // namespace internal diff --git a/Weights/include/CGAL/Weights/utils.h b/Weights/include/CGAL/Weights/utils.h index fe4f5705afd..43c0a0945da 100644 --- a/Weights/include/CGAL/Weights/utils.h +++ b/Weights/include/CGAL/Weights/utils.h @@ -16,44 +16,37 @@ #include +#include + namespace CGAL { namespace Weights { /// \cond SKIP_IN_MANUAL -template -typename GeomTraits::FT tangent(const typename GeomTraits::Point_2& p, - const typename GeomTraits::Point_2& q, - const typename GeomTraits::Point_2& r, - const GeomTraits& traits) -{ - return internal::tangent_2(traits, p, q, r); -} +// Computes cotangent between two 2D vectors. template -typename GeomTraits::FT tangent(const CGAL::Point_2& p, - const CGAL::Point_2& q, - const CGAL::Point_2& r) +typename GeomTraits::FT cotangent_2(const typename GeomTraits::Point_2& p, + const typename GeomTraits::Point_2& q, + const typename GeomTraits::Point_2& r, + const GeomTraits& traits) { - const GeomTraits traits; - return tangent(p, q, r, traits); -} + using FT = typename GeomTraits::FT; + using Vector_2 = typename GeomTraits::Vector_2; -template -typename GeomTraits::FT tangent(const typename GeomTraits::Point_3& p, - const typename GeomTraits::Point_3& q, - const typename GeomTraits::Point_3& r, - const GeomTraits& traits) -{ - return internal::tangent_3(traits, p, q, r); -} + auto dot_product_2 = traits.compute_scalar_product_2_object(); + auto determinant_2 = traits.compute_determinant_2_object(); + auto vector_2 = traits.construct_vector_2_object(); -template -typename GeomTraits::FT tangent(const CGAL::Point_3& p, - const CGAL::Point_3& q, - const CGAL::Point_3& r) -{ - const GeomTraits traits; - return tangent(p, q, r, traits); + const Vector_2 v1 = vector_2(q, r); + const Vector_2 v2 = vector_2(q, p); + + const FT dot = dot_product_2(v1, v2); + const FT length = CGAL::abs(determinant_2(v1, v2)); + + if (!is_zero(length)) + return dot / length; + else + return FT(0); // undefined } template @@ -62,127 +55,197 @@ typename GeomTraits::FT cotangent(const typename GeomTraits::Point_2& p, const typename GeomTraits::Point_2& r, const GeomTraits& traits) { - return internal::cotangent_2(traits, p, q, r); + return cotangent_2(p, q, r, traits); } -template -typename GeomTraits::FT cotangent(const CGAL::Point_2& p, - const CGAL::Point_2& q, - const CGAL::Point_2& r) +template +typename Kernel::FT cotangent(const CGAL::Point_2& p, + const CGAL::Point_2& q, + const CGAL::Point_2& r) { - const GeomTraits traits; + const Kernel traits; return cotangent(p, q, r, traits); } +// ================================================================================================= + +// Computes cotangent between two 3D vectors. +template +typename GeomTraits::FT cotangent_3(const typename GeomTraits::Point_3& p, + const typename GeomTraits::Point_3& q, + const typename GeomTraits::Point_3& r, + const GeomTraits& traits) +{ + using FT = typename GeomTraits::FT; + using Vector_3 = typename GeomTraits::Vector_3; + + auto dot_product_3 = traits.compute_scalar_product_3_object(); + auto cross_product_3 = traits.construct_cross_product_vector_3_object(); + auto vector_3 = traits.construct_vector_3_object(); + + const Vector_3 v1 = vector_3(q, r); + const Vector_3 v2 = vector_3(q, p); + + const FT dot = dot_product_3(v1, v2); + const Vector_3 cross = cross_product_3(v1, v2); + + const FT length = internal::length_3(cross, traits); + if (!is_zero(length)) + return dot / length; + else + return FT(0); // undefined +} + template typename GeomTraits::FT cotangent(const typename GeomTraits::Point_3& p, const typename GeomTraits::Point_3& q, const typename GeomTraits::Point_3& r, const GeomTraits& traits) { - return internal::cotangent_3(traits, p, q, r); + return cotangent_3(p, q, r, traits); } -template -typename GeomTraits::FT cotangent(const CGAL::Point_3& p, - const CGAL::Point_3& q, - const CGAL::Point_3& r) +template +typename Kernel::FT cotangent(const CGAL::Point_3& p, + const CGAL::Point_3& q, + const CGAL::Point_3& r) { - const GeomTraits traits; + const Kernel traits; return cotangent(p, q, r, traits); } -/// \endcond +// ================================================================================================= -/// \cond SKIP_IN_MANUAL -// These are free functions to be used when building weights from parts rather -// than using the predefined weight functions. In principle, they can be removed. -// They are here to have unified interface within the Weights package and its -// construction weight system. +// Computes tangent between two 2D vectors. template -typename GeomTraits::FT squared_distance(const CGAL::Point_2& p, - const CGAL::Point_2& q) -{ - const GeomTraits traits; - auto squared_distance_2 = traits.compute_squared_distance_2_object(); - return squared_distance_2(p, q); -} - -template -typename GeomTraits::FT squared_distance(const CGAL::Point_3& p, - const CGAL::Point_3& q) -{ - const GeomTraits traits; - auto squared_distance_3 = traits.compute_squared_distance_3_object(); - return squared_distance_3(p, q); -} - -template -typename GeomTraits::FT distance(const CGAL::Point_2& p, - const CGAL::Point_2& q) -{ - const GeomTraits traits; - return internal::distance_2(traits, p, q); -} - -template -typename GeomTraits::FT distance(const CGAL::Point_3& p, - const CGAL::Point_3& q) -{ - const GeomTraits traits; - return internal::distance_3(traits, p, q); -} - -template -typename GeomTraits::FT area(const CGAL::Point_2& p, - const CGAL::Point_2& q, - const CGAL::Point_2& r) -{ - const GeomTraits traits; - return internal::area_2(traits, p, q, r); -} - -template -typename GeomTraits::FT area(const CGAL::Point_3& p, - const CGAL::Point_3& q, - const CGAL::Point_3& r) -{ - const GeomTraits traits; - return internal::positive_area_3(traits, p, q, r); -} - -template -typename GeomTraits::FT scalar_product(const CGAL::Point_2& p, - const CGAL::Point_2& q, - const CGAL::Point_2& r) +typename GeomTraits::FT tangent_2(const typename GeomTraits::Point_2& p, + const typename GeomTraits::Point_2& q, + const typename GeomTraits::Point_2& r, + const GeomTraits& traits) { + using FT = typename GeomTraits::FT; using Vector_2 = typename GeomTraits::Vector_2; - const GeomTraits traits; + auto dot_product_2 = traits.compute_scalar_product_2_object(); + auto determinant_2 = traits.compute_determinant_2_object(); + auto vector_2 = traits.construct_vector_2_object(); - auto scalar_product_2 = traits.compute_scalar_product_2_object(); - auto construct_vector_2 = traits.construct_vector_2_object(); + const Vector_2 v1 = vector_2(q, r); + const Vector_2 v2 = vector_2(q, p); - const Vector_2 v1 = construct_vector_2(q, r); - const Vector_2 v2 = construct_vector_2(q, p); - return scalar_product_2(v1, v2); + const FT dot = dot_product_2(v1, v2); + if (!is_zero(dot)) + { + const FT cross = determinant_2(v1, v2); + const FT length = CGAL::abs(cross); + return length / dot; + } + else + { + return FT(0); // undefined + } } template -typename GeomTraits::FT scalar_product(const CGAL::Point_3& p, - const CGAL::Point_3& q, - const CGAL::Point_3& r) +typename GeomTraits::FT tangent(const typename GeomTraits::Point_2& p, + const typename GeomTraits::Point_2& q, + const typename GeomTraits::Point_2& r, + const GeomTraits& traits) { + return tangent_2(p, q, r, traits); +} + +template +typename Kernel::FT tangent(const CGAL::Point_2& p, + const CGAL::Point_2& q, + const CGAL::Point_2& r) +{ + const Kernel traits; + return tangent(p, q, r, traits); +} + +// ================================================================================================= + +// Computes tangent between two 3D vectors. +template +typename GeomTraits::FT tangent_3(const typename GeomTraits::Point_3& p, + const typename GeomTraits::Point_3& q, + const typename GeomTraits::Point_3& r, + const GeomTraits& traits) +{ + using FT = typename GeomTraits::FT; using Vector_3 = typename GeomTraits::Vector_3; - const GeomTraits traits; - - auto scalar_product_3 = traits.compute_scalar_product_3_object(); + auto dot_product_3 = traits.compute_scalar_product_3_object(); + auto cross_product_3 = traits.construct_cross_product_vector_3_object(); auto vector_3 = traits.construct_vector_3_object(); const Vector_3 v1 = vector_3(q, r); const Vector_3 v2 = vector_3(q, p); - return scalar_product_3(v1, v2); + + const FT dot = dot_product_3(v1, v2); + if (!is_zero(dot)) + { + const Vector_3 cross = cross_product_3(v1, v2); + const FT length = internal::length_3(cross, traits); + return length / dot; + } + else + { + return FT(0); // undefined + } +} + +template +typename GeomTraits::FT tangent(const typename GeomTraits::Point_3& p, + const typename GeomTraits::Point_3& q, + const typename GeomTraits::Point_3& r, + const GeomTraits& traits) +{ + return tangent_3(p, q, r, traits); +} + +template +typename Kernel::FT tangent(const CGAL::Point_3& p, + const CGAL::Point_3& q, + const CGAL::Point_3& r) +{ + const Kernel traits; + return tangent(p, q, r, traits); +} + +template +typename GeomTraits::FT cotangent_3_clamped(const typename GeomTraits::Point_3& p, + const typename GeomTraits::Point_3& q, + const typename GeomTraits::Point_3& r, + const GeomTraits& traits) +{ + using FT = typename GeomTraits::FT; + using Vector_3 = typename GeomTraits::Vector_3; + + using Get_sqrt = internal::Get_sqrt; + auto sqrt = Get_sqrt::sqrt_object(traits); + + auto dot_product_3 = traits.compute_scalar_product_3_object(); + auto vector_3 = traits.construct_vector_3_object(); + + const Vector_3 v1 = vector_3(q, r); + const Vector_3 v2 = vector_3(q, p); + + const FT dot = dot_product_3(v1, v2); + const FT length_v1 = internal::length_3(v1, traits); + const FT length_v2 = internal::length_3(v2, traits); + + const FT lb = -FT(999) / FT(1000), + ub = FT(999) / FT(1000); + const FT cosine = boost::algorithm::clamp(dot / (length_v1 * length_v2), lb, ub); + const FT sine = sqrt(FT(1) - square(cosine)); + + CGAL_assertion(!is_zero(sine)); + if (!is_zero(sine)) + return cosine / sine; + + return FT(0); // undefined } /// \endcond From 5f89766c5cf1e74f2c559999221040dde11f29ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Thu, 20 Oct 2022 17:17:06 +0200 Subject: [PATCH 08/35] Uniformize notations across the package + re-introduce documentation --- Weights/doc/Weights/PackageDescription.txt | 14 +- .../include/CGAL/Weights/authalic_weights.h | 96 +++--- .../CGAL/Weights/barycentric_region_weights.h | 52 +++- .../include/CGAL/Weights/cotangent_weights.h | 76 +++-- .../CGAL/Weights/discrete_harmonic_weights.h | 104 ++++--- .../CGAL/Weights/inverse_distance_weights.h | 112 +++++-- .../include/CGAL/Weights/mean_value_weights.h | 146 +++++---- .../Weights/mixed_voronoi_region_weights.h | 47 ++- .../include/CGAL/Weights/shepard_weights.h | 137 +++++--- .../include/CGAL/Weights/tangent_weights.h | 292 +++++++++++------- .../CGAL/Weights/three_point_family_weights.h | 107 ++++--- .../CGAL/Weights/triangular_region_weights.h | 51 ++- .../CGAL/Weights/uniform_region_weights.h | 47 ++- .../include/CGAL/Weights/uniform_weights.h | 85 ++--- Weights/include/CGAL/Weights/utils.h | 5 + .../CGAL/Weights/voronoi_region_weights.h | 57 +++- .../include/CGAL/Weights/wachspress_weights.h | 111 ++++--- 17 files changed, 990 insertions(+), 549 deletions(-) diff --git a/Weights/doc/Weights/PackageDescription.txt b/Weights/doc/Weights/PackageDescription.txt index b3c78d87b5f..76186f8025d 100644 --- a/Weights/doc/Weights/PackageDescription.txt +++ b/Weights/doc/Weights/PackageDescription.txt @@ -101,7 +101,7 @@ a model of `AnalyticWeightTraits_3` for 3D points \endverbatim This weight is computed as -\f$w = \frac{d_2^a A_1 - d^a B + d_1^a A_2}{A_1 A_2}\f$ +\f$w = \frac{d_2^a A_0 - d^a B + d_0^a A_2}{A_0 A_2}\f$ with notations shown in the figure below and \f$a\f$ any real number being the power parameter. @@ -142,7 +142,7 @@ a model of `AnalyticWeightTraits_3` for 3D points \endverbatim This weight is computed as -\f$w = \frac{C}{A_1 A_2}\f$ +\f$w = \frac{C}{A_0 A_2}\f$ with notations shown in the figure below. Here, `q` is a query point and the points `p0`, `p1`, and `p2` are its neighbors. @@ -207,10 +207,10 @@ a model of `AnalyticWeightTraits_3` for 3D points \endverbatim This weight is computed as -\f$w = \pm 2 \sqrt{\frac{2 (d_1 d_2 - D)}{(d d_1 + D_1)(d d_2 + D_2)}}\f$ +\f$w = \pm 2 \sqrt{\frac{2 (d_0 d_2 - D)}{(d d_0 + D_0)(d d_2 + D_2)}}\f$ with notations shown in the figure below and dot products -\f$D_1 = (p_0 - q) \cdot (p_1 - q)\f$, +\f$D_0 = (p_0 - q) \cdot (p_1 - q)\f$, \f$D_2 = (p_1 - q) \cdot (p_2 - q)\f$, and \f$D = (p_0 - q) \cdot (p_2 - q)\f$. @@ -247,11 +247,11 @@ a model of `AnalyticWeightTraits_3` for 3D points This weight is computed as \f$w = 2 \frac{t_1 + t_2}{d}\f$, where -\f$t_1 = \frac{2 A_1}{d d_1 + D_1}\f$ and +\f$t_1 = \frac{2 A_0}{d d_0 + D_0}\f$ and \f$t_2 = \frac{2 A_2}{d d_2 + D_2}\f$ with notations shown in the figure below and dot products -\f$D_1 = (p_0 - q) \cdot (p_1 - q)\f$ and +\f$D_0 = (p_0 - q) \cdot (p_1 - q)\f$ and \f$D_2 = (p_1 - q) \cdot (p_2 - q)\f$. Here, `q` is a query point and the points `p0`, `p1`, and `p2` are its neighbors. @@ -283,7 +283,7 @@ a model of `AnalyticWeightTraits_3` for 3D points \endverbatim This weight is computed as -\f$w = \frac{d_2^2 A_1 - d^2 B + d_1^2 A_2}{A_1 A_2}\f$ +\f$w = \frac{d_2^2 A_0 - d^2 B + d_0^2 A_2}{A_0 A_2}\f$ with notations shown in the figure below. Here, `q` is a query point and the points `p0`, `p1`, and `p2` are its neighbors. diff --git a/Weights/include/CGAL/Weights/authalic_weights.h b/Weights/include/CGAL/Weights/authalic_weights.h index 0e9b18782ad..8c3eede9a25 100644 --- a/Weights/include/CGAL/Weights/authalic_weights.h +++ b/Weights/include/CGAL/Weights/authalic_weights.h @@ -57,79 +57,103 @@ FT weight(const FT cot_gamma, const FT cot_beta, const FT r2) \brief computes the half value of the authalic weight. - This function constructs the half of the authalic weight using the precomputed + This function computes the half of the authalic weight using the precomputed cotangent and squared distance values. The returned value is - \f$\frac{2\textbf{cot}}{\textbf{d2}}\f$. + \f$\frac{2\textbf{cot}}{\textbf{sq_d}}\f$. \tparam FT a model of `FieldNumberType` \param cot the cotangent value - \param d2 the squared distance value + \param sq_d the squared distance value - \pre d2 != 0 + \pre sq_d != 0 \sa `authalic_weight()` */ template -FT half_authalic_weight(const FT cot, const FT d2) +FT half_authalic_weight(const FT cot, const FT sq_d) { - return authalic_ns::half_weight(cot, d2); + return authalic_ns::half_weight(cot, sq_d); } +// 2D ============================================================================================== + +/*! + \ingroup PkgWeightsRefAuthalicWeights + \brief computes the authalic weight in 2D at `q` using the points `p0`, `p1`, and `p2`. + \tparam GeomTraits a model of `AnalyticWeightTraits_2` +*/ template -typename GeomTraits::FT authalic_weight(const typename GeomTraits::Point_2& t, - const typename GeomTraits::Point_2& r, - const typename GeomTraits::Point_2& p, +typename GeomTraits::FT authalic_weight(const typename GeomTraits::Point_2& p0, + const typename GeomTraits::Point_2& p1, + const typename GeomTraits::Point_2& p2, const typename GeomTraits::Point_2& q, const GeomTraits& traits) { using FT = typename GeomTraits::FT; + const FT cot_gamma = cotangent_2(p0, p1, q, traits); + const FT cot_beta = cotangent_2(q, p1, p2, traits); + auto squared_distance_2 = traits.compute_squared_distance_2_object(); + const FT sq_d = squared_distance_2(q, p1); - const FT cot_gamma = internal::cotangent_2(traits, t, r, q); - const FT cot_beta = internal::cotangent_2(traits, q, r, p); - - const FT d2 = squared_distance_2(q, r); - return authalic_ns::weight(cot_gamma, cot_beta, d2); + return authalic_ns::weight(cot_gamma, cot_beta, sq_d); } -template -typename GeomTraits::FT authalic_weight(const CGAL::Point_2& t, - const CGAL::Point_2& r, - const CGAL::Point_2& p, - const CGAL::Point_2& q) +/*! + \ingroup PkgWeightsRefAuthalicWeights + \brief computes the authalic weight in 2D at `q` using the points `p0`, `p1`, and `p2`. + \tparam Kernel a model of `Kernel` +*/ +template +typename Kernel::FT authalic_weight(const CGAL::Point_2& p0, + const CGAL::Point_2& p1, + const CGAL::Point_2& p2, + const CGAL::Point_2& q) { - const GeomTraits traits; - return authalic_weight(t, r, p, q, traits); + const Kernel traits; + return authalic_weight(p0, p1, p2, q, traits); } +// 3D ============================================================================================== + +/*! + \ingroup PkgWeightsRefAuthalicWeights + \brief computes the authalic weight in 3D at `q` using the points `p0`, `p1`, and `p2`. + \tparam GeomTraits a model of `AnalyticWeightTraits_3` +*/ template -typename GeomTraits::FT authalic_weight(const typename GeomTraits::Point_3& t, - const typename GeomTraits::Point_3& r, - const typename GeomTraits::Point_3& p, +typename GeomTraits::FT authalic_weight(const typename GeomTraits::Point_3& p0, + const typename GeomTraits::Point_3& p1, + const typename GeomTraits::Point_3& p2, const typename GeomTraits::Point_3& q, const GeomTraits& traits) { using FT = typename GeomTraits::FT; + const FT cot_gamma = cotangent_3(p0, p1, q, traits); + const FT cot_beta = cotangent_3(q, p1, p2, traits); + auto squared_distance_3 = traits.compute_squared_distance_3_object(); + const FT sq_d = squared_distance_3(q, p1); - const FT cot_gamma = internal::cotangent_3(traits, t, r, q); - const FT cot_beta = internal::cotangent_3(traits, q, r, p); - const FT d2 = squared_distance_3(q, r); - - return authalic_ns::weight(cot_gamma, cot_beta, d2); + return authalic_ns::weight(cot_gamma, cot_beta, sq_d); } -template -typename GeomTraits::FT authalic_weight(const CGAL::Point_3& t, - const CGAL::Point_3& r, - const CGAL::Point_3& p, - const CGAL::Point_3& q) +/*! + \ingroup PkgWeightsRefAuthalicWeights + \brief computes the authalic weight in 3D at `q` using the points `p0`, `p1`, and `p2`. + \tparam Kernel a model of `Kernel` +*/ +template +typename Kernel::FT authalic_weight(const CGAL::Point_3& p0, + const CGAL::Point_3& p1, + const CGAL::Point_3& p2, + const CGAL::Point_3& q) { - const GeomTraits traits; - return authalic_weight(t, r, p, q, traits); + const Kernel traits; + return authalic_weight(p0, p1, p2, q, traits); } } // namespace Weights diff --git a/Weights/include/CGAL/Weights/barycentric_region_weights.h b/Weights/include/CGAL/Weights/barycentric_region_weights.h index fe95dedd107..7d9f0bf2feb 100644 --- a/Weights/include/CGAL/Weights/barycentric_region_weights.h +++ b/Weights/include/CGAL/Weights/barycentric_region_weights.h @@ -22,6 +22,13 @@ namespace CGAL { namespace Weights { +// 2D ============================================================================================== + +/*! + \ingroup PkgWeightsRefBarycentricRegionWeights + \brief computes the area of the barycentric cell in 2D using the points `p`, `q`, and `r`. + \tparam GeomTraits a model of `AnalyticWeightTraits_2` +*/ template typename GeomTraits::FT barycentric_area(const typename GeomTraits::Point_2& p, const typename GeomTraits::Point_2& q, @@ -38,20 +45,32 @@ typename GeomTraits::FT barycentric_area(const typename GeomTraits::Point_2& p, const Point_2 m1 = midpoint_2(q, r); const Point_2 m2 = midpoint_2(q, p); - const FT A1 = internal::positive_area_2(traits, q, m1, center); - const FT A2 = internal::positive_area_2(traits, q, center, m2); + const FT A1 = internal::positive_area_2(q, m1, center, traits); + const FT A2 = internal::positive_area_2(q, center, m2, traits); return A1 + A2; } -template -typename GeomTraits::FT barycentric_area(const CGAL::Point_2& p, - const CGAL::Point_2& q, - const CGAL::Point_2& r) +/*! + \ingroup PkgWeightsRefBarycentricRegionWeights + \brief computes the area of the barycentric cell in 2D using the points `p`, `q`, and `r`. + \tparam Kernel a model of `Kernel` +*/ +template +typename Kernel::FT barycentric_area(const CGAL::Point_2& p, + const CGAL::Point_2& q, + const CGAL::Point_2& r) { - const GeomTraits traits; + const Kernel traits; return barycentric_area(p, q, r, traits); } +// 3D ============================================================================================== + +/*! + \ingroup PkgWeightsRefBarycentricRegionWeights + \brief computes the area of the barycentric cell in 3D using the points `p`, `q`, and `r`. + \tparam GeomTraits a model of `AnalyticWeightTraits_3` +*/ template typename GeomTraits::FT barycentric_area(const typename GeomTraits::Point_3& p, const typename GeomTraits::Point_3& q, @@ -68,17 +87,22 @@ typename GeomTraits::FT barycentric_area(const typename GeomTraits::Point_3& p, const Point_3 m1 = midpoint_3(q, r); const Point_3 m2 = midpoint_3(q, p); - const FT A1 = internal::positive_area_3(traits, q, m1, center); - const FT A2 = internal::positive_area_3(traits, q, center, m2); + const FT A1 = internal::positive_area_3(q, m1, center, traits); + const FT A2 = internal::positive_area_3(q, center, m2, traits); return A1 + A2; } -template -typename GeomTraits::FT barycentric_area(const CGAL::Point_3& p, - const CGAL::Point_3& q, - const CGAL::Point_3& r) +/*! + \ingroup PkgWeightsRefBarycentricRegionWeights + \brief computes the area of the barycentric cell in 3D using the points `p`, `q`, and `r`. + \tparam Kernel a model of `Kernel` +*/ +template +typename Kernel::FT barycentric_area(const CGAL::Point_3& p, + const CGAL::Point_3& q, + const CGAL::Point_3& r) { - const GeomTraits traits; + const Kernel traits; return barycentric_area(p, q, r, traits); } diff --git a/Weights/include/CGAL/Weights/cotangent_weights.h b/Weights/include/CGAL/Weights/cotangent_weights.h index be6b1b7876d..c7596aa53ee 100644 --- a/Weights/include/CGAL/Weights/cotangent_weights.h +++ b/Weights/include/CGAL/Weights/cotangent_weights.h @@ -65,57 +65,82 @@ FT half_cotangent_weight(const FT cot) return cotangent_ns::half_weight(cot); } +/*! + \ingroup PkgWeightsRefCotangentWeights + \brief computes the cotangent weight in 2D at `q` using the points `p0`, `p1`, and `p2`. + \tparam GeomTraits a model of `AnalyticWeightTraits_2` +*/ template -typename GeomTraits::FT cotangent_weight(const typename GeomTraits::Point_2& t, - const typename GeomTraits::Point_2& r, - const typename GeomTraits::Point_2& p, +typename GeomTraits::FT cotangent_weight(const typename GeomTraits::Point_2& p0, + const typename GeomTraits::Point_2& p1, + const typename GeomTraits::Point_2& p2, const typename GeomTraits::Point_2& q, const GeomTraits& traits) { using FT = typename GeomTraits::FT; - const FT cot_beta = internal::cotangent_2(traits, q, t, r); - const FT cot_gamma = internal::cotangent_2(traits, r, p, q); + const FT cot_beta = cotangent_2(q, p0, p1, traits); + const FT cot_gamma = cotangent_2(p1, p2, q, traits); return cotangent_ns::weight(cot_beta, cot_gamma); } -template -typename GeomTraits::FT cotangent_weight(const CGAL::Point_2& t, - const CGAL::Point_2& r, - const CGAL::Point_2& p, - const CGAL::Point_2& q) +/*! + \ingroup PkgWeightsRefCotangentWeights + \brief computes the cotangent weight in 2D at `q` using the points `p0`, `p1`, and `p2`. + \tparam Kernel a model of `Kernel` +*/ +template +typename Kernel::FT cotangent_weight(const CGAL::Point_2& p0, + const CGAL::Point_2& p1, + const CGAL::Point_2& p2, + const CGAL::Point_2& q) { - GeomTraits traits; - return cotangent_weight(t, r, p, q, traits); + Kernel traits; + return cotangent_weight(p0, p1, p2, q, traits); } +// 3D ============================================================================================== + +/*! + \ingroup PkgWeightsRefCotangentWeights + \brief computes the cotangent weight in 3D at `q` using the points `p0`, `p1`, and `p2`. + \tparam GeomTraits a model of `AnalyticWeightTraits_3` +*/ template -typename GeomTraits::FT cotangent_weight(const typename GeomTraits::Point_3& t, - const typename GeomTraits::Point_3& r, - const typename GeomTraits::Point_3& p, +typename GeomTraits::FT cotangent_weight(const typename GeomTraits::Point_3& p0, + const typename GeomTraits::Point_3& p1, + const typename GeomTraits::Point_3& p2, const typename GeomTraits::Point_3& q, const GeomTraits& traits) { using FT = typename GeomTraits::FT; - const FT cot_beta = internal::cotangent_3(traits, q, t, r); - const FT cot_gamma = internal::cotangent_3(traits, r, p, q); + const FT cot_beta = cotangent_3(q, p0, p1, traits); + const FT cot_gamma = cotangent_3(p1, p2, q, traits); return cotangent_ns::weight(cot_beta, cot_gamma); } -template -typename GeomTraits::FT cotangent_weight(const CGAL::Point_3& t, - const CGAL::Point_3& r, - const CGAL::Point_3& p, - const CGAL::Point_3& q) +/*! + \ingroup PkgWeightsRefCotangentWeights + \brief computes the cotangent weight in 3D at `q` using the points `p0`, `p1`, and `p2`. + \tparam Kernel a model of `Kernel` +*/ +template +typename Kernel::FT cotangent_weight(const CGAL::Point_3& p0, + const CGAL::Point_3& p1, + const CGAL::Point_3& p2, + const CGAL::Point_3& q) { - GeomTraits traits; - return cotangent_weight(t, r, p, q, traits); + Kernel traits; + return cotangent_weight(p0, p1, p2, q, traits); } +/// \cond SKIP_IN_MANUAL + // Undocumented cotangent weight class. +// // Its constructor takes a polygon mesh and a vertex to point map // and its operator() is defined based on the halfedge_descriptor only. // This version is currently used in: @@ -219,6 +244,7 @@ public: }; // Undocumented cotangent weight class. +// // Its constructor takes a boolean flag to choose between default and clamped // versions of the cotangent weights and its operator() is defined based on the // halfedge_descriptor, polygon mesh, and vertex to point map. @@ -460,6 +486,8 @@ private: } }; +/// \endcond + } // namespace Weights } // namespace CGAL diff --git a/Weights/include/CGAL/Weights/discrete_harmonic_weights.h b/Weights/include/CGAL/Weights/discrete_harmonic_weights.h index 514b25eb488..6faa6f189c4 100644 --- a/Weights/include/CGAL/Weights/discrete_harmonic_weights.h +++ b/Weights/include/CGAL/Weights/discrete_harmonic_weights.h @@ -31,82 +31,97 @@ namespace Weights { namespace discrete_harmonic_ns { template -FT weight(const FT d1, const FT d2, const FT d, - const FT A1, const FT A2, const FT B) +FT weight(const FT d0, const FT d2, const FT d, + const FT A0, const FT A2, const FT B) { FT w = FT(0); - CGAL_precondition(!is_zero(A1) && !is_zero(A2)); - const FT prod = A1 * A2; + CGAL_precondition(!is_zero(A0) && !is_zero(A2)); + const FT prod = A0 * A2; if (!is_zero(prod)) - w = (d2 * A1 - d * B + d1 * A2) / prod; + w = (d2 * A0 - d * B + d0 * A2) / prod; return w; } } // namespace discrete_harmonic_ns +/// \endcond + +// 2D ============================================================================================== + +/*! + \ingroup PkgWeightsRefDiscreteHarmonicWeights + \brief computes the discrete harmonic weight in 2D at `q` using the points `p0`, `p1`, and `p2`. + \tparam GeomTraits a model of `AnalyticWeightTraits_2` +*/ template -typename GeomTraits::FT discrete_harmonic_weight(const typename GeomTraits::Point_2& t, - const typename GeomTraits::Point_2& r, - const typename GeomTraits::Point_2& p, +typename GeomTraits::FT discrete_harmonic_weight(const typename GeomTraits::Point_2& p0, + const typename GeomTraits::Point_2& p1, + const typename GeomTraits::Point_2& p2, const typename GeomTraits::Point_2& q, const GeomTraits& traits) { using FT = typename GeomTraits::FT; auto squared_distance_2 = traits.compute_squared_distance_2_object(); + auto area_2 = traits.compute_area_2_object(); - const FT d1 = squared_distance_2(q, t); - const FT d2 = squared_distance_2(q, r); - const FT d3 = squared_distance_2(q, p); + const FT d0 = squared_distance_2(q, p0); + const FT d = squared_distance_2(q, p1); + const FT d2 = squared_distance_2(q, p2); - const FT A1 = internal::area_2(traits, r, q, t); - const FT A2 = internal::area_2(traits, p, q, r); - const FT B = internal::area_2(traits, p, q, t); + const FT A0 = area_2(p1, q, p0); + const FT A2 = area_2(p2, q, p1); + const FT B = area_2(p2, q, p0); - return discrete_harmonic_ns::weight(d1, d2, d3, A1, A2, B); + return discrete_harmonic_ns::weight(d0, d2, d, A0, A2, B); } -template -typename GeomTraits::FT discrete_harmonic_weight(const CGAL::Point_2& t, - const CGAL::Point_2& r, - const CGAL::Point_2& p, - const CGAL::Point_2& q) +/*! + \ingroup PkgWeightsRefDiscreteHarmonicWeights + \brief computes the discrete harmonic weight in 2D at `q` using the points `p0`, `p1`, and `p2`. + \tparam Kernel a model of `Kernel` +*/ +template +typename Kernel::FT discrete_harmonic_weight(const CGAL::Point_2& p0, + const CGAL::Point_2& p1, + const CGAL::Point_2& p2, + const CGAL::Point_2& q) { - const GeomTraits traits; - return discrete_harmonic_weight(t, r, p, q, traits); + const Kernel traits; + return discrete_harmonic_weight(p0, p1, p2, q, traits); } -namespace internal { +// 3D ============================================================================================== + +/// \cond SKIP_IN_MANUAL template -typename GeomTraits::FT discrete_harmonic_weight(const typename GeomTraits::Point_3& t, - const typename GeomTraits::Point_3& r, - const typename GeomTraits::Point_3& p, +typename GeomTraits::FT discrete_harmonic_weight(const typename GeomTraits::Point_3& p0, + const typename GeomTraits::Point_3& p1, + const typename GeomTraits::Point_3& p2, const typename GeomTraits::Point_3& q, const GeomTraits& traits) { using Point_2 = typename GeomTraits::Point_2; - Point_2 tf, rf, pf, qf; - internal::flatten(traits, - t, r, p, q, - tf, rf, pf, qf); - return CGAL::Weights::discrete_harmonic_weight(tf, rf, pf, qf, traits); + Point_2 p0f, p1f, p2f, qf; + internal::flatten(p0, p1, p2, q, + p0f, p1f, p2f, qf, + traits); + return discrete_harmonic_weight(p0f, p1f, p2f, qf, traits); } -template -typename GeomTraits::FT discrete_harmonic_weight(const CGAL::Point_3& t, - const CGAL::Point_3& r, - const CGAL::Point_3& p, - const CGAL::Point_3& q) +template +typename Kernel::FT discrete_harmonic_weight(const CGAL::Point_3& p0, + const CGAL::Point_3& p1, + const CGAL::Point_3& p2, + const CGAL::Point_3& q) { - const GeomTraits traits; - return discrete_harmonic_weight(t, r, p, q, traits); + const Kernel traits; + return discrete_harmonic_weight(p0, p1, p2, q, traits); } -} // namespace internal - /// \endcond /*! @@ -125,7 +140,7 @@ typename GeomTraits::FT discrete_harmonic_weight(const CGAL::Point_3 \tparam VertexRange a model of `ConstRange` whose iterator type is `RandomAccessIterator` \tparam GeomTraits a model of `AnalyticWeightTraits_2` \tparam PointMap a model of `ReadablePropertyMap` whose key type is `VertexRange::value_type` and - value type is `Point_2`. The default is `CGAL::Identity_property_map`. + value type is `Point_2`. The default is `CGAL::Identity_property_map`. \cgalModels `BarycentricWeights_2` */ @@ -341,9 +356,9 @@ private: \return an output iterator to the element in the destination range, one past the last weight stored - \pre polygon.size() >= 3 - \pre polygon is simple - \pre polygon is strictly convex + \pre `polygon.size() >= 3` + \pre `polygon` is simple + \pre `polygon` is strictly convex */ template OutIterator discrete_harmonic_weights_2(const PointRange& polygon, diff --git a/Weights/include/CGAL/Weights/inverse_distance_weights.h b/Weights/include/CGAL/Weights/inverse_distance_weights.h index 332d18f9c4a..34e7a69bddd 100644 --- a/Weights/include/CGAL/Weights/inverse_distance_weights.h +++ b/Weights/include/CGAL/Weights/inverse_distance_weights.h @@ -38,29 +38,53 @@ FT weight(const FT d) } // namespace inverse_distance_ns +/// \endcond + +/*! + \ingroup PkgWeightsRefInverseDistanceWeights + \brief computes the inverse distance weight in 2D using the points `p` and `q`. + \tparam GeomTraits a model of `AnalyticWeightTraits_2` +*/ template typename GeomTraits::FT inverse_distance_weight(const typename GeomTraits::Point_2&, - const typename GeomTraits::Point_2& r, + const typename GeomTraits::Point_2& p, const typename GeomTraits::Point_2&, const typename GeomTraits::Point_2& q, const GeomTraits& traits) { using FT = typename GeomTraits::FT; - const FT d = internal::distance_2(traits, q, r); + const FT d = internal::distance_2(p, q, traits); return inverse_distance_ns::weight(d); } -template -typename GeomTraits::FT inverse_distance_weight(const CGAL::Point_2& t, - const CGAL::Point_2& r, - const CGAL::Point_2& p, - const CGAL::Point_2& q) +/*! + \ingroup PkgWeightsRefInverseDistanceWeights + \brief computes the inverse distance weight in 2D using the points `p` and `q`. + \tparam Kernel a model of `Kernel` +*/ +template +#ifdef DOXYGEN_RUNNING +typename Kernel::FT inverse_distance_weight(const CGAL::Point_2&, + const CGAL::Point_2& p, + const CGAL::Point_2&, + const CGAL::Point_2& q) +#else +typename Kernel::FT inverse_distance_weight(const CGAL::Point_2& stub_l, + const CGAL::Point_2& p, + const CGAL::Point_2& stub_r, + const CGAL::Point_2& q) +#endif { - const GeomTraits traits; - return inverse_distance_weight(t, r, p, q, traits); + const Kernel traits; + return inverse_distance_weight(stub_l, p, stub_r, q, traits); } +/*! + \ingroup PkgWeightsRefInverseDistanceWeights + \brief computes the inverse distance weight in 2D using the points `p` and `q`. + \tparam GeomTraits a model of `AnalyticWeightTraits_2` +*/ template typename GeomTraits::FT inverse_distance_weight(const typename GeomTraits::Point_2& p, const typename GeomTraits::Point_2& q, @@ -70,37 +94,66 @@ typename GeomTraits::FT inverse_distance_weight(const typename GeomTraits::Point return inverse_distance_weight(stub, p, stub, q, traits); } -template -typename GeomTraits::FT inverse_distance_weight(const CGAL::Point_2& p, - const CGAL::Point_2& q) +/*! + \ingroup PkgWeightsRefInverseDistanceWeights + \brief computes the inverse distance weight in 2D using the points `p` and `q`. + \tparam Kernel a model of `Kernel` +*/ +template +typename Kernel::FT inverse_distance_weight(const CGAL::Point_2& p, + const CGAL::Point_2& q) { - CGAL::Point_2 stub; + CGAL::Point_2 stub; return inverse_distance_weight(stub, p, stub, q); } +// 3D ============================================================================================== + +/*! + \ingroup PkgWeightsRefInverseDistanceWeights + \brief computes the inverse distance weight in 3D using the points `p` and `q`. + \tparam GeomTraits a model of `AnalyticWeightTraits_3` +*/ template typename GeomTraits::FT inverse_distance_weight(const typename GeomTraits::Point_3&, - const typename GeomTraits::Point_3& r, + const typename GeomTraits::Point_3& p, const typename GeomTraits::Point_3&, const typename GeomTraits::Point_3& q, const GeomTraits& traits) { using FT = typename GeomTraits::FT; - const FT d = internal::distance_3(traits, q, r); + const FT d = internal::distance_3(p, q, traits); return inverse_distance_ns::weight(d); } -template -typename GeomTraits::FT inverse_distance_weight(const CGAL::Point_3& t, - const CGAL::Point_3& r, - const CGAL::Point_3& p, - const CGAL::Point_3& q) +/*! + \ingroup PkgWeightsRefInverseDistanceWeights + \brief computes the inverse distance weight in 3D using the points `p` and `q`. + \tparam Kernel a model of `Kernel` +*/ +template +#ifdef DOXYGEN_RUNNING +typename Kernel::FT inverse_distance_weight(const CGAL::Point_3&, + const CGAL::Point_3& p, + const CGAL::Point_3&, + const CGAL::Point_3& q) +#else +typename Kernel::FT inverse_distance_weight(const CGAL::Point_3& stub_l, + const CGAL::Point_3& p, + const CGAL::Point_3& stub_r, + const CGAL::Point_3& q) +#endif { - const GeomTraits traits; - return inverse_distance_weight(t, r, p, q, traits); + const Kernel traits; + return inverse_distance_weight(stub_l, p, stub_r, q, traits); } +/*! + \ingroup PkgWeightsRefInverseDistanceWeights + \brief computes the inverse distance weight in 3D using the points `p` and `q`. + \tparam GeomTraits a model of `AnalyticWeightTraits_3` +*/ template typename GeomTraits::FT inverse_distance_weight(const typename GeomTraits::Point_3& p, const typename GeomTraits::Point_3& q, @@ -110,16 +163,19 @@ typename GeomTraits::FT inverse_distance_weight(const typename GeomTraits::Point return inverse_distance_weight(stub, p, stub, q, traits); } -template -typename GeomTraits::FT inverse_distance_weight(const CGAL::Point_3& p, - const CGAL::Point_3& q) +/*! + \ingroup PkgWeightsRefInverseDistanceWeights + \brief computes the inverse distance weight in 3D using the points `p` and `q`. + \tparam Kernel a model of `Kernel` +*/ +template +typename Kernel::FT inverse_distance_weight(const CGAL::Point_3& p, + const CGAL::Point_3& q) { - CGAL::Point_3 stub; + CGAL::Point_3 stub; return inverse_distance_weight(stub, p, stub, q); } -/// \endcond - } // namespace Weights } // namespace CGAL diff --git a/Weights/include/CGAL/Weights/mean_value_weights.h b/Weights/include/CGAL/Weights/mean_value_weights.h index 3271db9cbb0..a7bd53e9d6c 100644 --- a/Weights/include/CGAL/Weights/mean_value_weights.h +++ b/Weights/include/CGAL/Weights/mean_value_weights.h @@ -32,12 +32,12 @@ namespace Weights { namespace mean_value_ns { template -FT sign_of_weight(const FT A1, const FT A2, const FT B) +FT sign_of_weight(const FT A0, const FT A2, const FT B) { - if (A1 > FT(0) && A2 > FT(0) && B <= FT(0)) + if (A0 > FT(0) && A2 > FT(0) && B <= FT(0)) return +FT(1); - if (A1 < FT(0) && A2 < FT(0) && B >= FT(0)) + if (A0 < FT(0) && A2 < FT(0) && B >= FT(0)) return -FT(1); if (B > FT(0)) @@ -50,112 +50,127 @@ FT sign_of_weight(const FT A1, const FT A2, const FT B) } template -typename GeomTraits::FT weight(const GeomTraits& traits, - const typename GeomTraits::FT r1, - const typename GeomTraits::FT r2, - const typename GeomTraits::FT r3, - const typename GeomTraits::FT D1, +typename GeomTraits::FT weight(const typename GeomTraits::FT d0, + const typename GeomTraits::FT d2, + const typename GeomTraits::FT d, + const typename GeomTraits::FT D0, const typename GeomTraits::FT D2, const typename GeomTraits::FT D, - const typename GeomTraits::FT sign) + const typename GeomTraits::FT sign, + const GeomTraits& traits) { using FT = typename GeomTraits::FT; using Get_sqrt = internal::Get_sqrt; auto sqrt = Get_sqrt::sqrt_object(traits); - const FT P1 = r1 * r2 + D1; - const FT P2 = r2 * r3 + D2; + const FT P1 = d * d0 + D0; + const FT P2 = d * d2 + D2; FT w = FT(0); CGAL_precondition(!is_zero(P1) && !is_zero(P2)); const FT prod = P1 * P2; if (!is_zero(prod)) { - const FT inv = FT(1) / prod; - w = FT(2) * (r1 * r3 - D) * inv; + w = FT(2) * (d0 * d2 - D) / prod; CGAL_assertion(w >= FT(0)); w = sqrt(w); } - w *= FT(2); w *= sign; + w *= sign * FT(2); return w; } } // namespace mean_value_ns +/// \endcond + +// 2D ============================================================================================== + +/*! + \ingroup PkgWeightsRefMeanValueWeights + \brief computes the mean value weight in 2D at `q` using the points `p0`, `p1`, and `p2`. + \tparam GeomTraits a model of `AnalyticWeightTraits_2` +*/ template -typename GeomTraits::FT mean_value_weight(const typename GeomTraits::Point_2& t, - const typename GeomTraits::Point_2& r, - const typename GeomTraits::Point_2& p, +typename GeomTraits::FT mean_value_weight(const typename GeomTraits::Point_2& p0, + const typename GeomTraits::Point_2& p1, + const typename GeomTraits::Point_2& p2, const typename GeomTraits::Point_2& q, const GeomTraits& traits) { using FT = typename GeomTraits::FT; using Vector_2 = typename GeomTraits::Vector_2; + auto vector_2 = traits.construct_vector_2_object(); auto dot_product_2 = traits.compute_scalar_product_2_object(); - auto construct_vector_2 = traits.construct_vector_2_object(); + auto area_2 = traits.compute_area_2_object(); - const Vector_2 v1 = construct_vector_2(q, t); - const Vector_2 v2 = construct_vector_2(q, r); - const Vector_2 v3 = construct_vector_2(q, p); + const Vector_2 v1 = vector_2(q, p0); + const Vector_2 v = vector_2(q, p1); + const Vector_2 v2 = vector_2(q, p2); - const FT l1 = internal::length_2(traits, v1); - const FT l2 = internal::length_2(traits, v2); - const FT l3 = internal::length_2(traits, v3); + const FT d0 = internal::length_2(v1, traits); + const FT d = internal::length_2(v, traits); + const FT d2 = internal::length_2(v2, traits); - const FT D1 = dot_product_2(v1, v2); - const FT D2 = dot_product_2(v2, v3); - const FT D = dot_product_2(v1, v3); + const FT D0 = dot_product_2(v1, v); + const FT D2 = dot_product_2(v, v2); + const FT D = dot_product_2(v1, v2); - const FT A1 = internal::area_2(traits, r, q, t); - const FT A2 = internal::area_2(traits, p, q, r); - const FT B = internal::area_2(traits, p, q, t); + const FT A0 = area_2(p1, q, p0); + const FT A2 = area_2(p2, q, p1); + const FT B = area_2(p2, q, p0); - const FT sign = mean_value_ns::sign_of_weight(A1, A2, B); - return mean_value_ns::weight(traits, l1, l2, l3, D1, D2, D, sign); + const FT sign = mean_value_ns::sign_of_weight(A0, A2, B); + return mean_value_ns::weight(d0, d2, d, D0, D2, D, sign, traits); } -template -typename GeomTraits::FT mean_value_weight(const CGAL::Point_2& t, - const CGAL::Point_2& r, - const CGAL::Point_2& p, - const CGAL::Point_2& q) +/*! + \ingroup PkgWeightsRefMeanValueWeights + \brief computes the mean value weight in 2D at `q` using the points `p0`, `p1`, and `p2`. + \tparam Kernel a model of `Kernel` +*/ +template +typename Kernel::FT mean_value_weight(const CGAL::Point_2& p0, + const CGAL::Point_2& p1, + const CGAL::Point_2& p2, + const CGAL::Point_2& q) { - const GeomTraits traits; - return mean_value_weight(t, r, p, q, traits); + const Kernel traits; + return mean_value_weight(p0, p1, p2, q, traits); } -namespace internal { +// 3D ============================================================================================== + +/// \cond SKIP_IN_MANUAL template -typename GeomTraits::FT mean_value_weight(const typename GeomTraits::Point_3& t, - const typename GeomTraits::Point_3& r, - const typename GeomTraits::Point_3& p, +typename GeomTraits::FT mean_value_weight(const typename GeomTraits::Point_3& p0, + const typename GeomTraits::Point_3& p1, + const typename GeomTraits::Point_3& p2, const typename GeomTraits::Point_3& q, const GeomTraits& traits) { using Point_2 = typename GeomTraits::Point_2; - Point_2 tf, rf, pf, qf; - internal::flatten(traits, - t, r, p, q, - tf, rf, pf, qf); - return CGAL::Weights::mean_value_weight(tf, rf, pf, qf, traits); + + Point_2 p0f, p1f, p2f, qf; + internal::flatten(p0, p1, p2, q, + p0f, p1f, p2f, qf, + traits); + return CGAL::Weights::mean_value_weight(p0f, p1f, p2f, qf, traits); } -template -typename GeomTraits::FT mean_value_weight(const CGAL::Point_3& t, - const CGAL::Point_3& r, - const CGAL::Point_3& p, - const CGAL::Point_3& q) +template +typename Kernel::FT mean_value_weight(const CGAL::Point_3& p0, + const CGAL::Point_3& p1, + const CGAL::Point_3& p2, + const CGAL::Point_3& q) { - const GeomTraits traits; - return mean_value_weight(t, r, p, q, traits); + const Kernel traits; + return mean_value_weight(p0, p1, p2, q, traits); } -} // namespace internal - /// \endcond /*! @@ -163,13 +178,12 @@ typename GeomTraits::FT mean_value_weight(const CGAL::Point_3& t, \brief 2D mean value weights for polygons. - This class implements 2D mean value weights ( \cite cgal:bc:hf-mvcapp-06, - \cite cgal:bc:fhk-gcbcocp-06, \cite cgal:f-mvc-03 ) which can be computed - at any point inside and outside a simple polygon. + This class implements 2D mean value weights (\cite cgal:bc:fhk-gcbcocp-06, \cite cgal:f-mvc-03, + \cite cgal:bc:hf-mvcapp-06) which can be computed at any point inside and outside a simple polygon. Mean value weights are well-defined inside and outside a simple polygon and are non-negative in the kernel of a star-shaped polygon. These weights are computed - analytically using the formulation from the `tangent_weight()`. + analytically using the formulation from `tangent_weight()`. \tparam VertexRange a model of `ConstRange` whose iterator type is `RandomAccessIterator` \tparam GeomTraits a model of `AnalyticWeightTraits_2` @@ -188,6 +202,7 @@ public: /// @{ /// \cond SKIP_IN_MANUAL + using Vertex_range = VertexRange; using Geom_traits = GeomTraits; using Point_map = PointMap; @@ -199,6 +214,7 @@ public: using Scalar_product_2 = typename GeomTraits::Compute_scalar_product_2; using Get_sqrt = internal::Get_sqrt; using Sqrt = typename Get_sqrt::Sqrt; + /// \endcond /// Number type. @@ -274,6 +290,7 @@ public: /// @} /// \cond SKIP_IN_MANUAL + template OutIterator operator()(const Point_2& query, OutIterator weights, @@ -414,11 +431,10 @@ private: \param traits a traits class with geometric objects, predicates, and constructions; this parameter can be omitted if the traits class can be deduced from the point type - \return an output iterator to the element in the destination range, - one past the last weight stored + \return an output iterator to the element in the destination range, one past the last weight stored - \pre polygon.size() >= 3 - \pre polygon is simple + \pre `polygon.size() >= 3` + \pre `polygon` is simple */ template typename GeomTraits::FT mixed_voronoi_area(const typename GeomTraits::Point_2& p, const typename GeomTraits::Point_2& q, @@ -49,11 +55,17 @@ typename GeomTraits::FT mixed_voronoi_area(const typename GeomTraits::Point_2& p const Point_2 m1 = midpoint_2(q, r); const Point_2 m2 = midpoint_2(q, p); - const FT A1 = internal::positive_area_2(traits, q, m1, center); - const FT A2 = internal::positive_area_2(traits, q, center, m2); + const FT A1 = internal::positive_area_2(q, m1, center, traits); + const FT A2 = internal::positive_area_2(q, center, m2, traits); + return A1 + A2; } +/*! + \ingroup PkgWeightsRefMixedVoronoiRegionWeights + \brief computes the area of the mixed Voronoi cell in 2D using the points `p`, `q`, and `r`. + \tparam Kernel a model of `Kernel` +*/ template typename GeomTraits::FT mixed_voronoi_area(const CGAL::Point_2& p, const CGAL::Point_2& q, @@ -63,6 +75,13 @@ typename GeomTraits::FT mixed_voronoi_area(const CGAL::Point_2& p, return mixed_voronoi_area(p, q, r, traits); } +// 3D ============================================================================================== + +/*! + \ingroup PkgWeightsRefMixedVoronoiRegionWeights + \brief computes the area of the mixed Voronoi cell in 3D using the points `p`, `q`, and `r`. + \tparam GeomTraits a model of `AnalyticWeightTraits_3` +*/ template typename GeomTraits::FT mixed_voronoi_area(const typename GeomTraits::Point_3& p, const typename GeomTraits::Point_3& q, @@ -89,22 +108,26 @@ typename GeomTraits::FT mixed_voronoi_area(const typename GeomTraits::Point_3& p const Point_3 m1 = midpoint_3(q, r); const Point_3 m2 = midpoint_3(q, p); - const FT A1 = internal::positive_area_3(traits, q, m1, center); - const FT A2 = internal::positive_area_3(traits, q, center, m2); + const FT A1 = internal::positive_area_3(q, m1, center, traits); + const FT A2 = internal::positive_area_3(q, center, m2, traits); + return A1 + A2; } -template -typename GeomTraits::FT mixed_voronoi_area(const CGAL::Point_3& p, - const CGAL::Point_3& q, - const CGAL::Point_3& r) +/*! + \ingroup PkgWeightsRefMixedVoronoiRegionWeights + \brief computes the area of the mixed Voronoi cell in 3D using the points `p`, `q`, and `r`. + \tparam Kernel a model of `Kernel` +*/ +template +typename Kernel::FT mixed_voronoi_area(const CGAL::Point_3& p, + const CGAL::Point_3& q, + const CGAL::Point_3& r) { - const GeomTraits traits; + const Kernel traits; return mixed_voronoi_area(p, q, r, traits); } -/// \endcond - } // namespace Weights } // namespace CGAL diff --git a/Weights/include/CGAL/Weights/shepard_weights.h b/Weights/include/CGAL/Weights/shepard_weights.h index 8c12d55687d..e510cbd6507 100644 --- a/Weights/include/CGAL/Weights/shepard_weights.h +++ b/Weights/include/CGAL/Weights/shepard_weights.h @@ -26,13 +26,9 @@ namespace Weights { namespace shepard_ns { -template -typename GeomTraits::FT weight(const GeomTraits& traits, - const typename GeomTraits::FT d, - const typename GeomTraits::FT p) +template +FT weight(const FT d, const FT p) { - using FT = typename GeomTraits::FT; - FT w = FT(0); CGAL_precondition(is_positive(d)); if(is_positive(d)) @@ -43,31 +39,57 @@ typename GeomTraits::FT weight(const GeomTraits& traits, } // namespace shepard_ns +/// \endcond + +// 2D ============================================================================================== + +/*! + \ingroup PkgWeightsRefShepardWeights + \brief computes the Shepard weight in 2D using the points `p` and `q` and the power parameter `a`. + \tparam GeomTraits a model of `AnalyticWeightTraits_2` +*/ template typename GeomTraits::FT shepard_weight(const typename GeomTraits::Point_2&, - const typename GeomTraits::Point_2& r, + const typename GeomTraits::Point_2& p, const typename GeomTraits::Point_2&, const typename GeomTraits::Point_2& q, const typename GeomTraits::FT a, const GeomTraits& traits) { using FT = typename GeomTraits::FT; - - const FT d = internal::distance_2(traits, q, r); - return shepard_ns::weight(traits, d, a); + const FT d = internal::distance_2(p, q, traits); + return shepard_ns::weight(d, a); } -template -typename GeomTraits::FT shepard_weight(const CGAL::Point_2& t, - const CGAL::Point_2& r, - const CGAL::Point_2& p, - const CGAL::Point_2& q, - const typename GeomTraits::FT a = typename GeomTraits::FT(1)) +/*! + \ingroup PkgWeightsRefShepardWeights + \brief computes the Shepard weight in 2D using the points `p` and `q`, and the power parameter `a` + \tparam Kernel a model of `Kernel` +*/ +template +#ifdef DOXYGEN_RUNNING +typename Kernel::FT shepard_weight(const CGAL::Point_2&, + const CGAL::Point_2& p^, + const CGAL::Point_2&, + const CGAL::Point_2& q, + const typename Kernel::FT a = {1}) +#else +typename Kernel::FT shepard_weight(const CGAL::Point_2& stub_l, + const CGAL::Point_2& p, + const CGAL::Point_2& stub_r, + const CGAL::Point_2& q, + const typename Kernel::FT a = {1}) +#endif { - const GeomTraits traits; - return shepard_weight(t, r, p, q, a, traits); + const Kernel traits; + return shepard_weight(stub_l, p, stub_r, q, a, traits); } +/*! + \ingroup PkgWeightsRefShepardWeights + \brief computes the Shepard weight in 2D using the points `p` and `q` and the power parameter `a`. + \tparam GeomTraits a model of `AnalyticWeightTraits_2` +*/ template typename GeomTraits::FT shepard_weight(const typename GeomTraits::Point_2& p, const typename GeomTraits::Point_2& q, @@ -78,39 +100,69 @@ typename GeomTraits::FT shepard_weight(const typename GeomTraits::Point_2& p, return shepard_weight(stub, p, stub, q, a, traits); } -template -typename GeomTraits::FT shepard_weight(const CGAL::Point_2& p, - const CGAL::Point_2& q, - const typename GeomTraits::FT a = typename GeomTraits::FT(1)) +/*! + \ingroup PkgWeightsRefShepardWeights + \brief computes the Shepard weight in 2D using the points `p` and `q`, and the power parameter `a`. + \tparam Kernel a model of `Kernel` +*/ +template +typename Kernel::FT shepard_weight(const CGAL::Point_2& p, + const CGAL::Point_2& q, + const typename Kernel::FT a = {1}) { - CGAL::Point_2 stub; + CGAL::Point_2 stub; return shepard_weight(stub, p, stub, q, a); } +// 3D ============================================================================================== + +/*! + \ingroup PkgWeightsRefShepardWeights + \brief computes the Shepard weight in 3D using the points `p` and `q` and the power parameter `a`. + \tparam GeomTraits a model of `AnalyticWeightTraits_3` +*/ template typename GeomTraits::FT shepard_weight(const typename GeomTraits::Point_3&, - const typename GeomTraits::Point_3& r, + const typename GeomTraits::Point_3& p, const typename GeomTraits::Point_3&, const typename GeomTraits::Point_3& q, const typename GeomTraits::FT a, const GeomTraits& traits) { using FT = typename GeomTraits::FT; - const FT d = internal::distance_3(traits, q, r); - return shepard_ns::weight(traits, d, a); + const FT d = internal::distance_3(p, q, traits); + return shepard_ns::weight(d, a); } -template -typename GeomTraits::FT shepard_weight(const CGAL::Point_3& t, - const CGAL::Point_3& r, - const CGAL::Point_3& p, - const CGAL::Point_3& q, - const typename GeomTraits::FT a = typename GeomTraits::FT(1)) +/*! + \ingroup PkgWeightsRefShepardWeights + \brief computes the Shepard weight in 3D using the points `p` and `q`, and the power parameter `a`. + \tparam Kernel a model of `Kernel` +*/ +template +#ifdef DOXYGEN_RUNNING +typename Kernel::FT shepard_weight(const CGAL::Point_3& p, + const CGAL::Point_3&, + const CGAL::Point_3& q, + const CGAL::Point_3&, + const typename Kernel::FT a = {1}) +#else +typename Kernel::FT shepard_weight(const CGAL::Point_3& stub_l, + const CGAL::Point_3& p, + const CGAL::Point_3& stub_r, + const CGAL::Point_3& q, + const typename Kernel::FT a = {1}) +#endif { - const GeomTraits traits; - return shepard_weight(t, r, p, q, a, traits); + const Kernel traits; + return shepard_weight(stub_l, p, stub_r, q, a, traits); } +/*! + \ingroup PkgWeightsRefShepardWeights + \brief computes the Shepard weight in 3D using the points `p` and `q` and the power parameter `a`. + \tparam GeomTraits a model of `AnalyticWeightTraits_3` +*/ template typename GeomTraits::FT shepard_weight(const typename GeomTraits::Point_3& p, const typename GeomTraits::Point_3& q, @@ -121,17 +173,20 @@ typename GeomTraits::FT shepard_weight(const typename GeomTraits::Point_3& p, return shepard_weight(stub, p, stub, q, a, traits); } -template -typename GeomTraits::FT shepard_weight(const CGAL::Point_3& p, - const CGAL::Point_3& q, - const typename GeomTraits::FT a = typename GeomTraits::FT(1)) +/*! + \ingroup PkgWeightsRefShepardWeights + \brief computes the Shepard weight in 3D using the points `p` and `q`, and the power parameter `a`. + \tparam Kernel a model of `Kernel` +*/ +template +typename Kernel::FT shepard_weight(const CGAL::Point_3& p, + const CGAL::Point_3& q, + const typename Kernel::FT a = {1}) { - CGAL::Point_3 stub; + CGAL::Point_3 stub; return shepard_weight(stub, p, stub, q, a); } -/// \endcond - } // namespace Weights } // namespace CGAL diff --git a/Weights/include/CGAL/Weights/tangent_weights.h b/Weights/include/CGAL/Weights/tangent_weights.h index 4c4260314fd..119dee11623 100644 --- a/Weights/include/CGAL/Weights/tangent_weights.h +++ b/Weights/include/CGAL/Weights/tangent_weights.h @@ -40,32 +40,33 @@ FT half_weight(const FT t, const FT r) } template -FT weight(const FT t1, const FT t2, const FT r) +FT weight(const FT t0, const FT t2, const FT r) { FT w = FT(0); CGAL_precondition(r != FT(0)); if (r != FT(0)) - w = FT(2) * (t1 + t2) / r; + w = FT(2) * (t0 + t2) / r; return w; } template -FT weight(const FT d1, const FT d, const FT d2, - const FT A1, const FT A2, - const FT D1, const FT D2) +FT weight(const FT d0, const FT d2, const FT d, + const FT A0, const FT A2, + const FT D0, const FT D2) { - const FT P1 = d1 * d + D1; - const FT P2 = d2 * d + D2; + const FT P0 = d * d0 + D0; + const FT P2 = d * d2 + D2; FT w = FT(0); - CGAL_precondition(!is_zero(P1) && !is_zero(P2)); - if (!is_zero(P1) && !is_zero(P2)) + CGAL_precondition(!is_zero(P0) && !is_zero(P2)); + if (!is_zero(P0) && !is_zero(P2)) { - const FT t1 = FT(2) * A1 / P1; + const FT t0 = FT(2) * A0 / P0; const FT t2 = FT(2) * A2 / P2; - w = weight(t1, t2, d); + w = weight(t0, t2, d); } + return w; } @@ -73,9 +74,9 @@ FT weight(const FT d1, const FT d, const FT d2, // This version is based on the positive area. // This version is more precise for all positive cases. template -typename GeomTraits::FT tangent_weight_v1(const typename GeomTraits::Point_3& t, - const typename GeomTraits::Point_3& r, - const typename GeomTraits::Point_3& p, +typename GeomTraits::FT tangent_weight_v1(const typename GeomTraits::Point_3& p0, + const typename GeomTraits::Point_3& p1, + const typename GeomTraits::Point_3& p2, const typename GeomTraits::Point_3& q, const GeomTraits& traits) { @@ -83,92 +84,62 @@ typename GeomTraits::FT tangent_weight_v1(const typename GeomTraits::Point_3& t, using Vector_3 = typename GeomTraits::Vector_3; auto dot_product_3 = traits.compute_scalar_product_3_object(); - auto construct_vector_3 = traits.construct_vector_3_object(); + auto vector_3 = traits.construct_vector_3_object(); - const Vector_3 v1 = construct_vector_3(q, t); - const Vector_3 v2 = construct_vector_3(q, r); - const Vector_3 v3 = construct_vector_3(q, p); + const Vector_3 v0 = vector_3(q, p0); + const Vector_3 v = vector_3(q, p1); + const Vector_3 v2 = vector_3(q, p2); - const FT l1 = internal::length_3(traits, v1); - const FT l2 = internal::length_3(traits, v2); - const FT l3 = internal::length_3(traits, v3); + const FT d0 = internal::length_3(v0, traits); + const FT d = internal::length_3(v, traits); + const FT d2 = internal::length_3(v2, traits); - const FT A1 = internal::positive_area_3(traits, r, q, t); - const FT A2 = internal::positive_area_3(traits, p, q, r); + const FT A0 = internal::positive_area_3(p1, q, p0, traits); + const FT A2 = internal::positive_area_3(p2, q, p1, traits); - const FT D1 = dot_product_3(v1, v2); - const FT D2 = dot_product_3(v2, v3); + const FT D0 = dot_product_3(v0, v); + const FT D2 = dot_product_3(v, v2); - return weight(l1, l2, l3, A1, A2, D1, D2); + return weight(d0, d2, d, A0, A2, D0, D2); } // This version handles both positive and negative cases. // However, it is less precise. template -typename GeomTraits::FT tangent_weight_v2(const typename GeomTraits::Point_3& t, - const typename GeomTraits::Point_3& r, - const typename GeomTraits::Point_3& p, +typename GeomTraits::FT tangent_weight_v2(const typename GeomTraits::Point_3& p0, + const typename GeomTraits::Point_3& p1, + const typename GeomTraits::Point_3& p2, const typename GeomTraits::Point_3& q, const GeomTraits& traits) { using FT = typename GeomTraits::FT; using Vector_3 = typename GeomTraits::Vector_3; - auto construct_vector_3 = traits.construct_vector_3_object(); + auto vector_3 = traits.construct_vector_3_object(); - Vector_3 v1 = construct_vector_3(q, t); - Vector_3 v2 = construct_vector_3(q, r); - Vector_3 v3 = construct_vector_3(q, p); + Vector_3 v0 = vector_3(q, p0); + Vector_3 v = vector_3(q, p1); + Vector_3 v2 = vector_3(q, p2); - const FT l2 = internal::length_3(traits, v2); + const FT l2 = internal::length_3(v, traits); - internal::normalize_3(traits, v1); - internal::normalize_3(traits, v2); - internal::normalize_3(traits, v3); + internal::normalize_3(v0, traits); + internal::normalize_3(v, traits); + internal::normalize_3(v2, traits); - const double ha_rad_1 = internal::angle_3(traits, v1, v2) / 2.0; - const double ha_rad_2 = internal::angle_3(traits, v2, v3) / 2.0; - const FT t1 = static_cast(std::tan(ha_rad_1)); + const double ha_rad_1 = internal::angle_3(v0, v, traits) / 2.0; + const double ha_rad_2 = internal::angle_3(v, v2, traits) / 2.0; + const FT t0 = static_cast(std::tan(ha_rad_1)); const FT t2 = static_cast(std::tan(ha_rad_2)); - return weight(t1, t2, l2); + return weight(t0, t2, l2); } } // namespace tangent_ns /// \endcond -/*! - \ingroup PkgWeightsRefTangentWeights - - \brief computes the tangent of the half angle. - - This function computes the tangent of the half angle using the precomputed - distance, area, and dot product values. The returned value is - \f$\frac{2\textbf{A}}{\textbf{d}\textbf{d_1} + \textbf{D_1}}\f$. - - \tparam FT a model of `FieldNumberType` - - \param d1 the first distance value - \param d2 the second distance value - \param A the area value - \param D the dot product value - - \pre (d1 * d2 + D) != 0 - - \sa `half_tangent_weight()` -*/ -template -FT tangent_half_angle(const FT d1, const FT d2, const FT A, const FT D) -{ - FT t = FT(0); - const FT P = d1 * d2 + D; - CGAL_precondition(!is_zero(P)); - if (!is_zero(P)) - t = FT(2) * A / P; - - return t; -} +// 2D ============================================================================================== /*! \ingroup PkgWeightsRefTangentWeights @@ -195,6 +166,42 @@ FT half_tangent_weight(const FT tan05, const FT d) return tangent_ns::half_weight(tan05, d); } +/*! + \ingroup PkgWeightsRefTangentWeights + + \brief computes the tangent of the half angle. + + This function computes the tangent of the half angle using the precomputed + distance, area, and dot product values. The returned value is + \f$\frac{2\textbf{A}}{\textbf{d}\textbf{l} + \textbf{D}}\f$. + + \tparam FT a model of `FieldNumberType` + + \param d the distance value + \param l the distance value + \param A the area value + \param D the dot product value + + \pre (d * l + D) != 0 + + \sa `half_tangent_weight()` +*/ +template +FT tangent_half_angle(const FT d, const FT l, const FT A, const FT D) +{ + // tan(theta/2) = sin(theta) / ( 1 + cos(theta) ), also = (1 - cos(theta)) / sin(theta). + // = ( 2*A / |v1|*|v2| ) / ( 1 + v1.v2 / |v1|*|v2| ) + // = 2*A / ( |v1|*|v2| + v1.v2 ) + + FT t = FT(0); + const FT P = d * l + D; + CGAL_precondition(!is_zero(P)); + if (!is_zero(P)) + t = FT(2) * A / P; + + return t; +} + /*! \ingroup PkgWeightsRefTangentWeights @@ -224,65 +231,138 @@ FT half_tangent_weight(const FT d, const FT l, const FT A, const FT D) } /// \cond SKIP_IN_MANUAL + template -typename GeomTraits::FT tangent_weight(const typename GeomTraits::Point_2& t, - const typename GeomTraits::Point_2& r, - const typename GeomTraits::Point_2& p, +typename GeomTraits::FT half_tangent_weight(const typename GeomTraits::Point_2& p0, + const typename GeomTraits::Point_2& q, + const typename GeomTraits::Point_2& p2, + const GeomTraits& traits) +{ + using FT = typename GeomTraits::FT; + + auto vector_2 = traits.construct_vector_2_object(); + auto dot_product_2 = traits.compute_scalar_product_2_object(); + auto area_2 = traits.compute_area_2_object(); + + const Vector_2 v0 = vector_2(q, p0); + const Vector_2 v2 = vector_2(q, p2); + + const FT l0 = internal::length_2(v0, traits); + const FT l2 = internal::length_2(v2, traits); + const FT A = area_2(p2, q, p0); + const FT D = dot_product_2(v0, v2); + + return half_tangent_weight(l0, l2, A, D); +} + +template +typename GeomTraits::FT half_tangent_weight(const typename GeomTraits::Point_3& p0, + const typename GeomTraits::Point_3& q, + const typename GeomTraits::Point_3& p2, + const GeomTraits& traits) +{ + using FT = typename GeomTraits::FT; + + auto vector_3 = traits.construct_vector_3_object(); + auto dot_product_3 = traits.compute_scalar_product_3_object(); + + const Vector_3 v0 = vector_3(q, p0); + const Vector_3 v2 = vector_3(q, p2); + + const FT l0 = internal::length_3(v0, traits); + const FT l2 = internal::length_3(v2, traits); + const FT A = internal::area_3(p2, q, p0, traits); + const FT D = dot_product_3(v0, v2); + + return half_tangent_weight(l0, l2, A, D); +} + +/// \endcond + +// 2D ============================================================================================== + +/*! + \ingroup PkgWeightsRefTangentWeights + \brief computes the tangent weight in 2D at `q` using the points `p0`, `p1`, and `p2` + \tparam GeomTraits a model of `AnalyticWeightTraits_2` +*/ +template +typename GeomTraits::FT tangent_weight(const typename GeomTraits::Point_2& p0, + const typename GeomTraits::Point_2& p1, + const typename GeomTraits::Point_2& p2, const typename GeomTraits::Point_2& q, const GeomTraits& traits) { using FT = typename GeomTraits::FT; using Vector_2 = typename GeomTraits::Vector_2; + auto vector_2 = traits.construct_vector_2_object(); auto dot_product_2 = traits.compute_scalar_product_2_object(); - auto construct_vector_2 = traits.construct_vector_2_object(); + auto area_2 = traits.compute_area_2_object(); - const Vector_2 v1 = construct_vector_2(q, t); - const Vector_2 v2 = construct_vector_2(q, r); - const Vector_2 v3 = construct_vector_2(q, p); + const Vector_2 v0 = vector_2(q, p0); + const Vector_2 v = vector_2(q, p1); + const Vector_2 v2 = vector_2(q, p2); - const FT l1 = internal::length_2(traits, v1); - const FT l2 = internal::length_2(traits, v2); - const FT l3 = internal::length_2(traits, v3); + const FT l0 = internal::length_2(v0, traits); + const FT l = internal::length_2(v, traits); + const FT l2 = internal::length_2(v2, traits); - const FT A1 = internal::area_2(traits, r, q, t); - const FT A2 = internal::area_2(traits, p, q, r); + const FT A0 = area_2(p1, q, p0); + const FT A2 = area_2(p2, q, p1); - const FT D1 = dot_product_2(v1, v2); - const FT D2 = dot_product_2(v2, v3); + const FT D0 = dot_product_2(v0, v); + const FT D2 = dot_product_2(v, v2); - return tangent_ns::weight(l1, l2, l3, A1, A2, D1, D2); + return tangent_ns::weight(l0, l2, l, A0, A2, D0, D2); } -template -typename GeomTraits::FT tangent_weight(const CGAL::Point_2& t, - const CGAL::Point_2& r, - const CGAL::Point_2& p, - const CGAL::Point_2& q) +/*! + \ingroup PkgWeightsRefTangentWeights + \brief computes the tangent weight in 2D at `q` using the points `p0`, `p1`, and `p2` + \tparam Kernel a model of `Kernel` +*/ +template +typename Kernel::FT tangent_weight(const CGAL::Point_2& p0, + const CGAL::Point_2& p1, + const CGAL::Point_2& p2, + const CGAL::Point_2& q) { - const GeomTraits traits; - return tangent_weight(t, r, p, q, traits); + const Kernel traits; + return tangent_weight(p0, p1, p2, q, traits); } +// 3D ============================================================================================== + +/*! + \ingroup PkgWeightsRefTangentWeights + \brief computes the tangent weight in 3D at `q` using the points `p0`, `p1`, and `p2` + \tparam GeomTraits a model of `AnalyticWeightTraits_3` +*/ template -typename GeomTraits::FT tangent_weight(const typename GeomTraits::Point_3& t, - const typename GeomTraits::Point_3& r, - const typename GeomTraits::Point_3& p, +typename GeomTraits::FT tangent_weight(const typename GeomTraits::Point_3& p0, + const typename GeomTraits::Point_3& p1, + const typename GeomTraits::Point_3& p2, const typename GeomTraits::Point_3& q, const GeomTraits& traits) { - // return tangent_ns::tangent_weight_v1(t, r, p, q, traits); - return tangent_ns::tangent_weight_v2(t, r, p, q, traits); +// return tangent_ns::tangent_weight_v1(p0, p1, p2, q, traits); + return tangent_ns::tangent_weight_v2(p0, p1, p2, q, traits); } -template -typename GeomTraits::FT tangent_weight(const CGAL::Point_3& t, - const CGAL::Point_3& r, - const CGAL::Point_3& p, - const CGAL::Point_3& q) +/*! + \ingroup PkgWeightsRefTangentWeights + \brief computes the tangent weight in 3D at `q` using the points `p0`, `p1`, and `p2` + \tparam Kernel a model of `Kernel` +*/ +template +typename Kernel::FT tangent_weight(const CGAL::Point_3& p0, + const CGAL::Point_3& p1, + const CGAL::Point_3& p2, + const CGAL::Point_3& q) { - const GeomTraits traits; - return tangent_weight(t, r, p, q, traits); + const Kernel traits; + return tangent_weight(p0, p1, p2, q, traits); } // Undocumented tangent weight class. diff --git a/Weights/include/CGAL/Weights/three_point_family_weights.h b/Weights/include/CGAL/Weights/three_point_family_weights.h index f5b08ce9c48..51bdf0eeb51 100644 --- a/Weights/include/CGAL/Weights/three_point_family_weights.h +++ b/Weights/include/CGAL/Weights/three_point_family_weights.h @@ -26,90 +26,109 @@ namespace Weights { namespace three_point_family_ns { template -FT weight(const FT d1, const FT d2, const FT d, - const FT A1, const FT A2, const FT B, +FT weight(const FT d0, const FT d2, const FT d, + const FT A0, const FT A2, const FT B, const FT p) { FT w = FT(0); - CGAL_precondition(!is_zero(A1) && !is_zero(A2)); - const FT prod = A1 * A2; + CGAL_precondition(!is_zero(A0) && !is_zero(A2)); + const FT prod = A0 * A2; if (!is_zero(prod)) { - const FT r1 = internal::power(d1, p); + const FT r0 = internal::power(d0, p); + const FT r = internal::power(d , p); const FT r2 = internal::power(d2, p); - const FT r = internal::power(d , p); - w = (r2 * A1 - r * B + r1 * A2) / prod; + w = (r2 * A0 - r * B + r0 * A2) / prod; } return w; } } // namespace three_point_family_ns +/// \endcond + +// 2D ============================================================================================== + +/*! + \ingroup PkgWeightsRefThreePointFamilyWeights + \brief computes the three-point family weight in 2D at `q` using the points `p0`, `p1` and `p2`, + and the power parameter `a`. + \tparam GeomTraits a model of `AnalyticWeightTraits_2` +*/ template -typename GeomTraits::FT three_point_family_weight(const typename GeomTraits::Point_2& t, - const typename GeomTraits::Point_2& r, - const typename GeomTraits::Point_2& p, +typename GeomTraits::FT three_point_family_weight(const typename GeomTraits::Point_2& p0, + const typename GeomTraits::Point_2& p1, + const typename GeomTraits::Point_2& p2, const typename GeomTraits::Point_2& q, const typename GeomTraits::FT a, const GeomTraits& traits) { using FT = typename GeomTraits::FT; - const FT d1 = internal::distance_2(traits, q, t); - const FT d2 = internal::distance_2(traits, q, r); - const FT d3 = internal::distance_2(traits, q, p); + auto area_2 = traits.compute_area_2_object(); - const FT A1 = internal::area_2(traits, r, q, t); - const FT A2 = internal::area_2(traits, p, q, r); - const FT B = internal::area_2(traits, p, q, t); + const FT d0 = internal::distance_2(q, p0, traits); + const FT d = internal::distance_2(q, p1, traits); + const FT d2 = internal::distance_2(q, p2, traits); - return three_point_family_ns::weight(traits, d1, d2, d3, A1, A2, B, a); + const FT A0 = area_2(p1, q, p0); + const FT A2 = area_2(p2, q, p1); + const FT B = area_2(p2, q, p0); + + return three_point_family_ns::weight(d0, d2, d, A0, A2, B, a); } -template -typename GeomTraits::FT three_point_family_weight(const CGAL::Point_2& t, - const CGAL::Point_2& r, - const CGAL::Point_2& p, - const CGAL::Point_2& q, - const typename GeomTraits::FT a = typename GeomTraits::FT(1)) +/*! + \ingroup PkgWeightsRefThreePointFamilyWeights + \brief computes the three-point family weight in 2D at `q` using the points `p0`, `p1` and `p2`, + and the power parameter `a`. + \tparam Kernel a model of `Kernel` +*/ +template +typename Kernel::FT three_point_family_weight(const CGAL::Point_2& p0, + const CGAL::Point_2& p1, + const CGAL::Point_2& p2, + const CGAL::Point_2& q, + const typename Kernel::FT a = {1}) { - const GeomTraits traits; - return three_point_family_weight(t, r, p, q, a, traits); + const Kernel traits; + return three_point_family_weight(p0, p1, p2, q, a, traits); } -namespace internal { +// 3D ============================================================================================== + +/// \cond SKIP_IN_MANUAL template -typename GeomTraits::FT three_point_family_weight(const typename GeomTraits::Point_3& t, - const typename GeomTraits::Point_3& r, - const typename GeomTraits::Point_3& p, +typename GeomTraits::FT three_point_family_weight(const typename GeomTraits::Point_3& p0, + const typename GeomTraits::Point_3& p1, + const typename GeomTraits::Point_3& p2, const typename GeomTraits::Point_3& q, const typename GeomTraits::FT a, const GeomTraits& traits) { using Point_2 = typename GeomTraits::Point_2; - Point_2 tf, rf, pf, qf; - internal::flatten(traits, - t, r, p, q, - tf, rf, pf, qf); - return CGAL::Weights::three_point_family_weight(tf, rf, pf, qf, a, traits); + Point_2 p0f, p1f, p2f, qf; + internal::flatten(p0, p1, p2 , q, + p0f, p1f, p2f, qf, + traits); + + return CGAL::Weights::three_point_family_weight(p0f, p1f, p2f, qf, a, traits); } -template -typename GeomTraits::FT three_point_family_weight(const CGAL::Point_3& t, - const CGAL::Point_3& r, - const CGAL::Point_3& p, - const CGAL::Point_3& q, - const typename GeomTraits::FT a = typename GeomTraits::FT(1)) +template +typename Kernel::FT three_point_family_weight(const CGAL::Point_3& p0, + const CGAL::Point_3& p1, + const CGAL::Point_3& p2, + const CGAL::Point_3& q, + const typename Kernel::FT a = {1}) { - const GeomTraits traits; - return three_point_family_weight(t, r, p, q, a, traits); + const Kernel traits; + return three_point_family_weight(p0, p1, p2, q, a, traits); } -} // namespace internal - /// \endcond } // namespace Weights diff --git a/Weights/include/CGAL/Weights/triangular_region_weights.h b/Weights/include/CGAL/Weights/triangular_region_weights.h index 9e0f7d2facd..aa4b20a567a 100644 --- a/Weights/include/CGAL/Weights/triangular_region_weights.h +++ b/Weights/include/CGAL/Weights/triangular_region_weights.h @@ -22,45 +22,66 @@ namespace CGAL { namespace Weights { -/// \cond SKIP_IN_MANUAL +// 2D ============================================================================================== + +/*! + \ingroup PkgWeightsRefTriangularRegionWeights + \brief computes the area of the triangular cell in 2D using the points `p`, `q`, and `r` + \tparam GeomTraits a model of `AnalyticWeightTraits_2` +*/ template typename GeomTraits::FT triangular_area(const typename GeomTraits::Point_2& p, const typename GeomTraits::Point_2& q, const typename GeomTraits::Point_2& r, const GeomTraits& traits) { - return internal::positive_area_2(traits, p, q, r); + return internal::positive_area_2(p, q, r, traits); } -template -typename GeomTraits::FT triangular_area(const CGAL::Point_2& p, - const CGAL::Point_2& q, - const CGAL::Point_2& r) +/*! + \ingroup PkgWeightsRefTriangularRegionWeights + \brief computes the area of the triangular cell in 2D using the points `p`, `q`, and `r`. + \tparam Kernel a model of `Kernel` +*/ +template +typename Kernel::FT triangular_area(const CGAL::Point_2& p, + const CGAL::Point_2& q, + const CGAL::Point_2& r) { - const GeomTraits traits; + const Kernel traits; return triangular_area(p, q, r, traits); } +// 3D ============================================================================================== + +/*! + \ingroup PkgWeightsRefTriangularRegionWeights + \brief computes the area of the triangular cell in 3D using the points `p`, `q`, and `r`. + \tparam GeomTraits a model of `AnalyticWeightTraits_3` +*/ template typename GeomTraits::FT triangular_area(const typename GeomTraits::Point_3& p, const typename GeomTraits::Point_3& q, const typename GeomTraits::Point_3& r, const GeomTraits& traits) { - return internal::positive_area_3(traits, p, q, r); + return internal::positive_area_3(p, q, r, traits); } -template -typename GeomTraits::FT triangular_area(const CGAL::Point_3& p, - const CGAL::Point_3& q, - const CGAL::Point_3& r) +/*! + \ingroup PkgWeightsRefTriangularRegionWeights + \brief computes the area of the triangular cell in 3D using the points `p`, `q`, and `r`. + \tparam Kernel a model of `Kernel` +*/ +template +typename Kernel::FT triangular_area(const CGAL::Point_3& p, + const CGAL::Point_3& q, + const CGAL::Point_3& r) { - const GeomTraits traits; + const Kernel traits; return triangular_area(p, q, r, traits); } -/// \endcond - } // namespace Weights } // namespace CGAL diff --git a/Weights/include/CGAL/Weights/uniform_region_weights.h b/Weights/include/CGAL/Weights/uniform_region_weights.h index a7035fcccdd..6ed0f0726b8 100644 --- a/Weights/include/CGAL/Weights/uniform_region_weights.h +++ b/Weights/include/CGAL/Weights/uniform_region_weights.h @@ -20,7 +20,13 @@ namespace CGAL { namespace Weights { -/// \cond SKIP_IN_MANUAL +// 2D ============================================================================================== + +/*! + \ingroup PkgWeightsRefUniformRegionWeights + \brief this function always returns `1`, given three 2D points. + \tparam GeomTraits a model of `AnalyticWeightTraits_2` +*/ template typename GeomTraits::FT uniform_area(const typename GeomTraits::Point_2&, const typename GeomTraits::Point_2&, @@ -31,15 +37,27 @@ typename GeomTraits::FT uniform_area(const typename GeomTraits::Point_2&, return FT(1); } -template -typename GeomTraits::FT uniform_area(const CGAL::Point_2& p, - const CGAL::Point_2& q, - const CGAL::Point_2& r) +/*! + \ingroup PkgWeightsRefUniformRegionWeights + \brief this function always returns `1`, given three 2D points in 2D. + \tparam Kernel a model of `Kernel` +*/ +template +typename Kernel::FT uniform_area(const CGAL::Point_2& p, + const CGAL::Point_2& q, + const CGAL::Point_2& r) { - const GeomTraits traits; + const Kernel traits; return uniform_area(p, q, r, traits); } +// 3D ============================================================================================== + +/*! + \ingroup PkgWeightsRefUniformRegionWeights + \brief this function always returns `1`, given three 3D points. + \tparam GeomTraits a model of `AnalyticWeightTraits_3` +*/ template typename GeomTraits::FT uniform_area(const typename GeomTraits::Point_3&, const typename GeomTraits::Point_3&, @@ -50,17 +68,20 @@ typename GeomTraits::FT uniform_area(const typename GeomTraits::Point_3&, return FT(1); } -template -typename GeomTraits::FT uniform_area(const CGAL::Point_3& p, - const CGAL::Point_3& q, - const CGAL::Point_3& r) +/*! + \ingroup PkgWeightsRefUniformRegionWeights + \brief this function always returns `1`, given three 3D points. + \tparam Kernel a model of `Kernel` +*/ +template +typename Kernel::FT uniform_area(const CGAL::Point_3& p, + const CGAL::Point_3& q, + const CGAL::Point_3& r) { - const GeomTraits traits; + const Kernel traits; return uniform_area(p, q, r, traits); } -/// \endcond - } // namespace Weights } // namespace CGAL diff --git a/Weights/include/CGAL/Weights/uniform_weights.h b/Weights/include/CGAL/Weights/uniform_weights.h index be69470d143..541dd95937a 100644 --- a/Weights/include/CGAL/Weights/uniform_weights.h +++ b/Weights/include/CGAL/Weights/uniform_weights.h @@ -22,51 +22,68 @@ namespace CGAL { namespace Weights { -/// \cond SKIP_IN_MANUAL -template -typename GeomTraits::FT uniform_weight( - const typename GeomTraits::Point_2&, - const typename GeomTraits::Point_2&, - const typename GeomTraits::Point_2&, - const typename GeomTraits::Point_2&, - const GeomTraits&) { +// 2D ============================================================================================== - using FT = typename GeomTraits::FT; - return FT(1); +/*! + \ingroup PkgWeightsRefUniformWeights + \brief returns `1`. + \tparam GeomTraits a model of `AnalyticWeightTraits_2` +*/ +template +typename GeomTraits::FT uniform_weight(const typename GeomTraits::Point_2&, + const typename GeomTraits::Point_2&, + const typename GeomTraits::Point_2&, + const typename GeomTraits::Point_2&, + const GeomTraits&) +{ + return {1}; } +/*! + \ingroup PkgWeightsRefUniformWeights + \brief returns `1`. + \tparam Kernel a model of `Kernel` +*/ template -typename GeomTraits::FT uniform_weight( - const CGAL::Point_2& q, - const CGAL::Point_2& t, - const CGAL::Point_2& r, - const CGAL::Point_2& p) { - +typename GeomTraits::FT uniform_weight(const CGAL::Point_2& p0, + const CGAL::Point_2& p1, + const CGAL::Point_2& p2, + const CGAL::Point_2& q) +{ const GeomTraits traits; - return uniform_weight(q, t, r, p, traits); + return uniform_weight(p0, p1, p2, q, traits); } -template -typename GeomTraits::FT uniform_weight( - const typename GeomTraits::Point_3&, - const typename GeomTraits::Point_3&, - const typename GeomTraits::Point_3&, - const typename GeomTraits::Point_3&, - const GeomTraits&) { +// 3D ============================================================================================== - using FT = typename GeomTraits::FT; - return FT(1); +/*! + \ingroup PkgWeightsRefUniformWeights + \brief returns `1`. + \tparam GeomTraits a model of `AnalyticWeightTraits_2` +*/ +template +typename GeomTraits::FT uniform_weight(const typename GeomTraits::Point_3&, + const typename GeomTraits::Point_3&, + const typename GeomTraits::Point_3&, + const typename GeomTraits::Point_3&, + const GeomTraits&) +{ + return {1}; } +/*! + \ingroup PkgWeightsRefUniformWeights + \brief returns `1`. + \tparam Kernel a model of `Kernel` +*/ template -typename GeomTraits::FT uniform_weight( - const CGAL::Point_3& q, - const CGAL::Point_3& t, - const CGAL::Point_3& r, - const CGAL::Point_3& p) { - +typename GeomTraits::FT uniform_weight(const CGAL::Point_3& p0, + const CGAL::Point_3& p1, + const CGAL::Point_3& p2, + const CGAL::Point_3& q) +{ const GeomTraits traits; - return uniform_weight(q, t, r, p, traits); + return uniform_weight(p0, p1, p2, q, traits); } // Undocumented uniform weight class taking as input a polygon mesh. @@ -85,8 +102,6 @@ public: double w_ij(halfedge_descriptor) { return 1.; } }; -/// \endcond - } // namespace Weights } // namespace CGAL diff --git a/Weights/include/CGAL/Weights/utils.h b/Weights/include/CGAL/Weights/utils.h index 43c0a0945da..9f75bd14854 100644 --- a/Weights/include/CGAL/Weights/utils.h +++ b/Weights/include/CGAL/Weights/utils.h @@ -214,6 +214,11 @@ typename Kernel::FT tangent(const CGAL::Point_3& p, return tangent(p, q, r, traits); } +// ================================================================================================= + +// Computes a clamped cotangent between two 3D vectors. +// In the old version of weights in PMP, it was called "Cotangent_value_Meyer_secure". +// See Weights/internal/pmp_weights_deprecated.h for more information. template typename GeomTraits::FT cotangent_3_clamped(const typename GeomTraits::Point_3& p, const typename GeomTraits::Point_3& q, diff --git a/Weights/include/CGAL/Weights/voronoi_region_weights.h b/Weights/include/CGAL/Weights/voronoi_region_weights.h index 61880e73ff8..86d06a07243 100644 --- a/Weights/include/CGAL/Weights/voronoi_region_weights.h +++ b/Weights/include/CGAL/Weights/voronoi_region_weights.h @@ -22,7 +22,13 @@ namespace CGAL { namespace Weights { -/// \cond SKIP_IN_MANUAL +// 2D ============================================================================================== + +/*! + \ingroup PkgWeightsRefVoronoiRegionWeights + \brief computes the area of the Voronoi cell in 2D using the points `p`, `q`, and `r`. + \tparam GeomTraits a model of `AnalyticWeightTraits_2` +*/ template typename GeomTraits::FT voronoi_area(const typename GeomTraits::Point_2& p, const typename GeomTraits::Point_2& q, @@ -39,20 +45,33 @@ typename GeomTraits::FT voronoi_area(const typename GeomTraits::Point_2& p, const Point_2 m1 = midpoint_2(q, r); const Point_2 m2 = midpoint_2(q, p); - const FT A1 = internal::positive_area_2(traits, q, m1, center); - const FT A2 = internal::positive_area_2(traits, q, center, m2); + const FT A1 = internal::positive_area_2(q, m1, center,traits); + const FT A2 = internal::positive_area_2(q, center, m2, traits); + return A1 + A2; } -template -typename GeomTraits::FT voronoi_area(const CGAL::Point_2& p, - const CGAL::Point_2& q, - const CGAL::Point_2& r) +/*! + \ingroup PkgWeightsRefVoronoiRegionWeights + \brief computes the area of the Voronoi cell in 2D using the points `p`, `q`, and `r`. + \tparam Kernel a model of `Kernel` +*/ +template +typename Kernel::FT voronoi_area(const CGAL::Point_2& p, + const CGAL::Point_2& q, + const CGAL::Point_2& r) { - const GeomTraits traits; + const Kernel traits; return voronoi_area(p, q, r, traits); } +// 3D ============================================================================================== + +/*! + \ingroup PkgWeightsRefVoronoiRegionWeights + \brief computes the area of the Voronoi cell in 3D using the points `p`, `q`, and `r` + \tparam GeomTraits a model of `AnalyticWeightTraits_3`. +*/ template typename GeomTraits::FT voronoi_area(const typename GeomTraits::Point_3& p, const typename GeomTraits::Point_3& q, @@ -69,22 +88,26 @@ typename GeomTraits::FT voronoi_area(const typename GeomTraits::Point_3& p, const Point_3 m1 = midpoint_3(q, r); const Point_3 m2 = midpoint_3(q, p); - const FT A1 = internal::positive_area_3(traits, q, m1, center); - const FT A2 = internal::positive_area_3(traits, q, center, m2); + const FT A1 = internal::positive_area_3(q, m1, center, traits); + const FT A2 = internal::positive_area_3(q, center, m2, traits); + return A1 + A2; } -template -typename GeomTraits::FT voronoi_area(const CGAL::Point_3& p, - const CGAL::Point_3& q, - const CGAL::Point_3& r) +/*! + \ingroup PkgWeightsRefVoronoiRegionWeights + \brief computes the area of the Voronoi cell in 3D using the points `p`, `q`, and `r`. + \tparam Kernel a model of `Kernel` +*/ +template +typename Kernel::FT voronoi_area(const CGAL::Point_3& p, + const CGAL::Point_3& q, + const CGAL::Point_3& r) { - const GeomTraits traits; + const Kernel traits; return voronoi_area(p, q, r, traits); } -/// \endcond - } // namespace Weights } // namespace CGAL diff --git a/Weights/include/CGAL/Weights/wachspress_weights.h b/Weights/include/CGAL/Weights/wachspress_weights.h index 58face6b47a..9a1c9e7bd1b 100644 --- a/Weights/include/CGAL/Weights/wachspress_weights.h +++ b/Weights/include/CGAL/Weights/wachspress_weights.h @@ -31,75 +31,92 @@ namespace Weights { namespace wachspress_ns { template -FT weight(const FT A1, const FT A2, const FT C) +FT weight(const FT A0, const FT A2, const FT C) { FT w = FT(0); - CGAL_precondition(A1 != FT(0) && A2 != FT(0)); - const FT prod = A1 * A2; - if (prod != FT(0)) - { - const FT inv = FT(1) / prod; - w = C * inv; - } + CGAL_precondition(!is_zero(A0) && !is_zero(A2)); + const FT prod = A0 * A2; + if (!is_zero(prod)) + w = C / prod; + return w; } -} // wachspress_ns +} // namespace wachspress_ns +/// \endcond + +// 2D ============================================================================================== + +/*! + \ingroup PkgWeightsRefWachspressWeights + \brief computes the Wachspress weight in 2D at `q` using the points `p0`, `p1`, and `p2`. + \tparam GeomTraits a model of `AnalyticWeightTraits_2` +*/ template -typename GeomTraits::FT wachspress_weight(const typename GeomTraits::Point_2& t, - const typename GeomTraits::Point_2& r, - const typename GeomTraits::Point_2& p, +typename GeomTraits::FT wachspress_weight(const typename GeomTraits::Point_2& p0, + const typename GeomTraits::Point_2& p1, + const typename GeomTraits::Point_2& p2, const typename GeomTraits::Point_2& q, const GeomTraits& traits) { using FT = typename GeomTraits::FT; - const FT A1 = internal::area_2(traits, r, q, t); - const FT A2 = internal::area_2(traits, p, q, r); - const FT C = internal::area_2(traits, t, r, p); - return wachspress_ns::weight(A1, A2, C); + + auto area_2 = traits.compute_area_2_object(); + + const FT A0 = area_2(p1, q, p0); + const FT A2 = area_2(p2, q, p1); + const FT C = area_2(p0, p1, p2); + + return wachspress_ns::weight(A0, A2, C); } -template -typename GeomTraits::FT wachspress_weight(const CGAL::Point_2& t, - const CGAL::Point_2& r, - const CGAL::Point_2& p, - const CGAL::Point_2& q) +/*! + \ingroup PkgWeightsRefWachspressWeights + \brief computes the Wachspress weight in 2D at `q` using the points `p0`, `p1`, and `p2`. + \tparam Kernel a model of `Kernel` +*/ +template +typename Kernel::FT wachspress_weight(const CGAL::Point_2& p0, + const CGAL::Point_2& p1, + const CGAL::Point_2& p2, + const CGAL::Point_2& q) { - const GeomTraits traits; - return wachspress_weight(t, r, p, q, traits); + const Kernel traits; + return wachspress_weight(p0, p1, p2, q, traits); } -namespace internal { +// 3D ============================================================================================== + +/// \cond SKIP_IN_MANUAL template -typename GeomTraits::FT wachspress_weight(const typename GeomTraits::Point_3& t, - const typename GeomTraits::Point_3& r, - const typename GeomTraits::Point_3& p, +typename GeomTraits::FT wachspress_weight(const typename GeomTraits::Point_3& p0, + const typename GeomTraits::Point_3& p1, + const typename GeomTraits::Point_3& p2, const typename GeomTraits::Point_3& q, const GeomTraits& traits) { using Point_2 = typename GeomTraits::Point_2; - Point_2 tf, rf, pf, qf; - internal::flatten(traits, - t, r, p, q, - tf, rf, pf, qf); - return CGAL::Weights::wachspress_weight(tf, rf, pf, qf, traits); + Point_2 p0f, p1f, p2f, qf; + internal::flatten(p0, p1, p2, q, + p0f, p1f, p2f, qf, + traits); + + return CGAL::Weights::wachspress_weight(p0f, p1f, p2f, qf, traits); } -template -typename GeomTraits::FT wachspress_weight(const CGAL::Point_3& t, - const CGAL::Point_3& r, - const CGAL::Point_3& p, - const CGAL::Point_3& q) +template +typename Kernel::FT wachspress_weight(const CGAL::Point_3& p0, + const CGAL::Point_3& p1, + const CGAL::Point_3& p2, + const CGAL::Point_3& q) { - const GeomTraits traits; - return wachspress_weight(t, r, p, q, traits); + const Kernel traits; + return wachspress_weight(p0, p1, p2, q, traits); } -} // namespace internal - /// \endcond /*! @@ -164,9 +181,9 @@ public: \param point_map an instance of `PointMap` that maps a vertex from `polygon` to `Point_2`; the default initialization is provided - \pre polygon.size() >= 3 - \pre polygon is simple - \pre polygon is strictly convex + \pre `polygon.size() >= 3` + \pre `polygon` is simple + \pre `polygon` is strictly convex */ Wachspress_weights_2(const VertexRange& polygon, const GeomTraits traits = GeomTraits(), @@ -331,9 +348,9 @@ private: \return an output iterator to the element in the destination range, one past the last weight stored - \pre polygon.size() >= 3 - \pre polygon is simple - \pre polygon is strictly convex + \pre `polygon.size() >= 3` + \pre `polygon` is simple + \pre `polygon` is strictly convex */ template Date: Thu, 20 Oct 2022 17:21:43 +0200 Subject: [PATCH 09/35] Misc minor code cleaning --- .../Harmonic_coordinates_2.h | 3 +- .../Surface_mesh_geodesic_distances_3.h | 12 +-- .../include/CGAL/Mesh_3/vertex_perturbation.h | 2 +- .../CGAL/Polygon_mesh_processing/fair.h | 28 +++---- .../Hole_filling/Triangulate_hole_polyline.h | 12 +-- .../include/CGAL/Weights/cotangent_weights.h | 4 +- .../CGAL/Weights/internal/polygon_utils_2.h | 5 +- Weights/include/CGAL/Weights/internal/utils.h | 76 ++++++++++--------- Weights/include/CGAL/Weights/utils.h | 20 ++--- 9 files changed, 79 insertions(+), 83 deletions(-) diff --git a/Barycentric_coordinates_2/include/CGAL/Barycentric_coordinates_2/Harmonic_coordinates_2.h b/Barycentric_coordinates_2/include/CGAL/Barycentric_coordinates_2/Harmonic_coordinates_2.h index 8e7efbd5fc3..164861dc6aa 100644 --- a/Barycentric_coordinates_2/include/CGAL/Barycentric_coordinates_2/Harmonic_coordinates_2.h +++ b/Barycentric_coordinates_2/include/CGAL/Barycentric_coordinates_2/Harmonic_coordinates_2.h @@ -587,8 +587,7 @@ namespace Barycentric_coordinates { const auto& p0 = m_domain.vertex(neighbors[jm]); const auto& p1 = m_domain.vertex(neighbors[j]); const auto& p2 = m_domain.vertex(neighbors[jp]); - const FT w = -Weights::cotangent_weight( - p0, p1, p2, query, m_traits) / FT(2); + const FT w = -Weights::cotangent_weight(p0, p1, p2, query, m_traits) / FT(2); W -= w; if (m_domain.is_on_boundary(idx)) { diff --git a/Heat_method_3/include/CGAL/Heat_method_3/Surface_mesh_geodesic_distances_3.h b/Heat_method_3/include/CGAL/Heat_method_3/Surface_mesh_geodesic_distances_3.h index fd38855d2d5..64c1782bb9c 100644 --- a/Heat_method_3/include/CGAL/Heat_method_3/Surface_mesh_geodesic_distances_3.h +++ b/Heat_method_3/include/CGAL/Heat_method_3/Surface_mesh_geodesic_distances_3.h @@ -545,22 +545,19 @@ private: pj = p_j; pk = p_k; - const double cotan_i = CGAL::to_double( - CGAL::Weights::cotangent(pk, pi, pj, traits)); + const double cotan_i = CGAL::to_double(CGAL::Weights::cotangent(pk, pi, pj, traits)); m_cotan_matrix.add_coef(j, k, -(1./2) * cotan_i); m_cotan_matrix.add_coef(k, j, -(1./2) * cotan_i); m_cotan_matrix.add_coef(j, j, (1./2) * cotan_i); m_cotan_matrix.add_coef(k, k, (1./2) * cotan_i); - const double cotan_j = CGAL::to_double( - CGAL::Weights::cotangent(pk, pj, pi, traits)); + const double cotan_j = CGAL::to_double(CGAL::Weights::cotangent(pk, pj, pi, traits)); m_cotan_matrix.add_coef(i, k, -(1./2) * cotan_j); m_cotan_matrix.add_coef(k, i, -(1./2) * cotan_j); m_cotan_matrix.add_coef(i, i, (1./2) * cotan_j); m_cotan_matrix.add_coef(k, k, (1./2) * cotan_j); - const double cotan_k = CGAL::to_double( - CGAL::Weights::cotangent(pj, pk, pi, traits)); + const double cotan_k = CGAL::to_double(CGAL::Weights::cotangent(pj, pk, pi, traits)); m_cotan_matrix.add_coef(i, j, -(1./2) * cotan_k); m_cotan_matrix.add_coef(j, i, -(1./2) * cotan_k); m_cotan_matrix.add_coef(i, i, (1./2) * cotan_k); @@ -569,8 +566,7 @@ private: const Vector_3 v_ij = construct_vector(p_i, p_j); const Vector_3 v_ik = construct_vector(p_i, p_k); const Vector_3 cross = cross_product(v_ij, v_ik); - const double norm_cross = CGAL::sqrt( - CGAL::to_double(scalar_product(cross, cross))); + const double norm_cross = CGAL::sqrt(CGAL::to_double(scalar_product(cross, cross))); //double area_face = CGAL::Polygon_mesh_processing::face_area(f,tm); //cross is 2*area diff --git a/Mesh_3/include/CGAL/Mesh_3/vertex_perturbation.h b/Mesh_3/include/CGAL/Mesh_3/vertex_perturbation.h index 1b5e004548a..a7e610afe51 100644 --- a/Mesh_3/include/CGAL/Mesh_3/vertex_perturbation.h +++ b/Mesh_3/include/CGAL/Mesh_3/vertex_perturbation.h @@ -1058,7 +1058,7 @@ private: */ FT cotangent(const FT& value) const { - return FT(1/std::tan(CGAL::to_double(value))); + return FT(1./std::tan(CGAL::to_double(value))); } /** diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/fair.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/fair.h index b6e9d00b9d0..49ea054aa45 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/fair.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/fair.h @@ -41,18 +41,18 @@ namespace internal { typename TriangleMesh, typename VertexRange, typename VertexPointMap> - bool fair(TriangleMesh& tmesh, - const VertexRange& vertices, - SparseLinearSolver solver, - WeightCalculator weight_calculator, - unsigned int continuity, - VertexPointMap vpmap) - { - CGAL::Polygon_mesh_processing::internal::Fair_Polyhedron_3 - - fair_functor(tmesh, vpmap, weight_calculator); - return fair_functor.fair(vertices, solver, continuity); - } +bool fair(TriangleMesh& tmesh, + const VertexRange& vertices, + SparseLinearSolver solver, + WeightCalculator weight_calculator, + unsigned int continuity, + VertexPointMap vpmap) +{ + CGAL::Polygon_mesh_processing::internal::Fair_Polyhedron_3 + + fair_functor(tmesh, vpmap, weight_calculator); + return fair_functor.fair(vertices, solver, continuity); +} } //end namespace internal @@ -182,9 +182,9 @@ namespace internal { CGAL::Polygon_mesh_processing::parameters::all_default()); } -} //end namespace Polygon_mesh_processing +} // namespace Polygon_mesh_processing -} //end namespace CGAL +} // namespace CGAL #include diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Hole_filling/Triangulate_hole_polyline.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Hole_filling/Triangulate_hole_polyline.h index 99f6e0bd64d..1b915b25201 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Hole_filling/Triangulate_hole_polyline.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Hole_filling/Triangulate_hole_polyline.h @@ -385,9 +385,9 @@ class Weight_incomplete private: template Weight_incomplete(const std::vector& P, - const std::vector& Q, - int i, int j, int k, - const LookupTable& lambda) + const std::vector& Q, + int i, int j, int k, + const LookupTable& lambda) : weight(P,Q,i,j,k,lambda), patch_size(1) { } @@ -444,9 +444,9 @@ struct Weight_calculator template Weight operator()(const std::vector& P, - const std::vector& Q, - int i, int j, int k, - const LookupTable& lambda) const + const std::vector& Q, + int i, int j, int k, + const LookupTable& lambda) const { if( !is_valid(P,i,j,k) ) { return Weight::NOT_VALID(); } diff --git a/Weights/include/CGAL/Weights/cotangent_weights.h b/Weights/include/CGAL/Weights/cotangent_weights.h index c7596aa53ee..f4afc5c6f14 100644 --- a/Weights/include/CGAL/Weights/cotangent_weights.h +++ b/Weights/include/CGAL/Weights/cotangent_weights.h @@ -79,7 +79,7 @@ typename GeomTraits::FT cotangent_weight(const typename GeomTraits::Point_2& p0, { using FT = typename GeomTraits::FT; - const FT cot_beta = cotangent_2(q, p0, p1, traits); + const FT cot_beta = cotangent_2(q, p0, p1, traits); const FT cot_gamma = cotangent_2(p1, p2, q, traits); return cotangent_ns::weight(cot_beta, cot_gamma); @@ -116,7 +116,7 @@ typename GeomTraits::FT cotangent_weight(const typename GeomTraits::Point_3& p0, { using FT = typename GeomTraits::FT; - const FT cot_beta = cotangent_3(q, p0, p1, traits); + const FT cot_beta = cotangent_3(q, p0, p1, traits); const FT cot_gamma = cotangent_3(p1, p2, q, traits); return cotangent_ns::weight(cot_beta, cot_gamma); diff --git a/Weights/include/CGAL/Weights/internal/polygon_utils_2.h b/Weights/include/CGAL/Weights/internal/polygon_utils_2.h index f2933317972..361896fc105 100644 --- a/Weights/include/CGAL/Weights/internal/polygon_utils_2.h +++ b/Weights/include/CGAL/Weights/internal/polygon_utils_2.h @@ -106,7 +106,7 @@ Edge_case bounded_side_2(const VertexRange& polygon, auto orientation_2 = traits.orientation_2_object(); bool is_inside = false; - auto curr_y_comp_res = compare_y_2(get(point_map, *curr), query); + Comparison_result curr_y_comp_res = compare_y_2(get(point_map, *curr), query); // Check if the segment (curr, next) intersects // the ray { (t, query.y()) | t >= query.x() }. @@ -225,7 +225,8 @@ bool is_convex_2(const VertexRange& polygon, return true; auto equal_2 = traits.equal_2_object(); - while (equal_2(get(point_map, *prev), get(point_map, *curr))) { + while (equal_2(get(point_map, *prev), get(point_map, *curr))) + { curr = next; ++next; if (next == last) return true; diff --git a/Weights/include/CGAL/Weights/internal/utils.h b/Weights/include/CGAL/Weights/internal/utils.h index 2c01c4e1e30..f51136186b9 100644 --- a/Weights/include/CGAL/Weights/internal/utils.h +++ b/Weights/include/CGAL/Weights/internal/utils.h @@ -135,9 +135,10 @@ void normalize_2(typename GeomTraits::Vector_2& v, const GeomTraits& traits) { using FT = typename GeomTraits::FT; - const FT length = length_2(traits, v); - CGAL_assertion(length != FT(0)); - if (length == FT(0)) + + const FT length = length_2(v, traits); + CGAL_assertion(!is_zero(length)); + if (is_zero(length)) return; v /= length; @@ -174,15 +175,15 @@ void normalize_3(typename GeomTraits::Vector_3& v, const GeomTraits& traits) { using FT = typename GeomTraits::FT; - - const FT length = length_3(traits, v); - CGAL_assertion(length != FT(0)); - if (length == FT(0)) + const FT length = length_3(v, traits); + CGAL_assertion(!is_zero(length)); + if (is_zero(length)) return; v /= length; } +// the angle is in radians template double angle_3(const typename GeomTraits::Vector_3& v1, const typename GeomTraits::Vector_3& v2, @@ -213,24 +214,26 @@ typename GeomTraits::Point_3 rotate_point_3(const double angle_rad, using FT = typename GeomTraits::FT; using Point_3 = typename GeomTraits::Point_3; + auto point_3 = traits.construct_point_3_object(); + const FT c = static_cast(std::cos(angle_rad)); const FT s = static_cast(std::sin(angle_rad)); const FT C = FT(1) - c; - const FT x = axis.x(); - const FT y = axis.y(); - const FT z = axis.z(); + const FT& x = axis.x(); + const FT& y = axis.y(); + const FT& z = axis.z(); - return Point_3( - (x * x * C + c) * query.x() + - (x * y * C - z * s) * query.y() + - (x * z * C + y * s) * query.z(), - (y * x * C + z * s) * query.x() + - (y * y * C + c) * query.y() + - (y * z * C - x * s) * query.z(), - (z * x * C - y * s) * query.x() + - (z * y * C + x * s) * query.y() + - (z * z * C + c) * query.z()); + return point_3( + (x * x * C + c) * query.x() + + (x * y * C - z * s) * query.y() + + (x * z * C + y * s) * query.z(), + (y * x * C + z * s) * query.x() + + (y * y * C + c) * query.y() + + (y * z * C - x * s) * query.z(), + (z * x * C - y * s) * query.x() + + (z * y * C + x * s) * query.y() + + (z * z * C + c) * query.z()); } // Computes two 3D orthogonal base vectors wrt a given normal. @@ -245,9 +248,9 @@ void orthogonal_bases_3(const typename GeomTraits::Vector_3& normal, auto cross_product_3 = traits.construct_cross_product_vector_3_object(); - const FT nx = normal.x(); - const FT ny = normal.y(); - const FT nz = normal.z(); + const FT& nx = normal.x(); + const FT& ny = normal.y(); + const FT& nz = normal.z(); if (CGAL::abs(nz) >= CGAL::abs(ny)) b1 = Vector_3(nz, 0, -nx); @@ -268,13 +271,13 @@ typename GeomTraits::Point_2 to_2d(const typename GeomTraits::Vector_3& b1, const typename GeomTraits::Point_3& query, const GeomTraits& traits) { - using FT = typename GeomTraits::FT; - using Point_2 = typename GeomTraits::Point_2; + using FT = typename GeomTraits::FT; + using Point_2 = typename GeomTraits::Point_2; using Vector_3 = typename GeomTraits::Vector_3; - auto point_2 = traits.construct_point_2_object(); auto dot_product_3 = traits.compute_scalar_product_3_object(); auto vector_3 = traits.construct_vector_3_object(); + auto point_2 = traits.construct_point_2_object(); const Vector_3 v = vector_3(origin, query); const FT x = dot_product_3(b1, v); @@ -354,6 +357,7 @@ void flatten(const typename GeomTraits::Point_3& t, // prev neighbor/vertex/poin using Point_3 = typename GeomTraits::Point_3; using Vector_3 = typename GeomTraits::Vector_3; + auto point_3 = traits.construct_point_3_object(); auto cross_product_3 = traits.construct_cross_product_vector_3_object(); auto vector_3 = traits.construct_vector_3_object(); auto centroid_3 = traits.construct_centroid_3_object(); @@ -363,10 +367,10 @@ void flatten(const typename GeomTraits::Point_3& t, // prev neighbor/vertex/poin // std::cout << "centroid: " << center << std::endl; // Translate. - const Point_3 t1 = Point_3(t.x() - center.x(), t.y() - center.y(), t.z() - center.z()); - const Point_3 r1 = Point_3(r.x() - center.x(), r.y() - center.y(), r.z() - center.z()); - const Point_3 p1 = Point_3(p.x() - center.x(), p.y() - center.y(), p.z() - center.z()); - const Point_3 q1 = Point_3(q.x() - center.x(), q.y() - center.y(), q.z() - center.z()); + const Point_3 t1 = point_3(t.x() - center.x(), t.y() - center.y(), t.z() - center.z()); + const Point_3 r1 = point_3(r.x() - center.x(), r.y() - center.y(), r.z() - center.z()); + const Point_3 p1 = point_3(p.x() - center.x(), p.y() - center.y(), p.z() - center.z()); + const Point_3 q1 = point_3(q.x() - center.x(), q.y() - center.y(), q.z() - center.z()); // std::cout << "translated t1: " << t1 << std::endl; // std::cout << "translated r1: " << r1 << std::endl; @@ -447,10 +451,11 @@ typename GeomTraits::FT area_3(const typename GeomTraits::Point_3& p, const GeomTraits& traits) { using FT = typename GeomTraits::FT; - using Point_2 = typename GeomTraits::Point_2; using Point_3 = typename GeomTraits::Point_3; using Vector_3 = typename GeomTraits::Vector_3; + auto area_2 = traits.compute_area_2_object(); + auto point_3 = traits.construct_point_3_object(); auto cross_product_3 = traits.construct_cross_product_vector_3_object(); auto vector_3 = traits.construct_vector_3_object(); auto centroid_3 = traits.construct_centroid_3_object(); @@ -459,9 +464,9 @@ typename GeomTraits::FT area_3(const typename GeomTraits::Point_3& p, const Point_3 center = centroid_3(p, q, r); // Translate. - const Point_3 a = Point_3(p.x() - center.x(), p.y() - center.y(), p.z() - center.z()); - const Point_3 b = Point_3(q.x() - center.x(), q.y() - center.y(), q.z() - center.z()); - const Point_3 c = Point_3(r.x() - center.x(), r.y() - center.y(), r.z() - center.z()); + const Point_3 a = point_3(p.x() - center.x(), p.y() - center.y(), p.z() - center.z()); + const Point_3 b = point_3(q.x() - center.x(), q.y() - center.y(), q.z() - center.z()); + const Point_3 c = point_3(r.x() - center.x(), r.y() - center.y(), r.z() - center.z()); // Prev and next vectors. Vector_3 v1 = vector_3(b, a); @@ -483,8 +488,7 @@ typename GeomTraits::FT area_3(const typename GeomTraits::Point_3& p, const Point_2 qf = to_2d(b1, b2, origin, b, traits); const Point_2 rf = to_2d(b1, b2, origin, c, traits); - const FT A = area_2(traits, pf, qf, rf); - return A; + return area_2(pf, qf, rf); } // Computes positive area of a 3D triangle. diff --git a/Weights/include/CGAL/Weights/utils.h b/Weights/include/CGAL/Weights/utils.h index 9f75bd14854..67c10ce16c2 100644 --- a/Weights/include/CGAL/Weights/utils.h +++ b/Weights/include/CGAL/Weights/utils.h @@ -45,8 +45,8 @@ typename GeomTraits::FT cotangent_2(const typename GeomTraits::Point_2& p, if (!is_zero(length)) return dot / length; - else - return FT(0); // undefined + + return FT(0); // undefined } template @@ -92,8 +92,8 @@ typename GeomTraits::FT cotangent_3(const typename GeomTraits::Point_3& p, const FT length = internal::length_3(cross, traits); if (!is_zero(length)) return dot / length; - else - return FT(0); // undefined + + return FT(0); // undefined } template @@ -140,10 +140,8 @@ typename GeomTraits::FT tangent_2(const typename GeomTraits::Point_2& p, const FT length = CGAL::abs(cross); return length / dot; } - else - { - return FT(0); // undefined - } + + return FT(0); // undefined } template @@ -190,10 +188,8 @@ typename GeomTraits::FT tangent_3(const typename GeomTraits::Point_3& p, const FT length = internal::length_3(cross, traits); return length / dot; } - else - { - return FT(0); // undefined - } + + return FT(0); // undefined } template From 92ea84d672ba866286286c71975c9bd5aba3c714 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Thu, 20 Oct 2022 17:23:11 +0200 Subject: [PATCH 10/35] Factorize cotangent_weight classes --- .../include/CGAL/Weights/cotangent_weights.h | 361 ++++++------------ 1 file changed, 119 insertions(+), 242 deletions(-) diff --git a/Weights/include/CGAL/Weights/cotangent_weights.h b/Weights/include/CGAL/Weights/cotangent_weights.h index f4afc5c6f14..93413b7cb24 100644 --- a/Weights/include/CGAL/Weights/cotangent_weights.h +++ b/Weights/include/CGAL/Weights/cotangent_weights.h @@ -140,236 +140,165 @@ typename Kernel::FT cotangent_weight(const CGAL::Point_3& p0, /// \cond SKIP_IN_MANUAL // Undocumented cotangent weight class. -// -// Its constructor takes a polygon mesh and a vertex to point map -// and its operator() is defined based on the halfedge_descriptor only. -// This version is currently used in: -// Polygon_mesh_processing -> curvature_flow_impl.h -template< - typename PolygonMesh, - typename VertexPointMap = typename boost::property_map::type> -class Edge_cotangent_weight -{ - using GeomTraits = typename CGAL::Kernel_traits::value_type>::type; - using FT = typename GeomTraits::FT; - - const PolygonMesh& m_pmesh; - const VertexPointMap m_pmap; - GeomTraits m_traits; - -public: - using vertex_descriptor = typename boost::graph_traits::vertex_descriptor; - using halfedge_descriptor = typename boost::graph_traits::halfedge_descriptor; - - Edge_cotangent_weight(const PolygonMesh& pmesh, const VertexPointMap pmap) - : m_pmesh(pmesh), m_pmap(pmap), m_traits() - { } - - FT operator()(const halfedge_descriptor he) const - { - - FT weight = FT(0); - if (is_border_edge(he, m_pmesh)) - { - const halfedge_descriptor h1 = next(he, m_pmesh); - - const vertex_descriptor v0 = target(he, m_pmesh); - const vertex_descriptor v1 = source(he, m_pmesh); - const vertex_descriptor v2 = target(h1, m_pmesh); - - const auto& p0 = get(m_pmap, v0); - const auto& p1 = get(m_pmap, v1); - const auto& p2 = get(m_pmap, v2); - - weight = internal::cotangent_3(m_traits, p0, p2, p1); - - } - else - { - const halfedge_descriptor h1 = next(he, m_pmesh); - const halfedge_descriptor h2 = prev(opposite(he, m_pmesh), m_pmesh); - - const vertex_descriptor v0 = target(he, m_pmesh); - const vertex_descriptor v1 = source(he, m_pmesh); - const vertex_descriptor v2 = target(h1, m_pmesh); - const vertex_descriptor v3 = source(h2, m_pmesh); - - const auto& p0 = get(m_pmap, v0); - const auto& p1 = get(m_pmap, v1); - const auto& p2 = get(m_pmap, v2); - const auto& p3 = get(m_pmap, v3); - - weight = cotangent_weight(p2, p1, p3, p0) / FT(2); - } - return weight; - } -}; - -// Undocumented cotangent weight class. +// Returns: cot(beta) // // Returns a single cotangent weight, its operator() is defined based on the // halfedge_descriptor, polygon mesh, and vertex to point map. // For border edges it returns zero. // This version is currently used in: // Surface_mesh_deformation -> Surface_mesh_deformation.h -template +template::value_type>::type> class Single_cotangent_weight { -public: using vertex_descriptor = typename boost::graph_traits::vertex_descriptor; using halfedge_descriptor = typename boost::graph_traits::halfedge_descriptor; - template - decltype(auto) operator()(const halfedge_descriptor he, - const PolygonMesh& pmesh, - const VertexPointMap pmap) const + using Point_ref = typename boost::property_traits::reference; + using FT = typename GeomTraits::FT; + +private: + const PolygonMesh& m_pmesh; + const VertexPointMap m_vpm; + const GeomTraits m_traits; + +public: + Single_cotangent_weight(const PolygonMesh& pmesh, + const VertexPointMap vpm, + const GeomTraits& traits = GeomTraits()) + : m_pmesh(pmesh), m_vpm(vpm), m_traits(traits) + { } + + decltype(auto) operator()(const halfedge_descriptor he) const { - using GeomTraits = typename CGAL::Kernel_traits::value_type>::type; - using FT = typename GeomTraits::FT; - GeomTraits traits; + if (is_border(he, m_pmesh)) + return FT{0}; - if (is_border(he, pmesh)) - return FT(0); + const vertex_descriptor v0 = target(he, m_pmesh); + const vertex_descriptor v1 = source(he, m_pmesh); + const vertex_descriptor v2 = target(next(he, m_pmesh), m_pmesh); - const vertex_descriptor v0 = target(he, pmesh); - const vertex_descriptor v1 = source(he, pmesh); - const vertex_descriptor v2 = target(next(he, pmesh), pmesh); + const Point_ref p0 = get(m_vpm, v0); + const Point_ref p1 = get(m_vpm, v1); + const Point_ref p2 = get(m_vpm, v2); - const auto& p0 = get(pmap, v0); - const auto& p1 = get(pmap, v1); - const auto& p2 = get(pmap, v2); - - return internal::cotangent_3(traits, p0, p2, p1); + return cotangent_3(p0, p2, p1, m_traits); } }; // Undocumented cotangent weight class. +// Returns: 0.5 * (cot(beta) + cot(gamma)) // // Its constructor takes a boolean flag to choose between default and clamped // versions of the cotangent weights and its operator() is defined based on the // halfedge_descriptor, polygon mesh, and vertex to point map. // This version is currently used in: +// Polygon_mesh_processing -> curvature_flow_impl.h (no clamping, no bounding) // Surface_mesh_deformation -> Surface_mesh_deformation.h (default version) // Surface_mesh_parameterizer -> Orbifold_Tutte_parameterizer_3.h (default version) // Surface_mesh_skeletonization -> Mean_curvature_flow_skeletonization.h (clamped version) -template +template::value_type>::type> class Cotangent_weight { - bool m_use_clamped_version; - -public: using vertex_descriptor = typename boost::graph_traits::vertex_descriptor; using halfedge_descriptor = typename boost::graph_traits::halfedge_descriptor; - Cotangent_weight(const bool use_clamped_version = false) - : m_use_clamped_version(use_clamped_version) + using Point_ref = typename boost::property_traits::reference; + using FT = typename GeomTraits::FT; + +private: + const PolygonMesh& m_pmesh; + const VertexPointMap m_vpm; + const GeomTraits m_traits; + + bool m_use_clamped_version; + bool m_bound_from_below; + +public: + Cotangent_weight(const PolygonMesh& pmesh, + const VertexPointMap vpm, + const GeomTraits& traits = GeomTraits(), + const bool use_clamped_version = false, + const bool bound_from_below = true) + : m_pmesh(pmesh), m_vpm(vpm), m_traits(traits), + m_use_clamped_version(use_clamped_version), + m_bound_from_below(bound_from_below) { } - template - decltype(auto) operator()(const halfedge_descriptor he, - const PolygonMesh& pmesh, - const VertexPointMap pmap) const + decltype(auto) operator()(const halfedge_descriptor he) const { - using GeomTraits = typename CGAL::Kernel_traits::value_type>::type; - using FT = typename GeomTraits::FT; + if(is_border(he, m_pmesh)) + return FT{0}; - GeomTraits traits; - - const vertex_descriptor v0 = target(he, pmesh); - const vertex_descriptor v1 = source(he, pmesh); - - const auto& p0 = get(pmap, v0); - const auto& p1 = get(pmap, v1); - - FT weight = FT(0); - if (is_border_edge(he, pmesh)) + auto half_weight = [&] (const halfedge_descriptor he) -> FT { - const halfedge_descriptor he_cw = opposite(next(he, pmesh), pmesh); - auto v2 = source(he_cw, pmesh); + if(is_border(he, m_pmesh)) + return FT{0}; - if (is_border_edge(he_cw, pmesh)) - { - const halfedge_descriptor he_ccw = prev(opposite(he, pmesh), pmesh); - v2 = source(he_ccw, pmesh); + const vertex_descriptor v0 = target(he, m_pmesh); + const vertex_descriptor v1 = source(he, m_pmesh); + const vertex_descriptor v2 = target(next(he, m_pmesh), m_pmesh); - const auto& p2 = get(pmap, v2); - if (m_use_clamped_version) - weight = internal::cotangent_3_clamped(traits, p1, p2, p0); - else - weight = internal::cotangent_3(traits, p1, p2, p0); - - weight = (CGAL::max)(FT(0), weight); - weight /= FT(2); - } - else - { - const auto& p2 = get(pmap, v2); - if (m_use_clamped_version) - weight = internal::cotangent_3_clamped(traits, p0, p2, p1); - else - weight = internal::cotangent_3(traits, p0, p2, p1); - - weight = (CGAL::max)(FT(0), weight); - weight /= FT(2); - } - } - else - { - const halfedge_descriptor he_cw = opposite(next(he, pmesh), pmesh); - const vertex_descriptor v2 = source(he_cw, pmesh); - const halfedge_descriptor he_ccw = prev(opposite(he, pmesh), pmesh); - const vertex_descriptor v3 = source(he_ccw, pmesh); - - const auto& p2 = get(pmap, v2); - const auto& p3 = get(pmap, v3); - FT cot_beta = FT(0), cot_gamma = FT(0); + const Point_ref p0 = get(m_vpm, v0); + const Point_ref p1 = get(m_vpm, v1); + const Point_ref p2 = get(m_vpm, v2); + FT weight = 0; if (m_use_clamped_version) - cot_beta = internal::cotangent_3_clamped(traits, p0, p2, p1); + weight = cotangent_3_clamped(p1, p2, p0, m_traits); else - cot_beta = internal::cotangent_3(traits, p0, p2, p1); + weight = cotangent_3(p1, p2, p0, m_traits); - if (m_use_clamped_version) - cot_gamma = internal::cotangent_3_clamped(traits, p1, p3, p0); - else - cot_gamma = internal::cotangent_3(traits, p1, p3, p0); + if(m_bound_from_below) + weight = (CGAL::max)(FT(0), weight); - cot_beta = (CGAL::max)(FT(0), cot_beta); cot_beta /= FT(2); - cot_gamma = (CGAL::max)(FT(0), cot_gamma); cot_gamma /= FT(2); - weight = cot_beta + cot_gamma; - } + return weight / FT(2); + }; + FT weight = half_weight(he) + half_weight(opposite(he, m_pmesh)); return weight; } }; // Undocumented cotangent weight class. +// // Its constructor takes a polygon mesh and a vertex to point map // and its operator() is defined based on the halfedge_descriptor only. // This class is using a special clamped version of the cotangent weights. // This version is currently used in: // Polygon_mesh_processing -> fair.h // Polyhedron demo -> Hole_filling_plugin.cpp -template< - typename PolygonMesh, - typename VertexPointMap = typename boost::property_map::type> +template class Secure_cotangent_weight_with_voronoi_area { - using GeomTraits = typename CGAL::Kernel_traits::value_type>::type; - using FT = typename GeomTraits::FT; - using Vector_3 = typename GeomTraits::Vector_3; - - const PolygonMesh& m_pmesh; - const VertexPointMap m_pmap; - GeomTraits m_traits; - -public: using vertex_descriptor = typename boost::graph_traits::vertex_descriptor; using halfedge_descriptor = typename boost::graph_traits::halfedge_descriptor; + using Point_ref = typename boost::property_traits::reference; + using FT = typename GeomTraits::FT; + using Vector_3 = typename GeomTraits::Vector_3; + +private: + const PolygonMesh& m_pmesh; + const VertexPointMap m_vpm; + GeomTraits m_traits; + + Cotangent_weight cotangent_weight_calculator; + +public: Secure_cotangent_weight_with_voronoi_area(const PolygonMesh& pmesh, - const VertexPointMap pmap) - : m_pmesh(pmesh), m_pmap(pmap), m_traits() + const VertexPointMap vpm, + const GeomTraits& traits = GeomTraits()) + : m_pmesh(pmesh), m_vpm(vpm), m_traits(traits), + cotangent_weight_calculator(m_pmesh, m_vpm, m_traits, + true /*clamp*/, true /*bound from below*/) { } FT w_i(const vertex_descriptor v_i) const @@ -379,89 +308,46 @@ public: FT w_ij(const halfedge_descriptor he) const { - return cotangent_clamped(he); + return cotangent_weight_calculator(he); } private: - FT cotangent_clamped(const halfedge_descriptor he) const - { - - const vertex_descriptor v0 = target(he, m_pmesh); - const vertex_descriptor v1 = source(he, m_pmesh); - - const auto& p0 = get(m_pmap, v0); - const auto& p1 = get(m_pmap, v1); - - FT weight = FT(0); - if (is_border_edge(he, m_pmesh)) - { - const halfedge_descriptor he_cw = opposite(next(he, m_pmesh), m_pmesh); - vertex_descriptor v2 = source(he_cw, m_pmesh); - - if (is_border_edge(he_cw, m_pmesh)) - { - const halfedge_descriptor he_ccw = prev(opposite(he, m_pmesh), m_pmesh); - v2 = source(he_ccw, m_pmesh); - - const auto& p2 = get(m_pmap, v2); - weight = internal::cotangent_3_clamped(m_traits, p1, p2, p0); - } - else - { - const auto& p2 = get(m_pmap, v2); - weight = internal::cotangent_3_clamped(m_traits, p0, p2, p1); - } - } - else - { - const halfedge_descriptor he_cw = opposite(next(he, m_pmesh), m_pmesh); - const vertex_descriptor v2 = source(he_cw, m_pmesh); - const halfedge_descriptor he_ccw = prev(opposite(he, m_pmesh), m_pmesh); - const vertex_descriptor v3 = source(he_ccw, m_pmesh); - - const auto& p2 = get(m_pmap, v2); - const auto& p3 = get(m_pmap, v3); - - const FT cot_beta = internal::cotangent_3_clamped(m_traits, p0, p2, p1); - const FT cot_gamma = internal::cotangent_3_clamped(m_traits, p1, p3, p0); - weight = cot_beta + cot_gamma; - } - - return weight; - } - FT voronoi(const vertex_descriptor v0) const { auto squared_length_3 = m_traits.compute_squared_length_3_object(); auto vector_3 = m_traits.construct_vector_3_object(); FT voronoi_area = FT(0); - CGAL_assertion(CGAL::is_triangle_mesh(m_pmesh)); - for (const halfedge_descriptor& he : halfedges_around_target(halfedge(v0, m_pmesh), m_pmesh)) + for (const halfedge_descriptor he : halfedges_around_target(halfedge(v0, m_pmesh), m_pmesh)) { CGAL_assertion(v0 == target(he, m_pmesh)); + CGAL_assertion(CGAL::is_triangle(he, m_pmesh)); + if (is_border(he, m_pmesh)) continue; const vertex_descriptor v1 = source(he, m_pmesh); const vertex_descriptor v2 = target(next(he, m_pmesh), m_pmesh); - const auto& p0 = get(m_pmap, v0); - const auto& p1 = get(m_pmap, v1); - const auto& p2 = get(m_pmap, v2); + const Point_ref p0 = get(m_vpm, v0); + const Point_ref p1 = get(m_vpm, v1); + const Point_ref p2 = get(m_vpm, v2); - const Angle angle0 = CGAL::angle(p1, p0, p2); - const Angle angle1 = CGAL::angle(p2, p1, p0); - const Angle angle2 = CGAL::angle(p0, p2, p1); - - const bool obtuse = (angle0 == CGAL::OBTUSE) || - (angle1 == CGAL::OBTUSE) || - (angle2 == CGAL::OBTUSE); - - if (!obtuse) + const CGAL::Angle angle0 = CGAL::angle(p1, p0, p2); + if((angle0 == CGAL::OBTUSE) || + (CGAL::angle(p2, p1, p0) == CGAL::OBTUSE) || + (CGAL::angle(p0, p2, p1) == CGAL::OBTUSE)) { - const FT cot_p1 = internal::cotangent_3(m_traits, p2, p1, p0); - const FT cot_p2 = internal::cotangent_3(m_traits, p0, p2, p1); + const FT A = internal::positive_area_3(m_traits, p0, p1, p2); + if (angle0 == CGAL::OBTUSE) + voronoi_area += A / FT(2); + else + voronoi_area += A / FT(4); + } + else + { + const FT cot_p1 = cotangent_3_clamped(p2, p1, p0, m_traits); + const FT cot_p2 = cotangent_3_clamped(p0, p2, p1, m_traits); const Vector_3 v1 = vector_3(p0, p1); const Vector_3 v2 = vector_3(p0, p2); @@ -469,19 +355,10 @@ private: const FT t1 = cot_p1 * squared_length_3(v2); const FT t2 = cot_p2 * squared_length_3(v1); voronoi_area += (t1 + t2) / FT(8); - - } - else - { - const FT A = internal::positive_area_3(m_traits, p0, p1, p2); - if (angle0 == CGAL::OBTUSE) - voronoi_area += A / FT(2); - else - voronoi_area += A / FT(4); } } - CGAL_assertion(voronoi_area != FT(0)); + CGAL_assertion(!is_zero(voronoi_area)); return voronoi_area; } }; From 670fec5e3cef8cbd4f4427b4ecca1467d8ee4f08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Thu, 20 Oct 2022 17:23:54 +0200 Subject: [PATCH 11/35] Fix issues in tangent_weight classes - Edge_tangent_weight returns 0 if the halfedge is border - if opp(h, mesh) is tangent, properly returns tan of the HALF angle and not tangent_3. --- .../include/CGAL/Weights/tangent_weights.h | 114 ++++++++++-------- 1 file changed, 65 insertions(+), 49 deletions(-) diff --git a/Weights/include/CGAL/Weights/tangent_weights.h b/Weights/include/CGAL/Weights/tangent_weights.h index 119dee11623..afa64e2da90 100644 --- a/Weights/include/CGAL/Weights/tangent_weights.h +++ b/Weights/include/CGAL/Weights/tangent_weights.h @@ -365,16 +365,24 @@ typename Kernel::FT tangent_weight(const CGAL::Point_3& p0, return tangent_weight(p0, p1, p2, q, traits); } +/// \cond SKIP_IN_MANUAL + // Undocumented tangent weight class. +// // Its constructor takes a polygon mesh and a vertex to point map // and its operator() is defined based on the halfedge_descriptor only. // This version is currently used in: // Surface_mesh_parameterizer -> Iterative_authalic_parameterizer_3.h -template::type> +template< + typename PolygonMesh, + typename VertexPointMap, + typename GeomTraits> class Edge_tangent_weight { - using GeomTraits = typename CGAL::Kernel_traits::value_type>::type; + using vertex_descriptor = typename boost::graph_traits::vertex_descriptor; + using halfedge_descriptor = typename boost::graph_traits::halfedge_descriptor; + + using Point_ref = typename boost::property_traits::reference; using FT = typename GeomTraits::FT; const PolygonMesh& m_pmesh; @@ -382,17 +390,20 @@ class Edge_tangent_weight const GeomTraits m_traits; public: - using vertex_descriptor = typename boost::graph_traits::vertex_descriptor; - using halfedge_descriptor = typename boost::graph_traits::halfedge_descriptor; - Edge_tangent_weight(const PolygonMesh& pmesh, const VertexPointMap pmap) - : m_pmesh(pmesh), m_pmap(pmap), m_traits() + Edge_tangent_weight(const PolygonMesh& pmesh, + const VertexPointMap pmap, + const GeomTraits& traits) + : m_pmesh(pmesh), m_pmap(pmap), m_traits(traits) { } - FT operator()(const halfedge_descriptor he) const + FT operator()(halfedge_descriptor he) const { + if(is_border(he, m_pmesh)) + return FT(0); + FT weight = FT(0); - if (is_border_edge(he, m_pmesh)) + if (is_border_edge(he, m_pmesh)) // ie, opp(he, pmesh) is a border halfedge { const halfedge_descriptor h1 = next(he, m_pmesh); @@ -400,11 +411,11 @@ public: const vertex_descriptor v1 = source(he, m_pmesh); const vertex_descriptor v2 = target(h1, m_pmesh); - const auto& p0 = get(m_pmap, v0); - const auto& p1 = get(m_pmap, v1); - const auto& p2 = get(m_pmap, v2); + const Point_ref p0 = get(m_pmap, v0); + const Point_ref p1 = get(m_pmap, v1); + const Point_ref p2 = get(m_pmap, v2); - weight = internal::tangent_3(m_traits, p0, p2, p1); + weight = half_tangent_weight(p1, p0, p2, m_traits) / FT(2); } else { @@ -416,75 +427,80 @@ public: const vertex_descriptor v2 = target(h1, m_pmesh); const vertex_descriptor v3 = source(h2, m_pmesh); - const auto& p0 = get(m_pmap, v0); - const auto& p1 = get(m_pmap, v1); - const auto& p2 = get(m_pmap, v2); - const auto& p3 = get(m_pmap, v3); + const Point_ref p0 = get(m_pmap, v0); + const Point_ref p1 = get(m_pmap, v1); + const Point_ref p2 = get(m_pmap, v2); + const Point_ref p3 = get(m_pmap, v3); - weight = tangent_weight(p2, p1, p3, p0) / FT(2); + weight = tangent_weight(p2, p1, p3, p0, m_traits) / FT(2); } return weight; } }; // Undocumented tangent weight class. +// Returns - std::tan(theta/2); uses positive areas. +// // Its constructor takes three points either in 2D or 3D. // This version is currently used in: // Surface_mesh_parameterizer -> MVC_post_processor_3.h // Surface_mesh_parameterizer -> Orbifold_Tutte_parameterizer_3.h template -class Tangent_weight { +class Tangent_weight +{ FT m_d_r, m_d_p, m_w_base; public: - template - Tangent_weight(const CGAL::Point_2& p, - const CGAL::Point_2& q, - const CGAL::Point_2& r) + template + Tangent_weight(const CGAL::Point_2& p, + const CGAL::Point_2& q, + const CGAL::Point_2& r) { - using Vector_2 = typename GeomTraits::Vector_2; + const Kernel traits; - const GeomTraits traits; + using Vector_2 = typename Kernel::Vector_2; + auto vector_2 = traits.construct_vector_2_object(); auto scalar_product_2 = traits.compute_scalar_product_2_object(); - auto construct_vector_2 = traits.construct_vector_2_object(); - m_d_r = internal::distance_2(traits, q, r); - CGAL_assertion(m_d_r != FT(0)); // two points are identical! - m_d_p = internal::distance_2(traits, q, p); - CGAL_assertion(m_d_p != FT(0)); // two points are identical! + m_d_r = internal::distance_2(q, r, traits); + CGAL_assertion(is_positive(m_d_r)); // two points are identical! + m_d_p = internal::distance_2(q, p, traits); + CGAL_assertion(is_positive(m_d_p)); // two points are identical! - const Vector_2 v1 = construct_vector_2(q, r); - const Vector_2 v2 = construct_vector_2(q, p); + const Vector_2 v1 = vector_2(q, r); + const Vector_2 v2 = vector_2(q, p); + + const FT A = internal::positive_area_2(p, q, r, traits); + CGAL_assertion(!is_zero(A)); - const FT A = internal::positive_area_2(traits, p, q, r); - CGAL_assertion(A != FT(0)); // three points are identical! const FT S = scalar_product_2(v1, v2); m_w_base = -tangent_half_angle(m_d_r, m_d_p, A, S); } - template - Tangent_weight(const CGAL::Point_3& p, - const CGAL::Point_3& q, - const CGAL::Point_3& r) + template + Tangent_weight(const CGAL::Point_3& p, + const CGAL::Point_3& q, + const CGAL::Point_3& r) { - using Vector_3 = typename GeomTraits::Vector_3; + const Kernel traits; - const GeomTraits traits; + using Vector_3 = typename Kernel::Vector_3; + auto vector_3 = traits.construct_vector_3_object(); auto scalar_product_3 = traits.compute_scalar_product_3_object(); - auto construct_vector_3 = traits.construct_vector_3_object(); - m_d_r = internal::distance_3(traits, q, r); - CGAL_assertion(m_d_r != FT(0)); // two points are identical! - m_d_p = internal::distance_3(traits, q, p); - CGAL_assertion(m_d_p != FT(0)); // two points are identical! + m_d_r = internal::distance_3(q, r, traits); + CGAL_assertion(is_positive(m_d_r)); // two points are identical! + m_d_p = internal::distance_3(q, p, traits); + CGAL_assertion(is_positive(m_d_p)); // two points are identical! - const Vector_3 v1 = construct_vector_3(q, r); - const Vector_3 v2 = construct_vector_3(q, p); + const Vector_3 v1 = vector_3(q, r); + const Vector_3 v2 = vector_3(q, p); + + const FT A = internal::positive_area_3(p, q, r, traits); + CGAL_assertion(is_positive(A)); - const FT A = internal::positive_area_3(traits, p, q, r); - CGAL_assertion(A != FT(0)); // three points are identical! const FT S = scalar_product_3(v1, v2); m_w_base = -tangent_half_angle(m_d_r, m_d_p, A, S); } From 7eb3002790e1d593d4b420dacde8133b40cedec2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Thu, 20 Oct 2022 17:25:52 +0200 Subject: [PATCH 12/35] Avoid computing all angles if possible --- .../CGAL/Weights/mixed_voronoi_region_weights.h | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/Weights/include/CGAL/Weights/mixed_voronoi_region_weights.h b/Weights/include/CGAL/Weights/mixed_voronoi_region_weights.h index 35136a82ec5..647e771a7c9 100644 --- a/Weights/include/CGAL/Weights/mixed_voronoi_region_weights.h +++ b/Weights/include/CGAL/Weights/mixed_voronoi_region_weights.h @@ -42,12 +42,10 @@ typename GeomTraits::FT mixed_voronoi_area(const typename GeomTraits::Point_2& p auto midpoint_2 = traits.construct_midpoint_2_object(); auto circumcenter_2 = traits.construct_circumcenter_2_object(); - const Angle a1 = angle_2(p, q, r); - const Angle a2 = angle_2(q, r, p); - const Angle a3 = angle_2(r, p, q); - Point_2 center; - if (a1 != CGAL::OBTUSE && a2 != CGAL::OBTUSE && a3 != CGAL::OBTUSE) + if (angle_2(p, q, r) != CGAL::OBTUSE && + angle_2(q, r, p) != CGAL::OBTUSE && + angle_2(r, p, q) != CGAL::OBTUSE) center = circumcenter_2(p, q, r); else center = midpoint_2(r, p); @@ -95,12 +93,10 @@ typename GeomTraits::FT mixed_voronoi_area(const typename GeomTraits::Point_3& p auto midpoint_3 = traits.construct_midpoint_3_object(); auto circumcenter_3 = traits.construct_circumcenter_3_object(); - const Angle a1 = angle_3(p, q, r); - const Angle a2 = angle_3(q, r, p); - const Angle a3 = angle_3(r, p, q); - Point_3 center; - if (a1 != CGAL::OBTUSE && a2 != CGAL::OBTUSE && a3 != CGAL::OBTUSE) + if (angle_3(p, q, r) != CGAL::OBTUSE && + angle_3(q, r, p) != CGAL::OBTUSE && + angle_3(r, p, q) != CGAL::OBTUSE) center = circumcenter_3(p, q, r); else center = midpoint_3(r, p); From 6cd5c24f70c44431c9bd31ff8a40d4cade9f3500 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Thu, 20 Oct 2022 17:26:34 +0200 Subject: [PATCH 13/35] Pass traits to the secure Vor-weighted cotan functor --- .../include/CGAL/Polygon_mesh_processing/fair.h | 16 +++++++++------- .../Plugins/PMP/Hole_filling_plugin.cpp | 13 +++++++------ 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/fair.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/fair.h index 49ea054aa45..b90c3a798bc 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/fair.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/fair.h @@ -159,20 +159,22 @@ bool fair(TriangleMesh& tmesh, #endif typedef typename GetVertexPointMap < TriangleMesh, NamedParameters>::type VPMap; + VPMap vpmap = choose_parameter(get_parameter(np, internal_np::vertex_point), + get_property_map(vertex_point, tmesh)); + + typedef typename GetGeomTraits < TriangleMesh, NamedParameters>::type GT; + GT gt = choose_parameter(get_parameter(np, internal_np::geom_traits)); // Cotangent_weight_with_voronoi_area_fairing has been changed to the version: - // Cotangent_weight_with_voronoi_area_fairing_secure to avoid imprecisions from + // Secure_cotangent_weight_with_voronoi_area to avoid imprecisions from // the issue #4706 - https://github.com/CGAL/cgal/issues/4706. - typedef CGAL::Weights::Secure_cotangent_weight_with_voronoi_area Default_weight_calculator; - - VPMap vpmap_ = choose_parameter(get_parameter(np, internal_np::vertex_point), - get_property_map(vertex_point, tmesh)); + typedef CGAL::Weights::Secure_cotangent_weight_with_voronoi_area Default_weight_calculator; return internal::fair(tmesh, vertices, choose_parameter(get_parameter(np, internal_np::sparse_linear_solver)), - choose_parameter(get_parameter(np, internal_np::weight_calculator), Default_weight_calculator(tmesh, vpmap_)), + choose_parameter(get_parameter(np, internal_np::weight_calculator), Default_weight_calculator(tmesh, vpmap, gt)), choose_parameter(get_parameter(np, internal_np::fairing_continuity), 1), - vpmap_); + vpmap); } template diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp index c4a6207c968..423ee5124c6 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp @@ -725,14 +725,15 @@ bool Polyhedron_demo_hole_filling_plugin::fill use_delaunay_triangulation(use_DT))); } else { - auto pmap = get_property_map(CGAL::vertex_point, poly); + auto vpm = get_property_map(CGAL::vertex_point, poly); + auto weight_calc = CGAL::Weights::Secure_cotangent_weight_with_voronoi_area(poly, vpm, EPICK()); + success = std::get<0>(CGAL::Polygon_mesh_processing::triangulate_refine_and_fair_hole(poly, it, std::back_inserter(patch), CGAL::Emptyset_iterator(), - CGAL::Polygon_mesh_processing::parameters:: - weight_calculator(CGAL::Weights::Secure_cotangent_weight_with_voronoi_area(poly, pmap)). - density_control_factor(alpha). - fairing_continuity(continuity). - use_delaunay_triangulation(use_DT))); + CGAL::parameters::weight_calculator(weight_calc). + density_control_factor(alpha). + fairing_continuity(continuity). + use_delaunay_triangulation(use_DT))); } if(!success) { print_message("Error: fairing is not successful, only triangulation and refinement are applied!"); } From 19f847a74b6caed13faf7923073da7edf11c66d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Thu, 20 Oct 2022 17:27:39 +0200 Subject: [PATCH 14/35] Fix API of cotan functor in shape smoothing --- .../internal/Smoothing/curvature_flow_impl.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Smoothing/curvature_flow_impl.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Smoothing/curvature_flow_impl.h index fa600557af3..fa92c34bb3e 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Smoothing/curvature_flow_impl.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Smoothing/curvature_flow_impl.h @@ -78,7 +78,7 @@ public: vimap_(get(Vertex_local_index(), mesh_)), scale_volume_after_smoothing(true), traits_(traits), - weight_calculator_(mesh, vpmap) + weight_calculator_(mesh_, vpmap_, traits_, false /*no clamping*/, false /*no bounding from below*/) { } template @@ -177,7 +177,8 @@ public: if(is_source_constrained && is_target_constrained) continue; - const FT Lij = weight_calculator_(hi); + // Cotangent_weight returns (cot(beta) + cot(gamma)) / 2 + const FT Lij = FT(2) * weight_calculator_(hi); const std::size_t i_source = get(vimap_, v_source); const std::size_t i_target = get(vimap_, v_target); @@ -368,8 +369,8 @@ private: std::vector diagonal_; // index of vector -> index of vimap_ std::vector constrained_flags_; - const GeomTraits& traits_; - const CGAL::Weights::Edge_cotangent_weight weight_calculator_; + GeomTraits traits_; + const CGAL::Weights::Cotangent_weight weight_calculator_; }; } // internal From 91336eb213ab042b0c2fc61d1772eed9f27c751d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Thu, 20 Oct 2022 17:28:00 +0200 Subject: [PATCH 15/35] Use modern C++ --- .../internal/Smoothing/curvature_flow_impl.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Smoothing/curvature_flow_impl.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Smoothing/curvature_flow_impl.h index fa92c34bb3e..509d2394fdd 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Smoothing/curvature_flow_impl.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Smoothing/curvature_flow_impl.h @@ -186,14 +186,14 @@ public: // note that these constraints create asymmetry in the matrix if(!is_source_constrained) { - stiffness_elements.push_back(Triplet(i_source, i_target, Lij)); - diag_coeff.insert(std::make_pair(i_source, 0)).first->second -= Lij; + stiffness_elements.emplace_back(i_source, i_target, Lij); + diag_coeff.emplace(i_source, 0).first->second -= Lij; } if(!is_target_constrained) { - stiffness_elements.push_back(Triplet(i_target, i_source, Lij)); - diag_coeff.insert(std::make_pair(i_target, 0)).first->second -= Lij; + stiffness_elements.emplace_back(i_target, i_source, Lij); + diag_coeff.emplace(i_target, 0).first->second -= Lij; } } } @@ -201,7 +201,7 @@ public: typename std::unordered_map::iterator it = diag_coeff.begin(), end = diag_coeff.end(); for(; it!=end; ++it) - stiffness_elements.push_back(Triplet(it->first, it->first, it->second)); + stiffness_elements.emplace_back(it->first, it->first, it->second); } void update_mesh_no_scaling(const Eigen_vector& Xx, const Eigen_vector& Xy, const Eigen_vector& Xz) From 010e24f4ff10b75792ae6441d3b2295d2e8fa908 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Thu, 20 Oct 2022 17:28:42 +0200 Subject: [PATCH 16/35] Fix weight calculator initialization in Surface mesh deformation --- .../include/CGAL/Surface_mesh_deformation.h | 252 ++++++++---------- 1 file changed, 110 insertions(+), 142 deletions(-) diff --git a/Surface_mesh_deformation/include/CGAL/Surface_mesh_deformation.h b/Surface_mesh_deformation/include/CGAL/Surface_mesh_deformation.h index c267c49b808..a715accf733 100644 --- a/Surface_mesh_deformation/include/CGAL/Surface_mesh_deformation.h +++ b/Surface_mesh_deformation/include/CGAL/Surface_mesh_deformation.h @@ -55,49 +55,72 @@ enum Deformation_algorithm_tag /// @cond CGAL_DOCUMENT_INTERNAL namespace internal { -template +// property map that create a Simple_cartesian::Point_3 +// on the fly in order the deformation class to be used +// with points with minimal requirements +template +struct SC_on_the_fly_pmap + : public Vertex_point_map +{ + typedef boost::readable_property_map_tag category; + typedef CGAL::Simple_cartesian::Point_3 value_type; + typedef value_type reference; + typedef typename boost::property_traits::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::reference base= + get(static_cast(map), k); + return value_type(base[0], base[1], base[2]); + } +}; + +template struct Types_selectors; -template -struct Types_selectors { +template +struct Types_selectors +{ + typedef SC_on_the_fly_pmap Wrapped_VertexPointMap; + typedef CGAL::Weights::Single_cotangent_weight Weight_calculator; - // Get weight from the weight interface. - typedef CGAL::Weights::Single_cotangent_weight Weight_calculator; - - struct ARAP_visitor{ - template + struct ARAP_visitor + { void init(TriangleMesh, VertexPointMap){} - void rotation_matrix_pre( - typename boost::graph_traits::vertex_descriptor, - TriangleMesh&){} + void rotation_matrix_pre(typename boost::graph_traits::vertex_descriptor, + TriangleMesh&){} template - void update_covariance_matrix( - Square_matrix_3&, - const Square_matrix_3&){} + void update_covariance_matrix(Square_matrix_3&, + const Square_matrix_3&){} void set_sre_arap_alpha(double){} }; }; -template -struct Types_selectors { +template +struct Types_selectors +{ + typedef SC_on_the_fly_pmap Wrapped_VertexPointMap; + typedef CGAL::Weights::Cotangent_weight Weight_calculator; - // Get weight from the weight interface. - typedef CGAL::Weights::Cotangent_weight Weight_calculator; - - typedef typename Types_selectors - ::ARAP_visitor ARAP_visitor; + typedef typename Types_selectors::ARAP_visitor ARAP_visitor; }; -template -struct Types_selectors { +template +struct Types_selectors +{ + typedef SC_on_the_fly_pmap Wrapped_VertexPointMap; + typedef CGAL::Weights::Cotangent_weight Weight_calculator; - // Get weight from the weight interface. - typedef CGAL::Weights::Cotangent_weight Weight_calculator; - - class ARAP_visitor{ + class ARAP_visitor + { double m_nb_edges_incident; double m_area; double m_alpha; @@ -105,7 +128,6 @@ struct Types_selectors { public: ARAP_visitor(): m_alpha(0.02) {} - template void init(TriangleMesh triangle_mesh, const VertexPointMap& vpmap) { // calculate area @@ -144,31 +166,6 @@ struct Types_selectors { }; }; -// property map that create a Simple_cartesian::Point_3 -// on the fly in order the deformation class to be used -// with points with minimal requirements -template -struct SC_on_the_fly_pmap - : public Vertex_point_map -{ - typedef boost::readable_property_map_tag category; - typedef CGAL::Simple_cartesian::Point_3 value_type; - typedef value_type reference; - typedef typename boost::property_traits::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::reference base= - get(static_cast(map), k); - return value_type(base[0], base[1], base[2]); - } -}; - - }//namespace internal /// @endcond @@ -235,17 +232,6 @@ public: typedef HIM Hedge_index_map; #endif -// weight calculator -#ifndef DOXYGEN_RUNNING - typedef typename Default::Get< - WC, - typename internal::Types_selectors::Weight_calculator - >::type Weight_calculator; -#else - /// weight calculator functor type - typedef WC Weight_calculator; -#endif - // sparse linear solver #ifndef DOXYGEN_RUNNING typedef typename Default::Get< @@ -290,6 +276,17 @@ public: typedef VPM Vertex_point_map; #endif +// weight calculator +#ifndef DOXYGEN_RUNNING + typedef typename Default::Get< + WC, + typename internal::Types_selectors::Weight_calculator + >::type Weight_calculator; +#else + /// weight calculator functor type + typedef WC Weight_calculator; +#endif + /// The type for vertex descriptor typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; /// The type for halfedge descriptor @@ -304,8 +301,6 @@ public: private: typedef Surface_mesh_deformation Self; // Repeat Triangle_mesh types - typedef typename boost::graph_traits::vertex_iterator vertex_iterator; - typedef typename boost::graph_traits::halfedge_iterator halfedge_iterator; typedef typename boost::graph_traits::in_edge_iterator in_edge_iterator; typedef typename boost::graph_traits::out_edge_iterator out_edge_iterator; @@ -340,12 +335,11 @@ private: bool last_preprocess_successful; ///< stores the result of last call to preprocess() + Vertex_point_map vertex_point_map; Weight_calculator weight_calculator; - Vertex_point_map vertex_point_map; - public: - typename internal::Types_selectors::ARAP_visitor arap_visitor; + typename internal::Types_selectors::ARAP_visitor arap_visitor; private: #ifdef CGAL_DEFORM_MESH_USE_EXPERIMENTAL_SCALE @@ -359,68 +353,13 @@ public: public: /// \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(num_vertices(triangle_mesh), (std::numeric_limits::max)() )), - is_roi_map(std::vector(num_vertices(triangle_mesh), false)), - is_ctrl_map(std::vector(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(num_vertices(triangle_mesh), (std::numeric_limits::max)() )), - is_roi_map(std::vector(num_vertices(triangle_mesh), false)), - is_ctrl_map(std::vector(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(num_vertices(triangle_mesh), (std::numeric_limits::max)() )), - is_roi_map(std::vector(num_vertices(triangle_mesh), false)), - is_ctrl_map(std::vector(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 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, - Weight_calculator weight_calculator = Weight_calculator()) + Weight_calculator weight_calculator) : m_triangle_mesh(triangle_mesh), vertex_index_map(vertex_index_map), hedge_index_map(hedge_index_map), @@ -431,13 +370,47 @@ public: need_preprocess_factorization(true), need_preprocess_region_of_solution(true), 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(); } + + 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))) + { } + + 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 - #if DOXYGEN_RUNNING + +#if DOXYGEN_RUNNING /// \name Construction /// @{ /** @@ -457,21 +430,17 @@ public: Vertex_index_map vertex_index_map = unspecified_internal_vertex_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), - Weight_calculator weight_calculator = Weight_calculator()); + Weight_calculator weight_calculator = Weight_calculator(triangle_mesh, vertex_point_map)); /// @} #endif private: - void init() { - typedef internal::SC_on_the_fly_pmap 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( - this->weight_calculator(*eb, m_triangle_mesh, Wrapper(vertex_point_map))); - } + void init() + { + hedge_weight.reserve(num_halfedges(m_triangle_mesh)); + 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); } @@ -854,7 +823,6 @@ public: */ void overwrite_initial_geometry() { - typedef internal::SC_on_the_fly_pmap Wrapper; if(roi.empty()) { return; } // no ROI to overwrite 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); 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; halfedge_descriptor e_opp = opposite(he, m_triangle_mesh); 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; } } From b469a58df9b31d58349138cf878021c8028139bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Thu, 20 Oct 2022 17:29:44 +0200 Subject: [PATCH 17/35] Fix compilation of alternate, unused iterative authalic initializers --- .../Iterative_authalic_parameterizer_3.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Iterative_authalic_parameterizer_3.h b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Iterative_authalic_parameterizer_3.h index 2e475b11db8..50c2fb16165 100644 --- a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Iterative_authalic_parameterizer_3.h +++ b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Iterative_authalic_parameterizer_3.h @@ -478,7 +478,7 @@ private: double weight; }; - NT determinant(Point_2& v0, Point_2& v1) const + NT determinant(const Point_2& v0, const Point_2& v1) const { return (v0.x() * v1.y() - v1.x() * v0.y()); } @@ -489,8 +489,8 @@ private: const NT det0 = determinant(uv1, uv2); const NT det1 = determinant(uv2, uv0); const NT det2 = determinant(uv0, uv1); - const NT det3 = CGAL::determinant(Vector_2(uv1.x()-uv0.x(), uv1.y()-uv0.y()), - Vector_2(uv2.x()-uv0.x(), uv2.y()-uv0.y())); + NT det3 = CGAL::determinant(Vector_2(uv1.x()-uv0.x(), uv1.y()-uv0.y()), + Vector_2(uv2.x()-uv0.x(), uv2.y()-uv0.y())); CGAL_assertion(det3 > NT(0)); if(det3 <= NT(0)) det3 = NT(1); @@ -527,7 +527,7 @@ private: { Neighbor_list NL; NL.vertex = *v_j; - NL.vector = Vector_3(get(ppmap, v), tmesh.point(*v_j)); + NL.vector = Vector_3(get(ppmap, v), get(ppmap, *v_j)); NL.length = sqrt(NL.vector.squared_length()); neighbor_list.push_back(NL); ++neighborsCounter; From 936b02b87eb45f7127b36ce3d3b5f9e114e515d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Thu, 20 Oct 2022 17:30:18 +0200 Subject: [PATCH 18/35] Fix order of points: the circulator is clockwise around the vertex --- .../Discrete_authalic_parameterizer_3.h | 2 +- .../Discrete_conformal_map_parameterizer_3.h | 2 +- .../Iterative_authalic_parameterizer_3.h | 2 +- .../Mean_value_coordinates_parameterizer_3.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Discrete_authalic_parameterizer_3.h b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Discrete_authalic_parameterizer_3.h index aeb891cff92..ee6c011ce30 100644 --- a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Discrete_authalic_parameterizer_3.h +++ b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Discrete_authalic_parameterizer_3.h @@ -187,7 +187,7 @@ protected: ++next_vertex_v_l; const Point_3& position_v_l = get(ppmap, *next_vertex_v_l); - return CGAL::Weights::authalic_weight(position_v_k, position_v_j, position_v_l, position_v_i) / NT(2); + return CGAL::Weights::authalic_weight(position_v_l, position_v_j, position_v_k, position_v_i) / NT(2); } }; diff --git a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Discrete_conformal_map_parameterizer_3.h b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Discrete_conformal_map_parameterizer_3.h index 3d09fad861c..b1afca32d4e 100644 --- a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Discrete_conformal_map_parameterizer_3.h +++ b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Discrete_conformal_map_parameterizer_3.h @@ -183,7 +183,7 @@ protected: ++next_vertex_v_l; const Point_3& position_v_l = get(ppmap, *next_vertex_v_l); - return CGAL::Weights::cotangent_weight(position_v_k, position_v_j, position_v_l, position_v_i) / NT(2); + return CGAL::Weights::cotangent_weight(position_v_l, position_v_j, position_v_k, position_v_i) / NT(2); } }; diff --git a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Iterative_authalic_parameterizer_3.h b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Iterative_authalic_parameterizer_3.h index 50c2fb16165..fce8e6d3622 100644 --- a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Iterative_authalic_parameterizer_3.h +++ b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Iterative_authalic_parameterizer_3.h @@ -723,7 +723,7 @@ private: VertexIndexMap& vimap) const { auto vpm = get_const_property_map(CGAL::vertex_point, tmesh); - const CGAL::Weights::Edge_tangent_weight compute_mvc(tmesh, vpm); + const CGAL::Weights::Edge_tangent_weight weight_calc(tmesh, vpm, Kernel()); const int i = get(vimap, v); diff --git a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Mean_value_coordinates_parameterizer_3.h b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Mean_value_coordinates_parameterizer_3.h index 95593adf95e..630391fa28b 100644 --- a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Mean_value_coordinates_parameterizer_3.h +++ b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Mean_value_coordinates_parameterizer_3.h @@ -206,7 +206,7 @@ protected: ++next_vertex_v_l; const Point_3& position_v_l = get(ppmap, *next_vertex_v_l); - return CGAL::Weights::tangent_weight(position_v_k, position_v_j, position_v_l, position_v_i) / NT(2); + return CGAL::Weights::tangent_weight(position_v_l, position_v_j, position_v_k, position_v_i) / NT(2); } }; From ca93b406a2f57baad1a3d3bfc771805191ab62dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Thu, 20 Oct 2022 17:30:45 +0200 Subject: [PATCH 19/35] Avoid needless length check (the weight functors already do it) --- .../Iterative_authalic_parameterizer_3.h | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Iterative_authalic_parameterizer_3.h b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Iterative_authalic_parameterizer_3.h index fce8e6d3622..ca2fba0a85d 100644 --- a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Iterative_authalic_parameterizer_3.h +++ b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Iterative_authalic_parameterizer_3.h @@ -641,9 +641,6 @@ private: const PPM_ref position_v_i = get(ppmap, main_vertex_v_i); const PPM_ref position_v_j = get(ppmap, *neighbor_vertex_v_j); - const Vector_3 edge = position_v_i - position_v_j; - const NT squared_length = edge * edge; - vertex_around_target_circulator previous_vertex_v_k = neighbor_vertex_v_j; --previous_vertex_v_k; const PPM_ref position_v_k = get(ppmap, *previous_vertex_v_k); @@ -652,14 +649,10 @@ private: ++next_vertex_v_l; const PPM_ref position_v_l = get(ppmap, *next_vertex_v_l); - NT weight = NT(0); - CGAL_assertion(squared_length > NT(0)); // two points are identical! - if(squared_length != NT(0)) { - // This version was commented out to be an alternative weight - // in the original code by authors. - // weight = CGAL::Weights::authalic_weight(position_v_k, position_v_j, position_v_l, position_v_i) / NT(2); - weight = CGAL::Weights::cotangent_weight(position_v_k, position_v_j, position_v_l, position_v_i) / NT(2); - } + // This version was commented out to be an alternative weight in the original code by authors. +// NT weight = CGAL::Weights::authalic_weight(position_v_l, position_v_j, position_v_k, position_v_i) / NT(2); + NT weight = CGAL::Weights::cotangent_weight(position_v_l, position_v_j, position_v_k, position_v_i) / NT(2); + return weight; } From dfe3ff5d608fbdd4dbddb75b94a4ca426aa160c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Thu, 20 Oct 2022 17:31:22 +0200 Subject: [PATCH 20/35] Code clarifications --- .../ARAP_parameterizer_3.h | 1 + .../Iterative_authalic_parameterizer_3.h | 2 +- .../Orbifold_Tutte_parameterizer_3.h | 10 +++++++--- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/ARAP_parameterizer_3.h b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/ARAP_parameterizer_3.h index 33fef26c674..154b6f7f940 100644 --- a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/ARAP_parameterizer_3.h +++ b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/ARAP_parameterizer_3.h @@ -458,6 +458,7 @@ private: const Faces_vector& faces, Cot_map ctmap) const { + // Since we loop faces, we are implicitely defining the weight of border halfedges as 0... for(face_descriptor fd : faces) { halfedge_descriptor hd = halfedge(fd, mesh), hdb = hd; diff --git a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Iterative_authalic_parameterizer_3.h b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Iterative_authalic_parameterizer_3.h index ca2fba0a85d..06d0fbc09bd 100644 --- a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Iterative_authalic_parameterizer_3.h +++ b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Iterative_authalic_parameterizer_3.h @@ -726,7 +726,7 @@ private: for(halfedge_descriptor h : CGAL::halfedges_around_target(v, tmesh)) { - NT w_ij = NT(-1) * compute_mvc(h); + NT w_ij = NT(-1) * weight_calc(h); // w_ii = - sum of w_ijs w_ii -= w_ij; diff --git a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Orbifold_Tutte_parameterizer_3.h b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Orbifold_Tutte_parameterizer_3.h index 3f8337d0660..5256204c0fd 100644 --- a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Orbifold_Tutte_parameterizer_3.h +++ b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Orbifold_Tutte_parameterizer_3.h @@ -783,9 +783,13 @@ private: const int i = get(vimap, vi); const int j = get(vimap, vj); - if (i > j) continue; - const CGAL::Weights::Cotangent_weight cotangent_weight; - const NT w_ij = NT(2) * cotangent_weight(hd, mesh, pmap); + if (i > j) + continue; + + const CGAL::Weights::Cotangent_weight cotangent_weight(mesh, pmap); + + // x2 because Cotangent_weight returns 0.5 * (cot alpha + cot beta)... + const NT w_ij = NT(2) * cotangent_weight(hd); // ij M.set_coef(2*i, 2*j, w_ij, true /* new coef */); From 59f2021eaf76da9ddbc7a2dec3552f3ee09a3801 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Thu, 20 Oct 2022 17:32:20 +0200 Subject: [PATCH 21/35] Update Weights doc figure to use compatible notations --- Weights/doc/Weights/fig/discrete_harmonic.svg | 552 +++++++++++------ Weights/doc/Weights/fig/mean_value.svg | 208 +++++-- Weights/doc/Weights/fig/tangent.svg | 229 ++++--- .../doc/Weights/fig/three_point_family.svg | 546 +++++++++++------ Weights/doc/Weights/fig/wachspress.svg | 561 ++++++++++++------ 5 files changed, 1429 insertions(+), 667 deletions(-) diff --git a/Weights/doc/Weights/fig/discrete_harmonic.svg b/Weights/doc/Weights/fig/discrete_harmonic.svg index 21fdafc5cd7..08c74518014 100644 --- a/Weights/doc/Weights/fig/discrete_harmonic.svg +++ b/Weights/doc/Weights/fig/discrete_harmonic.svg @@ -1,235 +1,439 @@ - + - - diff --git a/Weights/doc/Weights/fig/mean_value.svg b/Weights/doc/Weights/fig/mean_value.svg index 0e40e87eaef..d102c8d130f 100644 --- a/Weights/doc/Weights/fig/mean_value.svg +++ b/Weights/doc/Weights/fig/mean_value.svg @@ -1,79 +1,163 @@ - + - - diff --git a/Weights/doc/Weights/fig/tangent.svg b/Weights/doc/Weights/fig/tangent.svg index a52fcf03170..9ee59f419e8 100644 --- a/Weights/doc/Weights/fig/tangent.svg +++ b/Weights/doc/Weights/fig/tangent.svg @@ -1,93 +1,174 @@ - + - - diff --git a/Weights/doc/Weights/fig/three_point_family.svg b/Weights/doc/Weights/fig/three_point_family.svg index 21fdafc5cd7..079ce8129b1 100644 --- a/Weights/doc/Weights/fig/three_point_family.svg +++ b/Weights/doc/Weights/fig/three_point_family.svg @@ -1,235 +1,433 @@ - + - - diff --git a/Weights/doc/Weights/fig/wachspress.svg b/Weights/doc/Weights/fig/wachspress.svg index cc751743d65..2b79da2a60b 100644 --- a/Weights/doc/Weights/fig/wachspress.svg +++ b/Weights/doc/Weights/fig/wachspress.svg @@ -1,244 +1,439 @@ - + - - From 141f05abd27680c6b8b7748f0f236a99588e316a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Thu, 20 Oct 2022 17:32:53 +0200 Subject: [PATCH 22/35] Use num_halfedges instead of 2*num_edges --- .../include/CGAL/Mean_curvature_flow_skeletonization.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Surface_mesh_skeletonization/include/CGAL/Mean_curvature_flow_skeletonization.h b/Surface_mesh_skeletonization/include/CGAL/Mean_curvature_flow_skeletonization.h index 3882180786a..aa86264e177 100644 --- a/Surface_mesh_skeletonization/include/CGAL/Mean_curvature_flow_skeletonization.h +++ b/Surface_mesh_skeletonization/include/CGAL/Mean_curvature_flow_skeletonization.h @@ -883,11 +883,9 @@ private: void compute_edge_weight() { m_edge_weight.clear(); - m_edge_weight.reserve(2 * num_edges(m_tmesh)); + m_edge_weight.reserve(num_halfedges(m_tmesh)); for(halfedge_descriptor hd : halfedges(m_tmesh)) - { m_edge_weight.push_back(m_weight_calculator(hd, m_tmesh, m_tmesh_point_pmap)); - } } /// Assemble the left hand side. From f4f6229c428e182fa59efb11e8a59901cab3cbc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Thu, 20 Oct 2022 17:34:02 +0200 Subject: [PATCH 23/35] Weights examples/tests improvements --- Weights/examples/Weights/convergence.cpp | 1 - .../examples/Weights/weighted_laplacian.cpp | 46 +- Weights/test/Weights/include/utils.h | 611 +++++++++--------- Weights/test/Weights/include/wrappers.h | 250 ++++--- .../test/Weights/test_authalic_weights.cpp | 23 +- .../test_barycentric_region_weights.cpp | 43 +- .../test/Weights/test_cotangent_weights.cpp | 33 +- .../test_discrete_harmonic_weights.cpp | 40 +- .../Weights/test_inverse_distance_weights.cpp | 48 +- .../test/Weights/test_mean_value_weights.cpp | 32 +- .../test_mixed_voronoi_region_weights.cpp | 21 +- .../test/Weights/test_projected_weights.cpp | 8 +- Weights/test/Weights/test_shepard_weights.cpp | 50 +- Weights/test/Weights/test_tangent_weights.cpp | 23 +- .../test_three_point_family_weights.cpp | 37 +- .../test_triangular_region_weights.cpp | 21 +- .../Weights/test_uniform_region_weights.cpp | 25 +- Weights/test/Weights/test_uniform_weights.cpp | 27 +- .../Weights/test_voronoi_region_weights.cpp | 21 +- .../test/Weights/test_wachspress_weights.cpp | 40 +- 20 files changed, 783 insertions(+), 617 deletions(-) diff --git a/Weights/examples/Weights/convergence.cpp b/Weights/examples/Weights/convergence.cpp index 8cc85915531..83bb06ebe83 100644 --- a/Weights/examples/Weights/convergence.cpp +++ b/Weights/examples/Weights/convergence.cpp @@ -1,5 +1,4 @@ #include -#include #include // Typedefs. diff --git a/Weights/examples/Weights/weighted_laplacian.cpp b/Weights/examples/Weights/weighted_laplacian.cpp index bd44f1fb0ea..af3e4345b41 100644 --- a/Weights/examples/Weights/weighted_laplacian.cpp +++ b/Weights/examples/Weights/weighted_laplacian.cpp @@ -20,18 +20,18 @@ using HD = boost::graph_traits::halfedge_descriptor; template FT get_w_ij(const Mesh& mesh, const HD he, const PointMap pmap) { - const auto v0 = target(he, mesh); - const auto v1 = source(he, mesh); + const VD v0 = target(he, mesh); + const VD v1 = source(he, mesh); const auto& q = get(pmap, v0); // query const auto& p1 = get(pmap, v1); // neighbor j if (is_border_edge(he, mesh)) { - const auto he_cw = opposite(next(he, mesh), mesh); - auto v2 = source(he_cw, mesh); + const HD he_cw = opposite(next(he, mesh), mesh); + VD v2 = source(he_cw, mesh); if (is_border_edge(he_cw, mesh)) { - const auto he_ccw = prev(opposite(he, mesh), mesh); + const HD he_ccw = prev(opposite(he, mesh), mesh); v2 = source(he_ccw, mesh); const auto& p2 = get(pmap, v2); // neighbor jp @@ -42,10 +42,10 @@ FT get_w_ij(const Mesh& mesh, const HD he, const PointMap pmap) { } } - const auto he_cw = opposite(next(he, mesh), mesh); - const auto v2 = source(he_cw, mesh); - const auto he_ccw = prev(opposite(he, mesh), mesh); - const auto v3 = source(he_ccw, mesh); + const HD he_cw = opposite(next(he, mesh), mesh); + const VD v2 = source(he_cw, mesh); + const HD he_ccw = prev(opposite(he, mesh), mesh); + const VD v3 = source(he_ccw, mesh); const auto& p0 = get(pmap, v2); // neighbor jm const auto& p2 = get(pmap, v3); // neighbor jp @@ -56,14 +56,14 @@ template FT get_w_i(const Mesh& mesh, const VD v_i, const PointMap pmap) { FT A_i = 0.0; - const auto v0 = v_i; - const auto init = halfedge(v_i, mesh); - for (const auto& he : halfedges_around_target(init, mesh)) { + const VD v0 = v_i; + const HD init = halfedge(v_i, mesh); + for (const HD he : halfedges_around_target(init, mesh)) { assert(v0 == target(he, mesh)); if (is_border(he, mesh)) { continue; } - const auto v1 = source(he, mesh); - const auto v2 = target(next(he, mesh), mesh); + const VD v1 = source(he, mesh); + const VD v2 = target(next(he, mesh), mesh); const auto& p = get(pmap, v0); const auto& q = get(pmap, v1); @@ -81,14 +81,14 @@ void set_laplacian_matrix(const Mesh& mesh, Matrix& L) { // Precompute Voronoi areas. std::map w_i; - for (const auto& v_i : vertices(mesh)) { + for (const VD v_i : vertices(mesh)) { w_i[get(imap, v_i)] = get_w_i(mesh, v_i, pmap); } // Fill the matrix. - for (const auto& he : halfedges(mesh)) { - const auto vi = source(he, mesh); - const auto vj = target(he, mesh); + for (const HD he : halfedges(mesh)) { + const VD vi = source(he, mesh); + const VD vj = target(he, mesh); const std::size_t i = get(imap, vi); const std::size_t j = get(imap, vj); @@ -106,11 +106,11 @@ int main() { // Create mesh. Mesh mesh; - const auto v0 = mesh.add_vertex(Point_3(0, 2, 0)); - const auto v1 = mesh.add_vertex(Point_3(2, 2, 0)); - const auto v2 = mesh.add_vertex(Point_3(0, 0, 0)); - const auto v3 = mesh.add_vertex(Point_3(2, 0, 0)); - const auto v4 = mesh.add_vertex(Point_3(1, 1, 1)); + const VD v0 = mesh.add_vertex(Point_3(0, 2, 0)); + const VD v1 = mesh.add_vertex(Point_3(2, 2, 0)); + const VD v2 = mesh.add_vertex(Point_3(0, 0, 0)); + const VD v3 = mesh.add_vertex(Point_3(2, 0, 0)); + const VD v4 = mesh.add_vertex(Point_3(1, 1, 1)); mesh.add_face(v0, v2, v4); mesh.add_face(v2, v3, v4); mesh.add_face(v3, v1, v4); diff --git a/Weights/test/Weights/include/utils.h b/Weights/test/Weights/include/utils.h index bfbc8d78086..90afd589149 100644 --- a/Weights/test/Weights/include/utils.h +++ b/Weights/test/Weights/include/utils.h @@ -1,113 +1,177 @@ #ifndef CGAL_WEIGHTS_TESTS_UTILS_H #define CGAL_WEIGHTS_TESTS_UTILS_H -// STL includes. +#include + +#include +#include + #include #include #include #include #include -// CGAL includes. -#include -#include -#include +namespace CGAL { +namespace Weights { +namespace internal { + +template +typename Kernel::FT squared_distance(const CGAL::Point_2& p, + const CGAL::Point_2& q) +{ + const Kernel traits; + auto squared_distance_2 = traits.compute_squared_distance_2_object(); + return squared_distance_2(p, q); +} + +template +typename Kernel::FT squared_distance(const CGAL::Point_3& p, + const CGAL::Point_3& q) +{ + const Kernel traits; + auto squared_distance_3 = traits.compute_squared_distance_3_object(); + return squared_distance_3(p, q); +} + +template +typename Kernel::FT distance(const CGAL::Point_2& p, + const CGAL::Point_2& q) +{ + const Kernel traits; + return CGAL::Weights::internal::distance_2(p, q, traits); +} + +template +typename Kernel::FT distance(const CGAL::Point_3& p, + const CGAL::Point_3& q) +{ + const Kernel traits; + return CGAL::Weights::internal::distance_3(p, q, traits); +} + +template +typename Kernel::FT area(const CGAL::Point_2& p, + const CGAL::Point_2& q, + const CGAL::Point_2& r) +{ + const Kernel traits; + return CGAL::Weights::internal::positive_area_2(p, q, r, traits); +} + +template +typename Kernel::FT area(const CGAL::Point_3& p, + const CGAL::Point_3& q, + const CGAL::Point_3& r) +{ + const Kernel traits; + return CGAL::Weights::internal::positive_area_3(p, q, r, traits); +} + +template +typename Kernel::FT scalar_product(const CGAL::Point_2& p, + const CGAL::Point_2& q, + const CGAL::Point_2& r) +{ + const Kernel traits; + auto scalar_product_2 = traits.compute_scalar_product_2_object(); + auto vector_2 = traits.construct_vector_2_object(); + + const auto v1 = vector_2(q, r); + const auto v2 = vector_2(q, p); + return scalar_product_2(v1, v2); +} + +template +typename Kernel::FT scalar_product(const CGAL::Point_3& p, + const CGAL::Point_3& q, + const CGAL::Point_3& r) +{ + const Kernel traits; + auto scalar_product_3 = traits.compute_scalar_product_3_object(); + auto vector_3 = traits.construct_vector_3_object(); + + const auto v1 = vector_3(q, r); + const auto v2 = vector_3(q, p); + + return scalar_product_3(v1, v2); +} + +} // namespace internal +} // namespace Weights +} // namespace CGAL namespace tests { template -FT get_tolerance() { - return FT(1) / FT(10000000000); -} +FT get_tolerance() { return FT(1e-10); } template std::vector< std::array > -get_all_triangles() { - +get_all_triangles() +{ using Point_2 = typename Kernel::Point_2; - const std::array triangle0 = { - Point_2(-1, 0), Point_2(0, -1), Point_2(1, 0) - }; - const std::array triangle1 = { - Point_2(-2, 0), Point_2(0, -1), Point_2(2, 0) - }; - const std::array triangle2 = { - Point_2(-2, 0), Point_2(-2, -2), Point_2(2, 0) - }; - const std::array triangle3 = { - Point_2(-2, 0), Point_2(2, -2), Point_2(2, 0) - }; + + const std::array triangle0 = { Point_2(-1, 0), Point_2(0, -1), Point_2(1, 0) }; + const std::array triangle1 = { Point_2(-2, 0), Point_2(0, -1), Point_2(2, 0) }; + const std::array triangle2 = { Point_2(-2, 0), Point_2(-2, -2), Point_2(2, 0) }; + const std::array triangle3 = { Point_2(-2, 0), Point_2(2, -2), Point_2(2, 0) }; + return { triangle0, triangle1, triangle2, triangle3 }; } template std::vector< std::array > -get_symmetric_triangles() { - +get_symmetric_triangles() +{ using Point_2 = typename Kernel::Point_2; - const std::array triangle0 = { - Point_2(-1, 0), Point_2(0, -1), Point_2(1, 0) - }; - const std::array triangle1 = { - Point_2(-2, 0), Point_2(0, -1), Point_2(2, 0) - }; - const std::array triangle2 = { - Point_2(-3, 0), Point_2(0, -1), Point_2(3, 0) - }; + + const std::array triangle0 = { Point_2(-1, 0), Point_2(0, -1), Point_2(1, 0) }; + const std::array triangle1 = { Point_2(-2, 0), Point_2(0, -1), Point_2(2, 0) }; + const std::array triangle2 = { Point_2(-3, 0), Point_2(0, -1), Point_2(3, 0) }; + return { triangle0, triangle1, triangle2 }; } template std::vector< std::array > -get_uniform_triangles() { - +get_uniform_triangles() +{ using Point_2 = typename Kernel::Point_2; - const std::array triangle0 = { - Point_2(-1, 0), Point_2(0, -1), Point_2(1, 0) - }; - const std::array triangle1 = { - Point_2(-2, 0), Point_2(0, -2), Point_2(2, 0) - }; - const std::array triangle2 = { - Point_2(1, 0), Point_2(-1, 0), Point_2(-1, -2) - }; - const std::array triangle3 = { - Point_2(1, -2), Point_2(1, 0), Point_2(-1, 0) - }; + + const std::array triangle0 = { Point_2(-1, 0), Point_2(0, -1), Point_2(1, 0) }; + const std::array triangle1 = { Point_2(-2, 0), Point_2(0, -2), Point_2(2, 0) }; + const std::array triangle2 = { Point_2(1, 0), Point_2(-1, 0), Point_2(-1, -2) }; + const std::array triangle3 = { Point_2(1, -2), Point_2(1, 0), Point_2(-1, 0) }; + return { triangle0, triangle1, triangle2, triangle3 }; } template std::vector< std::vector > -get_all_polygons() { - +get_all_polygons() +{ using Point_2 = typename Kernel::Point_2; - const std::vector polygon0 = { - Point_2(-2, -2), Point_2(2, -2), Point_2(0, 2) - }; - const std::vector polygon1 = { - Point_2(-1, -1), Point_2(1, -1), Point_2(1, 1), Point_2(-1, 1) - }; - const std::vector polygon2 = { - Point_2(-2, 0), Point_2(0, -2), Point_2(2, 0), Point_2(0, 2) - }; - const std::vector polygon3 = { - Point_2(-2, -2), Point_2(2, -2), Point_2(2, 0), Point_2(0, 2), Point_2(-2, 0) - }; + + const std::vector polygon0 = { Point_2(-2, -2), Point_2(2, -2), Point_2(0, 2) }; + const std::vector polygon1 = { Point_2(-1, -1), Point_2(1, -1), Point_2(1, 1), Point_2(-1, 1) }; + const std::vector polygon2 = { Point_2(-2, 0), Point_2(0, -2), Point_2(2, 0), Point_2(0, 2) }; + const std::vector polygon3 = { Point_2(-2, -2), Point_2(2, -2), Point_2(2, 0), + Point_2(0, 2), Point_2(-2, 0) }; + return { polygon0, polygon1, polygon2, polygon3 }; } -template< -typename Kernel, -typename Weight_wrapper> -bool test_query( - const Weight_wrapper& wrapper, - const typename Kernel::Point_2& query, - const std::array& neighbors) { - +template +void test_query(const Weight_wrapper& wrapper, + const typename Kernel::Point_2& query, + const std::array& neighbors) +{ using FT = typename Kernel::FT; using Point_2 = typename Kernel::Point_2; using Point_3 = typename Kernel::Point_3; + const FT tol = get_tolerance(); // 2D configuration. @@ -122,36 +186,28 @@ bool test_query( const Point_3 p3(p2.x(), p2.y(), 1); const Point_3 q3(q2.x(), q2.y(), 1); - const auto a2 = wrapper.weight_a(t2, r2, p2, q2); - const auto b2 = wrapper.weight_b(t2, r2, p2, q2); - CGAL_assertion(a2 >= FT(0) && b2 >= FT(0)); - if (a2 < FT(0) || b2 < FT(0)) return false; - CGAL_assertion(CGAL::abs(a2 - b2) < tol); - if (CGAL::abs(a2 - b2) >= tol) return false; + const FT a2 = wrapper.weight_a(t2, r2, p2, q2); + const FT b2 = wrapper.weight_b(t2, r2, p2, q2); + assert(a2 >= FT(0) && b2 >= FT(0)); + assert(CGAL::abs(a2 - b2) < tol); - if (wrapper.supports_3d()) { - const auto a3 = wrapper.weight_a(t3, r3, p3, q3); - const auto b3 = wrapper.weight_b(t3, r3, p3, q3); - CGAL_assertion(a3 >= FT(0) && b3 >= FT(0)); - if (a3 < FT(0) || b3 < FT(0)) return false; - CGAL_assertion(CGAL::abs(a3 - b3) < tol); - if (CGAL::abs(a3 - b3) >= tol) return false; - CGAL_assertion(CGAL::abs(a2 - a3) < tol); - CGAL_assertion(CGAL::abs(b2 - b3) < tol); - if (CGAL::abs(a2 - a3) >= tol) return false; - if (CGAL::abs(b2 - b3) >= tol) return false; + if (wrapper.supports_3d()) + { + const FT a3 = wrapper.weight_a(t3, r3, p3, q3); + const FT b3 = wrapper.weight_b(t3, r3, p3, q3); + assert(a3 >= FT(0) && b3 >= FT(0)); + assert(CGAL::abs(a3 - b3) < tol); + assert(CGAL::abs(a2 - a3) < tol); + assert(CGAL::abs(b2 - b3) < tol); } - return true; } -template< -typename Kernel, -typename Weight_wrapper> -bool test_symmetry_x( - const Weight_wrapper& wrapper, - const std::array& neighbors, - const typename Kernel::FT& x) { - +template +void test_symmetry_x(const Weight_wrapper& wrapper, + const std::array& neighbors, + const typename Kernel::FT& x) +{ using FT = typename Kernel::FT; using Point_2 = typename Kernel::Point_2; using Point_3 = typename Kernel::Point_3; @@ -167,41 +223,34 @@ bool test_symmetry_x( const Point_3 r3(r2.x(), r2.y(), 1); const Point_3 p3(p2.x(), p2.y(), 1); - const auto a2 = wrapper.weight_a(t2, r2, p2, Point_2(-x, 0)); - const auto b2 = wrapper.weight_a(t2, r2, p2, Point_2(+x, 0)); - CGAL_assertion(a2 >= FT(0) && b2 >= FT(0)); - if (a2 < FT(0) || b2 < FT(0)) return false; - CGAL_assertion(CGAL::abs(a2 - b2) < tol); - if (CGAL::abs(a2 - b2) >= tol) return false; + const FT a2 = wrapper.weight_a(t2, r2, p2, Point_2(-x, 0)); + const FT b2 = wrapper.weight_a(t2, r2, p2, Point_2(+x, 0)); + assert(a2 >= FT(0) && b2 >= FT(0)); + assert(CGAL::abs(a2 - b2) < tol); - if (wrapper.supports_3d()) { - const auto a3 = wrapper.weight_a(t3, r3, p3, Point_3(-x, 0, 1)); - const auto b3 = wrapper.weight_a(t3, r3, p3, Point_3(+x, 0, 1)); - CGAL_assertion(a3 >= FT(0) && b3 >= FT(0)); - if (a3 < FT(0) || b3 < FT(0)) return false; - CGAL_assertion(CGAL::abs(a3 - b3) < tol); - if (CGAL::abs(a3 - b3) >= tol) return false; - CGAL_assertion(CGAL::abs(a2 - a3) < tol); - CGAL_assertion(CGAL::abs(b2 - b3) < tol); - if (CGAL::abs(a2 - a3) >= tol) return false; - if (CGAL::abs(b2 - b3) >= tol) return false; + if (wrapper.supports_3d()) + { + const FT a3 = wrapper.weight_a(t3, r3, p3, Point_3(-x, 0, 1)); + const FT b3 = wrapper.weight_a(t3, r3, p3, Point_3(+x, 0, 1)); + assert(a3 >= FT(0) && b3 >= FT(0)); + assert(CGAL::abs(a3 - b3) < tol); + assert(CGAL::abs(a2 - a3) < tol); + assert(CGAL::abs(b2 - b3) < tol); } - return true; } -template< -typename Kernel, -typename Weight_wrapper_1, -typename Weight_wrapper_2> -bool test_compare( - const Weight_wrapper_1& wrapper1, - const Weight_wrapper_2& wrapper2, - const typename Kernel::Point_2& query, - const std::array& neighbors) { - +template +void test_compare(const Weight_wrapper_1& wrapper1, + const Weight_wrapper_2& wrapper2, + const typename Kernel::Point_2& query, + const std::array& neighbors) +{ using FT = typename Kernel::FT; using Point_2 = typename Kernel::Point_2; using Point_3 = typename Kernel::Point_3; + const FT tol = get_tolerance(); // 2D configuration. @@ -216,34 +265,29 @@ bool test_compare( const Point_3 p3(p2.x(), p2.y(), 1); const Point_3 q3(q2.x(), q2.y(), 1); - const auto a2 = wrapper1.weight_a(t2, r2, p2, q2); - const auto b2 = wrapper2.weight_a(t2, r2, p2, q2); - CGAL_assertion(a2 >= FT(0) && b2 >= FT(0)); - if (a2 < FT(0) || b2 < FT(0)) return false; - CGAL_assertion(CGAL::abs(a2 - b2) < tol); - if (CGAL::abs(a2 - b2) >= tol) return false; + const FT a2 = wrapper1.weight_a(t2, r2, p2, q2); + const FT b2 = wrapper2.weight_a(t2, r2, p2, q2); + assert(a2 >= FT(0) && b2 >= FT(0)); + assert(CGAL::abs(a2 - b2) < tol); - if (wrapper1.supports_3d() && wrapper2.supports_3d()) { - const auto a3 = wrapper1.weight_a(t3, r3, p3, q3); - const auto b3 = wrapper2.weight_a(t3, r3, p3, q3); - CGAL_assertion(a3 >= FT(0) && b3 >= FT(0)); - if (a3 < FT(0) || b3 < FT(0)) return false; - CGAL_assertion(CGAL::abs(a3 - b3) < tol); - if (CGAL::abs(a3 - b3) >= tol) return false; + if (wrapper1.supports_3d() && wrapper2.supports_3d()) + { + const FT a3 = wrapper1.weight_a(t3, r3, p3, q3); + const FT b3 = wrapper2.weight_a(t3, r3, p3, q3); + assert(a3 >= FT(0) && b3 >= FT(0)); + assert(CGAL::abs(a3 - b3) < tol); } - return true; } -template< -typename Kernel, -typename Weight_wrapper> -bool test_neighbors( - const Weight_wrapper& wrapper, - const std::array& neighbors) { - +template +void test_neighbors(const Weight_wrapper& wrapper, + const std::array& neighbors) +{ using FT = typename Kernel::FT; using Point_2 = typename Kernel::Point_2; using Point_3 = typename Kernel::Point_3; + const FT tol = get_tolerance(); // 2D configuration. @@ -256,22 +300,17 @@ bool test_neighbors( const Point_3 q3(q2.x(), q2.y(), 1); const Point_3 r3(r2.x(), r2.y(), 1); - const auto a2 = wrapper.weight(p2, q2, r2); - const auto a3 = wrapper.weight(p3, q3, r3); - CGAL_assertion(a2 >= FT(0) && a3 >= FT(0)); - if (a2 < FT(0) || a3 < FT(0)) return false; - CGAL_assertion(CGAL::abs(a2 - a3) < tol); - if (CGAL::abs(a2 - a3) >= tol) return false; - return true; + const FT a2 = wrapper.weight(p2, q2, r2); + const FT a3 = wrapper.weight(p3, q3, r3); + assert(a2 >= FT(0) && a3 >= FT(0)); + assert(CGAL::abs(a2 - a3) < tol); } -template< -typename Kernel, -typename Weight_wrapper> -bool test_area( - const Weight_wrapper& wrapper, - const std::array& neighbors) { - +template +void test_area(const Weight_wrapper& wrapper, + const std::array& neighbors) +{ using FT = typename Kernel::FT; using Point_2 = typename Kernel::Point_2; using Point_3 = typename Kernel::Point_3; @@ -286,129 +325,105 @@ bool test_area( const Point_3 q3(q2.x(), q2.y(), 1); const Point_3 r3(r2.x(), r2.y(), 1); - const auto a2 = wrapper.weight(p2, q2, r2); - const auto a3 = wrapper.weight(p3, q3, r3); - CGAL_assertion(a2 <= CGAL::Weights::area(p2, q2, r2)); - CGAL_assertion(a3 <= CGAL::Weights::area(p3, q3, r3)); - if (a2 > CGAL::Weights::area(p2, q2, r2)) return false; - if (a3 > CGAL::Weights::area(p3, q3, r3)) return false; - CGAL_assertion(a2 >= FT(0)); - CGAL_assertion(a3 >= FT(0)); - if (a2 < FT(0)) return false; - if (a3 < FT(0)) return false; - return true; + const FT a2 = wrapper.weight(p2, q2, r2); + const FT a3 = wrapper.weight(p3, q3, r3); + assert(a2 <= CGAL::Weights::internal::area(p2, q2, r2)); + assert(a3 <= CGAL::Weights::internal::area(p3, q3, r3)); + + assert(a2 >= FT(0)); + assert(a3 >= FT(0)); } template -bool test_coordinates( - const Point& query, - const std::vector& polygon, - const std::vector& weights) { - - CGAL_assertion(weights.size() > 0); - if (weights.size() == 0) return false; +void test_coordinates(const Point& query, + const std::vector& polygon, + const std::vector& weights) +{ + assert(weights.size() > 0); // Compute the sum of weights. const FT tol = get_tolerance(); FT sum = FT(0); - for (const FT& weight : weights) { + for (const FT& weight : weights) sum += weight; - } - CGAL_assertion(sum >= tol); - if (sum < tol) return false; + assert(sum >= tol); // Compute coordinates. std::vector coordinates; coordinates.reserve(weights.size()); - for (const FT& weight : weights) { + for (const FT& weight : weights) coordinates.push_back(weight / sum); - } - CGAL_assertion(coordinates.size() == weights.size()); - if (coordinates.size() != weights.size()) return false; + + assert(coordinates.size() == weights.size()); // Test partition of unity. sum = FT(0); - for (const FT& coordinate : coordinates) { + for (const FT& coordinate : coordinates) sum += coordinate; - } - CGAL_assertion(CGAL::abs(FT(1) - sum) < tol); - if (CGAL::abs(FT(1) - sum) >= tol) return false; + assert(CGAL::abs(FT(1) - sum) < tol); // Test linear precision. FT x = FT(0), y = FT(0); - for (std::size_t i = 0; i < polygon.size(); ++i) { + for (std::size_t i = 0; i < polygon.size(); ++i) + { x += coordinates[i] * polygon[i].x(); y += coordinates[i] * polygon[i].y(); } - CGAL_assertion(CGAL::abs(query.x() - x) < tol); - CGAL_assertion(CGAL::abs(query.y() - y) < tol); - if (CGAL::abs(query.x() - x) >= tol) return false; - if (CGAL::abs(query.y() - y) >= tol) return false; - return true; + assert(CGAL::abs(query.x() - x) < tol); + assert(CGAL::abs(query.y() - y) < tol); } -template< -typename Kernel, -typename Weight_wrapper> -bool test_on_polygon( - const Weight_wrapper& wrapper, - const typename Kernel::Point_2& query_2, - const std::vector& polygon_2) { - +template +void test_on_polygon(const Weight_wrapper& wrapper, + const typename Kernel::Point_2& query_2, + const std::vector& polygon_2) +{ // Get weights. using FT = typename Kernel::FT; - CGAL_assertion(polygon_2.size() >= 3); - if (polygon_2.size() < 3) return false; + assert(polygon_2.size() >= 3); // 2D version. std::vector weights_2; weights_2.reserve(polygon_2.size()); - wrapper.compute_on_polygon( - polygon_2, query_2, Kernel(), std::back_inserter(weights_2)); - CGAL_assertion(weights_2.size() == polygon_2.size()); - if (weights_2.size() != polygon_2.size()) return false; - if (!test_coordinates(query_2, polygon_2, weights_2)) return false; + wrapper.compute_on_polygon(polygon_2, query_2, Kernel(), std::back_inserter(weights_2)); + assert(weights_2.size() == polygon_2.size()); + test_coordinates(query_2, polygon_2, weights_2); // 3D version. using Point_3 = typename Kernel::Point_3; const Point_3 query_3(query_2.x(), query_2.y(), 1); std::vector polygon_3; polygon_3.reserve(polygon_2.size()); - for (const auto& vertex_2 : polygon_2) { - polygon_3.push_back(Point_3(vertex_2.x(), vertex_2.y(), 1)); - } - CGAL_assertion(polygon_3.size() == polygon_2.size()); - if (polygon_3.size() != polygon_2.size()) return false; - const CGAL::Projection_traits_xy_3 ptraits; + for (const auto& vertex_2 : polygon_2) + polygon_3.emplace_back(vertex_2.x(), vertex_2.y(), 1); + assert(polygon_3.size() == polygon_2.size()); + const CGAL::Projection_traits_xy_3 ptraits; std::vector weights_3; weights_3.reserve(polygon_3.size()); - wrapper.compute_on_polygon( - polygon_3, query_3, ptraits, std::back_inserter(weights_3)); - CGAL_assertion(weights_3.size() == polygon_3.size()); - if (weights_3.size() != polygon_3.size()) return false; - if (!test_coordinates(query_3, polygon_3, weights_3)) return false; - return true; + wrapper.compute_on_polygon(polygon_3, query_3, ptraits, std::back_inserter(weights_3)); + assert(weights_3.size() == polygon_3.size()); + + test_coordinates(query_3, polygon_3, weights_3); } -template< -typename Kernel, -typename Weight_wrapper> -bool test_barycentric_properties( - const Weight_wrapper& wrapper, - const typename Kernel::Point_2& query, - const std::vector& polygon) { - +template +void test_barycentric_properties(const Weight_wrapper& wrapper, + const typename Kernel::Point_2& query, + const std::vector& polygon) +{ // Get weights. using FT = typename Kernel::FT; const std::size_t n = polygon.size(); - CGAL_assertion(n >= 3); - if (n < 3) return false; + assert(n >= 3); // Check properties. std::vector weights; weights.reserve(n); - for (std::size_t i = 0; i < n; ++i) { + for (std::size_t i = 0; i < n; ++i) + { const std::size_t im = (i + n - 1) % n; const std::size_t ip = (i + 1) % n; const auto& t = polygon[im]; @@ -418,24 +433,20 @@ bool test_barycentric_properties( const FT weight = wrapper.weight_a(t, r, p, q); weights.push_back(weight); } - CGAL_assertion(weights.size() == n); - if (weights.size() != n) return false; - if (!test_coordinates(query, polygon, weights)) return false; - return true; + assert(weights.size() == n); + + test_coordinates(query, polygon, weights); } -template< -typename Kernel, -typename Weight_wrapper_1, -typename Weight_wrapper_2> -bool test_analytic_weight( - const Weight_wrapper_1& weight, - const Weight_wrapper_2& alternative) { - +template +void test_analytic_weight(const Weight_wrapper_1& weight, + const Weight_wrapper_2& alternative) +{ using FT = typename Kernel::FT; using Point_2 = typename Kernel::Point_2; - // Data. const FT q = FT(1) / FT(4); const FT h = FT(1) / FT(2); const FT t = FT(3) / FT(4); @@ -449,66 +460,59 @@ bool test_analytic_weight( // Test query points. auto configs = get_all_triangles(); - for (const auto& config : configs) { - if (!test_query(weight, zero, config)) return false; - for (const auto& query : queries) { - if (!test_query(weight, query, config)) return false; - } + for (const auto& config : configs) + { + test_query(weight, zero, config); + for (const auto& query : queries) + test_query(weight, query, config); } // Test alternative formulations. - for (const auto& config : configs) { - if (!test_compare(weight, alternative, zero, config)) { - return false; - } - for (const auto& query : queries) { - if (!test_compare(weight, alternative, query, config)) { - return false; - } - } + for (const auto& config : configs) + { + test_compare(weight, alternative, zero, config); + for (const auto& query : queries) + test_compare(weight, alternative, query, config); } // Test symmetry along x axis. configs = get_symmetric_triangles(); - for (const auto& config : configs) { - if (!test_symmetry_x(weight, config, q)) return false; - if (!test_symmetry_x(weight, config, h)) return false; - if (!test_symmetry_x(weight, config, t)) return false; + for (const auto& config : configs) + { + test_symmetry_x(weight, config, q); + test_symmetry_x(weight, config, h); + test_symmetry_x(weight, config, t); } // Test barycentric properties. - if (weight.is_barycentric()) { + if (weight.is_barycentric()) + { const auto polygons = get_all_polygons(); - for (const auto& polygon : polygons) { - if (!test_barycentric_properties(weight, zero, polygon)) { - return false; - } - for (const auto& query : queries) { - if (!test_barycentric_properties(weight, query, polygon)) { - return false; - } - } + for (const auto& polygon : polygons) + { + test_barycentric_properties(weight, zero, polygon); + for (const auto& query : queries) + test_barycentric_properties(weight, query, polygon); } } - return true; + + return; } -template< -typename Kernel, -typename Weight_wrapper_1, -typename Weight_wrapper_2> -bool test_barycentric_weight( - const Weight_wrapper_1& weight, - const Weight_wrapper_2& alternative) { - +template +void test_barycentric_weight(const Weight_wrapper_1& weight, + const Weight_wrapper_2& alternative) +{ using FT = typename Kernel::FT; using Point_2 = typename Kernel::Point_2; - // Data. const FT q = FT(1) / FT(4); const FT h = FT(1) / FT(2); const Point_2 zero(0, 0); - const std::vector queries = { + const std::vector queries = + { Point_2(-h, 0), Point_2(+h, 0), Point_2(-q, 0), Point_2(+q, 0), Point_2( 0, -h), Point_2( 0, +h), Point_2( 0, -q), Point_2( 0, +q), Point_2(-h, -h), Point_2(+h, +h), Point_2(-q, -q), Point_2(+q, +q), @@ -516,40 +520,29 @@ bool test_barycentric_weight( }; // Test analytic formulations. - if (!test_analytic_weight(weight, alternative)) { - return false; - } + test_analytic_weight(weight, alternative); // Test on polygons. const auto polygons = get_all_polygons(); - for (const auto& polygon : polygons) { - if (!test_on_polygon(weight, zero, polygon)) return false; - for (const auto& query : queries) { - if (!test_on_polygon(weight, query, polygon)) { - return false; - } - } + for (const auto& polygon : polygons) + { + test_on_polygon(weight, zero, polygon); + for (const auto& query : queries) + test_on_polygon(weight, query, polygon); } - return true; } -template< -typename Kernel, -typename Weight_wrapper> -bool test_region_weight(const Weight_wrapper& weight) { - - // Test neighborhoods. +template +void test_region_weight(const Weight_wrapper& weight) +{ auto configs = get_all_triangles(); - for (const auto& config : configs) { - if (!test_neighbors(weight, config)) return false; - } + for (const auto& config : configs) + test_neighbors(weight, config); - // Test areas. configs = get_uniform_triangles(); - for (const auto& config : configs) { - if (!test_area(weight, config)) return false; - } - return true; + for (const auto& config : configs) + test_area(weight, config); } } // namespace tests diff --git a/Weights/test/Weights/include/wrappers.h b/Weights/test/Weights/include/wrappers.h index 9946236476a..9a6bdbbb653 100644 --- a/Weights/test/Weights/include/wrappers.h +++ b/Weights/test/Weights/include/wrappers.h @@ -1,261 +1,345 @@ #ifndef CGAL_WEIGHTS_TESTS_WRAPPERS_H #define CGAL_WEIGHTS_TESTS_WRAPPERS_H -// STL includes. +#include "utils.h" + +#include + #include #include -// CGAL includes. -#include - namespace wrappers { template -struct Authalic_wrapper { +struct Authalic_wrapper +{ using FT = typename Kernel::FT; + template - FT weight_a(const Point& t, const Point& r, const Point& p, const Point& q) const { - return CGAL::Weights::authalic_weight(t, r, p, q); + FT weight_a(const Point& p0, const Point& p1, const Point& p2, const Point& q) const + { + return CGAL::Weights::authalic_weight(p0, p1, p2, q); } + template - FT weight_b(const Point& t, const Point& r, const Point& p, const Point& q) const { - return - CGAL::Weights::half_authalic_weight( - CGAL::Weights::cotangent(t, r, q), - CGAL::Weights::squared_distance(q, r)) + - CGAL::Weights::half_authalic_weight( - CGAL::Weights::cotangent(q, r, p), - CGAL::Weights::squared_distance(q, r)); + FT weight_b(const Point& p0, const Point& p1, const Point& p2, const Point& q) const + { + return CGAL::Weights::half_authalic_weight(CGAL::Weights::cotangent(p0, p1, q), + CGAL::Weights::internal::squared_distance(q, p1)) + + CGAL::Weights::half_authalic_weight(CGAL::Weights::cotangent(q, p1, p2), + CGAL::Weights::internal::squared_distance(q, p1)); } + bool supports_3d() const { return true; } bool is_barycentric() const { return true; } }; template -struct Cotangent_wrapper { +struct Cotangent_wrapper +{ using FT = typename Kernel::FT; + template - FT weight_a(const Point& t, const Point& r, const Point& p, const Point& q) const { - return CGAL::Weights::cotangent_weight(t, r, p, q); + FT weight_a(const Point& p0, const Point& p1, const Point& p2, const Point& q) const + { + return CGAL::Weights::cotangent_weight(p0, p1, p2, q); } + template - FT weight_b(const Point& t, const Point& r, const Point& p, const Point& q) const { - return - CGAL::Weights::half_cotangent_weight( - CGAL::Weights::cotangent(q, t, r)) + - CGAL::Weights::half_cotangent_weight( - CGAL::Weights::cotangent(r, p, q)); + FT weight_b(const Point& p0, const Point& p1, const Point& p2, const Point& q) const + { + return CGAL::Weights::half_cotangent_weight(CGAL::Weights::cotangent(q, p0, p1)) + + CGAL::Weights::half_cotangent_weight(CGAL::Weights::cotangent(p1, p2, q)); } + bool supports_3d() const { return true; } bool is_barycentric() const { return true; } }; template -struct Tangent_wrapper { +struct Tangent_wrapper +{ using FT = typename Kernel::FT; + template - FT weight_a(const Point& t, const Point& r, const Point& p, const Point& q) const { + FT weight_a(const Point& t, const Point& r, const Point& p, const Point& q) const + { return CGAL::Weights::tangent_weight(t, r, p, q); } + template - FT weight_b(const Point& t, const Point& r, const Point& p, const Point& q) const { - return - CGAL::Weights::half_tangent_weight( - CGAL::Weights::distance(r, q), - CGAL::Weights::distance(t, q), - CGAL::Weights::area(r, q, t), - CGAL::Weights::scalar_product(r, q, t)) + - CGAL::Weights::half_tangent_weight( - CGAL::Weights::distance(r, q), - CGAL::Weights::distance(p, q), - CGAL::Weights::area(p, q, r), - CGAL::Weights::scalar_product(p, q, r)); + FT weight_b(const Point& t, const Point& r, const Point& p, const Point& q) const + { + return CGAL::Weights::half_tangent_weight(CGAL::Weights::internal::distance(r, q), + CGAL::Weights::internal::distance(t, q), + CGAL::Weights::internal::area(r, q, t), + CGAL::Weights::internal::scalar_product(r, q, t)) + + CGAL::Weights::half_tangent_weight(CGAL::Weights::internal::distance(r, q), + CGAL::Weights::internal::distance(p, q), + CGAL::Weights::internal::area(p, q, r), + CGAL::Weights::internal::scalar_product(p, q, r)); } + bool supports_3d() const { return true; } bool is_barycentric() const { return true; } }; template -struct Wachspress_wrapper { +struct Wachspress_wrapper +{ using FT = typename Kernel::FT; using Point_2 = typename Kernel::Point_2; using Point_3 = typename Kernel::Point_3; - FT weight_a(const Point_2& t, const Point_2& r, const Point_2& p, const Point_2& q) const { - return CGAL::Weights::wachspress_weight(t, r, p, q); + + FT weight_a(const Point_2& p0, const Point_2& p1, const Point_2& p2, const Point_2& q) const + { + return CGAL::Weights::wachspress_weight(p0, p1, p2, q); } - FT weight_a(const Point_3&, const Point_3&, const Point_3&, const Point_3&) const { + + FT weight_a(const Point_3&, const Point_3&, const Point_3&, const Point_3&) const + { return FT(-1); } + template - FT weight_b(const Point& t, const Point& r, const Point& p, const Point& q) const { - return weight_a(t, r, p, q); + FT weight_b(const Point& p0, const Point& p1, const Point& p2, const Point& q) const + { + return weight_a(p0, p1, p2, q); } + template - void compute_on_polygon( - const Polygon& polygon, const Point& query, const Traits& traits, OutputIterator out) const { + void compute_on_polygon(const Polygon& polygon, + const Point& query, + const Traits& traits, + OutputIterator out) const + { CGAL::Weights::wachspress_weights_2(polygon, query, out, traits); } + bool supports_3d() const { return false; } bool is_barycentric() const { return true; } }; template -struct Discrete_harmonic_wrapper { +struct Discrete_harmonic_wrapper +{ using FT = typename Kernel::FT; using Point_2 = typename Kernel::Point_2; using Point_3 = typename Kernel::Point_3; - FT weight_a(const Point_2& t, const Point_2& r, const Point_2& p, const Point_2& q) const { - return CGAL::Weights::discrete_harmonic_weight(t, r, p, q); + + FT weight_a(const Point_2& p0, const Point_2& p1, const Point_2& p2, const Point_2& q) const + { + return CGAL::Weights::discrete_harmonic_weight(p0, p1, p2, q); } - FT weight_a(const Point_3&, const Point_3&, const Point_3&, const Point_3&) const { + + FT weight_a(const Point_3&, const Point_3&, const Point_3&, const Point_3&) const + { return FT(-1); } + template - FT weight_b(const Point& t, const Point& r, const Point& p, const Point& q) const { - return weight_a(t, r, p, q); + FT weight_b(const Point& p0, const Point& p1, const Point& p2, const Point& q) const + { + return weight_a(p0, p1, p2, q); } + template - void compute_on_polygon( - const Polygon& polygon, const Point& query, const Traits& traits, OutputIterator out) const { + void compute_on_polygon(const Polygon& polygon, + const Point& query, + const Traits& traits, + OutputIterator out) const + { CGAL::Weights::discrete_harmonic_weights_2(polygon, query, out, traits); } + bool supports_3d() const { return false; } bool is_barycentric() const { return true; } }; template -struct Mean_value_wrapper { +struct Mean_value_wrapper +{ using FT = typename Kernel::FT; using Point_2 = typename Kernel::Point_2; using Point_3 = typename Kernel::Point_3; - FT weight_a(const Point_2& t, const Point_2& r, const Point_2& p, const Point_2& q) const { + + FT weight_a(const Point_2& t, const Point_2& r, const Point_2& p, const Point_2& q) const + { return CGAL::Weights::mean_value_weight(t, r, p, q); } - FT weight_a(const Point_3&, const Point_3&, const Point_3&, const Point_3&) const { + + FT weight_a(const Point_3&, const Point_3&, const Point_3&, const Point_3&) const + { return FT(-1); } + template - FT weight_b(const Point& t, const Point& r, const Point& p, const Point& q) const { + FT weight_b(const Point& t, const Point& r, const Point& p, const Point& q) const + { return weight_a(t, r, p, q); } + template - void compute_on_polygon( - const Polygon& polygon, const Point& query, const Traits& traits, OutputIterator out) const { + void compute_on_polygon(const Polygon& polygon, + const Point& query, + const Traits& traits, + OutputIterator out) const + { CGAL::Weights::mean_value_weights_2(polygon, query, out, traits); } + bool supports_3d() const { return false; } bool is_barycentric() const { return true; } }; template -struct Three_point_family_wrapper { +struct Three_point_family_wrapper +{ using FT = typename Kernel::FT; using Point_2 = typename Kernel::Point_2; using Point_3 = typename Kernel::Point_3; + const FT a; + Three_point_family_wrapper(const FT a) : a(a) { } - FT weight_a(const Point_2& t, const Point_2& r, const Point_2& p, const Point_2& q) const { + FT weight_a(const Point_2& t, const Point_2& r, const Point_2& p, const Point_2& q) const + { return CGAL::Weights::three_point_family_weight(t, r, p, q, a); } - FT weight_a(const Point_3&, const Point_3&, const Point_3&, const Point_3&) const { + + FT weight_a(const Point_3&, const Point_3&, const Point_3&, const Point_3&) const + { return FT(-1); } + template - FT weight_b(const Point& t, const Point& r, const Point& p, const Point& q) const { + FT weight_b(const Point& t, const Point& r, const Point& p, const Point& q) const + { return weight_a(t, r, p, q); } + bool supports_3d() const { return false; } bool is_barycentric() const { return true; } }; template -struct Uniform_region_wrapper { +struct Uniform_region_wrapper +{ using FT = typename Kernel::FT; template - FT weight(const Point& p, const Point& q, const Point& r) const { + FT weight(const Point& p, const Point& q, const Point& r) const + { return CGAL::Weights::uniform_area(p, q, r); } }; template -struct Triangular_region_wrapper { +struct Triangular_region_wrapper +{ using FT = typename Kernel::FT; template - FT weight(const Point& p, const Point& q, const Point& r) const { + FT weight(const Point& p, const Point& q, const Point& r) const + { return CGAL::Weights::triangular_area(p, q, r); } }; template -struct Barycentric_region_wrapper { +struct Barycentric_region_wrapper +{ using FT = typename Kernel::FT; template - FT weight(const Point& p, const Point& q, const Point& r) const { + FT weight(const Point& p, const Point& q, const Point& r) const + { return CGAL::Weights::barycentric_area(p, q, r); } }; template -struct Voronoi_region_wrapper { +struct Voronoi_region_wrapper +{ using FT = typename Kernel::FT; template - FT weight(const Point& p, const Point& q, const Point& r) const { + FT weight(const Point& p, const Point& q, const Point& r) const + { return CGAL::Weights::voronoi_area(p, q, r); } }; template -struct Mixed_voronoi_region_wrapper { +struct Mixed_voronoi_region_wrapper +{ using FT = typename Kernel::FT; template - FT weight(const Point& p, const Point& q, const Point& r) const { + FT weight(const Point& p, const Point& q, const Point& r) const + { return CGAL::Weights::mixed_voronoi_area(p, q, r); } }; template -struct Uniform_wrapper { +struct Uniform_wrapper +{ using FT = typename Kernel::FT; + template - FT weight_a(const Point& t, const Point& r, const Point& p, const Point& q) const { + FT weight_a(const Point& t, const Point& r, const Point& p, const Point& q) const + { return CGAL::Weights::uniform_weight(t, r, p, q); } + template - FT weight_b(const Point& t, const Point& r, const Point& p, const Point& q) const { + FT weight_b(const Point& t, const Point& r, const Point& p, const Point& q) const + { return weight_a(t, r, p, q); } + bool supports_3d() const { return true; } bool is_barycentric() const { return false; } }; template -struct Inverse_distance_wrapper { +struct Inverse_distance_wrapper +{ using FT = typename Kernel::FT; + template - FT weight_a(const Point& t, const Point& r, const Point& p, const Point& q) const { + FT weight_a(const Point& t, const Point& r, const Point& p, const Point& q) const + { return CGAL::Weights::inverse_distance_weight(t, r, p, q); } + template - FT weight_b(const Point& t, const Point& r, const Point& p, const Point& q) const { + FT weight_b(const Point& t, const Point& r, const Point& p, const Point& q) const + { return weight_a(t, r, p, q); } + bool supports_3d() const { return true; } bool is_barycentric() const { return false; } }; template -struct Shepard_wrapper { +struct Shepard_wrapper +{ using FT = typename Kernel::FT; + const FT a; + Shepard_wrapper(const FT a) : a(a) { } + template - FT weight_a(const Point& t, const Point& r, const Point& p, const Point& q) const { + FT weight_a(const Point& t, const Point& r, const Point& p, const Point& q) const + { return CGAL::Weights::shepard_weight(t, r, p, q, a); } + template - FT weight_b(const Point& t, const Point& r, const Point& p, const Point& q) const { + FT weight_b(const Point& t, const Point& r, const Point& p, const Point& q) const + { return weight_a(t, r, p, q); } + bool supports_3d() const { return true; } bool is_barycentric() const { return false; } }; diff --git a/Weights/test/Weights/test_authalic_weights.cpp b/Weights/test/Weights/test_authalic_weights.cpp index 1aa439a3523..68aa6553417 100644 --- a/Weights/test/Weights/test_authalic_weights.cpp +++ b/Weights/test/Weights/test_authalic_weights.cpp @@ -1,26 +1,29 @@ +#include "include/utils.h" +#include "include/wrappers.h" + #include #include #include -#include "include/utils.h" -#include "include/wrappers.h" - -// Typedefs. using SCKER = CGAL::Simple_cartesian; using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel; using EPECK = CGAL::Exact_predicates_exact_constructions_kernel; template -bool test_kernel() { +void test_kernel() +{ const wrappers::Authalic_wrapper aut; const wrappers::Wachspress_wrapper whp; - return tests::test_analytic_weight(aut, whp); + const wrappers::Three_point_family_wrapper tpf(0); + tests::test_analytic_weight(aut, whp); + tests::test_analytic_weight(aut, tpf); } -int main() { - assert(test_kernel()); - assert(test_kernel()); - assert(test_kernel()); +int main(int, char**) +{ + test_kernel(); + test_kernel(); + test_kernel(); std::cout << "* test_authalic_weights: SUCCESS" << std::endl; return EXIT_SUCCESS; } diff --git a/Weights/test/Weights/test_barycentric_region_weights.cpp b/Weights/test/Weights/test_barycentric_region_weights.cpp index 49be26810bf..39dfebe8c39 100644 --- a/Weights/test/Weights/test_barycentric_region_weights.cpp +++ b/Weights/test/Weights/test_barycentric_region_weights.cpp @@ -1,25 +1,48 @@ +#include "include/utils.h" +#include "include/wrappers.h" + #include #include #include -#include "include/utils.h" -#include "include/wrappers.h" - -// Typedefs. using SCKER = CGAL::Simple_cartesian; using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel; using EPECK = CGAL::Exact_predicates_exact_constructions_kernel; template -bool test_kernel() { +void test_kernel() +{ + using FT = typename Kernel::FT; + using Point_2 = typename Kernel::Point_2; + using Point_3 = typename Kernel::Point_3; + + const Point_2 p( 1, 0); + const Point_2 q( 0, 6); + const Point_2 r(-1, 0); + const FT w1 = CGAL::Weights::barycentric_area(p, q, r); + const FT w2 = CGAL::Weights::barycentric_area(r, p, q); + const FT w3 = CGAL::Weights::barycentric_area(q, r, p); + assert(w1 == FT(2)); // medians subdivide a triangle into 6 triangles of equal areas + assert(w1 == w2 && w2 == w3); + + const Point_3 s( 0, -1, 0); + const Point_3 t( 0, 0, 6); + const Point_3 u( 0, 1, 0); + const FT w4 = CGAL::Weights::barycentric_area(s, t, u); + const FT w5 = CGAL::Weights::barycentric_area(t, u, s); + const FT w6 = CGAL::Weights::barycentric_area(u, s, t); + assert(w4 == FT(2)); + assert(w4 == w5 && w5 == w6); + const wrappers::Barycentric_region_wrapper bar; - return tests::test_region_weight(bar); + tests::test_region_weight(bar); } -int main() { - assert(test_kernel()); - assert(test_kernel()); - assert(test_kernel()); +int main(int, char**) +{ + test_kernel(); + test_kernel(); + test_kernel(); std::cout << "* test_barycentric_region_weights: SUCCESS" << std::endl; return EXIT_SUCCESS; } diff --git a/Weights/test/Weights/test_cotangent_weights.cpp b/Weights/test/Weights/test_cotangent_weights.cpp index 962ed140c44..e1bcb98da72 100644 --- a/Weights/test/Weights/test_cotangent_weights.cpp +++ b/Weights/test/Weights/test_cotangent_weights.cpp @@ -1,26 +1,39 @@ +#include "include/utils.h" +#include "include/wrappers.h" + #include #include #include -#include "include/utils.h" -#include "include/wrappers.h" - -// Typedefs. using SCKER = CGAL::Simple_cartesian; using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel; using EPECK = CGAL::Exact_predicates_exact_constructions_kernel; template -bool test_kernel() { +void test_kernel() +{ + using FT = typename Kernel::FT; + using Point_2 = typename Kernel::Point_2; + + const Point_2 p0(-2, 1); + const Point_2 p1( 0, 1); + const Point_2 p2( 0, 3); + const Point_2 q( -2, 3); + const FT w = CGAL::Weights::cotangent_weight(p0, p1, p2, q); + assert(w == FT(0)); + const wrappers::Cotangent_wrapper cot; const wrappers::Discrete_harmonic_wrapper dhw; - return tests::test_analytic_weight(cot, dhw); + const wrappers::Three_point_family_wrapper tpf(2); + tests::test_analytic_weight(cot, dhw); + tests::test_analytic_weight(cot, tpf); } -int main() { - assert(test_kernel()); - assert(test_kernel()); - assert(test_kernel()); +int main(int, char**) +{ + test_kernel(); + test_kernel(); + test_kernel(); std::cout << "* test_cotangent_weights: SUCCESS" << std::endl; return EXIT_SUCCESS; } diff --git a/Weights/test/Weights/test_discrete_harmonic_weights.cpp b/Weights/test/Weights/test_discrete_harmonic_weights.cpp index b49d7beac51..f358f412191 100644 --- a/Weights/test/Weights/test_discrete_harmonic_weights.cpp +++ b/Weights/test/Weights/test_discrete_harmonic_weights.cpp @@ -1,17 +1,17 @@ +#include "include/utils.h" +#include "include/wrappers.h" + #include #include #include -#include "include/utils.h" -#include "include/wrappers.h" - -// Typedefs. using SCKER = CGAL::Simple_cartesian; using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel; using EPECK = CGAL::Exact_predicates_exact_constructions_kernel; template -void test_overloads() { +void test_overloads() +{ using FT = typename Kernel::FT; using Point_2 = typename Kernel::Point_2; using Point_3 = typename Kernel::Point_3; @@ -19,36 +19,42 @@ void test_overloads() { const Point_2 r1( 0, -1); const Point_2 p1( 1, 0); const Point_2 q1( 0, 0); + const Point_3 t2(-1, 0, 1); const Point_3 r2( 0, -1, 1); const Point_3 p2( 1, 0, 1); const Point_3 q2( 0, 0, 1); + const FT a2 = CGAL::Weights::discrete_harmonic_weight(t1, r1, p1, q1); - const FT a3 = CGAL::Weights::internal::discrete_harmonic_weight(t2, r2, p2, q2); - assert(a2 >= FT(0)); - assert(a3 >= FT(0)); + const FT a3 = CGAL::Weights::discrete_harmonic_weight(t2, r2, p2, q2); + assert(a2 == FT(4)); + assert(a3 == FT(4)); assert(a2 == a3); + struct Traits : public Kernel { }; assert(CGAL::Weights::discrete_harmonic_weight(t1, r1, p1, q1, Traits()) == a2); - assert(CGAL::Weights::internal::discrete_harmonic_weight(t2, r2, p2, q2, Traits()) == a3); + assert(CGAL::Weights::discrete_harmonic_weight(t2, r2, p2, q2, Traits()) == a3); + CGAL::Projection_traits_xy_3 ptraits; const FT a23 = CGAL::Weights::discrete_harmonic_weight(t2, r2, p2, q2, ptraits); - assert(a23 >= FT(0)); - assert(a23 == a2 && a23 == a3); + assert(a23 == FT(4)); + assert(a23 == a2); } template -bool test_kernel() { +void test_kernel() +{ test_overloads(); const wrappers::Discrete_harmonic_wrapper dhw; const wrappers::Cotangent_wrapper cot; - return tests::test_barycentric_weight(dhw, cot); + tests::test_barycentric_weight(dhw, cot); } -int main() { - assert(test_kernel()); - assert(test_kernel()); - assert(test_kernel()); +int main(int, char**) +{ + test_kernel(); + test_kernel(); + test_kernel(); std::cout << "* test_discrete_harmonic_weights: SUCCESS" << std::endl; return EXIT_SUCCESS; } diff --git a/Weights/test/Weights/test_inverse_distance_weights.cpp b/Weights/test/Weights/test_inverse_distance_weights.cpp index a19dec04749..5cccd29824b 100644 --- a/Weights/test/Weights/test_inverse_distance_weights.cpp +++ b/Weights/test/Weights/test_inverse_distance_weights.cpp @@ -1,47 +1,53 @@ +#include "include/utils.h" +#include "include/wrappers.h" + #include #include #include -#include "include/utils.h" -#include "include/wrappers.h" - -// Typedefs. using SCKER = CGAL::Simple_cartesian; using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel; using EPECK = CGAL::Exact_predicates_exact_constructions_kernel; template -void test_overloads() { +void test_overloads() +{ using FT = typename Kernel::FT; using Point_2 = typename Kernel::Point_2; using Point_3 = typename Kernel::Point_3; const Point_2 p1(0, 0); - const Point_2 q1(1, 0); + const Point_2 q1(2, 0); const Point_3 p2(0, 0, 1); - const Point_3 q2(1, 0, 1); - const FT a2 = CGAL::Weights::inverse_distance_weight(p1, q1); - const FT a3 = CGAL::Weights::inverse_distance_weight(p2, q2); - assert(a2 == FT(1)); - assert(a3 == FT(1)); - assert(CGAL::Weights::inverse_distance_weight(p1, p1, q1, q1) == a2); - assert(CGAL::Weights::inverse_distance_weight(p2, p2, q2, q2) == a3); + const Point_3 q2(2, 0, 1); + + const FT w1 = CGAL::Weights::inverse_distance_weight(p1, q1); + const FT w2 = CGAL::Weights::inverse_distance_weight(p2, q2); + assert(w1 == FT(1) / FT(2)); + assert(w2 == FT(1) / FT(2)); + assert(CGAL::Weights::inverse_distance_weight(p1, p1, q1, q1) == w1); + assert(CGAL::Weights::inverse_distance_weight(p2, p2, q2, q2) == w2); + struct Traits : public Kernel { }; - assert(CGAL::Weights::inverse_distance_weight(p1, p1, q1, q1, Traits()) == a2); - assert(CGAL::Weights::inverse_distance_weight(p2, p2, q2, q2, Traits()) == a3); + assert(CGAL::Weights::inverse_distance_weight(p1, q1, Traits()) == w1); + assert(CGAL::Weights::inverse_distance_weight(p2, q2, Traits()) == w2); + assert(CGAL::Weights::inverse_distance_weight(p1, p1, q1, q1, Traits()) == w1); + assert(CGAL::Weights::inverse_distance_weight(p2, p2, q2, q2, Traits()) == w2); } template -bool test_kernel() { +void test_kernel() +{ test_overloads(); const wrappers::Inverse_distance_wrapper idw; const wrappers::Shepard_wrapper spw(1); - return tests::test_analytic_weight(idw, spw); + tests::test_analytic_weight(idw, spw); } -int main() { - assert(test_kernel()); - assert(test_kernel()); - assert(test_kernel()); +int main(int, char**) +{ + test_kernel(); + test_kernel(); + test_kernel(); std::cout << "* test_inverse_distance_weights: SUCCESS" << std::endl; return EXIT_SUCCESS; } diff --git a/Weights/test/Weights/test_mean_value_weights.cpp b/Weights/test/Weights/test_mean_value_weights.cpp index 883ff79d591..74ec6ffa4a5 100644 --- a/Weights/test/Weights/test_mean_value_weights.cpp +++ b/Weights/test/Weights/test_mean_value_weights.cpp @@ -1,17 +1,17 @@ +#include "include/utils.h" +#include "include/wrappers.h" + #include #include #include -#include "include/utils.h" -#include "include/wrappers.h" - -// Typedefs. using SCKER = CGAL::Simple_cartesian; using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel; using EPECK = CGAL::Exact_predicates_exact_constructions_kernel; template -void test_overloads() { +void test_overloads() +{ using FT = typename Kernel::FT; using Point_2 = typename Kernel::Point_2; using Point_3 = typename Kernel::Point_3; @@ -23,14 +23,16 @@ void test_overloads() { const Point_3 r2( 0, -1, 1); const Point_3 p2( 1, 0, 1); const Point_3 q2( 0, 0, 1); + const FT a2 = CGAL::Weights::mean_value_weight(t1, r1, p1, q1); - const FT a3 = CGAL::Weights::internal::mean_value_weight(t2, r2, p2, q2); + const FT a3 = CGAL::Weights::mean_value_weight(t2, r2, p2, q2); assert(a2 >= FT(0)); assert(a3 >= FT(0)); assert(a2 == a3); + struct Traits : public Kernel { }; assert(CGAL::Weights::mean_value_weight(t1, r1, p1, q1, Traits()) == a2); - assert(CGAL::Weights::internal::mean_value_weight(t2, r2, p2, q2, Traits()) == a3); + assert(CGAL::Weights::mean_value_weight(t2, r2, p2, q2, Traits()) == a3); CGAL::Projection_traits_xy_3 ptraits; const FT a23 = CGAL::Weights::mean_value_weight(t2, r2, p2, q2, ptraits); assert(a23 >= FT(0)); @@ -38,17 +40,21 @@ void test_overloads() { } template -bool test_kernel() { +void test_kernel() +{ test_overloads(); const wrappers::Mean_value_wrapper mvw; const wrappers::Tangent_wrapper tan; - return tests::test_barycentric_weight(mvw, tan); + const wrappers::Three_point_family_wrapper tpf(1); + tests::test_barycentric_weight(mvw, tan); + tests::test_barycentric_weight(mvw, tpf); } -int main() { - assert(test_kernel()); - assert(test_kernel()); - assert(test_kernel()); +int main(int, char**) +{ + test_kernel(); + test_kernel(); + test_kernel(); std::cout << "* test_mean_value_weights: SUCCESS" << std::endl; return EXIT_SUCCESS; } diff --git a/Weights/test/Weights/test_mixed_voronoi_region_weights.cpp b/Weights/test/Weights/test_mixed_voronoi_region_weights.cpp index 3c78f1f18a2..d0c6571d95e 100644 --- a/Weights/test/Weights/test_mixed_voronoi_region_weights.cpp +++ b/Weights/test/Weights/test_mixed_voronoi_region_weights.cpp @@ -1,25 +1,26 @@ +#include "include/utils.h" +#include "include/wrappers.h" + #include #include #include -#include "include/utils.h" -#include "include/wrappers.h" - -// Typedefs. using SCKER = CGAL::Simple_cartesian; using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel; using EPECK = CGAL::Exact_predicates_exact_constructions_kernel; template -bool test_kernel() { +void test_kernel() +{ const wrappers::Mixed_voronoi_region_wrapper mix; - return tests::test_region_weight(mix); + tests::test_region_weight(mix); } -int main() { - assert(test_kernel()); - assert(test_kernel()); - assert(test_kernel()); +int main(int, char**) +{ + test_kernel(); + test_kernel(); + test_kernel(); std::cout << "* test_mixed_voronoi_region_weights: SUCCESS" << std::endl; return EXIT_SUCCESS; } diff --git a/Weights/test/Weights/test_projected_weights.cpp b/Weights/test/Weights/test_projected_weights.cpp index 96d01644499..874bc73d22b 100644 --- a/Weights/test/Weights/test_projected_weights.cpp +++ b/Weights/test/Weights/test_projected_weights.cpp @@ -1,18 +1,19 @@ #include #include #include + #include #include #include #include -// Typedefs. using SCKER = CGAL::Simple_cartesian; using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel; using EPECK = CGAL::Exact_predicates_exact_constructions_kernel; template -void test_kernel() { +void test_kernel() +{ using FT = typename Kernel::FT; using Point_2 = typename Kernel::Point_2; using Point_3 = typename Kernel::Point_3; @@ -110,7 +111,8 @@ void test_kernel() { assert(CGAL::Weights::three_point_family_weight(t3, r3, p3, q3, 1, yz_traits) == ref_value); } -int main() { +int main(int, char**) +{ test_kernel(); test_kernel(); test_kernel(); diff --git a/Weights/test/Weights/test_shepard_weights.cpp b/Weights/test/Weights/test_shepard_weights.cpp index e178b574144..9806892d386 100644 --- a/Weights/test/Weights/test_shepard_weights.cpp +++ b/Weights/test/Weights/test_shepard_weights.cpp @@ -1,49 +1,55 @@ +#include "include/utils.h" +#include "include/wrappers.h" + #include #include #include -#include "include/utils.h" -#include "include/wrappers.h" - -// Typedefs. using SCKER = CGAL::Simple_cartesian; using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel; using EPECK = CGAL::Exact_predicates_exact_constructions_kernel; template -void test_overloads() { +void test_overloads() +{ using FT = typename Kernel::FT; using Point_2 = typename Kernel::Point_2; using Point_3 = typename Kernel::Point_3; + const Point_2 p1(0, 0); - const Point_2 q1(1, 0); + const Point_2 q1(2, 0); const Point_3 p2(0, 0, 1); - const Point_3 q2(1, 0, 1); - const FT a2 = CGAL::Weights::shepard_weight(p1, q1); - const FT a3 = CGAL::Weights::shepard_weight(p2, q2); - assert(a2 == FT(1)); - assert(a3 == FT(1)); - assert(CGAL::Weights::shepard_weight(p1, p1, q1, q1) == a2); - assert(CGAL::Weights::shepard_weight(p2, p2, q2, q2) == a3); + const Point_3 q2(2, 0, 1); + + const FT a2 = CGAL::Weights::shepard_weight(p1, q1, 3); + const FT a3 = CGAL::Weights::shepard_weight(p2, q2, 3); + assert(a2 == FT(1)/FT(8)); + assert(a3 == FT(1)/FT(8)); + + assert(CGAL::Weights::shepard_weight(p1, p1, q1, q1, 3) == a2); + assert(CGAL::Weights::shepard_weight(p2, p2, q2, q2, 3) == a3); + struct Traits : public Kernel { }; - assert(CGAL::Weights::shepard_weight(p1, p1, q1, q1, 1, Traits()) == a2); - assert(CGAL::Weights::shepard_weight(p2, p2, q2, q2, 1, Traits()) == a3); + assert(CGAL::Weights::shepard_weight(p1, p1, q1, q1, 3, Traits()) == a2); + assert(CGAL::Weights::shepard_weight(p2, p2, q2, q2, 3, Traits()) == a3); } template -bool test_kernel() { +void test_kernel() +{ test_overloads(); const wrappers::Shepard_wrapper spwa(1); const wrappers::Shepard_wrapper spwb(2); const wrappers::Inverse_distance_wrapper idw; - assert(tests::test_analytic_weight(spwa, idw)); - return tests::test_analytic_weight(spwb, spwb); + tests::test_analytic_weight(spwa, idw); + tests::test_analytic_weight(spwb, spwb); } -int main() { - assert(test_kernel()); - assert(test_kernel()); - assert(test_kernel()); +int main(int, char**) +{ + test_kernel(); + test_kernel(); + test_kernel(); std::cout << "* test_shepard_weights: SUCCESS" << std::endl; return EXIT_SUCCESS; } diff --git a/Weights/test/Weights/test_tangent_weights.cpp b/Weights/test/Weights/test_tangent_weights.cpp index 8fe08620ad7..aece71cb567 100644 --- a/Weights/test/Weights/test_tangent_weights.cpp +++ b/Weights/test/Weights/test_tangent_weights.cpp @@ -1,26 +1,29 @@ +#include "include/utils.h" +#include "include/wrappers.h" + #include #include #include -#include "include/utils.h" -#include "include/wrappers.h" - -// Typedefs. using SCKER = CGAL::Simple_cartesian; using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel; using EPECK = CGAL::Exact_predicates_exact_constructions_kernel; template -bool test_kernel() { +void test_kernel() +{ const wrappers::Tangent_wrapper tan; const wrappers::Mean_value_wrapper mvw; - return tests::test_analytic_weight(tan, mvw); + const wrappers::Three_point_family_wrapper tpf(1); + tests::test_analytic_weight(tan, mvw); + tests::test_analytic_weight(tan, tpf); } -int main() { - assert(test_kernel()); - assert(test_kernel()); - assert(test_kernel()); +int main(int, char**) +{ + test_kernel(); + test_kernel(); + test_kernel(); std::cout << "* test_tangent_weights: SUCCESS" << std::endl; return EXIT_SUCCESS; } diff --git a/Weights/test/Weights/test_three_point_family_weights.cpp b/Weights/test/Weights/test_three_point_family_weights.cpp index e6ebfb0f64b..85f231b7eb0 100644 --- a/Weights/test/Weights/test_three_point_family_weights.cpp +++ b/Weights/test/Weights/test_three_point_family_weights.cpp @@ -1,17 +1,17 @@ +#include "include/utils.h" +#include "include/wrappers.h" + #include #include #include -#include "include/utils.h" -#include "include/wrappers.h" - -// Typedefs. using SCKER = CGAL::Simple_cartesian; using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel; using EPECK = CGAL::Exact_predicates_exact_constructions_kernel; template -void test_overloads() { +void test_overloads() +{ using FT = typename Kernel::FT; using Point_2 = typename Kernel::Point_2; using Point_3 = typename Kernel::Point_3; @@ -23,14 +23,16 @@ void test_overloads() { const Point_3 r2( 0, -1, 1); const Point_3 p2( 1, 0, 1); const Point_3 q2( 0, 0, 1); + const FT a2 = CGAL::Weights::three_point_family_weight(t1, r1, p1, q1); - const FT a3 = CGAL::Weights::internal::three_point_family_weight(t2, r2, p2, q2); + const FT a3 = CGAL::Weights::three_point_family_weight(t2, r2, p2, q2); assert(a2 >= FT(0)); assert(a3 >= FT(0)); assert(a2 == a3); + struct Traits : public Kernel { }; assert(CGAL::Weights::three_point_family_weight(t1, r1, p1, q1, 1, Traits()) == a2); - assert(CGAL::Weights::internal::three_point_family_weight(t2, r2, p2, q2, 1, Traits()) == a3); + assert(CGAL::Weights::three_point_family_weight(t2, r2, p2, q2, 1, Traits()) == a3); CGAL::Projection_traits_xy_3 ptraits; const FT a23 = CGAL::Weights::three_point_family_weight(t2, r2, p2, q2, 0, ptraits); assert(a23 >= FT(0)); @@ -38,7 +40,8 @@ void test_overloads() { } template -bool test_kernel() { +void test_kernel() +{ test_overloads(); using FT = typename Kernel::FT; const FT h = FT(1) / FT(2); @@ -49,16 +52,18 @@ bool test_kernel() { const wrappers::Wachspress_wrapper whp; const wrappers::Mean_value_wrapper mvw; const wrappers::Discrete_harmonic_wrapper dhw; - assert(tests::test_analytic_weight(tpfa, whp)); - assert(tests::test_analytic_weight(tpfb, mvw)); - assert(tests::test_analytic_weight(tpfc, dhw)); - return tests::test_analytic_weight(tpfd, tpfd); + + tests::test_analytic_weight(tpfa, whp); + tests::test_analytic_weight(tpfb, mvw); + tests::test_analytic_weight(tpfc, dhw); + tests::test_analytic_weight(tpfd, tpfd); } -int main() { - assert(test_kernel()); - assert(test_kernel()); - assert(test_kernel()); +int main(int, char**) +{ + test_kernel(); + test_kernel(); + test_kernel(); std::cout << "* test_three_point_family_weights: SUCCESS" << std::endl; return EXIT_SUCCESS; } diff --git a/Weights/test/Weights/test_triangular_region_weights.cpp b/Weights/test/Weights/test_triangular_region_weights.cpp index c6bde65c492..bafdc2ed189 100644 --- a/Weights/test/Weights/test_triangular_region_weights.cpp +++ b/Weights/test/Weights/test_triangular_region_weights.cpp @@ -1,25 +1,26 @@ +#include "include/utils.h" +#include "include/wrappers.h" + #include #include #include -#include "include/utils.h" -#include "include/wrappers.h" - -// Typedefs. using SCKER = CGAL::Simple_cartesian; using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel; using EPECK = CGAL::Exact_predicates_exact_constructions_kernel; template -bool test_kernel() { +void test_kernel() +{ const wrappers::Triangular_region_wrapper tri; - return tests::test_region_weight(tri); + tests::test_region_weight(tri); } -int main() { - assert(test_kernel()); - assert(test_kernel()); - assert(test_kernel()); +int main(int, char**) +{ + test_kernel(); + test_kernel(); + test_kernel(); std::cout << "* test_triangular_region_weights: SUCCESS" << std::endl; return EXIT_SUCCESS; } diff --git a/Weights/test/Weights/test_uniform_region_weights.cpp b/Weights/test/Weights/test_uniform_region_weights.cpp index 52124ede996..71d25a9a555 100644 --- a/Weights/test/Weights/test_uniform_region_weights.cpp +++ b/Weights/test/Weights/test_uniform_region_weights.cpp @@ -1,17 +1,17 @@ +#include "include/utils.h" +#include "include/wrappers.h" + #include #include #include -#include "include/utils.h" -#include "include/wrappers.h" - -// Typedefs. using SCKER = CGAL::Simple_cartesian; using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel; using EPECK = CGAL::Exact_predicates_exact_constructions_kernel; template -void test_overloads() { +void test_overloads() +{ using FT = typename Kernel::FT; using Point_2 = typename Kernel::Point_2; using Point_3 = typename Kernel::Point_3; @@ -20,22 +20,25 @@ void test_overloads() { const Point_3 q(0, 0, 0); assert(CGAL::Weights::uniform_area(p, p, p) == a); assert(CGAL::Weights::uniform_area(q, q, q) == a); + struct Traits : public Kernel { }; assert(CGAL::Weights::uniform_area(p, p, p, Traits()) == a); assert(CGAL::Weights::uniform_area(q, q, q, Traits()) == a); } template -bool test_kernel() { +void test_kernel() +{ test_overloads(); const wrappers::Uniform_region_wrapper uni; - return tests::test_region_weight(uni); + tests::test_region_weight(uni); } -int main() { - assert(test_kernel()); - assert(test_kernel()); - assert(test_kernel()); +int main(int, char**) +{ + test_kernel(); + test_kernel(); + test_kernel(); std::cout << "* test_uniform_region_weights: SUCCESS" << std::endl; return EXIT_SUCCESS; } diff --git a/Weights/test/Weights/test_uniform_weights.cpp b/Weights/test/Weights/test_uniform_weights.cpp index 68ae5af005c..00501f1f13d 100644 --- a/Weights/test/Weights/test_uniform_weights.cpp +++ b/Weights/test/Weights/test_uniform_weights.cpp @@ -1,41 +1,46 @@ +#include "include/utils.h" +#include "include/wrappers.h" + #include #include #include -#include "include/utils.h" -#include "include/wrappers.h" - -// Typedefs. using SCKER = CGAL::Simple_cartesian; using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel; using EPECK = CGAL::Exact_predicates_exact_constructions_kernel; template -void test_overloads() { +void test_overloads() +{ using FT = typename Kernel::FT; using Point_2 = typename Kernel::Point_2; using Point_3 = typename Kernel::Point_3; + const FT a = FT(1); const Point_2 p(0, 0); const Point_3 q(0, 0, 0); + assert(CGAL::Weights::uniform_weight(p, p, p, p) == a); assert(CGAL::Weights::uniform_weight(q, q, q, q) == a); + struct Traits : public Kernel { }; assert(CGAL::Weights::uniform_weight(p, p, p, p, Traits()) == a); assert(CGAL::Weights::uniform_weight(q, q, q, q, Traits()) == a); } template -bool test_kernel() { +void test_kernel() +{ test_overloads(); const wrappers::Uniform_wrapper uni; - return tests::test_analytic_weight(uni, uni); + tests::test_analytic_weight(uni, uni); } -int main() { - assert(test_kernel()); - assert(test_kernel()); - assert(test_kernel()); +int main(int, char**) +{ + test_kernel(); + test_kernel(); + test_kernel(); std::cout << "* test_uniform_weights: SUCCESS" << std::endl; return EXIT_SUCCESS; } diff --git a/Weights/test/Weights/test_voronoi_region_weights.cpp b/Weights/test/Weights/test_voronoi_region_weights.cpp index a0d6bcc43d4..7040392d029 100644 --- a/Weights/test/Weights/test_voronoi_region_weights.cpp +++ b/Weights/test/Weights/test_voronoi_region_weights.cpp @@ -1,25 +1,26 @@ +#include "include/utils.h" +#include "include/wrappers.h" + #include #include #include -#include "include/utils.h" -#include "include/wrappers.h" - -// Typedefs. using SCKER = CGAL::Simple_cartesian; using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel; using EPECK = CGAL::Exact_predicates_exact_constructions_kernel; template -bool test_kernel() { +void test_kernel() +{ const wrappers::Voronoi_region_wrapper vor; - return tests::test_region_weight(vor); + tests::test_region_weight(vor); } -int main() { - assert(test_kernel()); - assert(test_kernel()); - assert(test_kernel()); +int main(int, char**) +{ + test_kernel(); + test_kernel(); + test_kernel(); std::cout << "* test_voronoi_region_weights: SUCCESS" << std::endl; return EXIT_SUCCESS; } diff --git a/Weights/test/Weights/test_wachspress_weights.cpp b/Weights/test/Weights/test_wachspress_weights.cpp index 75b43f46437..f370c383745 100644 --- a/Weights/test/Weights/test_wachspress_weights.cpp +++ b/Weights/test/Weights/test_wachspress_weights.cpp @@ -1,17 +1,17 @@ +#include "include/utils.h" +#include "include/wrappers.h" + #include #include #include -#include "include/utils.h" -#include "include/wrappers.h" - -// Typedefs. using SCKER = CGAL::Simple_cartesian; using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel; using EPECK = CGAL::Exact_predicates_exact_constructions_kernel; template -void test_overloads() { +void test_overloads() +{ using FT = typename Kernel::FT; using Point_2 = typename Kernel::Point_2; using Point_3 = typename Kernel::Point_3; @@ -23,32 +23,38 @@ void test_overloads() { const Point_3 r2( 0, -1, 1); const Point_3 p2( 1, 0, 1); const Point_3 q2( 0, 0, 1); + const FT a2 = CGAL::Weights::wachspress_weight(t1, r1, p1, q1); - const FT a3 = CGAL::Weights::internal::wachspress_weight(t2, r2, p2, q2); - assert(a2 >= FT(0)); - assert(a3 >= FT(0)); + const FT a3 = CGAL::Weights::wachspress_weight(t2, r2, p2, q2); + assert(a2 == FT(4)); + assert(a3 == FT(4)); assert(a2 == a3); + struct Traits : public Kernel { }; assert(CGAL::Weights::wachspress_weight(t1, r1, p1, q1, Traits()) == a2); - assert(CGAL::Weights::internal::wachspress_weight(t2, r2, p2, q2, Traits()) == a3); + assert(CGAL::Weights::wachspress_weight(t2, r2, p2, q2, Traits()) == a3); CGAL::Projection_traits_xy_3 ptraits; const FT a23 = CGAL::Weights::wachspress_weight(t2, r2, p2, q2, ptraits); - assert(a23 >= FT(0)); - assert(a23 == a2 && a23 == a3); + assert(a23 == FT(4)); + assert(a23 == a2); } template -bool test_kernel() { +void test_kernel() +{ test_overloads(); const wrappers::Wachspress_wrapper whp; const wrappers::Authalic_wrapper aut; - return tests::test_barycentric_weight(whp, aut); + const wrappers::Three_point_family_wrapper tpf(0); + tests::test_barycentric_weight(whp, aut); + tests::test_barycentric_weight(whp, tpf); } -int main() { - assert(test_kernel()); - assert(test_kernel()); - assert(test_kernel()); +int main(int, char**) +{ + test_kernel(); + test_kernel(); + test_kernel(); std::cout << "* test_wachspress_weights: SUCCESS" << std::endl; return EXIT_SUCCESS; } From 0640470f5d1253ddd3347053b1277cd0332b4d1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Thu, 20 Oct 2022 17:34:34 +0200 Subject: [PATCH 24/35] Hide pmp_weights_deprecated.h behind CGAL_NO_DEPRECATED_CODE --- Weights/include/CGAL/Weights/internal/pmp_weights_deprecated.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Weights/include/CGAL/Weights/internal/pmp_weights_deprecated.h b/Weights/include/CGAL/Weights/internal/pmp_weights_deprecated.h index fb44deac937..7a7cd14a4c2 100644 --- a/Weights/include/CGAL/Weights/internal/pmp_weights_deprecated.h +++ b/Weights/include/CGAL/Weights/internal/pmp_weights_deprecated.h @@ -19,6 +19,8 @@ "This part of the package is deprecated since the version 5.4 of CGAL!" #include +#ifndef CGAL_NO_DEPRECATED_CODE + // README: // This header collects all weights which have been in CGAL before unifying them // into the new package Weights. This header is for information purpose only. It From b9e7c2aa13b6312cf6e86538be6fb3eb28136cf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Thu, 20 Oct 2022 17:35:19 +0200 Subject: [PATCH 25/35] Misc minor fixes --- .../CGAL/Weights/internal/polygon_utils_2.h | 2 +- Weights/include/CGAL/Weights/internal/utils.h | 17 ++++++++++------- Weights/include/CGAL/Weights/uniform_weights.h | 5 +++++ 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/Weights/include/CGAL/Weights/internal/polygon_utils_2.h b/Weights/include/CGAL/Weights/internal/polygon_utils_2.h index 361896fc105..8b2bb361673 100644 --- a/Weights/include/CGAL/Weights/internal/polygon_utils_2.h +++ b/Weights/include/CGAL/Weights/internal/polygon_utils_2.h @@ -114,7 +114,7 @@ Edge_case bounded_side_2(const VertexRange& polygon, const auto& currp = get(point_map, *curr); const auto& nextp = get(point_map, *next); - auto next_y_comp_res = compare_y_2(nextp, query); + Comparison_result next_y_comp_res = compare_y_2(nextp, query); switch (curr_y_comp_res) { case CGAL::SMALLER: switch (next_y_comp_res) { diff --git a/Weights/include/CGAL/Weights/internal/utils.h b/Weights/include/CGAL/Weights/internal/utils.h index f51136186b9..af5e3f27c91 100644 --- a/Weights/include/CGAL/Weights/internal/utils.h +++ b/Weights/include/CGAL/Weights/internal/utils.h @@ -191,17 +191,19 @@ double angle_3(const typename GeomTraits::Vector_3& v1, { auto dot_product_3 = traits.compute_scalar_product_3_object(); + const double product = CGAL::sqrt(to_double(scalar_product(v1,v1)) * to_double(scalar_product(v2,v2))); + if(product == 0.) + return 0.; + const double dot = CGAL::to_double(dot_product_3(v1, v2)); + const double costine = dot / product; - double angle_rad = 0.0; if (dot < -1.0) - angle_rad = std::acos(-1.0); + return std::acos(-1.0); else if (dot > 1.0) - angle_rad = std::acos(+1.0); + return std::acos(+1.0); else - angle_rad = std::acos(dot); - - return angle_rad; + return std::acos(dot); } // Rotates a 3D point around axis. @@ -441,7 +443,8 @@ typename GeomTraits::FT positive_area_2(const typename GeomTraits::Point_2& p, const typename GeomTraits::Point_2& r, const GeomTraits& traits) { - return CGAL::abs(area_2(traits, p, q, r)); + auto area_2 = traits.compute_area_2_object(); + return CGAL::abs(area_2(p, q, r)); } template diff --git a/Weights/include/CGAL/Weights/uniform_weights.h b/Weights/include/CGAL/Weights/uniform_weights.h index 541dd95937a..69d1cf2a288 100644 --- a/Weights/include/CGAL/Weights/uniform_weights.h +++ b/Weights/include/CGAL/Weights/uniform_weights.h @@ -86,7 +86,10 @@ typename GeomTraits::FT uniform_weight(const CGAL::Point_3& p0, return uniform_weight(p0, p1, p2, q, traits); } +/// \cond SKIP_IN_MANUAL + // Undocumented uniform weight class taking as input a polygon mesh. +// // It is currently used in: // Polygon_mesh_processing -> triangulate_hole_Polyhedron_3_test.cpp // Polygon_mesh_processing -> triangulate_hole_Polyhedron_3_no_delaunay_test.cpp @@ -102,6 +105,8 @@ public: double w_ij(halfedge_descriptor) { return 1.; } }; +/// \endcond + } // namespace Weights } // namespace CGAL From 0d00ad237b2e851488af4276184e1276f7eaf107 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 21 Oct 2022 00:05:20 +0200 Subject: [PATCH 26/35] Remove needless normalization calls --- Weights/include/CGAL/Weights/internal/utils.h | 19 +++++-------------- .../include/CGAL/Weights/tangent_weights.h | 4 ---- 2 files changed, 5 insertions(+), 18 deletions(-) diff --git a/Weights/include/CGAL/Weights/internal/utils.h b/Weights/include/CGAL/Weights/internal/utils.h index af5e3f27c91..483616d8254 100644 --- a/Weights/include/CGAL/Weights/internal/utils.h +++ b/Weights/include/CGAL/Weights/internal/utils.h @@ -191,19 +191,19 @@ double angle_3(const typename GeomTraits::Vector_3& v1, { auto dot_product_3 = traits.compute_scalar_product_3_object(); - const double product = CGAL::sqrt(to_double(scalar_product(v1,v1)) * to_double(scalar_product(v2,v2))); + const double product = CGAL::sqrt(to_double(dot_product_3(v1,v1) * dot_product_3(v2,v2))); if(product == 0.) return 0.; const double dot = CGAL::to_double(dot_product_3(v1, v2)); - const double costine = dot / product; + const double cosine = dot / product; - if (dot < -1.0) + if (cosine < -1.0) return std::acos(-1.0); - else if (dot > 1.0) + else if (cosine > 1.0) return std::acos(+1.0); else - return std::acos(dot); + return std::acos(cosine); } // Rotates a 3D point around axis. @@ -387,16 +387,10 @@ void flatten(const typename GeomTraits::Point_3& t, // prev neighbor/vertex/poin Vector_3 v1 = vector_3(q1, t1); Vector_3 v2 = vector_3(q1, p1); - normalize_3(v1, traits); - normalize_3(v2, traits); - // Two triangle normals. Vector_3 n1 = cross_product_3(v1, ax); Vector_3 n2 = cross_product_3(ax, v2); - normalize_3(n1, traits); - normalize_3(n2, traits); - // std::cout << "normal n1: " << n1 << std::endl; // std::cout << "normal n2: " << n2 << std::endl; @@ -474,12 +468,9 @@ typename GeomTraits::FT area_3(const typename GeomTraits::Point_3& p, // Prev and next vectors. Vector_3 v1 = vector_3(b, a); Vector_3 v2 = vector_3(b, c); - normalize_3(v1, traits); - normalize_3(v2, traits); // Compute normal. Vector_3 normal = cross_product_3(v1, v2); - normalize_3(normal, traits); // Compute orthogonal base vectors. Vector_3 b1, b2; diff --git a/Weights/include/CGAL/Weights/tangent_weights.h b/Weights/include/CGAL/Weights/tangent_weights.h index afa64e2da90..6f31b0b1c6c 100644 --- a/Weights/include/CGAL/Weights/tangent_weights.h +++ b/Weights/include/CGAL/Weights/tangent_weights.h @@ -123,10 +123,6 @@ typename GeomTraits::FT tangent_weight_v2(const typename GeomTraits::Point_3& p0 const FT l2 = internal::length_3(v, traits); - internal::normalize_3(v0, traits); - internal::normalize_3(v, traits); - internal::normalize_3(v2, traits); - const double ha_rad_1 = internal::angle_3(v0, v, traits) / 2.0; const double ha_rad_2 = internal::angle_3(v, v2, traits) / 2.0; const FT t0 = static_cast(std::tan(ha_rad_1)); From 6a5f099f4191455ca72ec9dc41afa3beac58644d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 21 Oct 2022 00:05:30 +0200 Subject: [PATCH 27/35] Add a test --- .../test/Weights/test_voronoi_region_weights.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Weights/test/Weights/test_voronoi_region_weights.cpp b/Weights/test/Weights/test_voronoi_region_weights.cpp index 7040392d029..49b0fe672af 100644 --- a/Weights/test/Weights/test_voronoi_region_weights.cpp +++ b/Weights/test/Weights/test_voronoi_region_weights.cpp @@ -12,6 +12,22 @@ using EPECK = CGAL::Exact_predicates_exact_constructions_kernel; template void test_kernel() { + using FT = typename Kernel::FT; + using Point_2 = typename Kernel::Point_2; + using Point_3 = typename Kernel::Point_3; + + const Point_2 p( 2, 0); + const Point_2 q( 0, 2); + const Point_2 r(-2, 0); + const FT w1 = CGAL::Weights::voronoi_area(p, q, r); + assert(w1 == FT(2)); + + const Point_3 s( 0, -2, 0); + const Point_3 t( 0, 0, 2); + const Point_3 u( 0, 2, 0); + const FT w4 = CGAL::Weights::voronoi_area(s, t, u); + assert(w4 == FT(2)); + const wrappers::Voronoi_region_wrapper vor; tests::test_region_weight(vor); } From 6a694366f035e422a7fcc45199b5914dd76bf872 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 21 Oct 2022 10:34:07 +0200 Subject: [PATCH 28/35] Remove trailing whitespace --- Weights/test/Weights/include/wrappers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Weights/test/Weights/include/wrappers.h b/Weights/test/Weights/include/wrappers.h index 9a6bdbbb653..2566a219a6c 100644 --- a/Weights/test/Weights/include/wrappers.h +++ b/Weights/test/Weights/include/wrappers.h @@ -245,7 +245,7 @@ struct Triangular_region_wrapper }; template -struct Barycentric_region_wrapper +struct Barycentric_region_wrapper { using FT = typename Kernel::FT; template From 82c0d0686e0f73a8ec9c85691b384f363a97c8e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 21 Oct 2022 11:23:36 +0200 Subject: [PATCH 29/35] Add missing typedef --- Weights/include/CGAL/Weights/internal/utils.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Weights/include/CGAL/Weights/internal/utils.h b/Weights/include/CGAL/Weights/internal/utils.h index 483616d8254..744af8be2d3 100644 --- a/Weights/include/CGAL/Weights/internal/utils.h +++ b/Weights/include/CGAL/Weights/internal/utils.h @@ -448,6 +448,7 @@ typename GeomTraits::FT area_3(const typename GeomTraits::Point_3& p, const GeomTraits& traits) { using FT = typename GeomTraits::FT; + using Point_2 = typename GeomTraits::Point_2; using Point_3 = typename GeomTraits::Point_3; using Vector_3 = typename GeomTraits::Vector_3; From b0c183fc3d90ee04400a7a6e6f6586e725987c69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 21 Oct 2022 12:07:12 +0200 Subject: [PATCH 30/35] Add missing typedef --- Weights/include/CGAL/Weights/tangent_weights.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Weights/include/CGAL/Weights/tangent_weights.h b/Weights/include/CGAL/Weights/tangent_weights.h index 6f31b0b1c6c..2ec910d67e2 100644 --- a/Weights/include/CGAL/Weights/tangent_weights.h +++ b/Weights/include/CGAL/Weights/tangent_weights.h @@ -235,6 +235,7 @@ typename GeomTraits::FT half_tangent_weight(const typename GeomTraits::Point_2& const GeomTraits& traits) { using FT = typename GeomTraits::FT; + using Vector_2 = typename GeomTraits::Vector_2; auto vector_2 = traits.construct_vector_2_object(); auto dot_product_2 = traits.compute_scalar_product_2_object(); From 8d7669d559d543c9e7251a7b3bf8d023a74b9979 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 21 Oct 2022 12:15:03 +0200 Subject: [PATCH 31/35] Test alternate API + add missing typedef --- Weights/include/CGAL/Weights/tangent_weights.h | 1 + Weights/test/Weights/include/wrappers.h | 5 +---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Weights/include/CGAL/Weights/tangent_weights.h b/Weights/include/CGAL/Weights/tangent_weights.h index 2ec910d67e2..7788a961218 100644 --- a/Weights/include/CGAL/Weights/tangent_weights.h +++ b/Weights/include/CGAL/Weights/tangent_weights.h @@ -259,6 +259,7 @@ typename GeomTraits::FT half_tangent_weight(const typename GeomTraits::Point_3& const GeomTraits& traits) { using FT = typename GeomTraits::FT; + using Vector_3 = typename GeomTraits::Vector_3; auto vector_3 = traits.construct_vector_3_object(); auto dot_product_3 = traits.compute_scalar_product_3_object(); diff --git a/Weights/test/Weights/include/wrappers.h b/Weights/test/Weights/include/wrappers.h index 2566a219a6c..94138e735df 100644 --- a/Weights/test/Weights/include/wrappers.h +++ b/Weights/test/Weights/include/wrappers.h @@ -70,10 +70,7 @@ struct Tangent_wrapper template FT weight_b(const Point& t, const Point& r, const Point& p, const Point& q) const { - return CGAL::Weights::half_tangent_weight(CGAL::Weights::internal::distance(r, q), - CGAL::Weights::internal::distance(t, q), - CGAL::Weights::internal::area(r, q, t), - CGAL::Weights::internal::scalar_product(r, q, t)) + + return CGAL::Weights::half_tangent_weight(r, q, t, Kernel()) + CGAL::Weights::half_tangent_weight(CGAL::Weights::internal::distance(r, q), CGAL::Weights::internal::distance(p, q), CGAL::Weights::internal::area(p, q, r), From 4d4bf04b835849a4735a28833a3b722c1a5f78b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 21 Oct 2022 12:47:52 +0200 Subject: [PATCH 32/35] Fix constructor of Mean_curvature_flow_skeletonization + weight API --- .../CGAL/Mean_curvature_flow_skeletonization.h | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Surface_mesh_skeletonization/include/CGAL/Mean_curvature_flow_skeletonization.h b/Surface_mesh_skeletonization/include/CGAL/Mean_curvature_flow_skeletonization.h index aa86264e177..43a6a41ceb6 100644 --- a/Surface_mesh_skeletonization/include/CGAL/Mean_curvature_flow_skeletonization.h +++ b/Surface_mesh_skeletonization/include/CGAL/Mean_curvature_flow_skeletonization.h @@ -223,7 +223,7 @@ public: typedef typename boost::graph_traits::edge_iterator edge_iterator; // Get weight from the weight interface. - typedef CGAL::Weights::Cotangent_weight Weight_calculator; + typedef CGAL::Weights::Cotangent_weight Weight_calculator; typedef internal::Curve_skeleton Vertex_pair; std::vector v2v; copy_face_graph(tmesh, m_tmesh, - CGAL::parameters::vertex_to_vertex_output_iterator(std::back_inserter(v2v))); + CGAL::parameters::vertex_to_vertex_output_iterator(std::back_inserter(v2v)) + .vertex_point_map(vpm)); // copy input vertices to keep correspondence for(const Vertex_pair& vp : v2v) From bd83e152e3f85642539792feb1f18bc2b812c761 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 21 Oct 2022 13:52:55 +0200 Subject: [PATCH 33/35] Fix initialization and usage of Weights in skeletonization --- .../include/CGAL/Mean_curvature_flow_skeletonization.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Surface_mesh_skeletonization/include/CGAL/Mean_curvature_flow_skeletonization.h b/Surface_mesh_skeletonization/include/CGAL/Mean_curvature_flow_skeletonization.h index 43a6a41ceb6..58e8e0b4d43 100644 --- a/Surface_mesh_skeletonization/include/CGAL/Mean_curvature_flow_skeletonization.h +++ b/Surface_mesh_skeletonization/include/CGAL/Mean_curvature_flow_skeletonization.h @@ -371,7 +371,11 @@ public: Mean_curvature_flow_skeletonization(const TriangleMesh& tmesh, VertexPointMap vertex_point_map, const Traits& traits = Traits()) - : m_traits(traits), m_weight_calculator(tmesh, vertex_point_map, traits, true /* use_clamped_version */) + : + m_tmesh(), + m_tmesh_point_pmap(get(CGAL::vertex_point, m_tmesh)), + m_traits(traits), + m_weight_calculator(m_tmesh, m_tmesh_point_pmap, m_traits, true /* use_clamped_version */) { init(tmesh, vertex_point_map); } @@ -884,7 +888,7 @@ private: m_edge_weight.clear(); m_edge_weight.reserve(num_halfedges(m_tmesh)); for(halfedge_descriptor hd : halfedges(m_tmesh)) - m_edge_weight.push_back(m_weight_calculator(hd, m_tmesh, m_tmesh_point_pmap)); + m_edge_weight.push_back(m_weight_calculator(hd)); } /// Assemble the left hand side. From 88b3d0ab88731588dbdf770c14848913131a5320 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 21 Oct 2022 14:32:42 +0200 Subject: [PATCH 34/35] Fix compilation --- Weights/include/CGAL/Weights/cotangent_weights.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Weights/include/CGAL/Weights/cotangent_weights.h b/Weights/include/CGAL/Weights/cotangent_weights.h index 93413b7cb24..d462c3f5174 100644 --- a/Weights/include/CGAL/Weights/cotangent_weights.h +++ b/Weights/include/CGAL/Weights/cotangent_weights.h @@ -338,7 +338,7 @@ private: (CGAL::angle(p2, p1, p0) == CGAL::OBTUSE) || (CGAL::angle(p0, p2, p1) == CGAL::OBTUSE)) { - const FT A = internal::positive_area_3(m_traits, p0, p1, p2); + const FT A = internal::positive_area_3(p0, p1, p2, m_traits); if (angle0 == CGAL::OBTUSE) voronoi_area += A / FT(2); else From 56244a493f0ae7efd00837cd5cbad363cc104d8e Mon Sep 17 00:00:00 2001 From: Mael Date: Mon, 7 Nov 2022 13:12:49 +0100 Subject: [PATCH 35/35] Fix test --- Weights/test/Weights/include/wrappers.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Weights/test/Weights/include/wrappers.h b/Weights/test/Weights/include/wrappers.h index 94138e735df..2566a219a6c 100644 --- a/Weights/test/Weights/include/wrappers.h +++ b/Weights/test/Weights/include/wrappers.h @@ -70,7 +70,10 @@ struct Tangent_wrapper template FT weight_b(const Point& t, const Point& r, const Point& p, const Point& q) const { - return CGAL::Weights::half_tangent_weight(r, q, t, Kernel()) + + return CGAL::Weights::half_tangent_weight(CGAL::Weights::internal::distance(r, q), + CGAL::Weights::internal::distance(t, q), + CGAL::Weights::internal::area(r, q, t), + CGAL::Weights::internal::scalar_product(r, q, t)) + CGAL::Weights::half_tangent_weight(CGAL::Weights::internal::distance(r, q), CGAL::Weights::internal::distance(p, q), CGAL::Weights::internal::area(p, q, r),