/*////////////////////////////////////////////////////////////////////////////// // 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 "vtkGeantSolid.h" #include #include #include #include #include #include #include #include #include #include #include #include namespace uLib { namespace Vtk { GeantSolid::GeantSolid(Content *content) : m_SolidActor(vtkActor::New()), m_Content(content) { this->InstallPipe(); } GeantSolid::~GeantSolid() { m_SolidActor->Delete(); } vtkPolyData *GeantSolid::GetPolyData() const { if (!m_SolidActor || !m_SolidActor->GetMapper()) return NULL; return vtkPolyData::SafeDownCast(m_SolidActor->GetMapper()->GetInput()); } void GeantSolid::Update() { this->UpdateGeometry(); this->UpdateTransform(); } void GeantSolid::UpdateGeometry() { if (!m_Content) return; G4VSolid *g4solid = m_Content->GetG4Solid(); if (!g4solid) return; // Get the polyhedron tessellation from Geant4 G4Polyhedron *polyhedron = g4solid->GetPolyhedron(); if (!polyhedron) return; vtkSmartPointer points = vtkSmartPointer::New(); vtkSmartPointer polys = vtkSmartPointer::New(); // Extract vertices int nVertices = polyhedron->GetNoVertices(); for (int i = 1; i <= nVertices; ++i) { G4Point3D vtx = polyhedron->GetVertex(i); points->InsertNextPoint(vtx.x(), vtx.y(), vtx.z()); } // Extract facets (polygons) int nFacets = polyhedron->GetNoFacets(); for (int f = 1; f <= nFacets; ++f) { G4int nEdges; G4int iVertex[4]; // G4Polyhedron facets have at most 4 vertices // GetNextFacet returns edges; for quads nEdges=4, for triangles nEdges=3 polyhedron->GetFacet(f, nEdges, iVertex); vtkIdType ids[4]; for (int e = 0; e < nEdges; ++e) { // G4Polyhedron vertices are 1-indexed; VTK expects 0-indexed ids[e] = static_cast(std::abs(iVertex[e]) - 1); } polys->InsertNextCell(nEdges, ids); } vtkPolyData *polyData = GetPolyData(); if (polyData) { polyData->SetPoints(points); polyData->SetPolys(polys); polyData->Modified(); } } void GeantSolid::UpdateTransform() { if (!m_Content || !m_SolidActor) return; // Apply the Geant4 transform (position/rotation) if placed if (m_Content->GetPhysical()) { auto *phys = m_Content->GetPhysical(); G4ThreeVector pos = phys->GetTranslation(); const G4RotationMatrix *rot = phys->GetRotation(); vtkSmartPointer transform = vtkSmartPointer::New(); transform->Identity(); transform->Translate(pos.x(), pos.y(), pos.z()); if (rot) { // G4RotationMatrix stores the inverse of the rotation for placement G4RotationMatrix invRot = rot->inverse(); double elements[16] = { invRot.xx(), invRot.xy(), invRot.xz(), 0, invRot.yx(), invRot.yy(), invRot.yz(), 0, invRot.zx(), invRot.zy(), invRot.zz(), 0, 0, 0, 0, 1 }; vtkSmartPointer mat = vtkSmartPointer::New(); mat->DeepCopy(elements); transform->Concatenate(mat); } m_SolidActor->SetUserTransform(transform); } } void GeantSolid::InstallPipe() { vtkSmartPointer polyData = vtkSmartPointer::New(); vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetInputData(polyData); m_SolidActor->SetMapper(mapper); // Default look: semi-transparent blue surface m_SolidActor->GetProperty()->SetColor(0.4, 0.6, 0.9); m_SolidActor->GetProperty()->SetOpacity(0.3); m_SolidActor->GetProperty()->SetAmbient(0.5); m_SolidActor->GetProperty()->SetDiffuse(0.6); m_SolidActor->GetProperty()->SetSpecular(0.2); m_SolidActor->GetProperty()->SetEdgeVisibility(1); m_SolidActor->GetProperty()->SetEdgeColor(0.2, 0.3, 0.5); this->SetProp(m_SolidActor); } } // namespace Vtk } // namespace uLib