/*////////////////////////////////////////////////////////////////////////////// // CMT Cosmic Muon Tomography project ////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova All rights reserved Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > ------------------------------------------------------------------ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. //////////////////////////////////////////////////////////////////////////////*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "vtkContainerBox.h" #include #include #include #include #include #include #include #include #include #include #include "Math/vtkDense.h" namespace uLib { namespace Vtk { struct ContainerBoxData { vtkSmartPointer m_Cube; vtkSmartPointer m_Axes; vtkSmartPointer m_VtkAsm; vtkSmartPointer m_Affine; uLib::Connection m_UpdateSignal; ContainerBoxData() : m_Cube(vtkSmartPointer::New()), m_Axes(vtkSmartPointer::New()), m_VtkAsm(vtkSmartPointer::New()), m_Affine(vtkSmartPointer::New()) {} ~ContainerBoxData() { } }; vtkContainerBox::vtkContainerBox(vtkContainerBox::Content *content) : d(new ContainerBoxData()), m_Content(content) { this->InstallPipe(); d->m_UpdateSignal = Object::connect(m_Content, &uLib::Object::Updated, this, &vtkContainerBox::Update); } vtkContainerBox::~vtkContainerBox() { delete d; } vtkPolyData *vtkContainerBox::GetPolyData() const { // TODO return NULL; } void vtkContainerBox::Update() { RecursiveMutex::ScopedLock lock(this->m_UpdateMutex); if (!m_Content) return; vtkProp3D* root = vtkProp3D::SafeDownCast(this->GetProp()); if (root) { // Apply local full matrix (TRS * LocalBox) so that nested assemblies work correctly Matrix4f fullLocal = m_Content->GetMatrix() * m_Content->GetLocalMatrix(); vtkNew m; Matrix4fToVtk(fullLocal, m); root->SetUserMatrix(m); root->Modified(); } // Delegate rest of update (appearance, render, etc) ConnectionBlock blocker(d->m_UpdateSignal); this->Puppet::Update(); } void vtkContainerBox::SyncFromVtk() { RecursiveMutex::ScopedLock lock(this->m_UpdateMutex); if (!m_Content) return; 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); // } Matrix4f vtkWorld = VtkToMatrix4f(rootMat); // 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(); } void vtkContainerBox::InstallPipe() { if (!m_Content) return; Content *c = m_Content; // CUBE vtkSmartPointer cube = vtkSmartPointer::New(); vtkSmartPointer mapper = vtkSmartPointer::New(); cube->SetBounds(0, 1, 0, 1, 0, 1); mapper->SetInputConnection(cube->GetOutputPort()); mapper->Update(); d->m_Cube->SetMapper(mapper); d->m_Cube->GetProperty()->SetRepresentationToWireframe(); d->m_Cube->GetProperty()->SetAmbient(0.7); // AXES // vtkSmartPointer axes = vtkSmartPointer::New(); axes->SetOrigin(0, 0, 0); mapper = vtkSmartPointer::New(); mapper->SetInputConnection(axes->GetOutputPort()); mapper->Update(); d->m_Axes->SetMapper(mapper); d->m_Axes->GetProperty()->SetLineWidth(3); d->m_Axes->GetProperty()->SetAmbient(0.4); d->m_Axes->GetProperty()->SetSpecular(0); // PIVOT // axes = vtkSmartPointer::New(); axes->SetOrigin(0, 0, 0); mapper = vtkSmartPointer::New(); mapper->SetInputConnection(axes->GetOutputPort()); mapper->Update(); d->m_VtkAsm->AddPart(d->m_Cube); d->m_VtkAsm->AddPart(d->m_Axes); this->SetProp(d->m_VtkAsm); vtkProp3D* root = d->m_VtkAsm; if (root) { d->m_Affine = Matrix4fToVtk(m_Content->GetMatrix()); root->SetUserMatrix(d->m_Affine); } this->Update(); } } // namespace Vtk } // namespace uLib