diff --git a/src/HEP/Geant/EmitterPrimary.cpp b/src/HEP/Geant/EmitterPrimary.cpp index 56c85cd..db22d62 100644 --- a/src/HEP/Geant/EmitterPrimary.cpp +++ b/src/HEP/Geant/EmitterPrimary.cpp @@ -71,14 +71,13 @@ void QuadMeshEmitterPrimary::CalculateAreas() { m_CumulativeAreas.clear(); m_TotalArea = 0.0; - const auto &points = m_Mesh->Points(); const auto &quads = m_Mesh->Quads(); for (const auto &q : quads) { - uLib::Vector3f v0 = points[q(0)]; - uLib::Vector3f v1 = points[q(1)]; - uLib::Vector3f v2 = points[q(2)]; - uLib::Vector3f v3 = points[q(3)]; + uLib::Vector3f v0 = m_Mesh->GetPoint(q(0)); + uLib::Vector3f v1 = m_Mesh->GetPoint(q(1)); + uLib::Vector3f v2 = m_Mesh->GetPoint(q(2)); + uLib::Vector3f v3 = m_Mesh->GetPoint(q(3)); double a1 = 0.5 * (v1 - v0).cross(v2 - v0).norm(); double a2 = 0.5 * (v2 - v0).cross(v3 - v0).norm(); @@ -96,11 +95,10 @@ void QuadMeshEmitterPrimary::GeneratePrimaries(G4Event *anEvent) { int quadIdx = std::distance(m_CumulativeAreas.begin(), it); const auto &q = m_Mesh->Quads()[quadIdx]; - const auto &points = m_Mesh->Points(); - uLib::Vector3f v0 = points[q(0)]; - uLib::Vector3f v1 = points[q(1)]; - uLib::Vector3f v2 = points[q(2)]; - uLib::Vector3f v3 = points[q(3)]; + uLib::Vector3f v0 = m_Mesh->GetPoint(q(0)); + uLib::Vector3f v1 = m_Mesh->GetPoint(q(1)); + uLib::Vector3f v2 = m_Mesh->GetPoint(q(2)); + uLib::Vector3f v3 = m_Mesh->GetPoint(q(3)); // 2. Choose a point on the quad double a1 = 0.5 * (v1 - v0).cross(v2 - v0).norm(); diff --git a/src/Math/ContainerBox.h b/src/Math/ContainerBox.h index af3a8f3..588225a 100644 --- a/src/Math/ContainerBox.h +++ b/src/Math/ContainerBox.h @@ -180,7 +180,7 @@ public: signals: // signal to emit when the box is updated // - void Updated() { ULIB_SIGNAL_EMIT(ContainerBox::Updated); } + virtual void Updated() override { ULIB_SIGNAL_EMIT(ContainerBox::Updated); } private: AffineTransform m_LocalT; diff --git a/src/Math/QuadMesh.cpp b/src/Math/QuadMesh.cpp index b9b18ac..8498cd3 100644 --- a/src/Math/QuadMesh.cpp +++ b/src/Math/QuadMesh.cpp @@ -35,10 +35,10 @@ void QuadMesh::PrintSelf(std::ostream &o) o << " #Quads : " << m_Quads.size() << "\n"; for(int i=0; i < m_Quads.size(); ++i ) { o << " - quad[" << i << "]" << - " " << m_Quads[i](0) << "->(" << m_Points[m_Quads[i](0)].transpose() << ") " << - " " << m_Quads[i](1) << "->(" << m_Points[m_Quads[i](1)].transpose() << ") " << - " " << m_Quads[i](2) << "->(" << m_Points[m_Quads[i](2)].transpose() << ") " << - " " << m_Quads[i](3) << "->(" << m_Points[m_Quads[i](3)].transpose() << ") " << + " " << m_Quads[i](0) << "->(" << GetPoint(m_Quads[i](0)).transpose() << ") " << + " " << m_Quads[i](1) << "->(" << GetPoint(m_Quads[i](1)).transpose() << ") " << + " " << m_Quads[i](2) << "->(" << GetPoint(m_Quads[i](2)).transpose() << ") " << + " " << m_Quads[i](3) << "->(" << GetPoint(m_Quads[i](3)).transpose() << ") " << " \n"; } o << " // ------------------------- // \n"; @@ -46,7 +46,16 @@ void QuadMesh::PrintSelf(std::ostream &o) void QuadMesh::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 QuadMesh::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 QuadMesh::AddQuad(const Id_t *id) @@ -63,9 +72,9 @@ void QuadMesh::AddQuad(const Vector4i &id) Vector3f QuadMesh::GetNormal(const Id_t id) const { const Vector4i &quad = m_Quads.at(id); - const Vector3f &v0 = m_Points.at(quad(0)); - const Vector3f &v1 = m_Points.at(quad(1)); - const Vector3f &v3 = m_Points.at(quad(3)); + const Vector3f v0 = this->GetPoint(quad(0)); + const Vector3f v1 = this->GetPoint(quad(1)); + const Vector3f v3 = this->GetPoint(quad(3)); Vector3f edge1 = v1 - v0; Vector3f edge2 = v3 - v0; diff --git a/src/Math/QuadMesh.h b/src/Math/QuadMesh.h index 6889e78..7a103fc 100644 --- a/src/Math/QuadMesh.h +++ b/src/Math/QuadMesh.h @@ -29,25 +29,33 @@ #include #include "Math/Dense.h" +#include "Core/Object.h" +#include "Math/Transform.h" namespace uLib { -class QuadMesh +class QuadMesh : 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 AddQuad(const Id_t *id); void AddQuad(const Vector4i &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 & Quads() { return this->m_Quads; } const Vector4i & GetQuad(const Id_t id) const { return m_Quads.at(id); } Vector3f GetNormal(const Id_t id) const; + virtual void Updated() override { ULIB_SIGNAL_EMIT(QuadMesh::Updated); } + private: std::vector m_Points; std::vector m_Quads; diff --git a/src/Math/testing/QuadMeshTest.cpp b/src/Math/testing/QuadMeshTest.cpp index 9e41b4c..bcd5fdb 100644 --- a/src/Math/testing/QuadMeshTest.cpp +++ b/src/Math/testing/QuadMeshTest.cpp @@ -47,5 +47,17 @@ int main() { ASSERT_EQ(mesh.Points().size(), 4); ASSERT_EQ(mesh.Quads().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/vtkQuadMeshTest.cpp b/src/Vtk/Math/testing/vtkQuadMeshTest.cpp index 1ecb57b..0b2b285 100644 --- a/src/Vtk/Math/testing/vtkQuadMeshTest.cpp +++ b/src/Vtk/Math/testing/vtkQuadMeshTest.cpp @@ -43,6 +43,17 @@ BOOST_AUTO_TEST_CASE(vtkQuadMeshConstruction) { mesh.AddQuad(Vector4i(0, 1, 2, 3)); Vtk::vtkQuadMesh v_mesh(mesh); + + Object::connect(&mesh, &QuadMesh::Updated, [&mesh]() { + Vector3f points[4]; + points[0] = mesh.GetPoint(0); + points[1] = mesh.GetPoint(1); + points[2] = mesh.GetPoint(2); + points[3] = mesh.GetPoint(3); + std::cout << "mesh updated: " << points[0] << " " << points[1] + << " " << points[2] << " " << points[3] << std::endl; + }); + v_mesh.Update(); if (std::getenv("CTEST_PROJECT_NAME") == nullptr) { diff --git a/src/Vtk/Math/vtkQuadMesh.cpp b/src/Vtk/Math/vtkQuadMesh.cpp index dcb164b..9ac8b89 100644 --- a/src/Vtk/Math/vtkQuadMesh.cpp +++ b/src/Vtk/Math/vtkQuadMesh.cpp @@ -40,6 +40,9 @@ #include #include +#include +#include +#include "Math/vtkDense.h" #include "Vtk/Math/vtkQuadMesh.h" #include @@ -55,12 +58,10 @@ void vtkQuadMesh::vtk2uLib_update() { << "number of quads = " << number_of_quads << "\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.Quads().resize(number_of_quads); @@ -86,11 +87,8 @@ void vtkQuadMesh::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(); @@ -110,7 +108,33 @@ void vtkQuadMesh::uLib2vtk_update() { m_Poly->SetPoints(points); m_Poly->SetPolys(polys); m_Poly->Modified(); +} + +void vtkQuadMesh::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 vtkQuadMesh::Update() { + vtkMatrix4x4 *vmat = m_Actor->GetUserMatrix(); + if (!vmat) return; + + Matrix4f transform = VtkToMatrix4f(vmat); + m_content.SetMatrix(transform); + m_content.Updated(); } // -------------------------------------------------------------------------- // @@ -121,10 +145,18 @@ vtkQuadMesh::vtkQuadMesh(vtkQuadMesh::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, &vtkQuadMesh::contentUpdate); + this->contentUpdate(); } vtkQuadMesh::~vtkQuadMesh() { + Object::disconnect(&m_content, &Content::Updated, this, &vtkQuadMesh::contentUpdate); m_Poly->Delete(); m_Actor->Delete(); } @@ -165,7 +197,5 @@ void vtkQuadMesh::ReadFromStlFile(const char *filename) { vtkPolyData *vtkQuadMesh::GetPolyData() const { return m_Poly; } -void vtkQuadMesh::Update() { uLib2vtk_update(); } - } // namespace Vtk } // namespace uLib diff --git a/src/Vtk/Math/vtkQuadMesh.h b/src/Vtk/Math/vtkQuadMesh.h index a49e2ab..b34282a 100644 --- a/src/Vtk/Math/vtkQuadMesh.h +++ b/src/Vtk/Math/vtkQuadMesh.h @@ -53,7 +53,9 @@ public: virtual class vtkPolyData *GetPolyData() const; - void Update(); + virtual void contentUpdate(); + + virtual void Update(); private: void vtk2uLib_update(); diff --git a/src/Vtk/vtkHandlerWidget.cpp b/src/Vtk/vtkHandlerWidget.cpp index 50b628a..47a8a52 100644 --- a/src/Vtk/vtkHandlerWidget.cpp +++ b/src/Vtk/vtkHandlerWidget.cpp @@ -261,7 +261,7 @@ void vtkHandlerWidget::OnMouseMove() { double dy = Y - this->StartEventPosition[1]; if (dx == 0 && dy == 0) return; - std::cout << "Interaction " << this->Interaction << " dx=" << dx << " dy=" << dy << std::endl; + // std::cout << "Interaction " << this->Interaction << " dx=" << dx << " dy=" << dy << std::endl; // Get current gizmo properties from its actors vtkMatrix4x4 *gizmo_mat = m_AxesX->GetUserMatrix();