/*////////////////////////////////////////////////////////////////////////////// // 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 "Vtk/HEP/MuonTomography/vtkVoxRaytracerRepresentation.h" #include "Math/VoxRaytracer.h" // #include "Vtk/HEP/Detectors/vtkMuonEvent.h" #include "Vtk/HEP/Detectors/vtkMuonScatter.h" namespace uLib { namespace Vtk { //////////////////////////////////////////////////////////////////////////////// ////// VOX RAYTRACER REPRESENTATION /////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// VoxRaytracerRepresentation::VoxRaytracerRepresentation(Content &content) : m_Content(&content), m_Sphere1(vtkSphereSource::New()), m_Sphere2(vtkSphereSource::New()), m_Line1(vtkLineSource::New()), m_Line2(vtkLineSource::New()), m_Line3(vtkLineSource::New()), m_RayLine(vtkAppendPolyData::New()), m_RayLineActor(vtkActor::New()), m_RayRepresentation(vtkAppendPolyData::New()), m_RayRepresentationActor(vtkActor::New()), m_Transform(vtkTransform::New()), m_Asm(vtkAssembly::New()), m_Muon(nullptr), m_HasMuon(false), m_HasPoca(false) { default_radius = content.GetImage()->GetSpacing()(0) / 4; m_Sphere1->SetRadius(default_radius); m_Sphere2->SetRadius(default_radius); m_SelectedElement = m_RayLine; this->SetSelectable(false); InstallPipe(); if (m_Content && m_Content->GetImage()) { Object::connect(m_Content->GetImage(), &StructuredGrid::Updated, this, &VoxRaytracerRepresentation::imageUpdate); } } VoxRaytracerRepresentation::~VoxRaytracerRepresentation() { m_RayLine->Delete(); m_RayLineActor->Delete(); m_RayRepresentationActor->Delete(); m_Transform->Delete(); if (m_Muon) delete m_Muon; } uLib::VoxRaytracer *VoxRaytracerRepresentation::GetRaytracerAlgorithm() { return m_Content; } void VoxRaytracerRepresentation::Update() { this->imageUpdate(); } void VoxRaytracerRepresentation::imageUpdate() { if (m_HasMuon && m_Muon) { if (m_HasPoca) { this->SetMuon(m_Muon->GetModel(), m_Poca); } else { this->SetMuon(*m_Muon); } } } vtkPolyData *VoxRaytracerRepresentation::GetPolyData() const { std::cout << "get Raytracer polydata\n"; m_SelectedElement->Update(); return m_SelectedElement->GetOutput(); } void VoxRaytracerRepresentation::SetRepresentationElements( VoxRaytracerRepresentation::RepresentationElements el) { switch (el) { case Vtk::VoxRaytracerRepresentation::RayElements: m_SelectedElement = m_RayLine; break; case Vtk::VoxRaytracerRepresentation::VoxelsElements: m_SelectedElement = m_RayRepresentation; break; default: m_SelectedElement = m_RayLine; break; } } void VoxRaytracerRepresentation::SetMuon(uLib::MuonScatter &muon) { if (m_Muon) delete m_Muon; m_Muon = new MuonScatter(muon); m_HasMuon = true; m_HasPoca = false; HPoint3f pt1, pt2, src; src = muon.LineIn().origin; m_Content->GetEntryPoint(muon.LineIn(), pt1); m_Sphere1->SetCenter(pt1(0), pt1(1), pt1(2)); m_Line1->SetPoint1(src(0), src(1), src(2)); m_Line1->SetPoint2(pt1(0), pt1(1), pt1(2)); HLine3f line_out = muon.LineOut(); src = line_out.origin; float *direction = line_out.direction.data(); for (int i = 0; i < 3; ++i) direction[i] *= -1; m_Content->GetEntryPoint(line_out, pt2); m_Sphere2->SetCenter(pt2(0), pt2(1), pt2(2)); m_Line2->SetPoint1(src(0), src(1), src(2)); m_Line2->SetPoint2(pt2(0), pt2(1), pt2(2)); m_Line3->SetPoint1(pt1(0), pt1(1), pt1(2)); m_Line3->SetPoint2(pt2(0), pt2(1), pt2(2)); vtkSmartPointer points = vtkSmartPointer::New(); points->InsertNextPoint(pt1(0), pt1(1), pt1(2)); points->InsertNextPoint(pt2(0), pt2(1), pt2(2)); vtkSmartPointer lines = vtkSmartPointer::New(); vtkSmartPointer line = vtkSmartPointer::New(); line->GetPointIds()->SetId(0, 0); line->GetPointIds()->SetId(1, 1); lines->InsertNextCell(line); vtkSmartPointer linesPolyData = vtkSmartPointer::New(); linesPolyData->SetPoints(points); linesPolyData->SetLines(lines); m_RayLine->RemoveAllInputs(); #if VTK_MAJOR_VERSION <= 5 m_RayLine->AddInputConnection(linesPolyData->GetProducerPort()); #else m_RayLine->AddInputData(linesPolyData); #endif m_RayLine->AddInputConnection(m_Line1->GetOutputPort()); m_RayLine->AddInputConnection(m_Sphere1->GetOutputPort()); m_RayLine->AddInputConnection(m_Line2->GetOutputPort()); m_RayLine->AddInputConnection(m_Sphere2->GetOutputPort()); vtkSmartPointer vmat = vtkSmartPointer::New(); Matrix4f mat = m_Content->GetImage()->GetWorldMatrix(); for (int i = 0; i < 4; ++i) for (int j = 0; j < 4; ++j) vmat->SetElement(i, j, mat(i, j)); m_Transform->SetMatrix(vmat); this->SetRay(pt1, pt2); } void VoxRaytracerRepresentation::SetMuon(uLib::MuonScatter &muon, HPoint3f poca) { if (m_Muon) delete m_Muon; m_Muon = new MuonScatter(muon); m_Poca = poca; m_HasMuon = true; m_HasPoca = true; HPoint3f pt1, pt2, src; src = muon.LineIn().origin; m_Content->GetEntryPoint(muon.LineIn(), pt1); m_Sphere1->SetCenter(pt1(0), pt1(1), pt1(2)); m_Line1->SetPoint1(src(0), src(1), src(2)); m_Line1->SetPoint2(pt1(0), pt1(1), pt1(2)); HLine3f line_out = muon.LineOut(); src = line_out.origin; float *direction = line_out.direction.data(); for (int i = 0; i < 3; ++i) direction[i] *= -1; m_Content->GetEntryPoint(line_out, pt2); m_Sphere2->SetCenter(pt2(0), pt2(1), pt2(2)); m_Line2->SetPoint1(src(0), src(1), src(2)); m_Line2->SetPoint2(pt2(0), pt2(1), pt2(2)); m_Line3->SetPoint1(pt1(0), pt1(1), pt1(2)); m_Line3->SetPoint2(pt2(0), pt2(1), pt2(2)); vtkSmartPointer points = vtkSmartPointer::New(); points->InsertNextPoint(pt1(0), pt1(1), pt1(2)); points->InsertNextPoint(poca(0), poca(1), poca(2)); points->InsertNextPoint(pt2(0), pt2(1), pt2(2)); vtkSmartPointer lines = vtkSmartPointer::New(); for (unsigned int i = 0; i < 2; i++) { vtkSmartPointer line = vtkSmartPointer::New(); line->GetPointIds()->SetId(0, i); line->GetPointIds()->SetId(1, i + 1); lines->InsertNextCell(line); } vtkSmartPointer linesPolyData = vtkSmartPointer::New(); linesPolyData->SetPoints(points); linesPolyData->SetLines(lines); m_RayLine->RemoveAllInputs(); #if VTK_MAJOR_VERSION <= 5 m_RayLine->AddInputConnection(linesPolyData->GetProducerPort()); #else m_RayLine->AddInputData(linesPolyData); #endif m_RayLine->AddInputConnection(m_Line1->GetOutputPort()); m_RayLine->AddInputConnection(m_Sphere1->GetOutputPort()); m_RayLine->AddInputConnection(m_Line2->GetOutputPort()); m_RayLine->AddInputConnection(m_Sphere2->GetOutputPort()); vtkSmartPointer poca_sphere = vtkSmartPointer::New(); poca_sphere->SetRadius(default_radius); poca_sphere->SetCenter(poca(0), poca(1), poca(2)); m_RayLine->AddInputConnection(poca_sphere->GetOutputPort()); vtkSmartPointer vmat = vtkSmartPointer::New(); Matrix4f mat = m_Content->GetImage()->GetWorldMatrix(); for (int i = 0; i < 4; ++i) for (int j = 0; j < 4; ++j) vmat->SetElement(i, j, mat(i, j)); m_Transform->SetMatrix(vmat); if (m_Content->GetImage()->IsInsideBounds(poca)) this->SetRay(pt1, poca, pt2); else this->SetRay(pt1, pt2); } void VoxRaytracerRepresentation::SetMuon(MuonScatter &muon) { HPoint3f poca = muon.GetPocaPoint(); uLib::MuonScatter &mu = muon.GetModel(); this->SetMuon(mu, poca); } VoxRaytracer::RayData VoxRaytracerRepresentation::GetRay() { return m_Ray; } void VoxRaytracerRepresentation::SetRay(HPoint3f in, HPoint3f out) { m_Ray = m_Content->TraceBetweenPoints(in, out); this->SetRay(&m_Ray); } void VoxRaytracerRepresentation::SetRay(HPoint3f in, HPoint3f mid, HPoint3f out) { m_Ray = m_Content->TraceBetweenPoints(in, mid); m_Ray.AppendRay(m_Content->TraceBetweenPoints(mid, out)); this->SetRay(&m_Ray); } void VoxRaytracerRepresentation::SetRay(VoxRaytracer::RayData *ray) { vtkAppendPolyData *appender = m_RayRepresentation; appender->RemoveAllInputs(); for (size_t i = 0; i < ray->Count(); ++i) { int id = ray->Data().at(i).vox_id; Vector3i idv = m_Content->GetImage()->UnMap(id); vtkSmartPointer cube = vtkSmartPointer::New(); cube->SetBounds(idv(0), idv(0) + 1, idv(1), idv(1) + 1, idv(2), idv(2) + 1); cube->Update(); #if VTK_MAJOR_VERSION <= 5 appender->AddInput(cube->GetOutput()); #else appender->AddInputData(cube->GetOutput()); #endif } appender->Modified(); } void VoxRaytracerRepresentation::SetVoxelsColor(Vector4f rgba) { this->SetColor(m_RayRepresentationActor, rgba); } void VoxRaytracerRepresentation::SetRayColor(Vector4f rgba) { this->SetColor(m_RayLineActor, rgba); } void VoxRaytracerRepresentation::SetColor(vtkActor *actor, Vector4f rgba) { if (!actor) return; vtkProperty *pr = actor->GetProperty(); pr->SetDiffuseColor(rgba(0), rgba(1), rgba(2)); pr->SetOpacity(rgba(3)); pr->SetDiffuse(1); } void VoxRaytracerRepresentation::InstallPipe() { vtkSmartPointer append = vtkSmartPointer::New(); append->AddInputConnection(m_Sphere1->GetOutputPort()); append->AddInputConnection(m_Sphere2->GetOutputPort()); append->AddInputConnection(m_Line1->GetOutputPort()); append->AddInputConnection(m_Line2->GetOutputPort()); vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetInputConnection(append->GetOutputPort()); vtkSmartPointer actor = vtkActor::New(); actor->SetMapper(mapper); actor->GetProperty()->SetColor(0.6, 0.6, 1); m_Asm->AddPart(actor); mapper = vtkSmartPointer::New(); mapper->SetInputConnection(m_RayLine->GetOutputPort()); m_RayLineActor->SetMapper(mapper); m_RayLineActor->GetProperty()->SetColor(1, 0, 0); m_Asm->AddPart(m_RayLineActor); vtkSmartPointer polyfilter = vtkSmartPointer::New(); polyfilter->SetInputConnection(m_RayRepresentation->GetOutputPort()); polyfilter->SetTransform(m_Transform); mapper = vtkSmartPointer::New(); mapper->SetInputConnection(polyfilter->GetOutputPort()); vtkActor *vra = m_RayRepresentationActor; vra->SetMapper(mapper); vra->GetProperty()->SetOpacity(0.2); vra->GetProperty()->SetEdgeVisibility(true); vra->GetProperty()->SetColor(0.5, 0.5, 0.5); m_Asm->AddPart(vra); this->SetProp(m_Asm); } } // namespace Vtk } // namespace uLib