diff --git a/src/OpenMesh/Core/Geometry/Vector11T.hh b/src/OpenMesh/Core/Geometry/Vector11T.hh index 796a9e9b..978e5408 100644 --- a/src/OpenMesh/Core/Geometry/Vector11T.hh +++ b/src/OpenMesh/Core/Geometry/Vector11T.hh @@ -414,10 +414,17 @@ class VectorT { /** normalize vector, return normalized vector and avoids div by zero */ - vector_type& normalize_cond() { - Scalar n = norm(); - if (n != (Scalar)0.0) - { + template::type> + typename std::enable_if< + sizeof(static_cast(0)) >= 0, + vector_type&>::type + normalize_cond() { + static_assert(sizeof(static_cast(0)) >= 0, + "normalize_cond() only works with Scalar types that can " + "be statically casted from 0."); + auto n = norm(); + if (n != static_cast(0)) { *this /= n; } return *this; diff --git a/src/Unittests/unittests_vector_type.cc b/src/Unittests/unittests_vector_type.cc index 1986ce22..ce845091 100644 --- a/src/Unittests/unittests_vector_type.cc +++ b/src/Unittests/unittests_vector_type.cc @@ -154,4 +154,13 @@ TEST_F(OpenMeshVectorTest, BasicLinearAlgebra) { EXPECT_NEAR(14, OpenMesh::Vec3d(-1, -2, -3) | OpenMesh::Vec3d(-1, -2, -3), 1e-6); } +TEST_F(OpenMeshVectorTest, normalized_cond) { + OpenMesh::Vec3d v1(1, -2, 3), v2(0, 0, 0); + EXPECT_EQ(OpenMesh::Vec3d(0, 0, 0), v2.normalize_cond()); + const auto r1 = OpenMesh::Vec3d(0.2672612419124244, -0.5345224838248488, 0.8017837257372732) - v1.normalize_cond(); + EXPECT_NEAR(r1[0], 0.0, 1e-6); + EXPECT_NEAR(r1[1], 0.0, 1e-6); + EXPECT_NEAR(r1[2], 0.0, 1e-6); +} + }