add assembly

This commit is contained in:
AndreaRigoni
2026-03-25 22:48:04 +00:00
parent 422113a0e9
commit 2c5d6842c3
18 changed files with 800 additions and 171 deletions

View File

@@ -25,6 +25,7 @@
#include "Vtk/Math/vtkCylinder.h"
#include <vtkActor.h>
#include <vtkAssembly.h>
#include <vtkCylinderSource.h>
#include <vtkMatrix4x4.h>
#include <vtkPolyDataMapper.h>
@@ -37,13 +38,14 @@ namespace uLib {
namespace Vtk {
vtkCylinder::vtkCylinder(vtkCylinder::Content *content)
: m_Actor(vtkActor::New()), m_Content(content) {
: m_Content(content), m_Actor(nullptr), m_VtkAsm(nullptr) {
this->InstallPipe();
Object::connect(m_Content, &Content::Updated, this, &vtkCylinder::contentUpdate);
}
vtkCylinder::~vtkCylinder() {
m_Actor->Delete();
if (m_Actor) m_Actor->Delete();
if (m_VtkAsm) m_VtkAsm->Delete();
}
void vtkCylinder::contentUpdate() {
@@ -53,28 +55,31 @@ void vtkCylinder::contentUpdate() {
vtkProp3D* root = vtkProp3D::SafeDownCast(this->GetProp());
if (!root) return;
// 1. Placement (Position/Rotation/Model-level Scale) goes to the root prop
vtkMatrix4x4* vmat = root->GetUserMatrix();
if (!vmat) {
vtkNew<vtkMatrix4x4> mat;
root->SetUserMatrix(mat);
vmat = mat;
}
// Multiply the placement matrix by the volume scaling (Radius, Radius, Height)
Matrix4f transform = m_Content->GetMatrix() * m_Content->GetLocalMatrix();
Matrix4f transform = m_Content->GetMatrix();
Matrix4fToVtk(transform, vmat);
// Update internal alignment based on active axis
// 2. Shape-local properties (Radius, Height, Axis alignment) go to the internal actor
vtkTransform* alignment = vtkTransform::SafeDownCast(m_Actor->GetUserTransform());
if (alignment) {
alignment->Identity();
alignment->PostMultiply();
// Initial source is centered Y-cylinder (Radial XZ [-1,1], Height Y [-0.5, 0.5])
// Apply Radius and Height scaling
alignment->Scale(m_Content->GetRadius(), m_Content->GetHeight(), m_Content->GetRadius());
// Apply Axis alignment
int axis = m_Content->GetAxis();
if (axis == 0) alignment->RotateZ(-90); // Y -> X
else if (axis == 1) ; // Y -> Y (identity)
else if (axis == 2) alignment->RotateX(90); // Y -> Z
// We keep it centered as per latest user preference in Step 677
// alignment->Translate(0, 0, 0); // Implicit
}
root->Modified();
@@ -90,16 +95,9 @@ void vtkCylinder::Update() {
vtkMatrix4x4* vmat = root->GetUserMatrix();
if (!vmat) return;
Matrix4f fullTransform = VtkToMatrix4f(vmat);
Matrix4f placementScale = m_Content->GetLocalMatrix().inverse();
Matrix4f transform = fullTransform * placementScale;
if (m_Content->GetParent()) {
Matrix4f localT = m_Content->GetParent()->GetWorldMatrix().inverse() * transform;
m_Content->SetMatrix(localT);
} else {
m_Content->SetMatrix(transform);
}
// Pull the placement matrix directly from VTK
Matrix4f transform = VtkToMatrix4f(vmat);
m_Content->SetMatrix(transform);
m_Content->Updated();
}
@@ -108,36 +106,27 @@ void vtkCylinder::InstallPipe() {
if (!m_Content)
return;
m_VtkAsm = ::vtkAssembly::New();
this->SetProp(m_VtkAsm);
vtkNew<vtkCylinderSource> cylinder;
cylinder->SetRadius(1.0);
cylinder->SetHeight(1.0);
cylinder->SetResolution(32);
m_Actor = vtkActor::New();
vtkNew<vtkTransform> alignment;
alignment->Identity();
alignment->Translate(0, 0, -0.5);
// Default to Y alignment (Identity) as per latest request
int axis = m_Content->GetAxis();
if (axis == 0) alignment->RotateZ(-90);
else if (axis == 2) alignment->RotateX(90);
m_Actor->SetUserTransform(alignment);
vtkNew<vtkPolyDataMapper> mapper;
mapper->SetInputConnection(cylinder->GetOutputPort());
m_Actor->SetMapper(mapper);
m_Actor->SetUserTransform(alignment);
m_Actor->GetProperty()->SetRepresentationToWireframe();
m_Actor->GetProperty()->SetAmbient(0.6);
this->SetProp(m_Actor);
vtkProp3D* root = vtkProp3D::SafeDownCast(this->GetProp());
if (root) {
vtkNew<vtkMatrix4x4> vmat;
Matrix4fToVtk(m_Content->GetMatrix() * m_Content->GetLocalMatrix(), vmat);
root->SetUserMatrix(vmat);
}
m_VtkAsm->AddPart(m_Actor);
this->contentUpdate();
}
} // namespace Vtk