From ca5f576b9912d15c159c34e8aad621f1fd0fef01 Mon Sep 17 00:00:00 2001 From: AndreaRigoni Date: Thu, 19 Mar 2026 13:11:49 +0000 Subject: [PATCH] add triangle mesh affine transform --- src/Math/TriangleMesh.cpp | 25 +++++++--- src/Math/TriangleMesh.h | 11 ++++- src/Math/testing/TriangleMeshTest.cpp | 15 ++++++ src/Vtk/Math/testing/vtkTriangleMeshTest.cpp | 10 ++++ src/Vtk/Math/vtkTriangleMesh.cpp | 52 +++++++++++++++----- src/Vtk/Math/vtkTriangleMesh.h | 4 +- 6 files changed, 96 insertions(+), 21 deletions(-) diff --git a/src/Math/TriangleMesh.cpp b/src/Math/TriangleMesh.cpp index 8c3b7df..3e1241c 100644 --- a/src/Math/TriangleMesh.cpp +++ b/src/Math/TriangleMesh.cpp @@ -34,14 +34,14 @@ void TriangleMesh::PrintSelf(std::ostream &o) o << " // ------- TRIANGLE MESH ------- // \n" ; o << " #Points : " << m_Points.size() << "\n"; o << " #Triang : " << m_Triangles.size() << "\n"; - for(int i=0; i < m_Triangles.size(); ++i ) { + for(int i=0; i < (int)m_Triangles.size(); ++i ) { o << " - triangle[" << i << "]" << " " << m_Triangles[i](0) << - "->(" << m_Points[m_Triangles[i](0)].transpose() << ") " << + "->(" << GetPoint(m_Triangles[i](0)).transpose() << ") " << " " << m_Triangles[i](1) << - "->(" << m_Points[m_Triangles[i](1)].transpose() << ") " << + "->(" << GetPoint(m_Triangles[i](1)).transpose() << ") " << " " << m_Triangles[i](2) << - "->(" << m_Points[m_Triangles[i](2)].transpose() << ") " << + "->(" << GetPoint(m_Triangles[i](2)).transpose() << ") " << " \n"; } o << " // ----------------------------- // \n"; @@ -49,7 +49,16 @@ void TriangleMesh::PrintSelf(std::ostream &o) void TriangleMesh::AddPoint(const Vector3f &pt) { - this->m_Points.push_back(pt); + Vector4f p(pt.x(), pt.y(), pt.z(), 1.0f); + Vector4f localP = this->GetWorldMatrix().inverse() * p; + this->m_Points.push_back(localP.head<3>()); +} + +Vector3f TriangleMesh::GetPoint(const Id_t id) const +{ + Vector4f p(m_Points.at(id).x(), m_Points.at(id).y(), m_Points.at(id).z(), 1.0f); + Vector4f worldP = this->GetWorldMatrix() * p; + return worldP.head<3>(); } void TriangleMesh::AddTriangle(const Id_t *id) @@ -66,9 +75,9 @@ void TriangleMesh::AddTriangle(const Vector3i &id) Vector3f TriangleMesh::GetNormal(const Id_t id) const { const Vector3i &trg = m_Triangles.at(id); - const Vector3f &v0 = m_Points.at(trg(0)); - const Vector3f &v1 = m_Points.at(trg(1)); - const Vector3f &v2 = m_Points.at(trg(2)); + const Vector3f v0 = this->GetPoint(trg(0)); + const Vector3f v1 = this->GetPoint(trg(1)); + const Vector3f v2 = this->GetPoint(trg(2)); Vector3f edge1 = v1 - v0; Vector3f edge2 = v2 - v0; diff --git a/src/Math/TriangleMesh.h b/src/Math/TriangleMesh.h index 1ebb43b..604c645 100644 --- a/src/Math/TriangleMesh.h +++ b/src/Math/TriangleMesh.h @@ -32,24 +32,33 @@ #include "Math/Dense.h" +#include "Core/Object.h" +#include "Math/Transform.h" + namespace uLib { -class TriangleMesh +class TriangleMesh : public AffineTransform, public Object { public: void PrintSelf(std::ostream &o); + /** @brief Adds a point in global coordinates. Stored in local coordinates. */ void AddPoint(const Vector3f &pt); void AddTriangle(const Id_t *id); void AddTriangle(const Vector3i &id); + /** @brief Returns point in global coordinates. */ + Vector3f GetPoint(const Id_t id) const; + inline std::vector & Points() { return this->m_Points; } inline std::vector & Triangles() { return this->m_Triangles; } const Vector3i & GetTriangle(const Id_t id) const { return m_Triangles.at(id); } Vector3f GetNormal(const Id_t id) const; + virtual void Updated() override { ULIB_SIGNAL_EMIT(TriangleMesh::Updated); } + private: std::vector m_Points; std::vector m_Triangles; diff --git a/src/Math/testing/TriangleMeshTest.cpp b/src/Math/testing/TriangleMeshTest.cpp index f44be3e..6632d72 100644 --- a/src/Math/testing/TriangleMeshTest.cpp +++ b/src/Math/testing/TriangleMeshTest.cpp @@ -43,5 +43,20 @@ int main() { mesh.PrintSelf(std::cout); + TEST1(mesh.Points().size() == 3); + TEST1(mesh.Triangles().size() == 1); + + // Test transformation + mesh.Translate(Vector3f(10, 20, 30)); + Vector3f p0 = mesh.GetPoint(0); + TEST1( (p0 - Vector3f(10, 20, 30)).norm() < 1e-6 ); + + // Test AddPoint during transformation + mesh.AddPoint(Vector3f(11, 21, 31)); // Should be stored as (1, 1, 1) locally + Id_t lastId = mesh.Points().size() - 1; + TEST1( (mesh.Points().at(lastId) - Vector3f(1, 1, 1)).norm() < 1e-5 ); + + mesh.PrintSelf(std::cout); + END_TESTING; } diff --git a/src/Vtk/Math/testing/vtkTriangleMeshTest.cpp b/src/Vtk/Math/testing/vtkTriangleMeshTest.cpp index f824314..4e64a79 100644 --- a/src/Vtk/Math/testing/vtkTriangleMeshTest.cpp +++ b/src/Vtk/Math/testing/vtkTriangleMeshTest.cpp @@ -41,6 +41,16 @@ BOOST_AUTO_TEST_CASE(vtkTriangleMeshConstruction) { mesh.AddTriangle(Vector3i(0, 1, 2)); Vtk::vtkTriangleMesh v_mesh(mesh); + + Object::connect(&mesh, &TriangleMesh::Updated, [&mesh]() { + Vector3f points[3]; + points[0] = mesh.GetPoint(0); + points[1] = mesh.GetPoint(1); + points[2] = mesh.GetPoint(2); + std::cout << "mesh updated: " << points[0].transpose() << " " << points[1].transpose() + << " " << points[2].transpose() << std::endl; + }); + v_mesh.Update(); if (std::getenv("CTEST_PROJECT_NAME") == nullptr) { diff --git a/src/Vtk/Math/vtkTriangleMesh.cpp b/src/Vtk/Math/vtkTriangleMesh.cpp index 8893308..9e2699f 100644 --- a/src/Vtk/Math/vtkTriangleMesh.cpp +++ b/src/Vtk/Math/vtkTriangleMesh.cpp @@ -40,6 +40,9 @@ #include #include +#include +#include +#include "Math/vtkDense.h" #include "Vtk/Math/vtkTriangleMesh.h" #include @@ -55,12 +58,10 @@ void vtkTriangleMesh::vtk2uLib_update() { << "number of polys = " << number_of_triangles << "\n" << "//////\n"; - m_content.Points().resize(number_of_points); + m_content.Points().clear(); for (int i = 0; i < number_of_points; ++i) { double *point = m_Poly->GetPoint(i); - m_content.Points()[i](0) = point[0]; - m_content.Points()[i](1) = point[1]; - m_content.Points()[i](2) = point[2]; + m_content.Points().push_back(Vector3f(point[0], point[1], point[2])); } m_content.Triangles().resize(number_of_triangles); @@ -83,11 +84,8 @@ void vtkTriangleMesh::uLib2vtk_update() { vtkSmartPointer points = vtkSmartPointer::New(); points->SetNumberOfPoints(number_of_points); for (vtkIdType i = 0; i < number_of_points; i++) { - double x, y, z; - x = m_content.Points().at(i)(0); - y = m_content.Points().at(i)(1); - z = m_content.Points().at(i)(2); - points->SetPoint(i, x, y, z); + Vector3f p = m_content.Points().at(i); + points->SetPoint(i, p(0), p(1), p(2)); } vtkSmartPointer polys = vtkSmartPointer::New(); @@ -105,7 +103,33 @@ void vtkTriangleMesh::uLib2vtk_update() { m_Poly->SetPoints(points); m_Poly->SetPolys(polys); m_Poly->Modified(); +} + +void vtkTriangleMesh::contentUpdate() { + vtkMatrix4x4 *vmat = m_Actor->GetUserMatrix(); + if (!vmat) { + vtkNew mat; + m_Actor->SetUserMatrix(mat); + vmat = mat; + } + + Matrix4f transform = m_content.GetWorldMatrix(); + Matrix4fToVtk(transform, vmat); + + uLib2vtk_update(); + + m_Poly->Modified(); m_Actor->GetMapper()->Update(); + Puppet::Update(); +} + +void vtkTriangleMesh::Update() { + vtkMatrix4x4 *vmat = m_Actor->GetUserMatrix(); + if (!vmat) return; + + Matrix4f transform = VtkToMatrix4f(vmat); + m_content.SetMatrix(transform); + m_content.Updated(); } // -------------------------------------------------------------------------- // @@ -116,10 +140,18 @@ vtkTriangleMesh::vtkTriangleMesh(vtkTriangleMesh::Content &content) vtkSmartPointer::New(); mapper->SetInputData(m_Poly); m_Actor->SetMapper(mapper); + + vtkNew vmat; + Matrix4fToVtk(m_content.GetWorldMatrix(), vmat); + m_Actor->SetUserMatrix(vmat); + this->SetProp(m_Actor); + Object::connect(&m_content, &Content::Updated, this, &vtkTriangleMesh::contentUpdate); + this->contentUpdate(); } vtkTriangleMesh::~vtkTriangleMesh() { + Object::disconnect(&m_content, &Content::Updated, this, &vtkTriangleMesh::contentUpdate); m_Poly->Delete(); m_Actor->Delete(); } @@ -160,7 +192,5 @@ void vtkTriangleMesh::ReadFromStlFile(const char *filename) { vtkPolyData *vtkTriangleMesh::GetPolyData() const { return m_Poly; } -void vtkTriangleMesh::Update() { uLib2vtk_update(); } - } // namespace Vtk } // namespace uLib diff --git a/src/Vtk/Math/vtkTriangleMesh.h b/src/Vtk/Math/vtkTriangleMesh.h index 8920c1e..6ef07d7 100644 --- a/src/Vtk/Math/vtkTriangleMesh.h +++ b/src/Vtk/Math/vtkTriangleMesh.h @@ -53,7 +53,9 @@ public: virtual class vtkPolyData *GetPolyData() const; - void Update(); + virtual void contentUpdate(); + + virtual void Update(); private: void vtk2uLib_update();