From e0fb2f4daec8c831b93a5840033105b33c7868e7 Mon Sep 17 00:00:00 2001 From: AndreaRigoni Date: Fri, 3 Apr 2026 16:44:00 +0000 Subject: [PATCH] refactor: unify vtkBoxSolid architecture with Puppet base and update build documentation --- .agents/rules/micromamba.md | 7 ++- src/HEP/Geant/Solid.cpp | 2 + src/Vtk/HEP/Geant/vtkBoxSolid.cpp | 96 ++++++++++------------------- src/Vtk/HEP/Geant/vtkBoxSolid.h | 15 ++++- src/Vtk/HEP/Geant/vtkGeantSolid.cpp | 1 + src/Vtk/Math/vtkContainerBox.h | 4 +- src/Vtk/Math/vtkCylinder.cpp | 14 +---- 7 files changed, 57 insertions(+), 82 deletions(-) diff --git a/.agents/rules/micromamba.md b/.agents/rules/micromamba.md index be21db6..fd0b4ec 100644 --- a/.agents/rules/micromamba.md +++ b/.agents/rules/micromamba.md @@ -2,6 +2,7 @@ trigger: always_on --- -build in build directory using always micromamba "mutom" env. -build with make flag -j$(nproc). - +build in build directory using always micromamba "uLib" env. +build with: + make flag -j$(nproc) + ninja -C build \ No newline at end of file diff --git a/src/HEP/Geant/Solid.cpp b/src/HEP/Geant/Solid.cpp index 16a99ee..a2b3c7a 100644 --- a/src/HEP/Geant/Solid.cpp +++ b/src/HEP/Geant/Solid.cpp @@ -105,6 +105,8 @@ void Solid::SetTransform(Matrix4f transform) { m_Physical->SetTranslation(*m_Position); m_Physical->SetRotation(m_Rotation); } + + std::cout << "Solid " << GetName() << " position: " << pos << " rotation: " << m << std::endl; } void Solid::SetParent(Solid *parent) { diff --git a/src/Vtk/HEP/Geant/vtkBoxSolid.cpp b/src/Vtk/HEP/Geant/vtkBoxSolid.cpp index 59d915c..c3329a1 100644 --- a/src/Vtk/HEP/Geant/vtkBoxSolid.cpp +++ b/src/Vtk/HEP/Geant/vtkBoxSolid.cpp @@ -10,9 +10,11 @@ //////////////////////////////////////////////////////////////////////////////*/ #include "vtkBoxSolid.h" +#include "Core/Monitor.h" #include #include #include +#include #include #include #include @@ -23,95 +25,59 @@ namespace uLib { namespace Vtk { vtkBoxSolid::vtkBoxSolid(Geant::BoxSolid *content) - : vtkGeantSolid(content), m_BoxContent(content), m_BoxPuppet(nullptr) { - - if (m_BoxContent && m_BoxContent->GetObject()) { - m_BoxPuppet = new vtkContainerBox(m_BoxContent->GetObject()); - // Use the specialized box puppet's representation as our main prop - this->SetProp(m_BoxPuppet->GetProp()); - } - + : vtkGeantSolid(content), m_BoxContent(content) { + this->InstallPipe(); + // Connect the model's Updated event to updateTransform to ensure VTK sync - Object::connect(m_BoxContent, &uLib::Object::Updated, this, &vtkBoxSolid::UpdateTransform); + m_UpdateConnection = Object::connect(m_BoxContent, &uLib::Object::Updated, this, &vtkBoxSolid::Update); // Initial sync this->Update(); } vtkBoxSolid::~vtkBoxSolid() { - if (m_BoxPuppet) { - delete m_BoxPuppet; - } } void vtkBoxSolid::Update() { + ConnectionBlock blocker(m_UpdateConnection); this->UpdateGeometry(); - this->UpdateTransform(); - // Ensure base Puppet properties (color, opacity, etc) are applied + // Ensure base Puppet properties (color, opacity, etc) and transform are applied this->Puppet::Update(); } void vtkBoxSolid::SyncFromVtk() { - vtkProp3D *root = vtkProp3D::SafeDownCast(this->GetProp()); - if (root && m_BoxContent) { - vtkMatrix4x4 *rootMat = root->GetUserMatrix(); - if (rootMat) { - Matrix4f vtkWorld = VtkToMatrix4f(rootMat); - m_BoxContent->SetTransform(vtkWorld); - m_BoxContent->Updated(); - } + this->Puppet::SyncFromVtk(); + if (auto* proxy = vtkProp3D::SafeDownCast(this->GetProxyProp())) { + if (vtkMatrix4x4* mat = proxy->GetUserMatrix()) { + m_BoxContent->SetTransform(VtkToMatrix4f(mat)); + } } } void vtkBoxSolid::UpdateGeometry() { - if (!m_BoxContent || !m_BoxContent->GetObject() || !m_BoxPuppet) { - // Fallback to base tessellation if no model object is available - vtkGeantSolid::UpdateGeometry(); - return; - } - - // The vtkContainerBox manages its own geometry update - m_BoxPuppet->Update(); + // Sync geometry from G4VSolid provided by vtkGeantSolid (tessellation) + vtkGeantSolid::UpdateGeometry(); } void vtkBoxSolid::UpdateTransform() { - if (!m_BoxContent || !m_BoxPuppet) { - vtkGeantSolid::UpdateTransform(); - return; + // Take transform from Puppet base (which uses GetContent() -> ContainerBox TRS) + this->Puppet::Update(); +} + +void vtkBoxSolid::serialize_display(uLib::Archive::display_properties_archive &ar, + const unsigned int version) { + // Expose Geant solid properties and underlying Box/TRS properties + this->Puppet::serialize_display(ar, version); + if (m_BoxContent) { + ar & NVP("Box", *m_BoxContent); + if (m_BoxContent->GetObject()) { + ar & NVP("Container", *m_BoxContent->GetObject()); + } } +} - // 1. Sync the inner box TRS (local box properties like size and offset) - m_BoxPuppet->Update(); - - // 2. Sync the Geant4-level placement (world position/rotation) - vtkProp3D* root = vtkProp3D::SafeDownCast(this->GetProp()); - if (root && m_BoxContent->GetPhysical()) { - auto *phys = m_BoxContent->GetPhysical(); - G4ThreeVector pos = phys->GetTranslation(); - const G4RotationMatrix *rot = phys->GetRotation(); - - vtkSmartPointer transform = vtkSmartPointer::New(); - transform->Identity(); - transform->Translate(pos.x(), pos.y(), pos.z()); - - if (rot) { - // G4RotationMatrix stores the inverse of the rotation for placement - G4RotationMatrix invRot = rot->inverse(); - double elements[16] = { - invRot.xx(), invRot.xy(), invRot.xz(), 0, - invRot.yx(), invRot.yy(), invRot.yz(), 0, - invRot.zx(), invRot.zy(), invRot.zz(), 0, - 0, 0, 0, 1 - }; - vtkSmartPointer mat = vtkSmartPointer::New(); - mat->DeepCopy(elements); - transform->Concatenate(mat); - } - // Apply the Geant4 transform on top of the local box's UserMatrix - root->SetUserTransform(transform); - } else if (root) { - root->SetUserTransform(nullptr); - } +void vtkBoxSolid::InstallPipe() { + vtkGeantSolid::InstallPipe(); } } // namespace Vtk diff --git a/src/Vtk/HEP/Geant/vtkBoxSolid.h b/src/Vtk/HEP/Geant/vtkBoxSolid.h index 64946c8..369fe26 100644 --- a/src/Vtk/HEP/Geant/vtkBoxSolid.h +++ b/src/Vtk/HEP/Geant/vtkBoxSolid.h @@ -31,7 +31,9 @@ #include "Core/Serializable.h" #include "vtkGeantSolid.h" -#include "Vtk/Math/vtkContainerBox.h" + +class vtkCubeSource; +class vtkActor; namespace uLib { namespace Vtk { @@ -51,14 +53,23 @@ public: virtual void UpdateTransform() override; virtual void SyncFromVtk() override; + virtual uLib::Object *GetContent() const override { + return m_BoxContent ? (::uLib::Object*)m_BoxContent->GetObject() : nullptr; + } + + virtual void serialize_display(uLib::Archive::display_properties_archive &ar, + const unsigned int version = 0) override; + template void serialize(Ar &ar, const unsigned int version) { ar & NVP("BoxSolid", *m_BoxContent); } +protected: + virtual void InstallPipe() override; Geant::BoxSolid *m_BoxContent; - vtkContainerBox *m_BoxPuppet; + uLib::Connection m_UpdateConnection; ULIB_DECLARE_PROPERTIES(vtkBoxSolid) }; diff --git a/src/Vtk/HEP/Geant/vtkGeantSolid.cpp b/src/Vtk/HEP/Geant/vtkGeantSolid.cpp index bd0e544..4a60d59 100644 --- a/src/Vtk/HEP/Geant/vtkGeantSolid.cpp +++ b/src/Vtk/HEP/Geant/vtkGeantSolid.cpp @@ -82,6 +82,7 @@ void vtkGeantSolid::UpdateGeometry() { int nVertices = polyhedron->GetNoVertices(); for (int i = 1; i <= nVertices; ++i) { G4Point3D vtx = polyhedron->GetVertex(i); + points->InsertNextPoint(vtx.x(), vtx.y(), vtx.z()); } diff --git a/src/Vtk/Math/vtkContainerBox.h b/src/Vtk/Math/vtkContainerBox.h index bf8d4a5..d6f0da6 100644 --- a/src/Vtk/Math/vtkContainerBox.h +++ b/src/Vtk/Math/vtkContainerBox.h @@ -38,8 +38,10 @@ namespace Vtk { struct ContainerBoxData; class vtkContainerBox : public Puppet, public Polydata { + + uLibTypeMacro(vtkContainerBox, Puppet, Polydata) typedef ContainerBox Content; - + public: vtkContainerBox(Content *content); ~vtkContainerBox(); diff --git a/src/Vtk/Math/vtkCylinder.cpp b/src/Vtk/Math/vtkCylinder.cpp index 7115604..9814ee9 100644 --- a/src/Vtk/Math/vtkCylinder.cpp +++ b/src/Vtk/Math/vtkCylinder.cpp @@ -72,8 +72,8 @@ void vtkCylinder::Update() { // Apply Axis alignment int axis = m_Content->GetAxis(); - if (axis == 0) alignment->RotateZ(-90); // Y -> X - else if (axis == 1) ; // Y -> Y (identity) + if (axis == 0) alignment->RotateZ(-90); // Y -> X + else if (axis == 1) ; // Y -> Y (identity) else if (axis == 2) alignment->RotateX(90); // Y -> Z } @@ -92,19 +92,11 @@ void vtkCylinder::SyncFromVtk() { if (!root) return; // VTK -> Model: Extract new world TRS from proxy - vtkMatrix4x4* rootMat = root->GetUserMatrix(); - if (rootMat) { - std::cout << "[vtkCylinder::SyncFromVtk] Read Proxy UserMatrix:" << std::endl; - rootMat->Print(std::cout); - } - + vtkMatrix4x4* rootMat = root->GetUserMatrix(); Matrix4f vtkWorld = VtkToMatrix4f(rootMat); // Directly sync model from the world matrix m_Content->FromMatrix(vtkWorld); - - std::cout << "[vtkCylinder::SyncFromVtk] New Model WorldMatrix:" << std::endl << m_Content->GetWorldMatrix() << std::endl; - m_Content->Updated(); }