From 99ae69f1e4ddeab5e30d54bc6ab6f031f786113a Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Wed, 2 Oct 2024 11:12:09 +0200 Subject: [PATCH] Don't estimate normal from collinear edges in TTL serializer --- src/serializers/TtlWktSerializer.cpp | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/serializers/TtlWktSerializer.cpp b/src/serializers/TtlWktSerializer.cpp index 482c088de1..f85578e0fe 100644 --- a/src/serializers/TtlWktSerializer.cpp +++ b/src/serializers/TtlWktSerializer.cpp @@ -265,14 +265,25 @@ void TtlWktSerializer::write(const IfcGeom::TriangulationElement* o) double lowest_z = std::numeric_limits::infinity(); for (const auto& f : o->geometry().polyhedral_faces_with_holes()) { - auto v0 = vertex_map.transpose().row(f[0][0]); - auto v1 = vertex_map.transpose().row(f[0][1]); - auto v2 = vertex_map.transpose().row(f[0][2]); - auto v1_v0 = v1 - v0; - auto v2_v0 = v2 - v0; + Eigen::Vector3d v0, v1, v2, v1_v0, v2_v0; + for (size_t i = 0; i < f[0].size(); ++i) { + v0 = vertex_map.transpose().row(f[0][0 + i]); + v1 = vertex_map.transpose().row(f[0][1 + i]); + v2 = vertex_map.transpose().row(f[0][2 + i]); + v1_v0 = v1 - v0; + v2_v0 = v2 - v0; + v1_v0.normalize(); + v2_v0.normalize(); + if ((std::abs(v1_v0.dot(v2_v0)) + 1.e-9) >= 1.0) { + // Don't derive normal from collinear edges + continue; + } + break; + } Eigen::Vector3d cross_product = v1_v0.cross(v2_v0); cross_product.normalize(); + // @nb we take abs because so that we can ignore face orientation and potential convatities rquire if ((std::abs(cross_product.z()) + 1.e-9) >= 1.0 && v0.z() < lowest_z) { lowest_face = f.begin();