Import Geant4 11.1.0.beta source tree
This commit is contained in:
@@ -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 ();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user