source: snovis/trunk/source/G4Lab/cxx/GeometryVisitor.cxx @ 233

Last change on this file since 233 was 233, checked in by barrand, 17 years ago
  • Property svn:eol-style set to native
File size: 7.6 KB
Line 
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//////////////////////////////////////////////////////////////////////////////
14G4Lab::GeometryVisitor::GeometryVisitor(
15) 
16:fIndex(0)
17//////////////////////////////////////////////////////////////////////////////
18//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
19{
20}
21//////////////////////////////////////////////////////////////////////////////
22G4Lab::GeometryVisitor::~GeometryVisitor(
23) 
24//////////////////////////////////////////////////////////////////////////////
25//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
26{
27}
28//////////////////////////////////////////////////////////////////////////////
29bool 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//////////////////////////////////////////////////////////////////////////////
162bool 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
Note: See TracBrowser for help on using the repository browser.