add vtk geant solid and scene
This commit is contained in:
156
src/Vtk/HEP/Geant/vtkGeantSolid.cpp
Normal file
156
src/Vtk/HEP/Geant/vtkGeantSolid.cpp
Normal file
@@ -0,0 +1,156 @@
|
||||
/*//////////////////////////////////////////////////////////////////////////////
|
||||
// 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 <vtkActor.h>
|
||||
#include <vtkPolyData.h>
|
||||
#include <vtkPoints.h>
|
||||
#include <vtkCellArray.h>
|
||||
#include <vtkPolyDataMapper.h>
|
||||
#include <vtkProperty.h>
|
||||
#include <vtkSmartPointer.h>
|
||||
#include <vtkTransform.h>
|
||||
#include <vtkMatrix4x4.h>
|
||||
|
||||
#include <Geant4/G4VSolid.hh>
|
||||
#include <Geant4/G4Polyhedron.hh>
|
||||
#include <Geant4/G4VPhysicalVolume.hh>
|
||||
|
||||
namespace uLib {
|
||||
namespace Vtk {
|
||||
|
||||
vtkGeantSolid::vtkGeantSolid(Content *content)
|
||||
: m_SolidActor(vtkActor::New()), m_Content(content) {
|
||||
this->InstallPipe();
|
||||
this->Update();
|
||||
}
|
||||
|
||||
vtkGeantSolid::~vtkGeantSolid() {
|
||||
m_SolidActor->Delete();
|
||||
}
|
||||
|
||||
vtkPolyData *vtkGeantSolid::GetPolyData() const {
|
||||
if (!m_SolidActor || !m_SolidActor->GetMapper())
|
||||
return NULL;
|
||||
return vtkPolyData::SafeDownCast(m_SolidActor->GetMapper()->GetInput());
|
||||
}
|
||||
|
||||
void vtkGeantSolid::Update() {
|
||||
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<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
|
||||
vtkSmartPointer<vtkCellArray> polys = vtkSmartPointer<vtkCellArray>::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<vtkIdType>(std::abs(iVertex[e]) - 1);
|
||||
}
|
||||
polys->InsertNextCell(nEdges, ids);
|
||||
}
|
||||
|
||||
vtkPolyData *polyData = GetPolyData();
|
||||
if (polyData) {
|
||||
polyData->SetPoints(points);
|
||||
polyData->SetPolys(polys);
|
||||
polyData->Modified();
|
||||
}
|
||||
|
||||
// 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<vtkTransform> transform = vtkSmartPointer<vtkTransform>::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<vtkMatrix4x4> mat = vtkSmartPointer<vtkMatrix4x4>::New();
|
||||
mat->DeepCopy(elements);
|
||||
transform->Concatenate(mat);
|
||||
}
|
||||
|
||||
m_SolidActor->SetUserTransform(transform);
|
||||
}
|
||||
}
|
||||
|
||||
void vtkGeantSolid::InstallPipe() {
|
||||
vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
|
||||
vtkSmartPointer<vtkPolyDataMapper> mapper =
|
||||
vtkSmartPointer<vtkPolyDataMapper>::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
|
||||
Reference in New Issue
Block a user