/*////////////////////////////////////////////////////////////////////////////// // 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 #include #include "Vtk/Math/vtkDense.h" namespace uLib { namespace Vtk { struct ContainerBoxData { vtkSmartPointer m_Cube; vtkSmartPointer m_Axes; vtkSmartPointer m_VtkAsm; vtkSmartPointer m_CubeSource; vtkSmartPointer m_AxesSource; uLib::Connection m_UpdateSignal; ContainerBoxData() : m_Cube(vtkSmartPointer::New()), m_Axes(vtkSmartPointer::New()), m_VtkAsm(vtkSmartPointer::New()), m_CubeSource(vtkSmartPointer::New()), m_AxesSource(vtkSmartPointer::New()) {} }; ContainerBox::ContainerBox(uLib::ContainerBox *model) : Prop3D(), d(new ContainerBoxData()) { this->m_model.reset(model); this->InstallPipe(); d->m_UpdateSignal = Object::connect( this->m_model.get(), &uLib::Object::Updated, this, &ContainerBox::Update); this->Update(); } ContainerBox::~ContainerBox() { uLib::Object::disconnect(this->m_model.get(), &uLib::Object::Updated, this, &ContainerBox::Update); delete d; } vtkPolyData *ContainerBox::GetPolyData() const { // TODO return NULL; } void ContainerBox::Update() { RecursiveMutex::ScopedLock lock(this->m_UpdateMutex); if (!this->m_model) return; // Update the sources with the model's dimensions. // This makes the "natural" bounds of the actors correct for VTK gizmos. Vector3f size = this->m_model->GetSize(); Vector3f origin = this->m_model->GetOrigin(); // HandlerWidget relies on vtkProp3D::GetBounds() to determine the size // and position of its transformation gizmos. Previously, we were applying // the Size of the container using the actor's UserMatrix. While this looks // correct visually, some VTK utilities (including certain internal paths // of GetBounds()) may prioritize the bounding box of the input geometry // (the PolyData) over the UserMatrix. This resulted in the gizmo defaulting // to a 1x1x1 size because the underlying vtkCubeSource was still 1x1x1. d->m_CubeSource->SetBounds(origin.x(), origin.x() + size.x(), origin.y(), origin.y() + size.y(), origin.z(), origin.z() + size.z()); d->m_CubeSource->Update(); d->m_AxesSource->SetOrigin(origin.x(), origin.y(), origin.z()); d->m_AxesSource->SetScaleFactor(std::max({size.x(), size.y(), size.z()})); d->m_AxesSource->Update(); // Ensure actors have identity UserMatrix since scaling is in the source. d->m_Cube->SetUserMatrix(nullptr); d->m_Axes->SetUserMatrix(nullptr); // Delegate the rest of the update (appearance, TR, render, etc) to Prop3D. // Prop3D::Update() applies the "outer" TRS matrix (Position/Rotation/Scaling) // to the assembly. this->Prop3D::Update(); } void ContainerBox::SyncFromVtk() { RecursiveMutex::ScopedLock lock(this->m_UpdateMutex); if (!this->m_model) return; // Sync the "outer" TRS from the assembly's matrix this->Prop3D::SyncFromVtk(); } void ContainerBox::InstallPipe() { if (!this->m_model) return; vtkSmartPointer mapper = vtkSmartPointer::New(); // CUBE // mapper->SetInputConnection(d->m_CubeSource->GetOutputPort()); d->m_Cube->SetMapper(mapper); d->m_Cube->GetProperty()->SetRepresentationToWireframe(); d->m_Cube->GetProperty()->SetAmbient(0.7); // AXES // mapper = vtkSmartPointer::New(); mapper->SetInputConnection(d->m_AxesSource->GetOutputPort()); d->m_Axes->SetMapper(mapper); d->m_Axes->GetProperty()->SetLineWidth(3); d->m_Axes->GetProperty()->SetAmbient(0.4); d->m_Axes->GetProperty()->SetSpecular(0); d->m_VtkAsm->AddPart(d->m_Cube); d->m_VtkAsm->AddPart(d->m_Axes); this->SetProp(d->m_VtkAsm); this->Update(); } } // namespace Vtk } // namespace uLib