| [233] | 1 | // From Geant4/source/visualization/modeling/G4PhysicalVolumeModel.
|
|---|
| 2 |
|
|---|
| 3 | // this :
|
|---|
| 4 | #include <G4Lab/GeometryVisitor.h>
|
|---|
| 5 |
|
|---|
| 6 | // Geant4 :
|
|---|
| 7 | #include <G4VPhysicalVolume.hh>
|
|---|
| 8 | #include <G4LogicalVolume.hh>
|
|---|
| 9 | #include <G4VPVParameterisation.hh>
|
|---|
| 10 | #include <G4VSolid.hh>
|
|---|
| 11 | #include <G4Material.hh>
|
|---|
| 12 |
|
|---|
| 13 | //////////////////////////////////////////////////////////////////////////////
|
|---|
| 14 | G4Lab::GeometryVisitor::GeometryVisitor(
|
|---|
| 15 | )
|
|---|
| 16 | :fIndex(0)
|
|---|
| 17 | //////////////////////////////////////////////////////////////////////////////
|
|---|
| 18 | //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
|
|---|
| 19 | {
|
|---|
| 20 | }
|
|---|
| 21 | //////////////////////////////////////////////////////////////////////////////
|
|---|
| 22 | G4Lab::GeometryVisitor::~GeometryVisitor(
|
|---|
| 23 | )
|
|---|
| 24 | //////////////////////////////////////////////////////////////////////////////
|
|---|
| 25 | //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
|
|---|
| 26 | {
|
|---|
| 27 | }
|
|---|
| 28 | //////////////////////////////////////////////////////////////////////////////
|
|---|
| 29 | bool G4Lab::GeometryVisitor::visit(
|
|---|
| 30 | G4VPhysicalVolume* aPV
|
|---|
| 31 | ,int aDepth
|
|---|
| 32 | ,const G4Transform3D& aTransform
|
|---|
| 33 | ,IVisitedVolume* aVisitedVolume
|
|---|
| 34 | )
|
|---|
| 35 | //////////////////////////////////////////////////////////////////////////////
|
|---|
| 36 | // Visits geometry structure to a given depth (aDepth), starting
|
|---|
| 37 | // at given physical volume with given starting transformation and
|
|---|
| 38 | // describes volumes to the scene handler.
|
|---|
| 39 | // aDepth < 0 (default) implies full visit.
|
|---|
| 40 | // aTransform is the Accumulated Transformation.
|
|---|
| 41 | //
|
|---|
| 42 | // Do not hold unnecessary variables on the stack during traversal.
|
|---|
| 43 | //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
|
|---|
| 44 | {
|
|---|
| 45 | if (aPV -> IsReplicated()) {
|
|---|
| 46 | if(aPV->GetParameterisation()) { // Parametrised volume.
|
|---|
| 47 | G4VPVParameterisation* params = aPV->GetParameterisation();
|
|---|
| 48 | G4int nReplicas; // Only this one is used latter.
|
|---|
| 49 | {EAxis axis;
|
|---|
| 50 | G4double width;
|
|---|
| 51 | G4double offset;
|
|---|
| 52 | G4bool consuming;
|
|---|
| 53 | aPV->GetReplicationData(axis,nReplicas,width,offset,consuming);}
|
|---|
| 54 | for (int n = 0; n < nReplicas; n++) {
|
|---|
| 55 | G4VSolid* solid = params -> ComputeSolid (n, aPV);
|
|---|
| 56 | G4Material* material = params -> ComputeMaterial (n, aPV);
|
|---|
| 57 | params -> ComputeTransformation (n, aPV);
|
|---|
| 58 | solid -> ComputeDimensions (params, n, aPV);
|
|---|
| 59 | aPV -> SetCopyNo (n);
|
|---|
| 60 | if(!descend(aPV,aDepth,solid,material,aTransform,aVisitedVolume))
|
|---|
| 61 | return false;
|
|---|
| 62 | }
|
|---|
| 63 | } else {
|
|---|
| 64 | // Plain replicated volume. From geometry_guide.txt...
|
|---|
| 65 | // The replica's positions are claculated by means of a linear formula.
|
|---|
| 66 | // Replication may occur along:
|
|---|
| 67 | //
|
|---|
| 68 | // o Cartesian axes (kXAxis,kYAxis,kZAxis)
|
|---|
| 69 | //
|
|---|
| 70 | // The replications, of specified width have coordinates of
|
|---|
| 71 | // form (-width*(nReplicas-1)*0.5+n*width,0,0) where n=0.. nReplicas-1
|
|---|
| 72 | // for the case of kXAxis, and are unrotated.
|
|---|
| 73 | //
|
|---|
| 74 | // o Radial axis (cylindrical polar) (kRho)
|
|---|
| 75 | //
|
|---|
| 76 | // The replications are cons/tubs sections, centred on the origin
|
|---|
| 77 | // and are unrotated.
|
|---|
| 78 | // They have radii of width*n+offset to width*(n+1)+offset
|
|---|
| 79 | // where n=0..nReplicas-1
|
|---|
| 80 | //
|
|---|
| 81 | // o Phi axis (cylindrical polar) (kPhi)
|
|---|
| 82 | // The replications are `phi sections' or wedges, and of cons/tubs form
|
|---|
| 83 | // They have phi of offset+n*width to offset+(n+1)*width where
|
|---|
| 84 | // n=0..nReplicas-1
|
|---|
| 85 | //
|
|---|
| 86 | EAxis axis;
|
|---|
| 87 | G4int nReplicas;
|
|---|
| 88 | G4double width;
|
|---|
| 89 | G4double offset;
|
|---|
| 90 | G4bool consuming;
|
|---|
| 91 | aPV->GetReplicationData(axis,nReplicas,width,offset,consuming);
|
|---|
| 92 | for (int n = 0; n < nReplicas; n++) {
|
|---|
| 93 | switch(axis) {
|
|---|
| 94 | default:
|
|---|
| 95 | case kXAxis:
|
|---|
| 96 | aPV->SetTranslation(G4ThreeVector
|
|---|
| 97 | (-width*(nReplicas-1)*0.5+n*width,0,0));
|
|---|
| 98 | aPV->SetRotation(0);
|
|---|
| 99 | aPV->SetCopyNo(n);
|
|---|
| 100 | if(!descend(aPV,aDepth,
|
|---|
| 101 | aPV->GetLogicalVolume()->GetSolid(),
|
|---|
| 102 | aPV->GetLogicalVolume()->GetMaterial(),
|
|---|
| 103 | aTransform,aVisitedVolume)) return false;
|
|---|
| 104 | break;
|
|---|
| 105 | case kYAxis:
|
|---|
| 106 | aPV->SetTranslation(G4ThreeVector
|
|---|
| 107 | (0,-width*(nReplicas-1)*0.5+n*width,0));
|
|---|
| 108 | aPV->SetRotation(0);
|
|---|
| 109 | aPV->SetCopyNo(n);
|
|---|
| 110 | if(!descend(aPV,aDepth,
|
|---|
| 111 | aPV->GetLogicalVolume()->GetSolid(),
|
|---|
| 112 | aPV->GetLogicalVolume()->GetMaterial(),
|
|---|
| 113 | aTransform,aVisitedVolume)) return false;
|
|---|
| 114 | break;
|
|---|
| 115 | case kZAxis:
|
|---|
| 116 | aPV->SetTranslation(G4ThreeVector
|
|---|
| 117 | (0,0,-width*(nReplicas-1)*0.5+n*width));
|
|---|
| 118 | aPV->SetRotation(0);
|
|---|
| 119 | aPV->SetCopyNo(n);
|
|---|
| 120 | if(!descend(aPV,aDepth,
|
|---|
| 121 | aPV->GetLogicalVolume()->GetSolid(),
|
|---|
| 122 | aPV->GetLogicalVolume()->GetMaterial(),
|
|---|
| 123 | aTransform,aVisitedVolume)) return false;
|
|---|
| 124 | break;
|
|---|
| 125 | case kRho:
|
|---|
| 126 | //Lib::Out::putL("GeometryVisitor::visit: WARNING:");
|
|---|
| 127 | //Lib::Out::putL(" built-in replicated volumes replicated");
|
|---|
| 128 | //Lib::Out::putL(" in radius are not yet properly visualizable.");
|
|---|
| 129 | aPV->SetTranslation(G4ThreeVector(0,0,0));
|
|---|
| 130 | aPV->SetRotation(0);
|
|---|
| 131 | aPV->SetCopyNo(n);
|
|---|
| 132 | if(!descend(aPV,aDepth,
|
|---|
| 133 | aPV->GetLogicalVolume()->GetSolid(),
|
|---|
| 134 | aPV->GetLogicalVolume()->GetMaterial(),
|
|---|
| 135 | aTransform,aVisitedVolume)) return false;
|
|---|
| 136 | break;
|
|---|
| 137 | case kPhi:
|
|---|
| 138 | {G4RotationMatrix rotation;
|
|---|
| 139 | rotation.rotateZ(-(offset+n*width));
|
|---|
| 140 | // Minus Sign because for the physical volume we need the
|
|---|
| 141 | // coordinate system rotation.
|
|---|
| 142 | aPV->SetTranslation(G4ThreeVector(0,0,0));
|
|---|
| 143 | aPV->SetRotation(&rotation);
|
|---|
| 144 | aPV->SetCopyNo(n);
|
|---|
| 145 | if(!descend(aPV,aDepth,
|
|---|
| 146 | aPV->GetLogicalVolume()->GetSolid(),
|
|---|
| 147 | aPV->GetLogicalVolume()->GetMaterial(),
|
|---|
| 148 | aTransform,aVisitedVolume)) return false;
|
|---|
| 149 | }break;
|
|---|
| 150 | }
|
|---|
| 151 | }
|
|---|
| 152 | }
|
|---|
| 153 | } else {
|
|---|
| 154 | if(!descend(aPV,aDepth,
|
|---|
| 155 | aPV->GetLogicalVolume()->GetSolid(),
|
|---|
| 156 | aPV->GetLogicalVolume()->GetMaterial(),
|
|---|
| 157 | aTransform,aVisitedVolume)) return false;
|
|---|
| 158 | }
|
|---|
| 159 | return true;
|
|---|
| 160 | }
|
|---|
| 161 | //////////////////////////////////////////////////////////////////////////////
|
|---|
| 162 | bool G4Lab::GeometryVisitor::descend(
|
|---|
| 163 | G4VPhysicalVolume* aPV
|
|---|
| 164 | ,int aDepth
|
|---|
| 165 | ,G4VSolid* aSolid
|
|---|
| 166 | ,G4Material* aMaterial
|
|---|
| 167 | ,const G4Transform3D& aTransform
|
|---|
| 168 | ,IVisitedVolume* aVisitedVolume
|
|---|
| 169 | )
|
|---|
| 170 | //////////////////////////////////////////////////////////////////////////////
|
|---|
| 171 | // Do not hold unnecessary variables on the stack during traversal.
|
|---|
| 172 | //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
|
|---|
| 173 | {
|
|---|
| 174 | G4Transform3D* transform =
|
|---|
| 175 | new G4Transform3D(*(aPV->GetObjectRotation()),aPV->GetTranslation());
|
|---|
| 176 | G4Transform3D newTransform = aTransform * (*transform);
|
|---|
| 177 | delete transform;
|
|---|
| 178 |
|
|---|
| 179 | IVisitedVolume::Status status =
|
|---|
| 180 | aVisitedVolume->beginVolume(aPV,aSolid,aMaterial,newTransform,fIndex);
|
|---|
| 181 |
|
|---|
| 182 | bool retval = true;
|
|---|
| 183 |
|
|---|
| 184 | if(status==IVisitedVolume::STOP) {
|
|---|
| 185 | retval = false;
|
|---|
| 186 | } else {
|
|---|
| 187 | if(status==IVisitedVolume::SIBLING) {
|
|---|
| 188 | } else { //DAUGHTERS
|
|---|
| 189 | if (aDepth) { // Descent daughters :
|
|---|
| 190 | fIndex ++;
|
|---|
| 191 | int nDaughters = aPV->GetLogicalVolume()->GetNoDaughters();
|
|---|
| 192 | aVisitedVolume->beginDaughters(aPV,nDaughters);
|
|---|
| 193 | for (int iDaughter = 0; iDaughter < nDaughters; iDaughter++) {
|
|---|
| 194 | if(!visit(aPV->GetLogicalVolume()->GetDaughter(iDaughter),
|
|---|
| 195 | aDepth-1,newTransform,aVisitedVolume)) {
|
|---|
| 196 | retval = false;
|
|---|
| 197 | break;
|
|---|
| 198 | }
|
|---|
| 199 | }
|
|---|
| 200 | aVisitedVolume->endDaughters(aPV,nDaughters);
|
|---|
| 201 | fIndex --;
|
|---|
| 202 | }
|
|---|
| 203 | }
|
|---|
| 204 | }
|
|---|
| 205 |
|
|---|
| 206 | aVisitedVolume->endVolume(aPV);
|
|---|
| 207 | return retval;
|
|---|
| 208 | }
|
|---|
| 209 |
|
|---|