Import Geant4 0.0.0 source tree
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
// 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: G4GeometryManager.cc,v 2.2 1998/07/13 16:51:22 urbi Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// class G4GeometryManager
|
||||
//
|
||||
// Implementation
|
||||
//
|
||||
// History:
|
||||
// 26.07.95 P.Kent Initial version, incuding optimisation Build
|
||||
|
||||
#include "G4GeometryManager.hh"
|
||||
|
||||
// Close geometry - perform sanity checks and optionally Build optimisation
|
||||
// for placed volumes (always built for replicas & parameterised)
|
||||
// NOTE: Currently no sanity checks
|
||||
G4bool G4GeometryManager::CloseGeometry(G4bool pOptimise)
|
||||
{
|
||||
if (!fIsClosed)
|
||||
{
|
||||
BuildOptimisations(pOptimise);
|
||||
fIsClosed=true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void G4GeometryManager::OpenGeometry()
|
||||
{
|
||||
if (fIsClosed)
|
||||
{
|
||||
DeleteOptimisations();
|
||||
fIsClosed=false;
|
||||
}
|
||||
}
|
||||
|
||||
// Static class variable: ptr to single instance of class
|
||||
G4GeometryManager* G4GeometryManager::fgInstance = 0;
|
||||
|
||||
G4GeometryManager* G4GeometryManager::GetInstance()
|
||||
{
|
||||
static G4GeometryManager worldManager;
|
||||
if (!fgInstance)
|
||||
{
|
||||
fgInstance = &worldManager;
|
||||
}
|
||||
return fgInstance;
|
||||
}
|
||||
|
||||
|
||||
// Constructor. Set the geometry to be open
|
||||
G4GeometryManager::G4GeometryManager()
|
||||
{
|
||||
fIsClosed=false;
|
||||
}
|
||||
|
||||
//
|
||||
// Create optimisation info. Build all voxels if allOpts=true
|
||||
// else only for replicated volumes
|
||||
//
|
||||
void G4GeometryManager::BuildOptimisations(const G4bool allOpts)
|
||||
{
|
||||
G4LogicalVolumeStore *Store;
|
||||
G4LogicalVolume *volume;
|
||||
G4SmartVoxelHeader *head;
|
||||
G4int nVolumes,n;
|
||||
Store=G4LogicalVolumeStore::GetInstance();
|
||||
nVolumes=Store->entries();
|
||||
for (n=0;n<nVolumes;n++)
|
||||
{
|
||||
volume=Store->operator()(n);
|
||||
// For safety, check if there are any existing voxels and delete before
|
||||
// replacement
|
||||
head = volume->GetVoxelHeader();
|
||||
if (head)
|
||||
{
|
||||
delete head;
|
||||
volume->SetVoxelHeader(0);
|
||||
}
|
||||
if ((volume->GetNoDaughters()>=kMinVoxelVolumesLevel1&&allOpts) ||
|
||||
(volume->GetNoDaughters()==1&&
|
||||
volume->GetDaughter(0)->IsReplicated()==true))
|
||||
{
|
||||
#ifdef G4GEOMETRY_VOXELDEBUG
|
||||
G4cout << "**** G4GeometryManager::BuildOptimisations" << endl
|
||||
<< " Examining logical volume name = " << volume->GetName() << endl;
|
||||
#endif
|
||||
head = new G4SmartVoxelHeader(volume);
|
||||
if (head)
|
||||
{
|
||||
volume->SetVoxelHeader(head);
|
||||
}
|
||||
else
|
||||
{
|
||||
G4Exception("G4GeometryManager::BuildOptimisations voxelheader new failed");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Don't create voxels for this node
|
||||
#ifdef G4GEOMETRY_VOXELDEBUG
|
||||
G4cout << "**** G4GeometryManager::BuildOptimisations"
|
||||
<< endl
|
||||
<< " Skipping logical volume name = "
|
||||
<< volume->GetName() << endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Remove all optimisation info
|
||||
//
|
||||
// Process:
|
||||
//
|
||||
// Loop over all logical volumes, deleting non-null voxels ptrs
|
||||
|
||||
void G4GeometryManager::DeleteOptimisations()
|
||||
{
|
||||
G4LogicalVolumeStore *Store=G4LogicalVolumeStore::GetInstance();
|
||||
G4LogicalVolume *volume;
|
||||
G4SmartVoxelHeader *head;
|
||||
G4int nVolumes,n;
|
||||
nVolumes=Store->entries();
|
||||
for (n=0;n<nVolumes;n++)
|
||||
{
|
||||
volume=Store->operator()(n);
|
||||
head=volume->GetVoxelHeader();
|
||||
if (head)
|
||||
{
|
||||
delete head;
|
||||
volume->SetVoxelHeader(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
// 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: G4LogicalVolume.cc,v 2.1 1998/11/11 11:38:21 japost Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
//
|
||||
// class G4LogicalVolume Implementation
|
||||
//
|
||||
// History:
|
||||
// 10.20.97 - P. MoraDeFreitas : "Fast" replaces "Parameterisation" in
|
||||
// class/method names. (release B.00 for parameterisation).
|
||||
// 04.08.97 P.MoraDeFreitas/J.A. Added methods for ParameterisedSimulation
|
||||
// 19.08.96 P.Kent Modified for G4VSensitive Detector
|
||||
// 11.07.95 P.Kent Initial version
|
||||
|
||||
#include "G4LogicalVolume.hh"
|
||||
#include "G4LogicalVolumeStore.hh"
|
||||
|
||||
// Constructor - set member data and add to logical Store, zero voxel ptr
|
||||
// Initialises daughter vector to 0 length
|
||||
G4LogicalVolume::G4LogicalVolume( G4VSolid *pSolid, G4Material *pMaterial,
|
||||
const G4String& name,
|
||||
G4FieldManager *pFieldMgr,
|
||||
G4VSensitiveDetector *pSDetector,
|
||||
G4UserLimits *pULimits) :
|
||||
fDaughters(0), fVoxel(0), fVisAttributes (0) , fFastSimulationManager (0),
|
||||
fIsEnvelope(FALSE), fFieldManager(pFieldMgr)
|
||||
{
|
||||
SetSolid(pSolid);
|
||||
SetMaterial(pMaterial);
|
||||
SetName(name);
|
||||
SetSensitiveDetector(pSDetector);
|
||||
SetUserLimits(pULimits);
|
||||
// Add to solid Store
|
||||
G4LogicalVolumeStore::Register(this);
|
||||
}
|
||||
|
||||
// Destructor - remove from solid Store
|
||||
// NOTE: Not virtual
|
||||
G4LogicalVolume::~G4LogicalVolume()
|
||||
{
|
||||
G4LogicalVolumeStore::DeRegister(this);
|
||||
}
|
||||
|
||||
// As this method is recursive, inlining it is harder (and asking for it
|
||||
// is pointless if not counterproductive: it will increase code size)
|
||||
//
|
||||
void G4LogicalVolume::SetFastSimulationManager (
|
||||
G4FastSimulationManager* pNewFastSimul,
|
||||
G4bool IsEnvelope)
|
||||
{
|
||||
if(!fIsEnvelope || IsEnvelope) {
|
||||
fIsEnvelope=IsEnvelope;
|
||||
fFastSimulationManager = pNewFastSimul;
|
||||
|
||||
G4int NoDaughters=GetNoDaughters();
|
||||
while((NoDaughters--)>0){
|
||||
G4LogicalVolume *DaughterLogVol;
|
||||
DaughterLogVol= GetDaughter(NoDaughters)->GetLogicalVolume();
|
||||
if(DaughterLogVol->GetFastSimulationManager() != pNewFastSimul) {
|
||||
DaughterLogVol->SetFastSimulationManager(pNewFastSimul,FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void G4LogicalVolume::
|
||||
ClearEnvelopeForFastSimulation( G4LogicalVolume* motherLogVol)
|
||||
{
|
||||
if( fIsEnvelope ) {
|
||||
G4FastSimulationManager* NewFastSimulationVal=NULL;
|
||||
|
||||
// This is no longer an envelope !
|
||||
fIsEnvelope=FALSE;
|
||||
|
||||
if( motherLogVol == NULL ) {
|
||||
motherLogVol = this->FindMotherLogicalVolumeForEnvelope();
|
||||
|
||||
} else {
|
||||
// Check that motherLogVol is this' mother.
|
||||
// If not, raise exception and set it to NULL.
|
||||
if ( FALSE ){
|
||||
G4Exception(
|
||||
"G4LogicalVolume::ClearEnvelope Gave wrong mother LogicalVolume" );
|
||||
motherLogVol = NULL;
|
||||
}
|
||||
}
|
||||
// Reset the ParameterisedSimulation values of self and all daughters
|
||||
// (after ensuring the mother was given correctly or was found)
|
||||
if( motherLogVol != NULL ) {
|
||||
NewFastSimulationVal = motherLogVol->
|
||||
GetFastSimulationManager();
|
||||
this->SetFastSimulationManager (NewFastSimulationVal,
|
||||
FALSE);
|
||||
}
|
||||
}else{
|
||||
G4Exception("Called G4LogicalVolume::ClearEnvelope for a non-envelope Logical Volume" );
|
||||
}
|
||||
}
|
||||
|
||||
void G4LogicalVolume::SetFieldManager (
|
||||
G4FieldManager* pNewFieldMgr,
|
||||
G4bool forceAllDaughters)
|
||||
{
|
||||
fFieldManager = pNewFieldMgr;
|
||||
|
||||
G4int NoDaughters=GetNoDaughters();
|
||||
while((NoDaughters--)>0){
|
||||
G4LogicalVolume *DaughterLogVol;
|
||||
DaughterLogVol= GetDaughter(NoDaughters)->GetLogicalVolume();
|
||||
if(forceAllDaughters || (DaughterLogVol->GetFieldManager() != 0)) {
|
||||
DaughterLogVol->SetFieldManager(pNewFieldMgr, forceAllDaughters);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// The following method returns a meaningful result IF and only IF
|
||||
// the current logical volume has exactly one physical volume that
|
||||
// uses it.
|
||||
|
||||
G4LogicalVolume*
|
||||
G4LogicalVolume::FindMotherLogicalVolumeForEnvelope()
|
||||
{
|
||||
G4LogicalVolume* motherLogVol= 0;
|
||||
G4LogicalVolumeStore *Store = G4LogicalVolumeStore::GetInstance();
|
||||
|
||||
// Look for the current volume's mother volume.
|
||||
|
||||
for (G4int LV=0;LV < Store->entries(); LV++){
|
||||
G4LogicalVolume *aLogVol;
|
||||
|
||||
aLogVol= Store->at(LV);
|
||||
if( (aLogVol!=this) && // Don't look for it inside itself...
|
||||
(aLogVol->GetFastSimulationManager()!=NULL)){
|
||||
|
||||
for (G4int daughter=0; daughter < aLogVol->GetNoDaughters();
|
||||
daughter++){
|
||||
if( aLogVol->GetDaughter(daughter)->GetLogicalVolume()==this) {
|
||||
// "- Oh Dear, aLogVol is my mother !!!"
|
||||
motherLogVol = aLogVol;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return motherLogVol;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
// 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: G4LogicalVolumeStore.cc,v 2.1 1998/07/12 02:55:38 urbi Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// G4LogicalVolumeStore
|
||||
//
|
||||
// Implementation for singleton container
|
||||
//
|
||||
// History:
|
||||
// 10.07.95 P.Kent Initial version
|
||||
|
||||
#include "G4LogicalVolumeStore.hh"
|
||||
#include "globals.hh"
|
||||
|
||||
// Protected constructor: Construct underlying container with
|
||||
// initial size of 100 entries
|
||||
G4LogicalVolumeStore::G4LogicalVolumeStore() : RWTPtrOrderedVector<G4LogicalVolume>(100)
|
||||
{
|
||||
}
|
||||
|
||||
// Destructor
|
||||
G4LogicalVolumeStore::~G4LogicalVolumeStore()
|
||||
{
|
||||
while (!isEmpty()) delete first();
|
||||
}
|
||||
|
||||
// Static class variable
|
||||
G4LogicalVolumeStore* G4LogicalVolumeStore::fgInstance = 0;
|
||||
|
||||
// Add volume to container
|
||||
void G4LogicalVolumeStore::Register(G4LogicalVolume* pVolume)
|
||||
{
|
||||
GetInstance()->insert(pVolume);
|
||||
}
|
||||
|
||||
// Remove volume from container
|
||||
void G4LogicalVolumeStore::DeRegister(G4LogicalVolume* pVolume)
|
||||
{
|
||||
GetInstance()->remove(pVolume);
|
||||
}
|
||||
|
||||
// Return ptr to Store, setting if necessary
|
||||
G4LogicalVolumeStore* G4LogicalVolumeStore::GetInstance()
|
||||
{
|
||||
static G4LogicalVolumeStore worldStore;
|
||||
if (!fgInstance)
|
||||
{
|
||||
fgInstance = &worldStore;
|
||||
}
|
||||
return fgInstance;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
// 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: G4PVParameterised.cc,v 2.0 1998/07/02 16:57:27 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
//
|
||||
// class G4PVParameterised
|
||||
//
|
||||
// Implementation
|
||||
|
||||
#include "G4PVParameterised.hh"
|
||||
|
||||
G4PVParameterised::G4PVParameterised(const G4String& pName,
|
||||
G4LogicalVolume* pLogical,
|
||||
G4VPhysicalVolume* pMother,
|
||||
const EAxis pAxis,
|
||||
const G4int nReplicas,
|
||||
G4VPVParameterisation *pParam) :
|
||||
G4PVReplica(pName,pLogical,pMother,pAxis,nReplicas,0,0),
|
||||
fparam(pParam)
|
||||
{
|
||||
}
|
||||
|
||||
G4PVParameterised::G4PVParameterised(const G4String& pName,
|
||||
G4LogicalVolume* pLogical,
|
||||
G4LogicalVolume* pMotherLogical,
|
||||
const EAxis pAxis,
|
||||
const G4int nReplicas,
|
||||
G4VPVParameterisation *pParam) :
|
||||
G4PVReplica(pName,pLogical,pMotherLogical,pAxis,nReplicas,0,0),
|
||||
fparam(pParam)
|
||||
{
|
||||
}
|
||||
|
||||
G4VPVParameterisation* G4PVParameterised::GetParameterisation() const
|
||||
{
|
||||
return fparam;
|
||||
}
|
||||
|
||||
void G4PVParameterised::GetReplicationData(EAxis& axis,
|
||||
G4int& nReplicas,
|
||||
G4double& width,
|
||||
G4double& offset,
|
||||
G4bool& consuming) const
|
||||
{
|
||||
axis=faxis;
|
||||
nReplicas=fnReplicas;
|
||||
width=fwidth;
|
||||
offset=foffset;
|
||||
consuming=false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
// 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: G4PVPlacement.cc,v 2.1 1998/07/12 02:55:39 urbi Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
//
|
||||
// class G4PVPlacement Implementation
|
||||
|
||||
#include "G4PVPlacement.hh"
|
||||
// #include "G4Transform3D.hh"
|
||||
#include "G4LogicalVolume.hh"
|
||||
|
||||
G4PVPlacement::G4PVPlacement(G4RotationMatrix *pRot,
|
||||
const G4ThreeVector &tlate,
|
||||
const G4String& pName,
|
||||
G4LogicalVolume *pLogical,
|
||||
G4VPhysicalVolume *pMother,
|
||||
G4bool pMany,
|
||||
G4int pCopyNo) :
|
||||
G4VPhysicalVolume(pRot,tlate,pName,pLogical,pMother),
|
||||
fcopyNo(pCopyNo), fmany(pMany), fallocatedRotM(false)
|
||||
{
|
||||
}
|
||||
|
||||
G4PVPlacement::G4PVPlacement(const G4Transform3D &Transform3D,
|
||||
const G4String& pName,
|
||||
G4LogicalVolume *pLogical,
|
||||
G4VPhysicalVolume *pMother,
|
||||
G4bool pMany,
|
||||
G4int pCopyNo) :
|
||||
G4VPhysicalVolume( NewPtrRotMatrix(Transform3D.getRotation().inverse()),
|
||||
Transform3D.getTranslation(),
|
||||
pName,pLogical,pMother),
|
||||
fcopyNo(pCopyNo), fmany(pMany)
|
||||
{
|
||||
fallocatedRotM= (this->GetRotation() != 0);
|
||||
}
|
||||
|
||||
//
|
||||
// The logical volume of the mother is utilised (not the physical)
|
||||
// [ The physical volume is needed, known and set only at tracking time. ]
|
||||
//
|
||||
|
||||
G4PVPlacement::G4PVPlacement(G4RotationMatrix *pRot,
|
||||
const G4ThreeVector &tlate,
|
||||
G4LogicalVolume *pCurrentLogical,
|
||||
const G4String& pName,
|
||||
G4LogicalVolume *pMotherLogical,
|
||||
G4bool pMany,
|
||||
G4int pCopyNo) :
|
||||
G4VPhysicalVolume(pRot,tlate,pName,pCurrentLogical,0),
|
||||
fcopyNo(pCopyNo), fmany(pMany), fallocatedRotM(false)
|
||||
{
|
||||
if (pMotherLogical) pMotherLogical->AddDaughter(this);
|
||||
}
|
||||
|
||||
|
||||
G4PVPlacement::G4PVPlacement( const G4Transform3D &Transform3D,
|
||||
G4LogicalVolume *pCurrentLogical,
|
||||
const G4String& pName,
|
||||
G4LogicalVolume *pMotherLogical,
|
||||
G4bool pMany,
|
||||
G4int pCopyNo):
|
||||
G4VPhysicalVolume( 0,
|
||||
Transform3D.getTranslation(),
|
||||
pName,
|
||||
pCurrentLogical,
|
||||
0),
|
||||
fcopyNo(pCopyNo),
|
||||
fmany(pMany)
|
||||
{
|
||||
this->SetRotation( NewPtrRotMatrix(Transform3D.getRotation().inverse()) );
|
||||
fallocatedRotM= (this->GetRotation() != 0);
|
||||
|
||||
if (pMotherLogical) pMotherLogical->AddDaughter(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
G4PVPlacement::~G4PVPlacement()
|
||||
{
|
||||
if( fallocatedRotM ){ delete frot; }
|
||||
}
|
||||
|
||||
G4bool G4PVPlacement::IsMany() const
|
||||
{
|
||||
return fmany;
|
||||
}
|
||||
|
||||
G4int G4PVPlacement::GetCopyNo() const
|
||||
{
|
||||
return fcopyNo;
|
||||
}
|
||||
|
||||
|
||||
void G4PVPlacement::SetCopyNo(G4int newCopyNo)
|
||||
{
|
||||
fcopyNo= newCopyNo;
|
||||
}
|
||||
|
||||
|
||||
G4bool G4PVPlacement::IsReplicated() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
G4VPVParameterisation* G4PVPlacement::GetParameterisation() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void G4PVPlacement::GetReplicationData(EAxis& axis,
|
||||
G4int& nReplicas,
|
||||
G4double& width,
|
||||
G4double& offset,
|
||||
G4bool& consuming) const
|
||||
{
|
||||
// No-operations
|
||||
}
|
||||
|
||||
void G4PVPlacement::Setup(G4VPhysicalVolume *pMother)
|
||||
{
|
||||
SetMother(pMother);
|
||||
}
|
||||
|
||||
//
|
||||
// Auxiliary function for 2nd & 4th constructors (the ones with G4Transform3D)
|
||||
// Creates a new RotMatrix on the heap (using "new") and copies
|
||||
// its argument into it.
|
||||
//
|
||||
// No entity is currently responsible to delete this memory.
|
||||
// This is a memory leak. <-- FIXME
|
||||
//
|
||||
|
||||
G4RotationMatrix* G4PVPlacement::NewPtrRotMatrix(const G4RotationMatrix &RotMat)
|
||||
{
|
||||
G4RotationMatrix *pRotMatrix;
|
||||
if ( RotMat.isIdentity() )
|
||||
pRotMatrix= 0;
|
||||
else{
|
||||
pRotMatrix= new G4RotationMatrix(RotMat);
|
||||
}
|
||||
// fallocatedRotM= ! (RotMat.isIdentity());
|
||||
|
||||
return pRotMatrix;
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
// 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: G4PVReplica.cc,v 2.0 1998/07/02 16:57:24 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
//
|
||||
// class G4PVReplica Implementation
|
||||
|
||||
#include "G4PVReplica.hh"
|
||||
#include "G4LogicalVolume.hh"
|
||||
|
||||
G4PVReplica::G4PVReplica(const G4String& pName,
|
||||
G4LogicalVolume* pLogical,
|
||||
G4VPhysicalVolume* pMother,
|
||||
const EAxis pAxis,
|
||||
const G4int nReplicas,
|
||||
const G4double width,
|
||||
const G4double offset) : G4VPhysicalVolume(0,G4ThreeVector(),pName,pLogical,pMother), fcopyNo(-1)
|
||||
{
|
||||
CheckAndSetParameters (pAxis, nReplicas, width, offset);
|
||||
}
|
||||
|
||||
G4PVReplica::G4PVReplica(const G4String& pName,
|
||||
G4LogicalVolume* pLogical,
|
||||
G4LogicalVolume* pMotherLogical,
|
||||
const EAxis pAxis,
|
||||
const G4int nReplicas,
|
||||
const G4double width,
|
||||
const G4double offset) : G4VPhysicalVolume(0,G4ThreeVector(),pName,pLogical,0), fcopyNo(-1)
|
||||
{
|
||||
if (pMotherLogical) pMotherLogical->AddDaughter(this);
|
||||
CheckAndSetParameters (pAxis, nReplicas, width, offset);
|
||||
}
|
||||
|
||||
void G4PVReplica::CheckAndSetParameters (const EAxis pAxis,
|
||||
const G4int nReplicas,
|
||||
const G4double width,
|
||||
const G4double offset) {
|
||||
|
||||
if (nReplicas<1)
|
||||
{
|
||||
G4Exception("G4PVReplica::G4PVReplica illegal no of replicas");
|
||||
}
|
||||
fnReplicas=nReplicas;
|
||||
if (width<0)
|
||||
{
|
||||
G4Exception("G4PVReplica::G4PVReplica Width must be positive");
|
||||
}
|
||||
fwidth=width;
|
||||
|
||||
foffset=offset;
|
||||
|
||||
faxis=pAxis;
|
||||
|
||||
// Create rotation matrix for phi axis case & check axis is valid
|
||||
G4RotationMatrix *pRMat;
|
||||
switch (faxis)
|
||||
{
|
||||
case kPhi:
|
||||
pRMat=new G4RotationMatrix();
|
||||
if (!pRMat)
|
||||
{
|
||||
G4Exception("G4PVReplica::G4PVReplica rotation matrix alloc failed");
|
||||
}
|
||||
SetRotation(pRMat);
|
||||
break;
|
||||
case kRho:
|
||||
case kXAxis:
|
||||
case kYAxis:
|
||||
case kZAxis:
|
||||
break;
|
||||
default:
|
||||
G4Exception("G4PVReplica::G4PVReplica Unknown axis");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
G4PVReplica::~G4PVReplica()
|
||||
{
|
||||
if (faxis==kPhi)
|
||||
{
|
||||
delete GetRotation();
|
||||
}
|
||||
}
|
||||
|
||||
G4bool G4PVReplica::IsMany() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
G4int G4PVReplica::GetCopyNo() const
|
||||
{
|
||||
// return 0;
|
||||
return fcopyNo;
|
||||
}
|
||||
|
||||
void G4PVReplica::SetCopyNo(G4int newCopyNo)
|
||||
{
|
||||
fcopyNo= newCopyNo;
|
||||
}
|
||||
|
||||
G4bool G4PVReplica::IsReplicated() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
G4VPVParameterisation* G4PVReplica::GetParameterisation() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void G4PVReplica::GetReplicationData(EAxis& axis,
|
||||
G4int& nReplicas,
|
||||
G4double& width,
|
||||
G4double& offset,
|
||||
G4bool& consuming) const
|
||||
{
|
||||
axis=faxis;
|
||||
nReplicas=fnReplicas;
|
||||
width=fwidth;
|
||||
offset=foffset;
|
||||
consuming=true;
|
||||
}
|
||||
|
||||
void G4PVReplica::Setup(G4VPhysicalVolume *pMother)
|
||||
{
|
||||
SetMother(pMother);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
// 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: G4PhysicalVolumeStore.cc,v 2.1 1998/07/12 02:55:40 urbi Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// G4PhysicalVolumeStore
|
||||
//
|
||||
// Implementation for singleton container
|
||||
//
|
||||
// History:
|
||||
// 25.07.95 P.Kent Initial version
|
||||
|
||||
#include "G4PhysicalVolumeStore.hh"
|
||||
#include "globals.hh"
|
||||
|
||||
// Protected constructor: Construct underlying container with
|
||||
// initial size of 100 entries
|
||||
G4PhysicalVolumeStore::G4PhysicalVolumeStore() : RWTPtrOrderedVector<G4VPhysicalVolume>(100)
|
||||
{
|
||||
}
|
||||
|
||||
// Destructor
|
||||
G4PhysicalVolumeStore::~G4PhysicalVolumeStore()
|
||||
{
|
||||
while (!isEmpty()) delete first();
|
||||
}
|
||||
|
||||
// Static class variable
|
||||
G4PhysicalVolumeStore* G4PhysicalVolumeStore::fgInstance = 0;
|
||||
|
||||
// Add Solid to container
|
||||
void G4PhysicalVolumeStore::Register(G4VPhysicalVolume* pVolume)
|
||||
{
|
||||
GetInstance()->insert(pVolume);
|
||||
}
|
||||
|
||||
// Remove Solid from container
|
||||
void G4PhysicalVolumeStore::DeRegister(G4VPhysicalVolume* pVolume)
|
||||
{
|
||||
GetInstance()->remove(pVolume);
|
||||
}
|
||||
|
||||
// Return ptr to Store, setting if necessary
|
||||
G4PhysicalVolumeStore* G4PhysicalVolumeStore::GetInstance()
|
||||
{
|
||||
static G4PhysicalVolumeStore worldStore;
|
||||
if (!fgInstance)
|
||||
{
|
||||
fgInstance = &worldStore;
|
||||
}
|
||||
return fgInstance;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,49 @@
|
||||
// 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: G4SmartVoxelNode.cc,v 2.1 1998/11/11 11:38:22 japost Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// Class G4SmartVoxelNode
|
||||
//
|
||||
// Implementation
|
||||
//
|
||||
|
||||
#include "G4SmartVoxelNode.hh"
|
||||
|
||||
// Return true if contents equal
|
||||
//
|
||||
// Preconditions:
|
||||
//
|
||||
// Node contents were entered in the same order
|
||||
G4bool G4SmartVoxelNode::operator == (const G4SmartVoxelNode& v) const
|
||||
{
|
||||
G4int maxNode=GetNoContained();
|
||||
if (maxNode==v.GetNoContained())
|
||||
{
|
||||
for (G4int node=0;node<maxNode;node++)
|
||||
{
|
||||
if (GetVolume(node)!=v.GetVolume(node))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
// 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: G4SolidStore.cc,v 2.1 1998/07/12 02:55:40 urbi Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// G4SolidStore
|
||||
//
|
||||
// Implementation for singleton container
|
||||
//
|
||||
// History:
|
||||
// 10.07.95 P.Kent Initial version
|
||||
|
||||
#include "G4SolidStore.hh"
|
||||
#include "globals.hh"
|
||||
|
||||
// Protected constructor: Construct underlying container with
|
||||
// initial size of 100 entries
|
||||
G4SolidStore::G4SolidStore() : RWTPtrOrderedVector<G4VSolid>(100)
|
||||
{
|
||||
}
|
||||
|
||||
// Destructor
|
||||
G4SolidStore::~G4SolidStore()
|
||||
{
|
||||
while (!isEmpty()) delete first();
|
||||
}
|
||||
|
||||
// Static class variable
|
||||
G4SolidStore* G4SolidStore::fgInstance = 0;
|
||||
|
||||
// Add Solid to container
|
||||
void G4SolidStore::Register(G4VSolid* pSolid)
|
||||
{
|
||||
GetInstance()->insert(pSolid);
|
||||
}
|
||||
|
||||
// Remove Solid from container
|
||||
void G4SolidStore::DeRegister(G4VSolid* pSolid)
|
||||
{
|
||||
GetInstance()->remove(pSolid);
|
||||
}
|
||||
|
||||
// Return ptr to Store, setting if necessary
|
||||
G4SolidStore* G4SolidStore::GetInstance()
|
||||
{
|
||||
static G4SolidStore worldStore;
|
||||
if (!fgInstance)
|
||||
{
|
||||
fgInstance = &worldStore;
|
||||
}
|
||||
return fgInstance;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// 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: G4VPVParameterisation.cc,v 2.0 1998/07/02 16:57:32 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// Default implementations for Parameterisations that do not
|
||||
// parameterise solid and/or material
|
||||
#include "G4VPVParameterisation.hh"
|
||||
#include "G4VPhysicalVolume.hh"
|
||||
#include "G4LogicalVolume.hh"
|
||||
// #include "G4Material.hh"
|
||||
|
||||
G4VSolid* G4VPVParameterisation::ComputeSolid(const G4int,
|
||||
G4VPhysicalVolume *pPhysicalVol)
|
||||
{
|
||||
return pPhysicalVol->GetLogicalVolume()->GetSolid();
|
||||
}
|
||||
|
||||
G4Material* G4VPVParameterisation::ComputeMaterial(const G4int,
|
||||
G4VPhysicalVolume *pPhysicalVol)
|
||||
{
|
||||
return pPhysicalVol->GetLogicalVolume()->GetMaterial();
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
// 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: G4VPhysicalVolume.cc,v 2.1 1998/07/12 02:55:41 urbi Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
//
|
||||
// class G4VPhysicalVolume Implementation
|
||||
|
||||
#include "G4VPhysicalVolume.hh"
|
||||
|
||||
#include "G4PhysicalVolumeStore.hh"
|
||||
#include "G4LogicalVolume.hh"
|
||||
|
||||
// Constructor: init parameters and register in Store
|
||||
G4VPhysicalVolume::G4VPhysicalVolume(G4RotationMatrix *pRot,
|
||||
const G4ThreeVector &tlate,
|
||||
const G4String& pName,
|
||||
G4LogicalVolume* pLogical,
|
||||
G4VPhysicalVolume* pMother)
|
||||
{
|
||||
ftrans=tlate;
|
||||
frot=pRot;
|
||||
SetName(pName);
|
||||
SetLogicalVolume(pLogical);
|
||||
SetMother(pMother);
|
||||
if (pMother) pMother->GetLogicalVolume()->AddDaughter(this);
|
||||
G4PhysicalVolumeStore::Register(this);
|
||||
}
|
||||
|
||||
// Destructor - remove from Store
|
||||
G4VPhysicalVolume::~G4VPhysicalVolume()
|
||||
{
|
||||
G4PhysicalVolumeStore::DeRegister(this);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,308 @@
|
||||
// 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: G4VSolid.cc,v 2.1 1998/07/12 02:55:42 urbi Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// class G4VSolid
|
||||
//
|
||||
// Implementation for solid base class
|
||||
//
|
||||
//
|
||||
// History:
|
||||
// 10.07.95 P.Kent Added == operator, solid Store entry
|
||||
// 30.06.95 P.Kent
|
||||
|
||||
#include "G4VSolid.hh"
|
||||
#include "G4SolidStore.hh"
|
||||
|
||||
#include "G4VoxelLimits.hh"
|
||||
|
||||
// Constructor
|
||||
// - Copies name
|
||||
// - Add ourselves to solid Store
|
||||
G4VSolid::G4VSolid(const G4String& name) :
|
||||
fshapeName(name)
|
||||
{
|
||||
G4SolidStore::GetInstance()->append(this);
|
||||
}
|
||||
|
||||
// Destructor (virtual)
|
||||
// - Remove ourselves from solid Store
|
||||
G4VSolid::~G4VSolid()
|
||||
{
|
||||
G4SolidStore::GetInstance()->remove(this);
|
||||
}
|
||||
|
||||
// Returns name by value
|
||||
G4String G4VSolid::GetName() const
|
||||
{
|
||||
return fshapeName;
|
||||
}
|
||||
|
||||
void G4VSolid::SetName(const G4String& name)
|
||||
{
|
||||
fshapeName=name;
|
||||
}
|
||||
|
||||
// Throw exception if ComputeDimensions called for illegal derived class
|
||||
void G4VSolid::ComputeDimensions(G4VPVParameterisation* p,
|
||||
const G4int n,
|
||||
const G4VPhysicalVolume* pRep)
|
||||
{
|
||||
G4Exception("G4VSolid::ComputeDimensions called illegally: not overloaded by derived class");
|
||||
}
|
||||
|
||||
// Calculate the maximum and minimum extents of the convex polygon pPolygon
|
||||
// along the axis pAxis, within the limits pVoxelLimit
|
||||
void G4VSolid::CalculateClippedPolygonExtent(G4ThreeVectorList& pPolygon,
|
||||
const G4VoxelLimits& pVoxelLimit,
|
||||
const EAxis pAxis,
|
||||
G4double& pMin, G4double& pMax) const
|
||||
{
|
||||
G4int noLeft,i;
|
||||
G4double component;
|
||||
ClipPolygon(pPolygon,pVoxelLimit);
|
||||
noLeft=pPolygon.entries();
|
||||
if (noLeft)
|
||||
{
|
||||
for (i=0;i<noLeft;i++)
|
||||
{
|
||||
component=pPolygon(i).operator()(pAxis);
|
||||
if (component<pMin)
|
||||
{
|
||||
pMin=component;
|
||||
}
|
||||
else if (component>pMax)
|
||||
{
|
||||
pMax=component;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate the maximum and minimum extents of the polygon described
|
||||
// by the vertices: pSectionIndex->pSectionIndex+1->
|
||||
// pSectionIndex+2->pSectionIndex+3->pSectionIndex
|
||||
// in the List pVertices
|
||||
//
|
||||
// If the minimum is <pMin pMin is set to the new minimum
|
||||
// If the maximum is >pMax pMax is set to the new maximum
|
||||
//
|
||||
// No modifications are made to pVertices
|
||||
void G4VSolid::ClipCrossSection(G4ThreeVectorList* pVertices,
|
||||
const G4int pSectionIndex,
|
||||
const G4VoxelLimits& pVoxelLimit,
|
||||
const EAxis pAxis,
|
||||
G4double& pMin, G4double& pMax) const
|
||||
{
|
||||
|
||||
G4ThreeVectorList polygon;
|
||||
polygon.append(pVertices->operator()(pSectionIndex));
|
||||
polygon.append(pVertices->operator()(pSectionIndex+1));
|
||||
polygon.append(pVertices->operator()(pSectionIndex+2));
|
||||
polygon.append(pVertices->operator()(pSectionIndex+3));
|
||||
CalculateClippedPolygonExtent(polygon,pVoxelLimit,pAxis,pMin,pMax);
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate the maximum and minimum extents of the polygons
|
||||
// joining the CrossSections at pSectionIndex->pSectionIndex+3 and
|
||||
// pSectionIndex+4->pSectionIndex7
|
||||
//
|
||||
// in the List pVertices, within the boundaries of the voxel limits pVoxelLimit
|
||||
//
|
||||
// If the minimum is <pMin pMin is set to the new minimum
|
||||
// If the maximum is >pMax pMax is set to the new maximum
|
||||
//
|
||||
// No modifications are made to pVertices
|
||||
|
||||
void G4VSolid::ClipBetweenSections(G4ThreeVectorList* pVertices,
|
||||
const G4int pSectionIndex,
|
||||
const G4VoxelLimits& pVoxelLimit,
|
||||
const EAxis pAxis,
|
||||
G4double& pMin, G4double& pMax) const
|
||||
{
|
||||
G4ThreeVectorList polygon;
|
||||
polygon.append(pVertices->operator()(pSectionIndex));
|
||||
polygon.append(pVertices->operator()(pSectionIndex+4));
|
||||
polygon.append(pVertices->operator()(pSectionIndex+5));
|
||||
polygon.append(pVertices->operator()(pSectionIndex+1));
|
||||
CalculateClippedPolygonExtent(polygon,pVoxelLimit,pAxis,pMin,pMax);
|
||||
polygon.clear();
|
||||
polygon.append(pVertices->operator()(pSectionIndex+1));
|
||||
polygon.append(pVertices->operator()(pSectionIndex+5));
|
||||
polygon.append(pVertices->operator()(pSectionIndex+6));
|
||||
polygon.append(pVertices->operator()(pSectionIndex+2));
|
||||
CalculateClippedPolygonExtent(polygon,pVoxelLimit,pAxis,pMin,pMax);
|
||||
polygon.clear();
|
||||
polygon.append(pVertices->operator()(pSectionIndex+2));
|
||||
polygon.append(pVertices->operator()(pSectionIndex+6));
|
||||
polygon.append(pVertices->operator()(pSectionIndex+7));
|
||||
polygon.append(pVertices->operator()(pSectionIndex+3));
|
||||
CalculateClippedPolygonExtent(polygon,pVoxelLimit,pAxis,pMin,pMax);
|
||||
polygon.clear();
|
||||
polygon.append(pVertices->operator()(pSectionIndex+3));
|
||||
polygon.append(pVertices->operator()(pSectionIndex+7));
|
||||
polygon.append(pVertices->operator()(pSectionIndex+4));
|
||||
polygon.append(pVertices->operator()(pSectionIndex));
|
||||
CalculateClippedPolygonExtent(polygon,pVoxelLimit,pAxis,pMin,pMax);
|
||||
return;
|
||||
}
|
||||
|
||||
// Clip the convex polygon described by the vertices at
|
||||
// pSectionIndex ->pSectionIndex+3 within pVertices to the limits pVoxelLimit
|
||||
//
|
||||
// Set pMin to the smallest
|
||||
//
|
||||
// Calculate the extent of the polygon along pAxis, when clipped to the
|
||||
// limits pVoxelLimit. If the polygon exists after clippin, set pMin to
|
||||
// the polygon's minimum extent along the axis if <pMin, and set pMax to
|
||||
// the polygon's maximum extent along the axis if >pMax.
|
||||
//
|
||||
// The polygon is described by a set of vectors, where each vector represents
|
||||
// a vertex, so that the polygon is described by the vertex sequence:
|
||||
// 0th->1st 1st->2nd 2nd->... nth->0th
|
||||
//
|
||||
// Modifications to the polygon are made
|
||||
//
|
||||
// NOTE: Execessive copying during clipping
|
||||
void G4VSolid::ClipPolygon(G4ThreeVectorList& pPolygon,
|
||||
const G4VoxelLimits& pVoxelLimit) const
|
||||
{
|
||||
G4ThreeVectorList outputPolygon;
|
||||
if (pVoxelLimit.IsLimited())
|
||||
{
|
||||
if (pVoxelLimit.IsXLimited())
|
||||
{
|
||||
G4VoxelLimits simpleLimit1;
|
||||
simpleLimit1.AddLimit(kXAxis,pVoxelLimit.GetMinXExtent(),kInfinity);
|
||||
ClipPolygonToSimpleLimits(pPolygon,outputPolygon,
|
||||
simpleLimit1);
|
||||
pPolygon.clear();
|
||||
if (!outputPolygon.entries())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
G4VoxelLimits simpleLimit2;
|
||||
simpleLimit2.AddLimit(kXAxis,-kInfinity,pVoxelLimit.GetMaxXExtent());
|
||||
ClipPolygonToSimpleLimits(outputPolygon,pPolygon,simpleLimit2);
|
||||
if (!pPolygon.entries())
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
outputPolygon.clear();
|
||||
}
|
||||
}
|
||||
|
||||
if (pVoxelLimit.IsYLimited())
|
||||
{
|
||||
G4VoxelLimits simpleLimit1;
|
||||
simpleLimit1.AddLimit(kYAxis,pVoxelLimit.GetMinYExtent(),kInfinity);
|
||||
ClipPolygonToSimpleLimits(pPolygon,outputPolygon,
|
||||
simpleLimit1);
|
||||
// Must always clear pPolygon - for clip to simpleLimit2 and incase of
|
||||
// early exit
|
||||
pPolygon.clear();
|
||||
if (!outputPolygon.entries())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
G4VoxelLimits simpleLimit2;
|
||||
simpleLimit2.AddLimit(kYAxis,-kInfinity,pVoxelLimit.GetMaxYExtent());
|
||||
ClipPolygonToSimpleLimits(outputPolygon,pPolygon,simpleLimit2);
|
||||
if (!pPolygon.entries())
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
outputPolygon.clear();
|
||||
}
|
||||
}
|
||||
|
||||
if (pVoxelLimit.IsZLimited())
|
||||
{
|
||||
G4VoxelLimits simpleLimit1;
|
||||
simpleLimit1.AddLimit(kZAxis,pVoxelLimit.GetMinZExtent(),kInfinity);
|
||||
ClipPolygonToSimpleLimits(pPolygon,outputPolygon,
|
||||
simpleLimit1);
|
||||
// Must always clear pPolygon - for clip to simpleLimit2 and incase of
|
||||
// early exit
|
||||
pPolygon.clear();
|
||||
if (!outputPolygon.entries())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
G4VoxelLimits simpleLimit2;
|
||||
simpleLimit2.AddLimit(kZAxis,-kInfinity,pVoxelLimit.GetMaxZExtent());
|
||||
ClipPolygonToSimpleLimits(outputPolygon,pPolygon,simpleLimit2);
|
||||
|
||||
// Return after final clip - no cleanup
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// pVoxelLimits must be only limited along one axis, and either the maximum
|
||||
// along the axis must be +kInfinity, or the minimum -kInfinity
|
||||
void G4VSolid::ClipPolygonToSimpleLimits(G4ThreeVectorList& pPolygon,
|
||||
G4ThreeVectorList& outputPolygon,
|
||||
const G4VoxelLimits& pVoxelLimit) const
|
||||
{
|
||||
G4int i;
|
||||
G4int noVertices=pPolygon.entries();
|
||||
G4ThreeVector vEnd,vStart;
|
||||
for (i=0;i<noVertices;i++)
|
||||
{
|
||||
vStart=pPolygon(i);
|
||||
if (i==noVertices-1)
|
||||
{
|
||||
vEnd=pPolygon(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
vEnd=pPolygon(i+1);
|
||||
}
|
||||
|
||||
if (pVoxelLimit.Inside(vStart))
|
||||
{
|
||||
if (pVoxelLimit.Inside(vEnd))
|
||||
{
|
||||
// vStart and vEnd inside -> output end point
|
||||
outputPolygon.insert(vEnd);
|
||||
}
|
||||
else
|
||||
{
|
||||
// vStart inside, vEnd outside -> output crossing point
|
||||
pVoxelLimit.ClipToLimits(vStart,vEnd);
|
||||
outputPolygon.insert(vEnd);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pVoxelLimit.Inside(vEnd))
|
||||
{
|
||||
// vStart outside, vEnd inside -> output inside section
|
||||
pVoxelLimit.ClipToLimits(vStart,vEnd);
|
||||
outputPolygon.insert(vStart);
|
||||
outputPolygon.insert(vEnd);
|
||||
}
|
||||
else
|
||||
// Both point outside -> no output
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,315 @@
|
||||
// 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: G4VoxelLimits.cc,v 2.1 1998/11/11 11:38:22 japost Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// class G4VoxelLimits
|
||||
//
|
||||
// Implementation
|
||||
//
|
||||
// History:
|
||||
// 13.07.95 P.Kent Initial version
|
||||
|
||||
#include "G4VoxelLimits.hh"
|
||||
|
||||
#include "G4ios.hh"
|
||||
|
||||
// Further restrict limits
|
||||
// No checks for illegal restrictions
|
||||
void G4VoxelLimits::AddLimit(const EAxis pAxis, const G4double pMin,
|
||||
const G4double pMax)
|
||||
{
|
||||
if (pAxis==kXAxis)
|
||||
{
|
||||
if (pMin>fxAxisMin)
|
||||
{
|
||||
fxAxisMin=pMin;
|
||||
}
|
||||
if (pMax<fxAxisMax)
|
||||
{
|
||||
fxAxisMax=pMax;
|
||||
}
|
||||
}
|
||||
else if (pAxis==kYAxis)
|
||||
{
|
||||
if (pMin>fyAxisMin)
|
||||
{
|
||||
fyAxisMin=pMin;
|
||||
}
|
||||
if (pMax<fyAxisMax)
|
||||
{
|
||||
fyAxisMax=pMax;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(pAxis==kZAxis);
|
||||
if (pMin>fzAxisMin)
|
||||
{
|
||||
fzAxisMin=pMin;
|
||||
}
|
||||
if (pMax<fzAxisMax)
|
||||
{
|
||||
fzAxisMax=pMax;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ClipToLimits
|
||||
//
|
||||
// Clip the line segment pStart->pEnd to the volume described by the
|
||||
// current limits. Return true if the line remains after clipping,
|
||||
// else false, and leave the vectors in an undefined state.
|
||||
//
|
||||
// Process:
|
||||
//
|
||||
// Use Cohen-Sutherland clipping in 3D
|
||||
// [Fundamentals of Interactive Computer Graphics,Foley & Van Dam]
|
||||
//
|
||||
G4bool G4VoxelLimits::ClipToLimits(G4ThreeVector& pStart,
|
||||
G4ThreeVector& pEnd) const
|
||||
{
|
||||
G4int sCode,eCode;
|
||||
G4bool remainsAfterClip;
|
||||
|
||||
// Determine if line is trivially inside (both outcodes==0) or outside
|
||||
// (logical AND of outcodes !=0)
|
||||
sCode=OutCode(pStart);
|
||||
eCode=OutCode(pEnd);
|
||||
|
||||
if (sCode&eCode)
|
||||
{
|
||||
// Trivially outside, no intersection with region
|
||||
remainsAfterClip=false;
|
||||
}
|
||||
else if (sCode==0&&eCode==0)
|
||||
{
|
||||
// Trivially inside, no intersections
|
||||
remainsAfterClip=true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// Line segment *may* cut volume boundaries
|
||||
// At most, one end point is inside
|
||||
G4double x1,y1,z1,x2,y2,z2;
|
||||
x1=pStart.x();
|
||||
y1=pStart.y();
|
||||
z1=pStart.z();
|
||||
x2=pEnd.x();
|
||||
y2=pEnd.y();
|
||||
z2=pEnd.z();
|
||||
|
||||
do
|
||||
{
|
||||
|
||||
// Copy vectors to work variables x1-z1,x2-z2
|
||||
// Ensure x1-z1 lies outside volume, swapping vectors and outcodes
|
||||
// if necessary
|
||||
|
||||
if (sCode)
|
||||
{
|
||||
|
||||
if (sCode&0x01)
|
||||
{
|
||||
// Clip against fxAxisMin
|
||||
z1+=(fxAxisMin-x1)*(z2-z1)/(x2-x1);
|
||||
y1+=(fxAxisMin-x1)*(y2-y1)/(x2-x1);
|
||||
x1=fxAxisMin;
|
||||
}
|
||||
else if (sCode&0x02)
|
||||
{
|
||||
// Clip against fxAxisMax
|
||||
z1+=(fxAxisMax-x1)*(z2-z1)/(x2-x1);
|
||||
y1+=(fxAxisMax-x1)*(y2-y1)/(x2-x1);
|
||||
x1=fxAxisMax;
|
||||
}
|
||||
else if (sCode&0x04)
|
||||
{
|
||||
// Clip against fyAxisMin
|
||||
x1+=(fyAxisMin-y1)*(x2-x1)/(y2-y1);
|
||||
z1+=(fyAxisMin-y1)*(z2-z1)/(y2-y1);
|
||||
y1=fyAxisMin;
|
||||
}
|
||||
else if (sCode&0x08)
|
||||
{
|
||||
// Clip against fyAxisMax
|
||||
x1+=(fyAxisMax-y1)*(x2-x1)/(y2-y1);
|
||||
z1+=(fyAxisMax-y1)*(z2-z1)/(y2-y1);
|
||||
y1=fyAxisMax;
|
||||
}
|
||||
else if (sCode&0x10)
|
||||
{
|
||||
// Clip against fzAxisMin
|
||||
x1+=(fzAxisMin-z1)*(x2-x1)/(z2-z1);
|
||||
y1+=(fzAxisMin-z1)*(y2-y1)/(z2-z1);
|
||||
z1=fzAxisMin;
|
||||
}
|
||||
else if (sCode&0x20)
|
||||
{
|
||||
// Clip against fzAxisMax
|
||||
x1+=(fzAxisMax-z1)*(x2-x1)/(z2-z1);
|
||||
y1+=(fzAxisMax-z1)*(y2-y1)/(z2-z1);
|
||||
z1=fzAxisMax;
|
||||
}
|
||||
}
|
||||
|
||||
if (eCode)
|
||||
{
|
||||
// Clip 2nd end: repeat of 1st, but 1<>2
|
||||
if (eCode&0x01)
|
||||
{
|
||||
// Clip against fxAxisMin
|
||||
z2+=(fxAxisMin-x2)*(z1-z2)/(x1-x2);
|
||||
y2+=(fxAxisMin-x2)*(y1-y2)/(x1-x2);
|
||||
x2=fxAxisMin;
|
||||
}
|
||||
else if (eCode&0x02)
|
||||
{
|
||||
// Clip against fxAxisMax
|
||||
z2+=(fxAxisMax-x2)*(z1-z2)/(x1-x2);
|
||||
y2+=(fxAxisMax-x2)*(y1-y2)/(x1-x2);
|
||||
x2=fxAxisMax;
|
||||
}
|
||||
else if (eCode&0x04)
|
||||
{
|
||||
// Clip against fyAxisMin
|
||||
x2+=(fyAxisMin-y2)*(x1-x2)/(y1-y2);
|
||||
z2+=(fyAxisMin-y2)*(z1-z2)/(y1-y2);
|
||||
y2=fyAxisMin;
|
||||
}
|
||||
else if (eCode&0x08)
|
||||
{
|
||||
// Clip against fyAxisMax
|
||||
x2+=(fyAxisMax-y2)*(x1-x2)/(y1-y2);
|
||||
z2+=(fyAxisMax-y2)*(z1-z2)/(y1-y2);
|
||||
y2=fyAxisMax;
|
||||
}
|
||||
else if (eCode&0x10)
|
||||
{
|
||||
// Clip against fzAxisMin
|
||||
x2+=(fzAxisMin-z2)*(x1-x2)/(z1-z2);
|
||||
y2+=(fzAxisMin-z2)*(y1-y2)/(z1-z2);
|
||||
z2=fzAxisMin;
|
||||
}
|
||||
else if (eCode&0x20)
|
||||
{
|
||||
// Clip against fzAxisMax
|
||||
x2+=(fzAxisMax-z2)*(x1-x2)/(z1-z2);
|
||||
y2+=(fzAxisMax-z2)*(y1-y2)/(z1-z2);
|
||||
z2=fzAxisMax;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pStart=G4ThreeVector(x1,y1,z1);
|
||||
pEnd=G4ThreeVector(x2,y2,z2);
|
||||
sCode=OutCode(pStart);
|
||||
eCode=OutCode(pEnd);
|
||||
} while (sCode!=eCode);
|
||||
|
||||
if (sCode==0&&eCode==0)
|
||||
{
|
||||
remainsAfterClip=true;
|
||||
}
|
||||
else
|
||||
{
|
||||
remainsAfterClip=false;
|
||||
}
|
||||
}
|
||||
return remainsAfterClip;
|
||||
}
|
||||
|
||||
// Calculate the `outcode' for the specified vector:
|
||||
// The following bits are set:
|
||||
// 0 pVec.x()<fxAxisMin && IsXLimited()
|
||||
// 1 pVec.x()>fxAxisMax && IsXLimited()
|
||||
// 2 pVec.y()<fyAxisMin && IsYLimited()
|
||||
// 3 pVec.y()>fyAxisMax && IsYLimited()
|
||||
// 4 pVec.z()<fzAxisMin && IsZLimited()
|
||||
// 5 pVec.z()>fzAxisMax && IsZLimited()
|
||||
|
||||
G4int G4VoxelLimits::OutCode(const G4ThreeVector& pVec) const
|
||||
{
|
||||
G4int code=0; // The outcode
|
||||
if (IsXLimited())
|
||||
{
|
||||
if (pVec.x()<fxAxisMin)
|
||||
{
|
||||
code|=0x01;
|
||||
}
|
||||
if (pVec.x()>fxAxisMax)
|
||||
{
|
||||
code|=0x02;
|
||||
}
|
||||
}
|
||||
if (IsYLimited())
|
||||
{
|
||||
if (pVec.y()<fyAxisMin)
|
||||
{
|
||||
code|=0x04;
|
||||
}
|
||||
if (pVec.y()>fyAxisMax)
|
||||
{
|
||||
code|=0x08;
|
||||
}
|
||||
}
|
||||
if (IsZLimited())
|
||||
{
|
||||
if (pVec.z()<fzAxisMin)
|
||||
{
|
||||
code|=0x10;
|
||||
}
|
||||
if (pVec.z()>fzAxisMax)
|
||||
{
|
||||
code|=0x20;
|
||||
}
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
ostream& operator << (ostream& os, const G4VoxelLimits& pLim)
|
||||
{
|
||||
os << "{";
|
||||
if (pLim.IsXLimited())
|
||||
{
|
||||
os << "(" << pLim.GetMinXExtent()
|
||||
<< "," << pLim.GetMaxXExtent() << ") ";
|
||||
}
|
||||
else
|
||||
{
|
||||
os << "(-,-) ";
|
||||
}
|
||||
if (pLim.IsYLimited())
|
||||
{
|
||||
os << "(" << pLim.GetMinYExtent()
|
||||
<< "," << pLim.GetMaxYExtent() << ") ";
|
||||
}
|
||||
else
|
||||
{
|
||||
os << "(-,-) ";
|
||||
}
|
||||
if (pLim.IsZLimited())
|
||||
{
|
||||
os << "(" << pLim.GetMinZExtent()
|
||||
<< "," << pLim.GetMaxZExtent() << ")";
|
||||
}
|
||||
else
|
||||
{
|
||||
os << "(-,-)";
|
||||
}
|
||||
os << "}";
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user