/*////////////////////////////////////////////////////////////////////////////// // 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. //////////////////////////////////////////////////////////////////////////////*/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "Vtk/HEP/Detectors/vtkDetectorChamber.h" namespace uLib { namespace Vtk { vtkDetectorChamber::vtkDetectorChamber(DetectorChamber *content) : vtkContainerBox(content) { m_Widget = vtkBoxWidget::New(); m_Callback = vtkWidgetCallback::New(); m_PickerCallback = vtkSelectionCallback::New(); m_Callback->SetChamber(this); m_PickerCallback->SetChamber(this); m_Widget->AddObserver(vtkCommand::InteractionEvent, m_Callback); m_Widget->SetRotationEnabled(1); m_Widget->SetTranslationEnabled(1); m_Widget->SetScalingEnabled(0); } vtkDetectorChamber::~vtkDetectorChamber() { m_Widget->Delete(); m_Callback->Delete(); m_PickerCallback->Delete(); } DetectorChamber *vtkDetectorChamber::GetContent() { return static_cast(m_Content); } void vtkDetectorChamber::PrintSelf(std::ostream &o) const { vtkContainerBox::PrintSelf(o); } void vtkDetectorChamber::ConnectInteractor( vtkRenderWindowInteractor *interactor) { if (!interactor) return; m_Widget->SetInteractor(interactor); m_Widget->SetProp3D(m_Cube); m_Widget->PlaceWidget(); interactor->AddObserver(vtkCommand::LeftButtonPressEvent, m_PickerCallback); } void vtkDetectorChamber::Update() { if (!m_Content) return; Matrix4f mat = static_cast(m_Content)->GetWorldMatrix(); vtkSmartPointer vmat = vtkSmartPointer::New(); for (int i = 0; i < 4; ++i) for (int j = 0; j < 4; ++j) vmat->SetElement(i, j, mat(i, j)); m_Cube->SetUserMatrix(vmat); m_Axes->SetUserMatrix(vmat); m_Pivot->SetUserMatrix(vmat); } void vtkDetectorChamber::InstallPipe() { if (!m_Content) return; // Cube: unit box (0,0,0) -> (1,1,1) vtkSmartPointer cube = vtkSmartPointer::New(); cube->SetBounds(0, 1, 0, 1, 0, 1); vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetInputConnection(cube->GetOutputPort()); m_Cube->SetMapper(mapper); m_Cube->GetProperty()->SetRepresentationToWireframe(); m_Cube->GetProperty()->SetAmbient(0.7); // Axes: corner origin vtkSmartPointer axes = vtkSmartPointer::New(); axes->SetOrigin(0, 0, 0); axes->SetScaleFactor(0.2); mapper = vtkSmartPointer::New(); mapper->SetInputConnection(axes->GetOutputPort()); m_Axes->SetMapper(mapper); m_Axes->GetProperty()->SetLineWidth(3); m_Axes->GetProperty()->SetAmbient(0.4); // Pivot: center of unit box vtkSmartPointer pivot = vtkSmartPointer::New(); pivot->SetOrigin(0.5, 0.5, 0.5); pivot->SetScaleFactor(0.1); mapper = vtkSmartPointer::New(); mapper->SetInputConnection(pivot->GetOutputPort()); m_Pivot->SetMapper(mapper); m_Pivot->GetProperty()->SetLineWidth(3); m_Pivot->GetProperty()->SetAmbient(0.4); this->SetProp(m_Cube); this->SetProp(m_Axes); this->SetProp(m_Pivot); this->Update(); } void vtkDetectorChamber::vtkWidgetCallback::Execute(vtkObject *caller, unsigned long, void *) { vtkBoxWidget *widget = reinterpret_cast(caller); vtkSmartPointer t = vtkSmartPointer::New(); widget->GetTransform(t); vtkMatrix4x4 *vmat = t->GetMatrix(); Matrix4f mat; for (int i = 0; i < 4; ++i) for (int j = 0; j < 4; ++j) mat(i, j) = vmat->GetElement(i, j); chamber->GetContent()->SetMatrix(mat); // Reset internal matrix to identity to avoid double-transformation vtkProp3D *prop = widget->GetProp3D(); if (prop) { prop->SetPosition(0, 0, 0); prop->SetOrientation(0, 0, 0); prop->SetScale(1, 1, 1); } chamber->Update(); } void vtkDetectorChamber::vtkSelectionCallback::Execute(vtkObject *caller, unsigned long, void *) { vtkRenderWindowInteractor *interactor = reinterpret_cast(caller); vtkSmartPointer picker = vtkSmartPointer::New(); int *pos = interactor->GetEventPosition(); picker->Pick( pos[0], pos[1], 0, interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()); vtkProp *picked = picker->GetViewProp(); if (picked == chamber->m_Cube || picked == chamber->m_Axes || picked == chamber->m_Pivot) { if (!chamber->m_Widget->GetEnabled()) { // Register current position/rotation/scale from content // Matrix4f mat = chamber->GetContent()->GetWorldMatrix(); vtkSmartPointer vmat = vtkSmartPointer::New(); for (int i = 0; i < 4; ++i) for (int j = 0; j < 4; ++j) vmat->SetElement(i, j, mat(i, j)); vtkSmartPointer t = vtkSmartPointer::New(); t->SetMatrix(vmat); chamber->m_Widget->SetTransform(t); chamber->m_Widget->PlaceWidget(); chamber->m_Widget->On(); } } else { if (chamber->m_Widget->GetEnabled()) { chamber->m_Widget->Off(); } } } } // namespace Vtk } // namespace uLib