Import Geant4 11.1.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2022-07-01 10:44:02 +02:00
parent b3bf75a2a1
commit c07cea1fe0
2172 changed files with 183300 additions and 123938 deletions
+2 -2
View File
@@ -1,3 +1,3 @@
# - G4modeling category build
geant4_global_library_target(COMPONENTS sources.cmake)
include(sources.cmake)
geant4_add_category(G4modeling MODULES G4modeling)
+1 -1
View File
@@ -8,7 +8,7 @@ ifndef G4INSTALL
G4INSTALL = ../../..
endif
GLOBLIBS = libG4tasking.lib libG4run.lib libG4event.lib
GLOBLIBS = libG4run.lib libG4event.lib
GLOBLIBS += libG4tracking.lib libG4processes.lib libG4digits_hits.lib
GLOBLIBS += libG4track.lib libG4particles.lib libG4geometry.lib
GLOBLIBS += libG4materials.lib libG4graphics_reps.lib
+93 -16
View File
@@ -1,23 +1,100 @@
-------------------------------------------------------------------
# Category modeling History
=========================================================
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
=========================================================
See `CONTRIBUTING.rst` for details of **required** info/format for each entry,
which **must** added in reverse chronological order (newest at the top). It must **not**
be used as a substitute for writing good git commit messages!
Category History file
---------------------
This file should be used by G4 developers and category coordinators
to briefly summarize all major modifications introduced in the code
and keep track of all category-tags.
It DOES NOT substitute the CVS log-message one should put at every
committal in the CVS repository !
----------------------------------------------------------
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
## 2022-06-09 Laurie Nevay (modeling-V11-00-10)
History file for visualization/modeling
---------------------------------------
- Allow arrow proportions to be greater than 1/100. Produces more
visible arrows for field visualisation and also obeys the input
parameters more closely.
## 2022-05-23 John Allison (modeling-V11-00-09)
- Co-works with visman-V11-00-18.
- Simplify `G4Mesh`.
- Now finds 1-deep rectangular meshes such as `G4PhantomParameterisation`.
- Improve commenting in `G4Mesh.hh`. Consult `G4Mesh.hh` for further
information.
## 2022-04-17 John Allison (modeling-V11-00-08)
- Co-works with `visman-V11-00-14`.
- Retire `G4BoundingSphereScene` and `G4PhysicalVolumeSearchScene`.
- `G4BoundingSphereScene` is superseded by `G4BoundingExtentScene`.
- `G4BoundingSphereScene` accumulated blinding spheres and often
overestimated the extent of the scene.
- `G4BoundingExtentScene` deals directly with extents, which makes
it neater and more tightly estimates. the overall extent of the
scene. It has existed and has been in normal use for some time. It
takes advantage of developments in `G4VisExtent` - see
modeling-V10-05-00 (19 February 2019).
- `G4PhysicalVolumeSearchScene` is superseded by
`G4PhysicalVolumesSearchScene` (note the extra 's').
- `G4PhysicalVolumeSearchScene` found only the first occurrence of
a physical volume.
- `G4PhysicalVolumesSearchScene` finds all occurrences and returns
a "findings vector". It has existed and has been in normal use
for some time.
- `G4PhysicalVolumesSearchScene`:
- Remove last ambiguous and misleading argument in the constructor.
- It was used only once in `G4VisCommandsSceneAdd.cc`
(`/vis/scene/add/volume`) and a better way has been found in
`visman-V11-00-14`.
## 2022-04-09 John Allison (modeling-V11-00-07)
- `G4Mesh`:
- Add `fpParameterisedVolume` and accessor.
- `G4PhysicalVolumeModel`:
- `G4PhysicalVolumeNodeID`: Add `Set` accessors.
- For `AddCompound(mesh)`:
- Provide an "artificial" node as an (optional) hook for anything that
might be generated.
## 2022-04-03 John Allison (modeling-V11-00-06)
- `G4PseudoScene`:
- Add `AddCompound(const G4Mesh&)`.
- If special mesh rendering is set, this catches mesh candidates
(certain types of parameterisations) and avoids descending into
the parameterisations.
- It is used in `G4PhysicalVolumeModel::CalculateExtent` (the
parameterised volumes anyway are enclosed in the "container" volume).
- `G4PhysicalVolumeModel.cc`:
- `SetSpecialMeshRendering(true);` to avoids traversing (certain
types of) parameterisations (see above).
- `G4BoundingExtentScene.cc`:
- Removed unnecessary blank line.
## 2022-03-30 John Allison (modeling-V11-00-05)
- `G4PhysicalVolumeModel.cc`: eliminate goto statements.
## 2022-02-02 John Allison (modeling-V11-00-04)
- G4Mesh: Programmed for parameterised tetrahedron mesh.
## 2022-01-28 Ben Morgan (modeling-V11-00-03)
- Replace `geant4_global_library_target` with direct file inclusion and
call to `geant4_add_category` to define library build from source modules.
## 2021-12-16 John Allison (modeling-V11-00-02)
- G4Mesh:
- Augment available data for 3D rectangular mesh.
## 2021-12-11 John Allison (modeling-V11-00-01)
- G4PhysicalVolumeModel:
- Add LocalExtent and GlobalExtent to G4PhysicalVolumeModel::GetAttDefs.
- G4PhysicalVolumeModel::TouchableProperties:
- Add fTouchableFullPVPath.
- G4PhysicalVolumesSearchScene::Findings:
- G4PhysicalVolumesSearchScene::ProcessVolume:
- G4TouchablePropertiesScene::ProcessVolume:
- Migrate to the above (fTouchableFullPVPath).
## 2021-12-10 Ben Morgan (modeling-V11-00-00)
- Change to new Markdown History format
---
# History entries prior to 11.0
05 November 2021 John Allison (modeling-V10-07-16)
- Fix bug in G4PhysicalVolumeModel::CalculateExtent.
@@ -1,74 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
//
// John Allison 7th June 1997
// An artificial scene to reuse G4VScene code to calculate a bounding sphere.
#ifndef G4BOUNDINGSPHERESCENE_HH
#define G4BOUNDINGSPHERESCENE_HH
#include "G4PseudoScene.hh"
#include "G4VisExtent.hh"
class G4VModel;
class G4BoundingSphereScene: public G4PseudoScene {
public:
G4BoundingSphereScene (G4VModel* pModel = 0);
virtual ~G4BoundingSphereScene ();
G4VisExtent GetBoundingSphereExtent ();
const G4Point3D& GetCentre() const {return fCentre;}
G4double GetRadius() const {return fRadius;}
void SetCentre(const G4Point3D& centre) {fCentre = centre;}
////////////////////////////////////////////////////////////////
// The following 2 functions can be used by any code which wishes to
// accrue a bounding sphere. Just instantiate a
// G4BoundingSphereScene and use AccrueBoundingSphere.
void ResetBoundingSphere ();
void AccrueBoundingSphere (const G4Point3D& centre,
G4double radius);
private:
void ProcessVolume (const G4VSolid& solid);
G4VModel* fpModel; // Instantiating code may optionally set this.
G4Point3D fCentre;
G4double fRadius;
};
#endif
+29 -12
View File
@@ -40,35 +40,52 @@
#define G4MESH_HH
#include "G4Transform3D.hh"
#include "geomdefs.hh"
class G4VPhysicalVolume;
class G4Mesh
{
public: // With description
enum MeshType
{
invalid,
rectangle,
cylinder,
sphere
public:
enum MeshType {
invalid
, rectangle
, nested3DRectangular
, cylinder
, sphere
, tetrahedron
};
struct ThreeDRectangleParameters {
EAxis fAxis1 = kUndefined, fAxis2 = kUndefined, fAxis3 = kUndefined;
G4int fNreplica1 = 0, fNreplica2 = 0, fNreplica3 = 0;
G4double fOffset1 = 0., fOffset2 = 0., fOffset3 = 0.;
G4double fWidth1 = 0., fWidth2 = 0., fWidth3 = 0.;
G4bool fConsuming1 = false, fConsuming2 = false, fConsuming3 = false;
G4double fHalfX = 0., fHalfY = 0., fHalfZ = 0.;
};
G4Mesh(G4VPhysicalVolume* containerVolume, const G4Transform3D&);
virtual ~G4Mesh();
const std::map<G4int,G4String>& GetEnumMap() const { return fEnumMap; }
G4VPhysicalVolume* GetContainerVolume() const { return fpContainerVolume; }
MeshType GetMeshType() const { return fMeshType; }
G4int GetMeshDepth() const { return fMeshDepth; }
const G4Transform3D& GetTransform() const { return fTransform; }
const std::map<G4int,G4String>& GetEnumMap() const {return fEnumMap;}
G4VPhysicalVolume* GetContainerVolume() const {return fpContainerVolume;}
G4VPhysicalVolume* GetParameterisedVolume() const {return fpParameterisedVolume;}
MeshType GetMeshType() const {return fMeshType;}
G4int GetMeshDepth() const {return fMeshDepth;}
const G4Transform3D& GetTransform() const {return fTransform;}
const ThreeDRectangleParameters& GetThreeDRectParameters() const {return f3DRPs;}
private:
static std::map<G4int,G4String> fEnumMap;
G4VPhysicalVolume* fpContainerVolume;
G4VPhysicalVolume* fpParameterisedVolume;
MeshType fMeshType;
G4int fMeshDepth;
G4Transform3D fTransform;
ThreeDRectangleParameters f3DRPs;
};
std::ostream& operator << (std::ostream& os, const G4Mesh& mesh);
@@ -102,12 +102,16 @@ public: // With description
fTransform(transform),
fDrawn(drawn) {}
G4VPhysicalVolume* GetPhysicalVolume() const {return fpPV;}
G4int GetCopyNo() const {return fCopyNo;}
G4int GetNonCulledDepth() const {return fNonCulledDepth;}
const G4Transform3D& GetTransform() const {return fTransform;}
G4bool GetDrawn() const {return fDrawn;}
void SetDrawn(G4bool drawn) {fDrawn = drawn;}
G4bool operator< (const G4PhysicalVolumeNodeID& right) const;
G4int GetCopyNo() const {return fCopyNo;}
G4int GetNonCulledDepth() const {return fNonCulledDepth;}
const G4Transform3D& GetTransform() const {return fTransform;}
G4bool GetDrawn() const {return fDrawn;}
void SetPhysicalVolume(G4VPhysicalVolume* v) {fpPV = v;}
void SetCopyNo (G4int n) {fCopyNo = n;}
void SetNonCulledDepth(G4int d) {fNonCulledDepth = d;}
void SetTransform (const G4Transform3D& t) {fTransform = t;}
void SetDrawn (G4bool b) {fDrawn = b;}
G4bool operator< (const G4PhysicalVolumeNodeID& right) const;
G4bool operator!= (const G4PhysicalVolumeNodeID& right) const;
G4bool operator== (const G4PhysicalVolumeNodeID& right) const {
return !operator!= (right);
@@ -143,6 +147,7 @@ public: // With description
G4int fCopyNo;
G4Transform3D fTouchableGlobalTransform;
std::vector<G4PhysicalVolumeNodeID> fTouchableBaseFullPVPath;
std::vector<G4PhysicalVolumeNodeID> fTouchableFullPVPath;
};
G4PhysicalVolumeModel
@@ -1,80 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
//
// John Allison 10th August 1998.
// An artificial scene to find physical volumes.
#ifndef G4PHYSICALVOLUMESEARCHSCENE_HH
#define G4PHYSICALVOLUMESEARCHSCENE_HH
#include "G4PseudoScene.hh"
#include "G4VisExtent.hh"
#include "G4VPhysicalVolume.hh"
#include "G4LogicalVolume.hh"
#include "G4PhysicalVolumeModel.hh"
class G4PhysicalVolumeSearchScene: public G4PseudoScene {
public:
G4PhysicalVolumeSearchScene
(G4PhysicalVolumeModel*,
const G4String& requiredPhysicalVolumeName,
G4int requiredCopyNo,
G4int verbosity = 99);
virtual ~G4PhysicalVolumeSearchScene ();
const std::vector<G4PhysicalVolumeModel::G4PhysicalVolumeNodeID>&
GetFoundFullPVPath() const
{return fFoundFullPVPath;}
G4int GetFoundDepth() const {return fFoundDepth;}
G4VPhysicalVolume* GetFoundVolume() const {return fpFoundPV;}
const G4Transform3D& GetFoundTransformation () const
{return fFoundObjectTransformation;}
private:
void ProcessVolume(const G4VSolid&);
const G4PhysicalVolumeModel* fpPVModel;
G4String fRequiredPhysicalVolumeName;
G4int fRequiredCopyNo;
std::vector<G4PhysicalVolumeModel::G4PhysicalVolumeNodeID>
fFoundFullPVPath; // Found full path.
G4int fFoundDepth; // Found depth.
G4VPhysicalVolume* fpFoundPV; // Found physical volume.
G4Transform3D fFoundObjectTransformation; // Found transformation.
G4int fVerbosity;
G4bool fMultipleOccurrence;
};
#endif
@@ -26,13 +26,14 @@
//
//
//
// John Allison 5th September 2018, based on G4PhysicalVolumeSearchScene
// An artificial scene to find physical volumes. Instead of returning the
// first occurrence (G4PhysicalVolumeSearchScene) this class (note the extra
// 's' in the name of this class) returns a vector of all occurrences.
// It can match a physical volume name with the required match. The latter can
// be of the form "/regexp/", where regexp is a regular expression (see C++
// regex), or a plain string, in which case there must be an exact match.
// John Allison 5th September 2018
// Originally G4PhysicalVolumeSearchScene, 10th August 1998, which only
// found the first occurrence of a volume.
// This class (note the extra 's' in the name) produces a vector of all
// occurrences. It can match a physical volume name with the required
// match. The latter can be of the form "/regexp/", where regexp is a
// regular expression (see C++ regex), or a plain string, in which case
// there must be an exact match.
#ifndef G4PHYSICALVOLUMESSEARCHSCENE_HH
#define G4PHYSICALVOLUMESSEARCHSCENE_HH
@@ -49,9 +50,7 @@ public:
G4PhysicalVolumesSearchScene
(G4PhysicalVolumeModel* pSearchVolumeModel, // usually a world
const G4String& requiredPhysicalVolumeName,
G4int requiredCopyNo = -1, // -1 means any copy no
// Don't continue beyond requiredContinuation once found
G4int requiredContinuation = G4PhysicalVolumeModel::UNLIMITED);
G4int requiredCopyNo = -1); // -1 means any copy no
virtual ~G4PhysicalVolumesSearchScene () {}
@@ -65,12 +64,16 @@ public:
std::vector<G4PhysicalVolumeModel::G4PhysicalVolumeNodeID>
foundBasePVPath =
std::vector<G4PhysicalVolumeModel::G4PhysicalVolumeNodeID>(),
std::vector<G4PhysicalVolumeModel::G4PhysicalVolumeNodeID>
foundFullPVPath =
std::vector<G4PhysicalVolumeModel::G4PhysicalVolumeNodeID>(),
G4Transform3D foundObjectTransformation = G4Transform3D())
: fpSearchPV(pSearchPV)
, fpFoundPV(pFoundPV)
, fFoundPVCopyNo(foundPVCopyNo)
, fFoundDepth(foundDepth)
, fFoundBasePVPath(foundBasePVPath)
, fFoundFullPVPath(foundFullPVPath)
, fFoundObjectTransformation(foundObjectTransformation) {}
Findings(const G4PhysicalVolumeModel::TouchableProperties& tp)
: fpSearchPV(nullptr)
@@ -78,6 +81,7 @@ public:
, fFoundPVCopyNo(tp.fCopyNo)
, fFoundDepth(0)
, fFoundBasePVPath(tp.fTouchableBaseFullPVPath)
, fFoundFullPVPath(tp.fTouchableFullPVPath)
, fFoundObjectTransformation(tp.fTouchableGlobalTransform) {}
G4VPhysicalVolume* fpSearchPV; // Searched physical volume.
G4VPhysicalVolume* fpFoundPV; // Found physical volume.
@@ -85,6 +89,8 @@ public:
G4int fFoundDepth; // Found depth.
std::vector<G4PhysicalVolumeModel::G4PhysicalVolumeNodeID>
fFoundBasePVPath; // Base path (e.g., empty for world volume)
std::vector<G4PhysicalVolumeModel::G4PhysicalVolumeNodeID>
fFoundFullPVPath; // Full path of found volume
G4Transform3D fFoundObjectTransformation; // Found transformation.
};
@@ -110,7 +116,6 @@ private:
const G4PhysicalVolumeModel* fpSearchVolumesModel;
Matcher fMatcher;
G4int fRequiredCopyNo;
G4int fRequiredContinuation;
std::vector<Findings> fFindings;
};
@@ -80,7 +80,7 @@ public:
void AddCompound (const G4VDigi&) {}
void AddCompound (const G4THitsMap<G4double>&) {}
void AddCompound (const G4THitsMap<G4StatDouble>&) {}
void AddCompound (const G4Mesh&) {}
void AddCompound (const G4Mesh&); // Catches mesh if special mesh rendering set
// Primitives
void BeginPrimitives (const G4Transform3D&) {}
void EndPrimitives () {}
@@ -9,7 +9,6 @@ geant4_add_module(G4modeling
G4AttributeFilterT.hh
G4AxesModel.hh
G4BoundingExtentScene.hh
G4BoundingSphereScene.hh
G4CallbackModel.hh
G4DigiFilterFactories.hh
G4DigiModel.hh
@@ -32,7 +31,6 @@ geant4_add_module(G4modeling
G4PSHitsModel.hh
G4PhysicalVolumeMassScene.hh
G4PhysicalVolumeModel.hh
G4PhysicalVolumeSearchScene.hh
G4PhysicalVolumesSearchScene.hh
G4PseudoScene.hh
G4TextModel.hh
@@ -66,7 +64,6 @@ geant4_add_module(G4modeling
G4AttFilterUtils.cc
G4AxesModel.cc
G4BoundingExtentScene.cc
G4BoundingSphereScene.cc
G4DigiFilterFactories.cc
G4DigiModel.cc
G4ElectricFieldModel.cc
@@ -82,7 +79,6 @@ geant4_add_module(G4modeling
G4PSHitsModel.cc
G4PhysicalVolumeMassScene.cc
G4PhysicalVolumeModel.cc
G4PhysicalVolumeSearchScene.cc
G4PhysicalVolumesSearchScene.cc
G4PseudoScene.cc
G4TextModel.cc
@@ -128,6 +124,5 @@ geant4_module_link_libraries(G4modeling
G4materials
G4volumes
G4run
G4tasking
G4detutils
G4detector)
@@ -42,6 +42,8 @@
#include "G4Transform3D.hh"
#include "G4GeometryTolerance.hh"
#include <cmath>
G4ArrowModel::~G4ArrowModel ()
{
delete fpHeadPolyhedron;
@@ -77,26 +79,33 @@ G4ArrowModel::G4ArrowModel
// Make a cylinder slightly shorter than the arrow length so that it
// doesn't stick out of the head.
const G4double tolerance = G4GeometryTolerance::GetInstance()->GetRadialTolerance();
G4double shaftLength = std::sqrt
(std::pow(x2-x1,2)+std::pow(y2-y1,2)+std::pow(z2-z1,2));
if (shaftLength < tolerance) shaftLength = tolerance;
G4double shaftRadius = width/2.;
if (shaftRadius > shaftLength/100.) shaftRadius = shaftLength/100.;
if (shaftRadius < tolerance) shaftRadius = tolerance;
const G4double halfShaftLength = shaftLength/2.;
const G4double halfReduction = 4.*shaftRadius;
G4double halfLength = halfShaftLength - halfReduction;
if (halfLength < tolerance) halfLength = tolerance;
const G4Tubs shaft("shaft",0.,shaftRadius,halfLength,0.,twopi);
G4double totalLength = std::hypot(x2-x1, y2-y1, z2-z1);
if (totalLength < tolerance)
{totalLength = tolerance;}
G4double shaftRadius = width/6.;
if (shaftRadius < tolerance)
{shaftRadius = tolerance;}
// case 1 - arrow length >> width -> arrow head is width and 1.5x width tall
// case 2 - arrow length < width -> arrow head is made to be 0.5x length
G4double arrowLength = std::min(1.5*width, 0.5*totalLength);
G4double shaftLength = totalLength - arrowLength;
if (shaftLength < 2*tolerance)
{shaftLength = 2*tolerance;}
const G4Tubs shaft("shaft",0.,shaftRadius,0.5*shaftLength,0.,twopi);
fpShaftPolyhedron = shaft.CreatePolyhedron();
// Move it a little so that the tail is at z = -halfShaftLength.
// translate the polyhedron down w.r.t. the centre of the whole arrow
if (fpShaftPolyhedron)
fpShaftPolyhedron->Transform(G4Translate3D(0,0,-halfReduction));
{fpShaftPolyhedron->Transform(G4Translate3D(0,0,-0.5*arrowLength));}
// Locate the head at +halfShaftLength.
const G4double zHi = halfShaftLength;
const G4double zLow = halfShaftLength - 12.*shaftRadius;
const G4double rExt = 8. * shaftRadius;
const G4double zHi = 0.5*totalLength;
const G4double zLow = zHi - arrowLength;
const G4double rExt = 0.5*width;
const G4double xExt = std::sqrt(3.)*rExt/2.;
const G4Tet head("head",
G4ThreeVector(0.,0.,zHi),
@@ -40,7 +40,6 @@ G4BoundingExtentScene::G4BoundingExtentScene (G4VModel* pModel)
G4BoundingExtentScene::~G4BoundingExtentScene () {}
void G4BoundingExtentScene::ProcessVolume(const G4VSolid& solid)
{
G4VisExtent newExtent = solid.GetExtent ();
@@ -1,110 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
//
// John Allison 7th June 1997
// An artificial scene to reuse G4VScene code to calculate a bounding sphere.
#include "G4BoundingSphereScene.hh"
#include "G4VSolid.hh"
#include "G4PhysicalVolumeModel.hh"
#include "G4Vector3D.hh"
G4BoundingSphereScene::G4BoundingSphereScene (G4VModel* pModel)
:fpModel(pModel)
,fRadius(-1.)
{}
G4BoundingSphereScene::~G4BoundingSphereScene () {}
G4VisExtent G4BoundingSphereScene::GetBoundingSphereExtent () {
return G4VisExtent (fCentre, fRadius);
}
void G4BoundingSphereScene::ProcessVolume(const G4VSolid& solid)
{
const G4VisExtent& newExtent = solid.GetExtent ();
G4Point3D newCentre = newExtent.GetExtentCentre ();
if (fpCurrentObjectTransformation) {
newCentre.transform (*fpCurrentObjectTransformation);
}
const G4double newRadius = newExtent.GetExtentRadius ();
AccrueBoundingSphere (newCentre, newRadius);
// Curtail descent - can assume daughters are contained within mother...
G4PhysicalVolumeModel* pPVM = dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
if (pPVM) pPVM->CurtailDescent();
}
void G4BoundingSphereScene::ResetBoundingSphere () {
fCentre = G4Point3D ();
fRadius = -1.;
fpCurrentObjectTransformation = 0;
}
void G4BoundingSphereScene::AccrueBoundingSphere
(const G4Point3D& newCentre,
G4double newRadius) {
if (fRadius < 0 ) { // First time.
fCentre = newCentre;
fRadius = newRadius;
}
else {
G4Vector3D join = newCentre - fCentre;
if (join == G4Vector3D (0., 0., 0.)) { // Centres coincide.
if (fRadius < newRadius) fRadius = newRadius;
}
else if (join.mag () + newRadius <= fRadius) { // Inside accrued sphere.
// Do nothing.
}
else {
G4Vector3D unitJoin = join.unit ();
G4Point3D oldExtremity1 = fCentre - fRadius * unitJoin;
G4Point3D newExtremity1 = newCentre - newRadius * unitJoin;
G4Point3D oldExtremity2 = fCentre + fRadius * unitJoin;
G4Point3D newExtremity2 = newCentre + newRadius * unitJoin;
G4Point3D extremity1;
if (oldExtremity1 * unitJoin < newExtremity1 * unitJoin) {
extremity1 = oldExtremity1;
}
else {
extremity1 = newExtremity1;
}
G4Point3D extremity2;
if (oldExtremity2 * unitJoin > newExtremity2 * unitJoin) {
extremity2 = oldExtremity2;
}
else {
extremity2 = newExtremity2;
}
fCentre = 0.5 * (extremity2 + extremity1);
fRadius = 0.5 * (extremity2 - extremity1).mag ();
}
}
}
+104 -49
View File
@@ -28,11 +28,33 @@
//
// John Allison May 2021
//
// G4Mesh encapsulates and validates a nested parameterisation, which we
// call a "mesh". If a valid mesh cannot be created out of this
// G4VPhysicalVolume* (which will probably be most common), it will
// have a type "invalid". Then, usually, it may simply be destroyed.
// The overhead of an invalid attempt is expected to be small.
// G4Mesh captures and validates a parameterisation, which we
// call a "mesh". This is typically intended for meshes with
// a large number of parameterisations, such as a medical phantom.
//
// G4Mesh is used by G4PhysicalVolumeModel if and only if
// G4ModelingParameters::fSpecialMeshRendering is set and if the
// name matches one in G4ModelingParameters::fSpecialMeshVolumes,
// if any. Then, if a valid mesh is found it calls the overriding
// implementation of G4VGraphicsScene::AddCompound(const G4Mesh&).
//
// To set the above parameters use the following commands in the
// standard Geant4 Visualisation System:
// /vis/viewer/set/specialMeshRendering
// /vis/viewer/set/specialMeshRenderingOption
// /vis/viewer/set/specialMeshVolumes
// See guidance on the above commmands for more detail.
//
// Note that if no special mesh volumes are specified,
// G4PhysicalVolumeModel will test all volumes, and therefore
// it will capture *all* parameterisations. This is not usually
// a problem, since there is usually only one, but to be
// selective you have to /vis/viewer/set/specialMeshVolumes.
//
// The specified G4VPhysicalVolume is searched for a
// parameterisation. If none is found it will have a type "invalid"
// and it should simply be destroyed (as in G4PhysicalVolumeModel).
// The overhead of an invalid attempt is small.
#include "G4Mesh.hh"
@@ -43,71 +65,92 @@
#include "G4Box.hh"
#include "G4Tubs.hh"
#include "G4Sphere.hh"
#include "G4Tet.hh"
std::map<G4int,G4String> G4Mesh::fEnumMap;
std::map<G4int,G4String> G4Mesh::fEnumMap = {
{invalid,"invalid"},
{rectangle,"rectangle"},
{nested3DRectangular,"nested3Drectangular"},
{cylinder,"cylinder"},
{sphere,"sphere"},
{tetrahedron,"tetrahedron"}
};
G4Mesh::G4Mesh (G4VPhysicalVolume* containerVolume,const G4Transform3D& transform)
: fpContainerVolume(containerVolume)
, fpParameterisedVolume(nullptr)
, fMeshType(invalid)
, fMeshDepth(0)
, fTransform(transform)
{
if (fpContainerVolume == nullptr) return;
G4VPhysicalVolume* pv0 = fpContainerVolume;
G4VPhysicalVolume* pv1 = nullptr;
G4VPhysicalVolume* pv2 = nullptr;
G4VPhysicalVolume* pv3 = nullptr;
G4LogicalVolume* lv0 = pv0->GetLogicalVolume();
G4LogicalVolume* lv1 = nullptr;
G4LogicalVolume* lv2 = nullptr;
static G4bool first = true;
if (first) {
first = false;
fEnumMap[invalid] = "invalid";
fEnumMap[rectangle] = "rectangle";
fEnumMap[cylinder] = "cylinder";
fEnumMap[sphere] = "sphere";
}
const G4LogicalVolume* pLV = fpContainerVolume->GetLogicalVolume();
// check if this is a container for a nested parameterisation
// Check if this is a container for a parameterisation
G4bool isContainer = false;
if (pLV->GetNoDaughters()) {
if (lv0->GetNoDaughters()) {
fMeshDepth++;
const auto d0 = pLV->GetDaughter(0);
const auto d0LV = d0->GetLogicalVolume();
if (d0LV->GetNoDaughters()) {
pv1 = lv0->GetDaughter(0);
lv1 = pv1->GetLogicalVolume();
if (dynamic_cast<G4PVParameterised*>(pv1)) {
isContainer = true;
fpParameterisedVolume = pv1;
} else if (lv1->GetNoDaughters()) {
fMeshDepth++;
const auto d00 = d0LV->GetDaughter(0);
const auto pvParam00 = dynamic_cast<G4PVParameterised*>(d00);
if (pvParam00) {
const auto param00 = pvParam00->GetParameterisation();
const auto nestedParam00 = dynamic_cast<G4VNestedParameterisation*>(param00);
if (nestedParam00) { // 2-deep mesh
isContainer = true;
}
} else {
const auto d00LV = d00->GetLogicalVolume();
if (d00LV->GetNoDaughters()) {
fMeshDepth++;
const auto d000 = d00LV->GetDaughter(0);
const auto pvParam000 = dynamic_cast<G4PVParameterised*>(d000);
if (pvParam000) {
const auto param000 = pvParam000->GetParameterisation();
const auto nestedParam000 = dynamic_cast<G4VNestedParameterisation*>(param000);
if (nestedParam000) { // 3-deep mesh
isContainer = true;
}
}
}
pv2 = lv1->GetDaughter(0);
lv2 = pv2->GetLogicalVolume();
if (dynamic_cast<G4PVParameterised*>(pv2)) {
isContainer = true;
fpParameterisedVolume = pv2;
} else if (lv2->GetNoDaughters()) {
fMeshDepth++;
pv3 = lv2->GetDaughter(0);
if (dynamic_cast<G4PVParameterised*>(pv3)) {
isContainer = true;
fpParameterisedVolume = pv3;
}
}
}
}
if (isContainer) {
// Get type
G4VSolid* pSol = pLV -> GetSolid ();
if (dynamic_cast<G4Box*>(pSol)) {
G4VSolid* pEndSol = fpParameterisedVolume->GetLogicalVolume()->GetSolid ();
if (dynamic_cast<G4Box*>(pEndSol)) {
fMeshType = rectangle;
} else if (dynamic_cast<G4Tubs*>(pSol)) {
auto pBox = static_cast<G4Box*>(pEndSol);
f3DRPs.fHalfX = pBox->GetXHalfLength();
f3DRPs.fHalfY = pBox->GetYHalfLength();
f3DRPs.fHalfZ = pBox->GetZHalfLength();
} else if (dynamic_cast<G4Tet*>(pEndSol)) {
fMeshType = tetrahedron;
} else if (dynamic_cast<G4Tubs*>(pEndSol)) {
fMeshType = cylinder;
} else if (dynamic_cast<G4Sphere*>(pSol)) {
} else if (dynamic_cast<G4Sphere*>(pEndSol)) {
fMeshType = sphere;
}
// Special case for rectangular nested paramaterisation - extra information
if (fMeshDepth == 3 && fMeshType == rectangle) {
auto nestedParam3 = dynamic_cast<G4VNestedParameterisation*>(pv3);
if (nestedParam3) {
fMeshType = nested3DRectangular;
pv1->GetReplicationData
(f3DRPs.fAxis1,f3DRPs.fNreplica1,f3DRPs.fWidth1,f3DRPs.fOffset1,f3DRPs.fConsuming1);
pv2->GetReplicationData
(f3DRPs.fAxis2,f3DRPs.fNreplica2,f3DRPs.fWidth2,f3DRPs.fOffset2,f3DRPs.fConsuming2);
pv3->GetReplicationData
(f3DRPs.fAxis3,f3DRPs.fNreplica3,f3DRPs.fWidth3,f3DRPs.fOffset3,f3DRPs.fConsuming3);
}
}
}
}
@@ -116,9 +159,21 @@ G4Mesh::~G4Mesh () {}
std::ostream& operator << (std::ostream& os, const G4Mesh& mesh) {
os << "G4Mesh: ";
os << "\nContainer: " << mesh.GetContainerVolume()->GetName();
os << "\nType: " << mesh.GetEnumMap().find(mesh.GetMeshType())->second;
const auto& map = mesh.GetEnumMap();
const auto& typeEntry = map.find(mesh.GetMeshType());
G4String type;
if (typeEntry != map.end()) {
type = typeEntry->second;
} else {
type = "unrecognised";
}
os << "\nType: " << type;
os << "\nDepth: " << mesh.GetMeshDepth();
os << "\nTranslation: " << mesh.GetTransform().getTranslation();
os << "\nRotation: " << mesh.GetTransform().getRotation();
if (mesh.GetMeshType() == G4Mesh::rectangle &&
mesh.GetMeshDepth() == 3) {
// Print ThreeDRectangleParameters
}
return os;
}
@@ -42,7 +42,6 @@
#include "G4Material.hh"
#include "G4VisAttributes.hh"
#include "G4BoundingExtentScene.hh"
#include "G4PhysicalVolumeSearchScene.hh"
#include "G4TransportationManager.hh"
#include "G4Polyhedron.hh"
#include "HepPolyhedronProcessor.h"
@@ -162,6 +161,7 @@ void G4PhysicalVolumeModel::CalculateExtent ()
0., // Density (not relevant if density culling false).
true, // Cull daughters of opaque mothers.
24); // No of sides (not relevant for this operation).
mParams.SetSpecialMeshRendering(true); // Avoids traversing parameterisations
fpMP = &mParams;
DescribeYourselfTo (beScene);
fExtent = beScene.GetBoundingExtent();
@@ -555,42 +555,47 @@ void G4PhysicalVolumeModel::DescribeAndDescend
// Check for special mesh rendering
if (fpMP->IsSpecialMeshRendering()) {
G4bool potentialG4Mesh = false;
if (fpMP->GetSpecialMeshVolumes().empty()) {
// No volumes specified - all are potentially possible
goto create_mesh;
potentialG4Mesh = true;
} else {
// Name and (optionally) copy number of container volume is specified
for (const auto& pvNameCopyNo: fpMP->GetSpecialMeshVolumes()) {
if (pVPV->GetName() == pvNameCopyNo.GetName()) {
// We have a name match
if (pvNameCopyNo.GetCopyNo() < 0) {
// Any copy number is OK
goto create_mesh;
} else {
if (pVPV->GetCopyNo() == pvNameCopyNo.GetCopyNo()) {
// We have a name and copy number match
goto create_mesh;
}
}
}
if (pVPV->GetName() == pvNameCopyNo.GetName()) {
// We have a name match
if (pvNameCopyNo.GetCopyNo() < 0) {
// Any copy number is OK
potentialG4Mesh = true;
} else {
if (pVPV->GetCopyNo() == pvNameCopyNo.GetCopyNo()) {
// We have a name and copy number match
potentialG4Mesh = true;
}
}
}
}
// We have fallen out of this loop without finding a match
goto continue_processing;
}
create_mesh:
// Create - or at least attempt to create - a mesh. If it cannot be created
// out of this pVPV the type will be "invalid".
G4Mesh mesh(pVPV,theNewAT);
if (mesh.GetMeshType() != G4Mesh::invalid) {
fFullPVPath.push_back(nodeID);
fDrawnPVPath.push_back(nodeID);
sceneHandler.AddCompound(mesh);
fFullPVPath.pop_back();
fDrawnPVPath.pop_back();
delete tempVisAtts; // Needs cleaning up (Coverity warning!!)
return;
} // else continue processing
if (potentialG4Mesh) {
// Create - or at least attempt to create - a mesh. If it cannot be created
// out of this pVPV the type will be "invalid".
G4Mesh mesh(pVPV,theNewAT);
if (mesh.GetMeshType() != G4Mesh::invalid) {
// Create "artificial" nodeID to represent the replaced volumes
G4int artCopyNo = 0;
auto artPV = mesh.GetParameterisedVolume();
auto artDepth = fCurrentDepth + 1;
auto artNodeID = G4PhysicalVolumeNodeID(artPV,artCopyNo,artDepth);
fFullPVPath.push_back(artNodeID);
fDrawnPVPath.push_back(artNodeID);
sceneHandler.AddCompound(mesh);
fFullPVPath.pop_back();
fDrawnPVPath.pop_back();
delete tempVisAtts; // Needs cleaning up (Coverity warning!!)
return; // Mesh found and processed - nothing more to do.
} // else continue processing
}
}
continue_processing:
// Make decision to draw...
G4bool thisToBeDrawn = true;
@@ -839,7 +844,6 @@ G4bool G4PhysicalVolumeModel::Validate (G4bool warn)
// the geometry tree but under some circumstances this consumed lots of CPU
// time. Instead, let us simply check that the volume (fpTopPV) exists in the
// physical volume store.
const auto& pvStore = G4PhysicalVolumeStore::GetInstance();
auto iterator = find(pvStore->begin(),pvStore->end(),fpTopPV);
if (iterator == pvStore->end()) {
@@ -852,56 +856,6 @@ G4bool G4PhysicalVolumeModel::Validate (G4bool warn)
} else {
return true;
}
// Previous algorithm
// G4TransportationManager* transportationManager =
// G4TransportationManager::GetTransportationManager ();
// size_t nWorlds = transportationManager->GetNoWorlds();
// G4bool found = false;
// std::vector<G4VPhysicalVolume*>::iterator iterWorld =
// transportationManager->GetWorldsIterator();
// for (size_t i = 0; i < nWorlds; ++i, ++iterWorld) {
// G4VPhysicalVolume* world = (*iterWorld);
// if (!world) break; // This can happen if geometry has been cleared/destroyed.
// // The idea now is to seek a PV with the same name and copy no
// // in the hope it's the same one!!
// G4PhysicalVolumeModel searchModel (world);
// G4int verbosity = 0; // Suppress messages from G4PhysicalVolumeSearchScene.
// G4PhysicalVolumeSearchScene searchScene
// (&searchModel, fTopPVName, fTopPVCopyNo, verbosity);
// G4ModelingParameters mp; // Default modeling parameters for this search.
// mp.SetDefaultVisAttributes(fpMP? fpMP->GetDefaultVisAttributes(): 0);
// searchModel.SetModelingParameters (&mp);
// searchModel.DescribeYourselfTo (searchScene);
// G4VPhysicalVolume* foundVolume = searchScene.GetFoundVolume ();
// if (foundVolume) {
// if (foundVolume != fpTopPV && warn) {
// G4cout <<
// "G4PhysicalVolumeModel::Validate(): A volume of the same name and"
// "\n copy number (\""
// << fTopPVName << "\", copy " << fTopPVCopyNo
// << ") still exists and is being used."
// "\n But it is not the same volume you originally specified"
// "\n in /vis/scene/add/."
// << G4endl;
// }
// fpTopPV = foundVolume;
// CalculateExtent ();
// found = true;
// }
// }
// if (found) return true;
// else {
// if (warn) {
// G4cout <<
// "G4PhysicalVolumeModel::Validate(): No volume of name and"
// "\n copy number (\""
// << fTopPVName << "\", copy " << fTopPVCopyNo
// << ") exists."
// << G4endl;
// }
// return false;
// }
}
const std::map<G4String,G4AttDef>* G4PhysicalVolumeModel::GetAttDefs() const
@@ -915,29 +869,33 @@ const std::map<G4String,G4AttDef>* G4PhysicalVolumeModel::GetAttDefs() const
(*store)["BasePVPath"] =
G4AttDef("BasePVPath","Base Physical Volume Path","Physics","","G4String");
(*store)["LVol"] =
G4AttDef("LVol","Logical Volume","Physics","","G4String");
G4AttDef("LVol","Logical Volume","Physics","","G4String");
(*store)["Solid"] =
G4AttDef("Solid","Solid Name","Physics","","G4String");
G4AttDef("Solid","Solid Name","Physics","","G4String");
(*store)["EType"] =
G4AttDef("EType","Entity Type","Physics","","G4String");
G4AttDef("EType","Entity Type","Physics","","G4String");
(*store)["DmpSol"] =
G4AttDef("DmpSol","Dump of Solid properties","Physics","","G4String");
G4AttDef("DmpSol","Dump of Solid properties","Physics","","G4String");
(*store)["LocalTrans"] =
G4AttDef("LocalTrans","Local transformation of volume","Physics","","G4String");
G4AttDef("LocalTrans","Local transformation of volume","Physics","","G4String");
(*store)["LocalExtent"] =
G4AttDef("LocalExtent","Local extent of volume","Physics","","G4String");
(*store)["GlobalTrans"] =
G4AttDef("GlobalTrans","Global transformation of volume","Physics","","G4String");
G4AttDef("GlobalTrans","Global transformation of volume","Physics","","G4String");
(*store)["GlobalExtent"] =
G4AttDef("GlobalExtent","Global extent of volume","Physics","","G4String");
(*store)["Material"] =
G4AttDef("Material","Material Name","Physics","","G4String");
G4AttDef("Material","Material Name","Physics","","G4String");
(*store)["Density"] =
G4AttDef("Density","Material Density","Physics","G4BestUnit","G4double");
G4AttDef("Density","Material Density","Physics","G4BestUnit","G4double");
(*store)["State"] =
G4AttDef("State","Material State (enum undefined,solid,liquid,gas)","Physics","","G4String");
G4AttDef("State","Material State (enum undefined,solid,liquid,gas)","Physics","","G4String");
(*store)["Radlen"] =
G4AttDef("Radlen","Material Radiation Length","Physics","G4BestUnit","G4double");
G4AttDef("Radlen","Material Radiation Length","Physics","G4BestUnit","G4double");
(*store)["Region"] =
G4AttDef("Region","Cuts Region","Physics","","G4String");
G4AttDef("Region","Cuts Region","Physics","","G4String");
(*store)["RootRegion"] =
G4AttDef("RootRegion","Root Region (0/1 = false/true)","Physics","","G4bool");
G4AttDef("RootRegion","Root Region (0/1 = false/true)","Physics","","G4bool");
}
return store;
}
@@ -996,34 +954,54 @@ std::vector<G4AttValue>* G4PhysicalVolumeModel::CreateCurrentAttValues() const
std::ostringstream oss; oss << fFullPVPath;
values->push_back(G4AttValue("PVPath", oss.str(),""));
oss.str(""); oss << fBaseFullPVPath;
values->push_back(G4AttValue("BasePVPath", oss.str(),""));
values->push_back(G4AttValue("LVol", fpCurrentLV->GetName(),""));
G4VSolid* pSol = fpCurrentLV->GetSolid();
values->push_back(G4AttValue("Solid", pSol->GetName(),""));
values->push_back(G4AttValue("EType", pSol->GetEntityType(),""));
oss.str(""); oss << '\n' << *pSol;
values->push_back(G4AttValue("DmpSol", oss.str(),""));
const G4RotationMatrix localRotation = fpCurrentPV->GetObjectRotationValue();
const G4ThreeVector& localTranslation = fpCurrentPV->GetTranslation();
oss.str(""); oss << '\n' << G4Transform3D(localRotation,localTranslation);
values->push_back(G4AttValue("LocalTrans", oss.str(),""));
oss.str(""); oss << '\n' << pSol->GetExtent() << std::endl;
values->push_back(G4AttValue("LocalExtent", oss.str(),""));
oss.str(""); oss << '\n' << fCurrentTransform;
values->push_back(G4AttValue("GlobalTrans", oss.str(),""));
oss.str(""); oss << '\n' << (pSol->GetExtent()).Transform(fCurrentTransform) << std::endl;
values->push_back(G4AttValue("GlobalExtent", oss.str(),""));
G4String matName = fpCurrentMaterial? fpCurrentMaterial->GetName(): G4String("No material");
values->push_back(G4AttValue("Material", matName,""));
G4double matDensity = fpCurrentMaterial? fpCurrentMaterial->GetDensity(): 0.;
values->push_back(G4AttValue("Density", G4BestUnit(matDensity,"Volumic Mass"),""));
G4State matState = fpCurrentMaterial? fpCurrentMaterial->GetState(): kStateUndefined;
oss.str(""); oss << matState;
values->push_back(G4AttValue("State", oss.str(),""));
G4double matRadlen = fpCurrentMaterial? fpCurrentMaterial->GetRadlen(): 0.;
values->push_back(G4AttValue("Radlen", G4BestUnit(matRadlen,"Length"),""));
G4Region* region = fpCurrentLV->GetRegion();
G4String regionName = region? region->GetName(): G4String("No region");
values->push_back(G4AttValue("Region", regionName,""));
oss.str(""); oss << fpCurrentLV->IsRootRegion();
values->push_back(G4AttValue("RootRegion", oss.str(),""));
return values;
}
@@ -1,103 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
//
// John Allison 10th August 1998.
// An artificial scene to find physical volumes.
#include "G4PhysicalVolumeSearchScene.hh"
#include "G4VSolid.hh"
#include "G4Vector3D.hh"
#include "G4PhysicalVolumeModel.hh"
G4PhysicalVolumeSearchScene::G4PhysicalVolumeSearchScene
(G4PhysicalVolumeModel* pPVModel,
const G4String& requiredPhysicalVolumeName,
G4int requiredCopyNo,
G4int verbosity):
fpPVModel (pPVModel),
fRequiredPhysicalVolumeName (requiredPhysicalVolumeName),
fRequiredCopyNo (requiredCopyNo),
fFoundDepth (0),
fpFoundPV (0),
fVerbosity (verbosity),
fMultipleOccurrence (false)
{}
G4PhysicalVolumeSearchScene::~G4PhysicalVolumeSearchScene () {}
void G4PhysicalVolumeSearchScene::ProcessVolume (const G4VSolid&) {
G4VPhysicalVolume* pCurrentPV = fpPVModel->GetCurrentPV();
/**************************************************
G4cout << "Required volume: \"" << fRequiredPhysicalVolumeName
<< "\", copy no. " << fRequiredCopyNo << G4endl;
G4cout << "PhysicalVolume: \"" << pCurrentPV -> GetName ()
<< "\", copy no. " << pCurrentPV -> GetCopyNo () << G4endl;
*******************************************/
const G4String& name = fpPVModel->GetCurrentPV() -> GetName ();
if (name.length() == fRequiredPhysicalVolumeName.length()) {
if (fRequiredPhysicalVolumeName == name) {
typedef G4PhysicalVolumeModel::G4PhysicalVolumeNodeID PVNodeID;
typedef std::vector<PVNodeID> PVPath;
const PVPath& fullPVPath = fpPVModel->GetFullPVPath();
G4int currentDepth = fpPVModel->GetCurrentDepth();
if ((fRequiredCopyNo < 0 || // I.e., ignore negative request.
fRequiredCopyNo == pCurrentPV -> GetCopyNo ())) {
// Current policy - take first one found!!
if (!fpFoundPV) { // i.e., if not already found.
fFoundFullPVPath = fullPVPath;
fFoundDepth = currentDepth;
fpFoundPV = pCurrentPV;
fFoundObjectTransformation = *fpCurrentObjectTransformation;
}
else {
if (!fMultipleOccurrence && fVerbosity > 0) {
fMultipleOccurrence = true;
G4cout << "G4PhysicalVolumeSearchScene::FindVolume:"
<< "\n Required volume \""
<< fRequiredPhysicalVolumeName
<< "\"";
if (fRequiredCopyNo >= 0) {
G4cout << ", copy no. " << fRequiredCopyNo << ",";
}
G4cout << " found more than once."
"\n This function is not smart enough to distinguish identical"
"\n physical volumes which have different parentage. It is"
"\n tricky to specify in general. This function gives you access"
"\n to the first occurrence only."
<< G4endl;
}
}
}
}
}
}
@@ -36,14 +36,12 @@
#include <regex>
G4PhysicalVolumesSearchScene::G4PhysicalVolumesSearchScene
(G4PhysicalVolumeModel* pSearchVolumesModel, // usually a world
(G4PhysicalVolumeModel* pSearchVolumesModel,
const G4String& requiredPhysicalVolumeName,
G4int requiredCopyNo,
G4int requiredContinuation)
G4int requiredCopyNo)
: fpSearchVolumesModel (pSearchVolumesModel)
, fMatcher (requiredPhysicalVolumeName)
, fRequiredCopyNo (requiredCopyNo)
, fRequiredContinuation (requiredContinuation)
{}
void G4PhysicalVolumesSearchScene::ProcessVolume (const G4VSolid&)
@@ -69,15 +67,8 @@ void G4PhysicalVolumesSearchScene::ProcessVolume (const G4VSolid&)
copyNo,
fpSearchVolumesModel->GetCurrentDepth(),
basePath,
fpSearchVolumesModel->GetFullPVPath(),
*fpCurrentObjectTransformation));
// If user has asked for limited descent
if (fRequiredContinuation >= 0) {
static G4int firstFoundDepth = fpSearchVolumesModel->GetCurrentDepth();
G4int foundDepth = fpSearchVolumesModel->GetCurrentDepth();
if (foundDepth >= firstFoundDepth + fRequiredContinuation) {
fpSearchVolumesModel->CurtailDescent();
}
}
}
}
}
@@ -31,6 +31,15 @@
#include "G4PseudoScene.hh"
#include "G4Mesh.hh"
#include "G4VPhysicalVolume.hh"
#include "G4LogicalVolume.hh"
void G4PseudoScene::AddCompound(const G4Mesh& mesh) {
// Catches mesh if special mesh rendering set
ProcessVolume(*mesh.GetContainerVolume()->GetLogicalVolume()->GetSolid());
}
void G4PseudoScene::ProcessVolume (const G4VSolid& solid)
{
G4ExceptionDescription ed;
@@ -71,6 +71,7 @@ void G4TouchablePropertiesScene::ProcessVolume (const G4VSolid& /*solid*/) {
fFoundTouchableProperties.fTouchableBaseFullPVPath = fpSearchPVModel->GetFullPVPath();
// Base path is one down from found PV
fFoundTouchableProperties.fTouchableBaseFullPVPath.pop_back();
fFoundTouchableProperties.fTouchableFullPVPath = fpSearchPVModel->GetFullPVPath();
fpSearchPVModel->Abort(); // No need to look further.
}
}