Import Geant4 0.0.0 source tree
This commit is contained in:
@@ -0,0 +1,406 @@
|
||||
// This code implementation is the intellectual property of
|
||||
// the RD44 GEANT4 collaboration.
|
||||
//
|
||||
// By copying, distributing or modifying the Program (or any work
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4PhysicalVolumeModel.cc,v 2.6 1998/11/25 16:25:49 allison Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
//
|
||||
// John Allison 31st December 1997.
|
||||
// Model for physical volumes.
|
||||
|
||||
#include "G4PhysicalVolumeModel.hh"
|
||||
|
||||
#include "G4ModelingParameters.hh"
|
||||
#include "G4VGraphicsScene.hh"
|
||||
#include "G4VPhysicalVolume.hh"
|
||||
#include "G4VPVParameterisation.hh"
|
||||
#include "G4LogicalVolume.hh"
|
||||
#include "G4VSolid.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4VisAttributes.hh"
|
||||
#include "G4BoundingSphereScene.hh"
|
||||
#include "G4PhysicalVolumeSearchScene.hh"
|
||||
#include "G4TransportationManager.hh"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <strstrea.h>
|
||||
#else
|
||||
#include <strstream.h>
|
||||
#endif
|
||||
|
||||
G4PhysicalVolumeModel::G4PhysicalVolumeModel
|
||||
(G4VPhysicalVolume* pVPV,
|
||||
G4int soughtDepth,
|
||||
const G4Transform3D& modelTransformation,
|
||||
const G4ModelingParameters* pMP):
|
||||
G4VModel (modelTransformation, pMP),
|
||||
fpTopPV (pVPV),
|
||||
fTopPVName (pVPV -> GetName ()),
|
||||
fTopPVCopyNo (pVPV -> GetCopyNo ()),
|
||||
fSoughtDepth (soughtDepth),
|
||||
fCurrentDepth (0),
|
||||
fpCurrentPV (0),
|
||||
fpCurrentLV (0),
|
||||
fpCurrentDepth (0),
|
||||
fppCurrentPV (0),
|
||||
fppCurrentLV (0)
|
||||
{
|
||||
const int len = 8; char a [len];
|
||||
ostrstream o (a, len); o.seekp (ios::beg);
|
||||
o << fpTopPV -> GetCopyNo () << ends;
|
||||
fGlobalTag = fpTopPV -> GetName () + "." + a;
|
||||
fGlobalDescription = "G4PhysicalVolumeModel " + fGlobalTag;
|
||||
|
||||
G4BoundingSphereScene bsScene;
|
||||
const G4ModelingParameters* tempMP = fpMP;
|
||||
G4ModelingParameters mParams
|
||||
(0, // No default vis attributes.
|
||||
G4ModelingParameters::wireframe,
|
||||
true, // Global culling.
|
||||
true, // Cull invisible volumes.
|
||||
false, // Density culling.
|
||||
0., // Density (not relevant if density culling false).
|
||||
true, // Cull daughters of opaque mothers.
|
||||
24); // No of sides (not relevant for this operation).
|
||||
fpMP = &mParams;
|
||||
//bsScene.SetBoundingSphereExtent
|
||||
// (fpTopPV -> GetLogicalVolume () -> GetSolid () -> GetExtent ());
|
||||
DescribeYourselfTo (bsScene);
|
||||
fExtent = bsScene.GetBoundingSphereExtent ();
|
||||
fpMP = tempMP;
|
||||
}
|
||||
|
||||
void G4PhysicalVolumeModel::DescribeYourselfTo (G4VGraphicsScene& scene) {
|
||||
|
||||
scene.EstablishSpecials (*this);
|
||||
// See .hh file for explanation of this mechanism.
|
||||
|
||||
fCurrentDepth = 0;
|
||||
// Store in working space (via pointer to working space).
|
||||
if (fpCurrentDepth) *fpCurrentDepth = fCurrentDepth;
|
||||
|
||||
//G4Transform3D startingTransformation = fTransform;
|
||||
G4Transform3D startingTransformation;
|
||||
|
||||
VisitGeometryAndGetVisReps (fpTopPV,
|
||||
fSoughtDepth,
|
||||
startingTransformation,
|
||||
scene);
|
||||
|
||||
// Clear current data and working space (via pointers to working space).
|
||||
fCurrentDepth = 0;
|
||||
fpCurrentPV = 0;
|
||||
fpCurrentLV = 0;
|
||||
if (fpCurrentDepth) *fpCurrentDepth = fCurrentDepth;
|
||||
if (fppCurrentPV) *fppCurrentPV = fpCurrentPV;
|
||||
if (fppCurrentLV) *fppCurrentLV = fpCurrentLV;
|
||||
|
||||
scene.DecommissionSpecials (*this);
|
||||
|
||||
// Clear pointers to working space.
|
||||
fpCurrentDepth = 0;
|
||||
fppCurrentPV = 0;
|
||||
fppCurrentLV = 0;
|
||||
}
|
||||
|
||||
G4String G4PhysicalVolumeModel::GetCurrentTag () const {
|
||||
const int len = 8; char a [len];
|
||||
ostrstream o (a, len); o.seekp (ios::beg);
|
||||
if (fpCurrentPV) {
|
||||
o << fpCurrentPV -> GetCopyNo () << ends;
|
||||
return fpCurrentPV -> GetName () + "." + a;
|
||||
}
|
||||
else {
|
||||
return "WARNING: NO CURRENT VOLUME - global tag is " + fGlobalTag;
|
||||
}
|
||||
}
|
||||
|
||||
G4String G4PhysicalVolumeModel::GetCurrentDescription () const {
|
||||
return "G4PhysicalVolumeModel " + GetCurrentTag ();
|
||||
}
|
||||
|
||||
void G4PhysicalVolumeModel::DefinePointersToWorkingSpace
|
||||
(G4int* pCurrentDepth,
|
||||
G4VPhysicalVolume** ppCurrentPV,
|
||||
G4LogicalVolume** ppCurrentLV) {
|
||||
fpCurrentDepth = pCurrentDepth;
|
||||
fppCurrentPV = ppCurrentPV;
|
||||
fppCurrentLV = ppCurrentLV;
|
||||
}
|
||||
|
||||
void G4PhysicalVolumeModel::VisitGeometryAndGetVisReps
|
||||
(G4VPhysicalVolume* pVPV,
|
||||
G4int soughtDepth,
|
||||
const G4Transform3D& theAT,
|
||||
G4VGraphicsScene& scene) {
|
||||
|
||||
// Visits geometry structure to a given depth (soughtDepth), starting
|
||||
// at given physical volume with given starting transformation and
|
||||
// describes volumes to the scene.
|
||||
// soughtDepth < 0 (default) implies full visit.
|
||||
// theAT is the Accumulated Transformation.
|
||||
|
||||
// Find corresponding logical volume and (later) solid, storing in
|
||||
// local variables to preserve re-entrancy.
|
||||
G4LogicalVolume* pLV = pVPV -> GetLogicalVolume ();
|
||||
|
||||
// Maintain data members and store in working space (via pointers to
|
||||
// working space).
|
||||
if (fpCurrentDepth) *fpCurrentDepth = fCurrentDepth;
|
||||
fpCurrentPV = pVPV;
|
||||
fpCurrentLV = pLV;
|
||||
if (fppCurrentPV) *fppCurrentPV = fpCurrentPV;
|
||||
if (fppCurrentLV) *fppCurrentLV = fpCurrentLV;
|
||||
|
||||
G4VSolid* pSol;
|
||||
G4Material* pMaterial;
|
||||
if (pVPV -> IsReplicated ()) {
|
||||
EAxis axis;
|
||||
G4int nReplicas;
|
||||
G4double width;
|
||||
G4double offset;
|
||||
G4bool consuming;
|
||||
pVPV -> GetReplicationData (axis, nReplicas, width, offset, consuming);
|
||||
G4VPVParameterisation* pP = pVPV -> GetParameterisation ();
|
||||
if (pP) { // Parametrised volume.
|
||||
for (int n = 0; n < nReplicas; n++) {
|
||||
pSol = pP -> ComputeSolid (n, pVPV);
|
||||
pMaterial = pP -> ComputeMaterial (n, pVPV);
|
||||
pP -> ComputeTransformation (n, pVPV);
|
||||
pSol -> ComputeDimensions (pP, n, pVPV);
|
||||
pVPV -> SetCopyNo (n);
|
||||
DescribeAndDescend (pVPV, soughtDepth, pLV, pSol, pMaterial,
|
||||
theAT, scene);
|
||||
}
|
||||
}
|
||||
else { // Plain replicated volume. From geometry_guide.txt...
|
||||
// The replica's positions are claculated by means of a linear formula.
|
||||
// Replication may occur along:
|
||||
//
|
||||
// o Cartesian axes (kXAxis,kYAxis,kZAxis)
|
||||
//
|
||||
// The replications, of specified width have coordinates of
|
||||
// form (-width*(nReplicas-1)*0.5+n*width,0,0) where n=0.. nReplicas-1
|
||||
// for the case of kXAxis, and are unrotated.
|
||||
//
|
||||
// o Radial axis (cylindrical polar) (kRho)
|
||||
//
|
||||
// The replications are cons/tubs sections, centred on the origin
|
||||
// and are unrotated.
|
||||
// They have radii of width*n+offset to width*(n+1)+offset
|
||||
// where n=0..nReplicas-1
|
||||
//
|
||||
// o Phi axis (cylindrical polar) (kPhi)
|
||||
// The replications are `phi sections' or wedges, and of cons/tubs form
|
||||
// They have phi of offset+n*width to offset+(n+1)*width where
|
||||
// n=0..nReplicas-1
|
||||
//
|
||||
for (int n = 0; n < nReplicas; n++) {
|
||||
G4ThreeVector translation; // Null.
|
||||
G4RotationMatrix rotation; // Null - life long enough for visualizing.
|
||||
G4RotationMatrix* pRotation = 0;
|
||||
switch (axis) {
|
||||
default:
|
||||
case kXAxis:
|
||||
translation = G4ThreeVector (-width*(nReplicas-1)*0.5+n*width,0,0);
|
||||
break;
|
||||
case kYAxis:
|
||||
translation = G4ThreeVector (0,-width*(nReplicas-1)*0.5+n*width,0);
|
||||
break;
|
||||
case kZAxis:
|
||||
translation = G4ThreeVector (0,0,-width*(nReplicas-1)*0.5+n*width);
|
||||
break;
|
||||
case kRho:
|
||||
G4cerr <<
|
||||
"G4PhysicalVolumeModel::VisitGeometryAndGetVisReps: WARNING:"
|
||||
"\n built-in replicated volumes replicated in radius are not yet"
|
||||
"\n properly visualizable."
|
||||
<< endl;
|
||||
break;
|
||||
case kPhi:
|
||||
rotation.rotateZ (-(offset+n*width));
|
||||
// Minus Sign because for the physical volume we need the
|
||||
// coordinate system rotation.
|
||||
pRotation = &rotation;
|
||||
break;
|
||||
}
|
||||
pVPV -> SetTranslation (translation);
|
||||
pVPV -> SetRotation (pRotation);
|
||||
pVPV -> SetCopyNo (n);
|
||||
pSol = pLV -> GetSolid ();
|
||||
pMaterial = pLV -> GetMaterial ();
|
||||
DescribeAndDescend (pVPV, soughtDepth, pLV, pSol, pMaterial,
|
||||
theAT, scene);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
pSol = pLV -> GetSolid ();
|
||||
pMaterial = pLV -> GetMaterial ();
|
||||
DescribeAndDescend (pVPV, soughtDepth, pLV, pSol, pMaterial, theAT, scene);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void G4PhysicalVolumeModel::DescribeAndDescend
|
||||
(G4VPhysicalVolume* pVPV,
|
||||
G4int soughtDepth,
|
||||
G4LogicalVolume* pLV,
|
||||
G4VSolid* pSol,
|
||||
const G4Material* pMaterial,
|
||||
const G4Transform3D& theAT,
|
||||
G4VGraphicsScene& scene) {
|
||||
|
||||
const HepRotation* pObjectRotation = pVPV -> GetObjectRotation ();
|
||||
const Hep3Vector& translation = pVPV -> GetTranslation ();
|
||||
G4Transform3D theLT = G4Transform3D (*pObjectRotation, translation);
|
||||
G4Transform3D theNewAT = theAT * theLT;
|
||||
|
||||
/********************************************************
|
||||
G4cout << "G4PhysicalVolumeModel::DescribeAndDescend: "
|
||||
<< pVPV -> GetName () << "." << pVPV -> GetCopyNo ();
|
||||
G4cout << "\n theAT: ";
|
||||
G4cout << "\n Rotation: ";
|
||||
HepRotation rotation = theAT.getRotation ();
|
||||
G4cout << rotation.thetaX() << ", "
|
||||
<< rotation.phiX() << ", "
|
||||
<< rotation.thetaY() << ", "
|
||||
<< rotation.phiY() << ", "
|
||||
<< rotation.thetaZ() << ", "
|
||||
<< rotation.phiZ();
|
||||
G4cout << "\n Translation: " << theAT.getTranslation();
|
||||
G4cout << "\n theNewAT: ";
|
||||
G4cout << "\n Rotation: ";
|
||||
rotation = theNewAT.getRotation ();
|
||||
G4cout << rotation.thetaX() << ", "
|
||||
<< rotation.phiX() << ", "
|
||||
<< rotation.thetaY() << ", "
|
||||
<< rotation.phiY() << ", "
|
||||
<< rotation.thetaZ() << ", "
|
||||
<< rotation.phiZ();
|
||||
G4cout << "\n Translation: " << theNewAT.getTranslation();
|
||||
G4cout << endl;
|
||||
**********************************************************/
|
||||
|
||||
// Make decision to Draw.
|
||||
G4bool thisToBeDrawn = !IsThisCulled (pLV, pMaterial);
|
||||
if (thisToBeDrawn) {
|
||||
scene.PreAddThis (theNewAT, *(pLV -> GetVisAttributes ()));
|
||||
pSol -> DescribeYourselfTo (scene);
|
||||
scene.PostAddThis ();
|
||||
}
|
||||
|
||||
// First check if mother covers...
|
||||
|
||||
// This is only effective in surface drawing style, and then only if
|
||||
// the volumes are visible and opaque, and then only if no sections
|
||||
// or cutways are in operation.
|
||||
G4bool cullDaughter = thisToBeDrawn && IsDaughterCulled (pLV);
|
||||
if (!(thisToBeDrawn && IsDaughterCulled (pLV))) {
|
||||
// OK, now let's check for daughters...
|
||||
if (soughtDepth != 0) {
|
||||
int nDaughters = pLV -> GetNoDaughters ();
|
||||
if (nDaughters) {
|
||||
for (int iDaughter = 0; iDaughter < nDaughters; iDaughter++) {
|
||||
G4VPhysicalVolume* pVPV = pLV -> GetDaughter (iDaughter);
|
||||
// Descend the geometry structure recursively...
|
||||
fCurrentDepth++;
|
||||
VisitGeometryAndGetVisReps (pVPV, soughtDepth - 1, theNewAT, scene);
|
||||
fCurrentDepth--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
G4bool G4PhysicalVolumeModel::IsThisCulled (const G4LogicalVolume* pLV,
|
||||
const G4Material* pMaterial) {
|
||||
// If true, cull, i.e., do not Draw.
|
||||
G4double density = pMaterial -> GetDensity ();
|
||||
const G4VisAttributes* pVisAttribs = pLV -> GetVisAttributes ();
|
||||
if (!pVisAttribs) pVisAttribs = fpMP -> GetDefaultVisAttributes ();
|
||||
if (fpMP) {
|
||||
return
|
||||
fpMP -> IsCulling () && // Global culling flag.
|
||||
(
|
||||
// Invisible volumes...
|
||||
(fpMP -> IsCullingInvisible () &&
|
||||
!(pVisAttribs ? pVisAttribs -> IsVisible () : true)) ||
|
||||
|
||||
// Low density volumes...
|
||||
(fpMP -> IsDensityCulling () &&
|
||||
(density < fpMP -> GetVisibleDensity ()))
|
||||
)
|
||||
;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
G4bool G4PhysicalVolumeModel::IsDaughterCulled
|
||||
(const G4LogicalVolume* pMotherLV) {
|
||||
// If true, cull, i.e., do not Draw.
|
||||
const G4VisAttributes* pVisAttribs = pMotherLV -> GetVisAttributes ();
|
||||
if (!pVisAttribs) pVisAttribs = fpMP -> GetDefaultVisAttributes ();
|
||||
if (fpMP) {
|
||||
return
|
||||
fpMP -> IsCulling () // Global culling flag.
|
||||
&&
|
||||
(
|
||||
// Does mother request daughters not to be drawn?
|
||||
(pVisAttribs ? pVisAttribs -> IsDaughtersInvisible () : false)
|
||||
||
|
||||
(
|
||||
// Global covered daughter flag. This is affected by drawing
|
||||
// style, etc. The enforcing of this is done in
|
||||
// G4VScene::CreateModelingParameters ()
|
||||
fpMP -> IsCullingCovered ()
|
||||
&&
|
||||
// Cull only if mother is visible...
|
||||
(pVisAttribs ? pVisAttribs -> IsVisible () : true)
|
||||
// &&
|
||||
// true // ...and opaque (transparency parameter not yet implemented).
|
||||
)
|
||||
)
|
||||
;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
G4bool G4PhysicalVolumeModel::Validate () {
|
||||
G4VPhysicalVolume* world =
|
||||
G4TransportationManager::GetTransportationManager ()
|
||||
-> GetNavigatorForTracking () -> GetWorldVolume ();
|
||||
// The idea now is to seek a PV with the same name and copy no
|
||||
// in the hope it's the same one!!
|
||||
G4cout << "G4PhysicalVolumeModel::Validate() called." << endl;
|
||||
G4PhysicalVolumeSearchScene searchScene (fTopPVName, fTopPVCopyNo);
|
||||
G4PhysicalVolumeModel searchModel (world);
|
||||
searchModel.DescribeYourselfTo (searchScene);
|
||||
G4VPhysicalVolume* foundVolume = searchScene.GetFoundVolume ();
|
||||
if (foundVolume) {
|
||||
G4cout << " Volume of the same name and copy number (\""
|
||||
<< fTopPVName << "\", copy " << fTopPVCopyNo
|
||||
<< ") still exists and is being used."
|
||||
"\n Be warned that this does not necessarily guarantee it's the same"
|
||||
"\n volume you originally specified in /vis/scene/add/."
|
||||
<< endl;
|
||||
fpTopPV = foundVolume;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
G4cout << " A volume of the same name and copy number (\""
|
||||
<< fTopPVName << "\", copy " << fTopPVCopyNo
|
||||
<< ") no longer exists."
|
||||
<< endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user