Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/visualization/modeling/src/G4Mesh.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  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"
 64 #include "G4VNestedParameterisation.hh"
 65 #include "G4Box.hh"
 66 #include "G4Tubs.hh"
 67 #include "G4Sphere.hh"
 68 #include "G4Tet.hh"
 69 
 70 std::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 
 79 G4Mesh::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;
 92   G4LogicalVolume*   lv0 = pv0->GetLogicalVolume();
 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 
161 G4Mesh::~G4Mesh () {}
162 
163 std::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 }
184