refactor: update transformation system, improve template readability, and reorganize VTK assembly management
This commit is contained in:
@@ -48,18 +48,28 @@ namespace uLib {
|
||||
namespace Vtk {
|
||||
|
||||
struct ContainerBoxData {
|
||||
vtkSmartPointer<vtkActor> m_Cube;
|
||||
vtkSmartPointer<vtkActor> m_Axes;
|
||||
vtkSmartPointer<vtkActor> m_Cube;
|
||||
vtkSmartPointer<vtkActor> m_Axes;
|
||||
vtkSmartPointer<vtkAssembly> m_VtkAsm;
|
||||
vtkSmartPointer<vtkMatrix4x4> m_Affine;
|
||||
uLib::Connection m_UpdateSignal;
|
||||
|
||||
ContainerBoxData() : m_Cube(vtkSmartPointer<vtkActor>::New()), m_Axes(vtkSmartPointer<vtkActor>::New()) {}
|
||||
ContainerBoxData() : m_Cube(vtkSmartPointer<vtkActor>::New()),
|
||||
m_Axes(vtkSmartPointer<vtkActor>::New()),
|
||||
m_VtkAsm(vtkSmartPointer<vtkAssembly>::New()),
|
||||
m_Affine(vtkSmartPointer<vtkMatrix4x4>::New()) {}
|
||||
~ContainerBoxData() {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
vtkContainerBox::vtkContainerBox(vtkContainerBox::Content *content)
|
||||
: d(new ContainerBoxData()), m_Content(content) {
|
||||
this->InstallPipe();
|
||||
Object::connect(m_Content, &Content::Updated, this, &vtkContainerBox::contentUpdate);
|
||||
d->m_UpdateSignal = Object::connect(m_Content, &uLib::Object::Updated, this, &vtkContainerBox::Update);
|
||||
}
|
||||
|
||||
vtkContainerBox::~vtkContainerBox() {
|
||||
@@ -72,47 +82,50 @@ vtkPolyData *vtkContainerBox::GetPolyData() const {
|
||||
}
|
||||
|
||||
|
||||
void vtkContainerBox::contentUpdate() {
|
||||
void vtkContainerBox::Update() {
|
||||
RecursiveMutex::ScopedLock lock(this->m_UpdateMutex);
|
||||
if (!m_Content)
|
||||
return;
|
||||
if (!m_Content) return;
|
||||
|
||||
vtkProp3D* root = vtkProp3D::SafeDownCast(this->GetProp());
|
||||
if (!root) return;
|
||||
if (root) {
|
||||
// Apply local full matrix (TRS * LocalBox) so that nested assemblies work correctly
|
||||
Matrix4f fullLocal = m_Content->GetMatrix() * m_Content->GetLocalMatrix();
|
||||
vtkNew<vtkMatrix4x4> m;
|
||||
Matrix4fToVtk(fullLocal, m);
|
||||
root->SetUserMatrix(m);
|
||||
root->Modified();
|
||||
}
|
||||
|
||||
d->m_Cube->SetUserMatrix(nullptr);
|
||||
d->m_Axes->SetUserMatrix(nullptr);
|
||||
|
||||
TRS trs(*m_Content);
|
||||
this->ApplyTransform(root);
|
||||
|
||||
root->Modified();
|
||||
m_BlockUpdate = false;
|
||||
Puppet::Update();
|
||||
// Delegate rest of update (appearance, render, etc)
|
||||
ConnectionBlock blocker(d->m_UpdateSignal);
|
||||
this->Puppet::Update();
|
||||
}
|
||||
|
||||
|
||||
void vtkContainerBox::Update() {
|
||||
this->contentUpdate();
|
||||
}
|
||||
|
||||
void vtkContainerBox::SyncFromVtk() {
|
||||
RecursiveMutex::ScopedLock lock(this->m_UpdateMutex);
|
||||
if (!m_Content) return;
|
||||
|
||||
vtkProp3D* assembly = vtkProp3D::SafeDownCast(this->GetProp());
|
||||
if (!assembly) return;
|
||||
|
||||
double pos[3], ori[3], scale[3];
|
||||
assembly->GetPosition(pos);
|
||||
assembly->GetOrientation(ori);
|
||||
assembly->GetScale(scale);
|
||||
vtkProp3D* root = this->GetProxyProp();
|
||||
if (!root) return;
|
||||
|
||||
// VTK -> Model: Extract new world TRS from proxy, which matches the model's TRS center
|
||||
vtkMatrix4x4* rootMat = root->GetUserMatrix();
|
||||
if (rootMat) {
|
||||
std::cout << "[vtkContainerBox::SyncFromVtk] Read Proxy UserMatrix:" << std::endl;
|
||||
rootMat->Print(std::cout);
|
||||
}
|
||||
|
||||
m_Content->SetPosition(Vector3f(pos[0], pos[1], pos[2]));
|
||||
m_Content->SetOrientation(Vector3f(ori[0], ori[1], ori[2]) * CLHEP::degree);
|
||||
m_Content->SetScale(Vector3f(scale[0], scale[1], scale[2]));
|
||||
Matrix4f vtkWorld = VtkToMatrix4f(rootMat);
|
||||
|
||||
m_Content->Updated(); // Notify change
|
||||
// Synchronize TRS property members from the updated local matrix
|
||||
m_Content->FromMatrix(vtkWorld);
|
||||
|
||||
std::cout << "[vtkContainerBox::SyncFromVtk] New Model WorldMatrix:" << std::endl << m_Content->GetWorldMatrix() << std::endl;
|
||||
|
||||
// Since we modified the model, notify observers, but block the loop back to VTK
|
||||
// ConnectionBlock blocker(d->m_UpdateSignal);
|
||||
m_Content->Updated();
|
||||
}
|
||||
|
||||
|
||||
@@ -154,17 +167,16 @@ void vtkContainerBox::InstallPipe() {
|
||||
mapper->SetInputConnection(axes->GetOutputPort());
|
||||
mapper->Update();
|
||||
|
||||
this->SetProp(d->m_Cube);
|
||||
this->SetProp(d->m_Axes);
|
||||
d->m_VtkAsm->AddPart(d->m_Cube);
|
||||
d->m_VtkAsm->AddPart(d->m_Axes);
|
||||
this->SetProp(d->m_VtkAsm);
|
||||
|
||||
vtkProp3D* root = vtkProp3D::SafeDownCast(this->GetProp());
|
||||
vtkProp3D* root = d->m_VtkAsm;
|
||||
if (root) {
|
||||
TRS trs(*c);
|
||||
root->SetPosition(trs.position.x(), trs.position.y(), trs.position.z());
|
||||
root->SetOrientation(trs.rotation.x(), trs.rotation.y(), trs.rotation.z());
|
||||
root->SetScale(trs.scaling.x(), trs.scaling.y(), trs.scaling.z());
|
||||
root->SetUserMatrix(nullptr);
|
||||
d->m_Affine = Matrix4fToVtk(m_Content->GetMatrix());
|
||||
root->SetUserMatrix(d->m_Affine);
|
||||
}
|
||||
this->Update();
|
||||
}
|
||||
|
||||
} // namespace Vtk
|
||||
|
||||
Reference in New Issue
Block a user