From dcacc0ce613893f3b3fe1988d6b0098e22a9c4fc Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Wed, 24 Jan 2024 12:38:02 +0100 Subject: [PATCH] add update normal functions --- include/vclib/algorithms/update/normal.h | 71 +++++++++++++++-------- include/vclib/space/plane.h | 2 +- include/vclib/space/point.h | 2 +- include/vclib/space/principal_curvature.h | 2 +- include/vclib/space/quaternion.h | 2 +- include/vclib/space/sphere.h | 2 +- include/vclib/space/tex_coord.h | 2 +- 7 files changed, 54 insertions(+), 29 deletions(-) diff --git a/include/vclib/algorithms/update/normal.h b/include/vclib/algorithms/update/normal.h index 6fb7e3a39..fb1943d77 100644 --- a/include/vclib/algorithms/update/normal.h +++ b/include/vclib/algorithms/update/normal.h @@ -25,35 +25,46 @@ #include #include +#include #include #include "../polygon.h" namespace vcl { +namespace detail { + +template +void normalizeNoThrow(auto& elem, LogType& log) +{ + try { + elem.normal().normalize(); + } + catch (const std::exception& e) { + log.log( + LogType::WARNING, + elementEnumString() + " " + + std::to_string(elem.index()) + ": " + e.what()); + } +} + +} // namespace vcl::detail + template void normalizePerElementNormals( MeshType& mesh, - bool noThrow = true, LogType& log = nullLogger) { vcl::requirePerElementComponent(mesh); - log.log(0, "Normalizing per-" + elementEnumString() + " normals"); + log.log(0, "Normalizing per-" + elementEnumString() + " normals."); - for (auto& elem : mesh.template elements()) { - try { - elem.normal().normalize(); - } - catch (const std::exception& e) { - if (noThrow) { - log.log(LogType::WARNING, e.what()); - } - else { - throw e; - } - } - } + // define a lambda that, for each element, normalizes the normal + auto normalize = [&](auto& elem) { + detail::normalizeNoThrow(elem, log); + }; + + vcl::parallelFor(mesh.template elements(), normalize); log.log( 100, "Per-" + elementEnumString() + " normals normalized."); @@ -160,6 +171,22 @@ void normalizePerVertexNormals(MeshType& m) normalizePerElementNormals(m); } +/** + * @brief Normalizes the length of normals the referenced vertices. + * + * @param m + * @param log + */ +template +void normalizePerReferencedVertexNormals(MeshType& m, LogType& log = nullLogger) +{ + for (auto& f : m.faces()) { + for (auto* v : f.vertices()) { + detail::normalizeNoThrow(*v, log); + } + } +} + /** * @brief Normalizes the length of the face normals. * @@ -289,24 +316,22 @@ void clearPerReferencedVertexNormals(MeshType& m) * @param[in] normalize: if true (default), normals are normalized after * computation. */ -template -void updatePerVertexNormals(MeshType& m, bool normalize = true) +void updatePerVertexNormals(FaceMeshConcept auto& m, bool normalize = true) { clearPerReferencedVertexNormals(m); + using MeshType = std::remove_reference_t; using VertexType = MeshType::VertexType; - using FaceType = MeshType::FaceType; using NormalType = VertexType::NormalType; + using NScalar = NormalType::ScalarType; - for (FaceType& f : m.faces()) { - NormalType n = - faceNormal(f).template cast(); + for (auto& f : m.faces()) { for (VertexType* v : f.vertices()) { - v->normal() += n; + v->normal() += faceNormal(f).template cast(); } } if (normalize) - normalizePerVertexNormals(m); + normalizePerReferencedVertexNormals(m); } /** diff --git a/include/vclib/space/plane.h b/include/vclib/space/plane.h index 8a989870d..61c409bd1 100644 --- a/include/vclib/space/plane.h +++ b/include/vclib/space/plane.h @@ -105,7 +105,7 @@ class Plane } template - Plane cast() const + auto cast() const { if constexpr (std::is_same::value) { return *this; diff --git a/include/vclib/space/point.h b/include/vclib/space/point.h index cdcc484aa..128434733 100644 --- a/include/vclib/space/point.h +++ b/include/vclib/space/point.h @@ -208,7 +208,7 @@ class Point * object, but with each scalar value casted to a different type. */ template - Point cast() const + auto cast() const { if constexpr (std::is_same_v) { return *this; diff --git a/include/vclib/space/principal_curvature.h b/include/vclib/space/principal_curvature.h index 918ea1650..68f4b6a3b 100644 --- a/include/vclib/space/principal_curvature.h +++ b/include/vclib/space/principal_curvature.h @@ -68,7 +68,7 @@ class PrincipalCurvature * a different type. */ template - PrincipalCurvature cast() const + auto cast() const { if constexpr (std::is_same::value) { return *this; diff --git a/include/vclib/space/quaternion.h b/include/vclib/space/quaternion.h index d17ce0390..779b810cb 100644 --- a/include/vclib/space/quaternion.h +++ b/include/vclib/space/quaternion.h @@ -145,7 +145,7 @@ class Quaternion * different type. */ template - const Quaternion cast() const + auto cast() const { if constexpr (std::is_same_v) { return *this; diff --git a/include/vclib/space/sphere.h b/include/vclib/space/sphere.h index 3fed1fdf8..e36e438c2 100644 --- a/include/vclib/space/sphere.h +++ b/include/vclib/space/sphere.h @@ -55,7 +55,7 @@ class Sphere Scalar& radius() { return r; } template - Sphere cast() const + auto cast() const { if constexpr (std::is_same_v) { return *this; diff --git a/include/vclib/space/tex_coord.h b/include/vclib/space/tex_coord.h index 12017b4df..9a5691b63 100644 --- a/include/vclib/space/tex_coord.h +++ b/include/vclib/space/tex_coord.h @@ -45,7 +45,7 @@ class TexCoord TexCoord(const Point2& p) : coord(p) {} template - TexCoord cast() const + auto cast() const { if constexpr (std::is_same::value) { return *this;