From 57f9c0a5c6fab8b50d5206083cb06c442ab53d16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag=20W=C3=A4stberg?= Date: Tue, 17 Sep 2024 13:41:17 +0200 Subject: [PATCH] add normalize normals method --- src/cpp/include/MeshBuilder.h | 1 + src/cpp/include/Triangulate.h | 6 ++-- src/cpp/include/model/Mesh.h | 59 +++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 2 deletions(-) diff --git a/src/cpp/include/MeshBuilder.h b/src/cpp/include/MeshBuilder.h index 5a08cff8..57265882 100644 --- a/src/cpp/include/MeshBuilder.h +++ b/src/cpp/include/MeshBuilder.h @@ -679,6 +679,7 @@ class MeshBuilder // multimesh.push_back(surface_mesh); // } auto mesh = MeshProcessor::merge_meshes(multimesh, weld); + mesh.normalize_normal_direction(); return mesh; } diff --git a/src/cpp/include/Triangulate.h b/src/cpp/include/Triangulate.h index cc27fec3..b692ee3a 100644 --- a/src/cpp/include/Triangulate.h +++ b/src/cpp/include/Triangulate.h @@ -134,7 +134,8 @@ static void call_triangle(Mesh &mesh, if (surface.vertices.size() == 3 && !has_holes) { mesh.vertices = surface.vertices; - mesh.faces.push_back(Simplex2D(0, 1, 2)); + mesh.faces.push_back(Simplex2D(0, 1, 2, false)); + mesh.sort_vertices(); return; } @@ -143,8 +144,9 @@ static void call_triangle(Mesh &mesh, mesh.vertices = surface.vertices; for (size_t i = 1; i < surface.vertices.size() - 1; i++) { - mesh.faces.push_back(Simplex2D(0, i, i + 1)); + mesh.faces.push_back(Simplex2D(0, i, i + 1, false)); } + mesh.sort_vertices(); } else { diff --git a/src/cpp/include/model/Mesh.h b/src/cpp/include/model/Mesh.h index 67841033..de9d3be3 100644 --- a/src/cpp/include/model/Mesh.h +++ b/src/cpp/include/model/Mesh.h @@ -44,12 +44,71 @@ class Mesh : public Printable return c; } + Vector3D centroid() const + { + Vector3D c{}; + for (auto &v : vertices) + { + c += Vector3D(v); + } + c /= vertices.size(); + return c; + } + + /// sort vertices of each face + void sort_vertices(bool ccw = true) + { + for (auto &face : faces) + { + // Get the vertices of the face + auto v0 = vertices[face.v0]; + auto v1 = vertices[face.v1]; + auto v2 = vertices[face.v2]; + auto normal = (v1 - v0).cross(v2 - v0); + // Check if the normal vector is pointing in the desired direction + bool swap = ccw ? normal.z < 0 : normal.z > 0; + if (swap) // Assuming z-axis is up + { + // Swap v1 and v2 to change the orientation + std::swap(face.v1, face.v2); + } + } + } + + void normalize_normal_direction(bool outwards = true) + { + for (auto &face : faces) + { + auto centroid = this->centroid(); + auto v0 = vertices[face.v0]; + auto v1 = vertices[face.v1]; + auto v2 = vertices[face.v2]; + auto normal = (v1 - v0).cross(v2 - v0); + // Calculate the vector from the centroid to the face + auto to_face = (v0 + v1 + v2) / 3.0 - centroid; + bool swap = outwards ? normal.dot(to_face) < 0 : normal.dot(to_face) > 0; + if (swap) + { + // Swap v1 and v2 to change the orientation + std::swap(face.v1, face.v2); + } + } + } + + + + + + + /// Pretty-print std::string __str__() const override { return "Mesh with " + str(vertices.size()) + " vertices and " + str(faces.size()) + " faces"; } + + }; } // namespace DTCC_BUILDER