// From Geant4/source/visualization/modeling/G4PhysicalVolumeModel. // this : #include // Geant4 : #include #include #include #include #include ////////////////////////////////////////////////////////////////////////////// G4Lab::GeometryVisitor::GeometryVisitor( ) :fIndex(0) ////////////////////////////////////////////////////////////////////////////// //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// { } ////////////////////////////////////////////////////////////////////////////// G4Lab::GeometryVisitor::~GeometryVisitor( ) ////////////////////////////////////////////////////////////////////////////// //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// { } ////////////////////////////////////////////////////////////////////////////// bool G4Lab::GeometryVisitor::visit( G4VPhysicalVolume* aPV ,int aDepth ,const G4Transform3D& aTransform ,IVisitedVolume* aVisitedVolume ) ////////////////////////////////////////////////////////////////////////////// // Visits geometry structure to a given depth (aDepth), starting // at given physical volume with given starting transformation and // describes volumes to the scene handler. // aDepth < 0 (default) implies full visit. // aTransform is the Accumulated Transformation. // // Do not hold unnecessary variables on the stack during traversal. //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// { if (aPV -> IsReplicated()) { if(aPV->GetParameterisation()) { // Parametrised volume. G4VPVParameterisation* params = aPV->GetParameterisation(); G4int nReplicas; // Only this one is used latter. {EAxis axis; G4double width; G4double offset; G4bool consuming; aPV->GetReplicationData(axis,nReplicas,width,offset,consuming);} for (int n = 0; n < nReplicas; n++) { G4VSolid* solid = params -> ComputeSolid (n, aPV); G4Material* material = params -> ComputeMaterial (n, aPV); params -> ComputeTransformation (n, aPV); solid -> ComputeDimensions (params, n, aPV); aPV -> SetCopyNo (n); if(!descend(aPV,aDepth,solid,material,aTransform,aVisitedVolume)) return false; } } 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 // EAxis axis; G4int nReplicas; G4double width; G4double offset; G4bool consuming; aPV->GetReplicationData(axis,nReplicas,width,offset,consuming); for (int n = 0; n < nReplicas; n++) { switch(axis) { default: case kXAxis: aPV->SetTranslation(G4ThreeVector (-width*(nReplicas-1)*0.5+n*width,0,0)); aPV->SetRotation(0); aPV->SetCopyNo(n); if(!descend(aPV,aDepth, aPV->GetLogicalVolume()->GetSolid(), aPV->GetLogicalVolume()->GetMaterial(), aTransform,aVisitedVolume)) return false; break; case kYAxis: aPV->SetTranslation(G4ThreeVector (0,-width*(nReplicas-1)*0.5+n*width,0)); aPV->SetRotation(0); aPV->SetCopyNo(n); if(!descend(aPV,aDepth, aPV->GetLogicalVolume()->GetSolid(), aPV->GetLogicalVolume()->GetMaterial(), aTransform,aVisitedVolume)) return false; break; case kZAxis: aPV->SetTranslation(G4ThreeVector (0,0,-width*(nReplicas-1)*0.5+n*width)); aPV->SetRotation(0); aPV->SetCopyNo(n); if(!descend(aPV,aDepth, aPV->GetLogicalVolume()->GetSolid(), aPV->GetLogicalVolume()->GetMaterial(), aTransform,aVisitedVolume)) return false; break; case kRho: //Lib::Out::putL("GeometryVisitor::visit: WARNING:"); //Lib::Out::putL(" built-in replicated volumes replicated"); //Lib::Out::putL(" in radius are not yet properly visualizable."); aPV->SetTranslation(G4ThreeVector(0,0,0)); aPV->SetRotation(0); aPV->SetCopyNo(n); if(!descend(aPV,aDepth, aPV->GetLogicalVolume()->GetSolid(), aPV->GetLogicalVolume()->GetMaterial(), aTransform,aVisitedVolume)) return false; break; case kPhi: {G4RotationMatrix rotation; rotation.rotateZ(-(offset+n*width)); // Minus Sign because for the physical volume we need the // coordinate system rotation. aPV->SetTranslation(G4ThreeVector(0,0,0)); aPV->SetRotation(&rotation); aPV->SetCopyNo(n); if(!descend(aPV,aDepth, aPV->GetLogicalVolume()->GetSolid(), aPV->GetLogicalVolume()->GetMaterial(), aTransform,aVisitedVolume)) return false; }break; } } } } else { if(!descend(aPV,aDepth, aPV->GetLogicalVolume()->GetSolid(), aPV->GetLogicalVolume()->GetMaterial(), aTransform,aVisitedVolume)) return false; } return true; } ////////////////////////////////////////////////////////////////////////////// bool G4Lab::GeometryVisitor::descend( G4VPhysicalVolume* aPV ,int aDepth ,G4VSolid* aSolid ,G4Material* aMaterial ,const G4Transform3D& aTransform ,IVisitedVolume* aVisitedVolume ) ////////////////////////////////////////////////////////////////////////////// // Do not hold unnecessary variables on the stack during traversal. //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// { G4Transform3D* transform = new G4Transform3D(*(aPV->GetObjectRotation()),aPV->GetTranslation()); G4Transform3D newTransform = aTransform * (*transform); delete transform; IVisitedVolume::Status status = aVisitedVolume->beginVolume(aPV,aSolid,aMaterial,newTransform,fIndex); bool retval = true; if(status==IVisitedVolume::STOP) { retval = false; } else { if(status==IVisitedVolume::SIBLING) { } else { //DAUGHTERS if (aDepth) { // Descent daughters : fIndex ++; int nDaughters = aPV->GetLogicalVolume()->GetNoDaughters(); aVisitedVolume->beginDaughters(aPV,nDaughters); for (int iDaughter = 0; iDaughter < nDaughters; iDaughter++) { if(!visit(aPV->GetLogicalVolume()->GetDaughter(iDaughter), aDepth-1,newTransform,aVisitedVolume)) { retval = false; break; } } aVisitedVolume->endDaughters(aPV,nDaughters); fIndex --; } } } aVisitedVolume->endVolume(aPV); return retval; }