refactor: extend Object property system and implement recursive property discovery in Vtk::Puppet archive
This commit is contained in:
@@ -61,8 +61,8 @@ int main(int argc, char** argv) {
|
||||
vtkTess.AddToViewer(viewer);
|
||||
|
||||
// Color them differently
|
||||
vtkActor::SafeDownCast(vtkBox.GetProp())->GetProperty()->SetColor(0.8, 0.2, 0.2); // Redish box
|
||||
vtkActor::SafeDownCast(vtkTess.GetProp())->GetProperty()->SetColor(0.2, 0.8, 0.2); // Greenish tess
|
||||
vtkBox.SetColor(0.8, 0.2, 0.2); // Redish box
|
||||
vtkTess.SetColor(0.2, 0.8, 0.2); // Greenish tess
|
||||
|
||||
// Position tessellated solid away from box
|
||||
Matrix4f trans = Matrix4f::Identity();
|
||||
|
||||
@@ -13,43 +13,104 @@
|
||||
#include <vtkCubeSource.h>
|
||||
#include <vtkPolyDataMapper.h>
|
||||
#include <vtkActor.h>
|
||||
#include <vtkAssembly.h>
|
||||
#include <vtkTransform.h>
|
||||
#include <vtkMatrix4x4.h>
|
||||
#include <Geant4/G4VPhysicalVolume.hh>
|
||||
#include "Vtk/Math/vtkDense.h"
|
||||
|
||||
namespace uLib {
|
||||
namespace Vtk {
|
||||
|
||||
vtkBoxSolid::vtkBoxSolid(Geant::BoxSolid *content)
|
||||
: vtkGeantSolid(content), m_BoxContent(content) {
|
||||
// Re-run Update for box-specific pipe
|
||||
: 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());
|
||||
}
|
||||
|
||||
// Connect the model's Updated event to updateTransform to ensure VTK sync
|
||||
Object::connect(m_BoxContent, &uLib::Object::Updated, this, &vtkBoxSolid::UpdateTransform);
|
||||
|
||||
// Initial sync
|
||||
this->Update();
|
||||
}
|
||||
|
||||
vtkBoxSolid::~vtkBoxSolid() {}
|
||||
vtkBoxSolid::~vtkBoxSolid() {
|
||||
if (m_BoxPuppet) {
|
||||
delete m_BoxPuppet;
|
||||
}
|
||||
}
|
||||
|
||||
void vtkBoxSolid::Update() {
|
||||
this->UpdateGeometry();
|
||||
this->UpdateTransform();
|
||||
// Ensure base Puppet properties (color, opacity, etc) 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vtkBoxSolid::UpdateGeometry() {
|
||||
if (!m_BoxContent || !m_BoxContent->GetObject()) {
|
||||
// Fallback to base tessellation if no model object
|
||||
if (!m_BoxContent || !m_BoxContent->GetObject() || !m_BoxPuppet) {
|
||||
// Fallback to base tessellation if no model object is available
|
||||
vtkGeantSolid::UpdateGeometry();
|
||||
return;
|
||||
}
|
||||
|
||||
// Use the underlying ContainerBox for precise geometry
|
||||
Vector3f size = m_BoxContent->GetObject()->GetSize();
|
||||
|
||||
vtkNew<vtkCubeSource> cube;
|
||||
cube->SetXLength(size(0));
|
||||
cube->SetYLength(size(1));
|
||||
cube->SetZLength(size(2));
|
||||
cube->Update();
|
||||
// The vtkContainerBox manages its own geometry update
|
||||
m_BoxPuppet->Update();
|
||||
}
|
||||
|
||||
vtkPolyData *poly = GetPolyData();
|
||||
if (poly) {
|
||||
poly->ShallowCopy(cube->GetOutput());
|
||||
poly->Modified();
|
||||
void vtkBoxSolid::UpdateTransform() {
|
||||
if (!m_BoxContent || !m_BoxPuppet) {
|
||||
vtkGeantSolid::UpdateTransform();
|
||||
return;
|
||||
}
|
||||
|
||||
// 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<vtkTransform> transform = vtkSmartPointer<vtkTransform>::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<vtkMatrix4x4> mat = vtkSmartPointer<vtkMatrix4x4>::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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,12 @@
|
||||
#ifndef U_VTKBOXSOLID_H
|
||||
#define U_VTKBOXSOLID_H
|
||||
|
||||
#include "Core/Types.h"
|
||||
#include "Core/Property.h"
|
||||
#include "Core/Serializable.h"
|
||||
|
||||
#include "vtkGeantSolid.h"
|
||||
#include "Vtk/Math/vtkContainerBox.h"
|
||||
|
||||
namespace uLib {
|
||||
namespace Vtk {
|
||||
@@ -35,15 +40,27 @@ namespace Vtk {
|
||||
* @brief VTK Puppet for visualizing a Geant::BoxSolid.
|
||||
*/
|
||||
class vtkBoxSolid : public vtkGeantSolid {
|
||||
uLibTypeMacro(vtkBoxSolid, uLib::Vtk::vtkGeantSolid)
|
||||
|
||||
public:
|
||||
vtkBoxSolid(Geant::BoxSolid *content);
|
||||
virtual ~vtkBoxSolid();
|
||||
|
||||
virtual void Update() override;
|
||||
virtual void UpdateGeometry() override;
|
||||
virtual void UpdateTransform() override;
|
||||
virtual void SyncFromVtk() override;
|
||||
|
||||
template <typename Ar>
|
||||
void serialize(Ar &ar, const unsigned int version) {
|
||||
ar & NVP("BoxSolid", *m_BoxContent);
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
Geant::BoxSolid *m_BoxContent;
|
||||
vtkContainerBox *m_BoxPuppet;
|
||||
|
||||
ULIB_DECLARE_PROPERTIES(vtkBoxSolid)
|
||||
};
|
||||
|
||||
} // namespace Vtk
|
||||
|
||||
Reference in New Issue
Block a user