Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4Mesh.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27//
28//
29// John Allison May 2021
30//
31// G4Mesh captures and validates a parameterisation, which we
32// call a "mesh". This is typically intended for meshes with
33// a large number of parameterisations, such as a medical phantom.
34//
35// G4Mesh is used by G4PhysicalVolumeModel if and only if
36// G4ModelingParameters::fSpecialMeshRendering is set and if the
37// name matches one in G4ModelingParameters::fSpecialMeshVolumes,
38// if any. Then, if a valid mesh is found it calls the overriding
39// implementation of G4VGraphicsScene::AddCompound(const G4Mesh&).
40//
41// To set the above parameters use the following commands in the
42// standard Geant4 Visualisation System:
43// /vis/viewer/set/specialMeshRendering
44// /vis/viewer/set/specialMeshRenderingOption
45// /vis/viewer/set/specialMeshVolumes
46// See guidance on the above commmands for more detail.
47//
48// Note that if no special mesh volumes are specified,
49// G4PhysicalVolumeModel will test all volumes, and therefore
50// it will capture *all* parameterisations. This is not usually
51// a problem, since there is usually only one, but to be
52// selective you have to /vis/viewer/set/specialMeshVolumes.
53//
54// The specified G4VPhysicalVolume is searched for a
55// parameterisation. If none is found it will have a type "invalid"
56// and it should simply be destroyed (as in G4PhysicalVolumeModel).
57// The overhead of an invalid attempt is small.
58
59#include "G4Mesh.hh"
60
61#include "G4VPhysicalVolume.hh"
62#include "G4LogicalVolume.hh"
63#include "G4PVParameterised.hh"
65#include "G4Box.hh"
66#include "G4Tubs.hh"
67#include "G4Sphere.hh"
68#include "G4Tet.hh"
69
70std::map<G4int,G4String> G4Mesh::fEnumMap = {
71 {invalid,"invalid"},
72 {rectangle,"rectangle"},
73 {nested3DRectangular,"nested3Drectangular"},
74 {cylinder,"cylinder"},
75 {sphere,"sphere"},
76 {tetrahedron,"tetrahedron"}
77};
78
79G4Mesh::G4Mesh (G4VPhysicalVolume* containerVolume,const G4Transform3D& transform)
80: fpContainerVolume(containerVolume)
81, fpParameterisedVolume(nullptr)
82, fMeshType(invalid)
83, fMeshDepth(0)
84, fTransform(transform)
85{
86 if (fpContainerVolume == nullptr) return;
87
88 G4VPhysicalVolume* pv0 = fpContainerVolume;
89 G4VPhysicalVolume* pv1 = nullptr;
90 G4VPhysicalVolume* pv2 = nullptr;
91 G4VPhysicalVolume* pv3 = nullptr;
93 G4LogicalVolume* lv1 = nullptr;
94 G4LogicalVolume* lv2 = nullptr;
95
96 // Check if this is a container for a parameterisation.
97 // A simple parameterisation may only be one level.
98 // Nested parameterisations may be 2- or 3-level.
99 G4bool isContainer = false;
100 if (lv0->GetNoDaughters()) {
101 fMeshDepth++;
102 pv1 = lv0->GetDaughter(0);
103 lv1 = pv1->GetLogicalVolume();
104 if (dynamic_cast<G4PVParameterised*>(pv1)) {
105 isContainer = true;
106 fpParameterisedVolume = pv1;
107 } else if (lv1->GetNoDaughters()) {
108 fMeshDepth++;
109 pv2 = lv1->GetDaughter(0);
110 lv2 = pv2->GetLogicalVolume();
111 if (dynamic_cast<G4PVParameterised*>(pv2) &&
112 dynamic_cast<G4VNestedParameterisation*>(pv2->GetParameterisation())) {
113 isContainer = true;
114 fpParameterisedVolume = pv2;
115 } else if (lv2->GetNoDaughters()) {
116 fMeshDepth++;
117 pv3 = lv2->GetDaughter(0);
118 if (dynamic_cast<G4PVParameterised*>(pv3) &&
119 dynamic_cast<G4VNestedParameterisation*>(pv3->GetParameterisation())) {
120 isContainer = true;
121 fpParameterisedVolume = pv3;
122 }
123 }
124 }
125 }
126
127 if (isContainer) {
128
129 // Get type
130 G4VSolid* pEndSol = fpParameterisedVolume->GetLogicalVolume()->GetSolid ();
131 if (dynamic_cast<G4Box*>(pEndSol)) {
132 fMeshType = rectangle;
133 auto pBox = static_cast<G4Box*>(pEndSol);
134 f3DRPs.fHalfX = pBox->GetXHalfLength();
135 f3DRPs.fHalfY = pBox->GetYHalfLength();
136 f3DRPs.fHalfZ = pBox->GetZHalfLength();
137 } else if (dynamic_cast<G4Tet*>(pEndSol)) {
138 fMeshType = tetrahedron;
139 } else if (dynamic_cast<G4Tubs*>(pEndSol)) {
140 fMeshType = cylinder;
141 } else if (dynamic_cast<G4Sphere*>(pEndSol)) {
142 fMeshType = sphere;
143 }
144
145 // Special case for rectangular nested paramaterisation - extra information
146 if (fMeshDepth == 3 && fMeshType == rectangle) {
147 auto nestedParam3 = dynamic_cast<G4VNestedParameterisation*>(pv3);
148 if (nestedParam3) {
149 fMeshType = nested3DRectangular;
150 pv1->GetReplicationData
151 (f3DRPs.fAxis1,f3DRPs.fNreplica1,f3DRPs.fWidth1,f3DRPs.fOffset1,f3DRPs.fConsuming1);
152 pv2->GetReplicationData
153 (f3DRPs.fAxis2,f3DRPs.fNreplica2,f3DRPs.fWidth2,f3DRPs.fOffset2,f3DRPs.fConsuming2);
154 pv3->GetReplicationData
155 (f3DRPs.fAxis3,f3DRPs.fNreplica3,f3DRPs.fWidth3,f3DRPs.fOffset3,f3DRPs.fConsuming3);
156 }
157 }
158 }
159}
160
162
163std::ostream& operator << (std::ostream& os, const G4Mesh& mesh) {
164 os << "G4Mesh: ";
165 os << "\nContainer: " << mesh.GetContainerVolume()->GetName();
166 const auto& map = mesh.GetEnumMap();
167 const auto& typeEntry = map.find(mesh.GetMeshType());
168 G4String type;
169 if (typeEntry != map.end()) {
170 type = typeEntry->second;
171 } else {
172 type = "unrecognised";
173 }
174 os << "\nType: " << type;
175 os << "\nDepth: " << mesh.GetMeshDepth();
176 os << "\nTranslation: " << mesh.GetTransform().getTranslation();
177 os << "\nRotation: " << mesh.GetTransform().getRotation();
178 if (mesh.GetMeshType() == G4Mesh::rectangle &&
179 mesh.GetMeshDepth() == 3) {
180 // Print ThreeDRectangleParameters
181 }
182 return os;
183}
const G4DNABoundingBox invalid
std::ostream & operator<<(std::ostream &os, const G4Mesh &mesh)
Definition G4Mesh.cc:163
bool G4bool
Definition G4Types.hh:86
Definition G4Box.hh:56
G4double GetXHalfLength() const
std::size_t GetNoDaughters() const
const std::map< G4int, G4String > & GetEnumMap() const
Definition G4Mesh.hh:72
virtual ~G4Mesh()
Definition G4Mesh.cc:161
MeshType GetMeshType() const
Definition G4Mesh.hh:75
G4VPhysicalVolume * GetContainerVolume() const
Definition G4Mesh.hh:73
const G4Transform3D & GetTransform() const
Definition G4Mesh.hh:77
@ rectangle
Definition G4Mesh.hh:53
G4Mesh(G4VPhysicalVolume *containerVolume, const G4Transform3D &)
Definition G4Mesh.cc:79
G4int GetMeshDepth() const
Definition G4Mesh.hh:76
Definition G4Tet.hh:56
G4LogicalVolume * GetLogicalVolume() const
const G4String & GetName() const
CLHEP::HepRotation getRotation() const
CLHEP::Hep3Vector getTranslation() const