Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/visualization/modeling/src/G4PhysicalVolumeModel.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /visualization/modeling/src/G4PhysicalVolumeModel.cc (Version 11.3.0) and /visualization/modeling/src/G4PhysicalVolumeModel.cc (Version 4.0)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                    <<   3 // * DISCLAIMER                                                       *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th <<   5 // * The following disclaimer summarizes all the specific disclaimers *
  6 // * the Geant4 Collaboration.  It is provided <<   6 // * of contributors to this software. The specific disclaimers,which *
  7 // * conditions of the Geant4 Software License <<   7 // * govern, are listed with their locations in:                      *
  8 // * LICENSE and available at  http://cern.ch/ <<   8 // *   http://cern.ch/geant4/license                                  *
  9 // * include a list of copyright holders.      << 
 10 // *                                                9 // *                                                                  *
 11 // * Neither the authors of this software syst     10 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     11 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     12 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     13 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file  <<  14 // * use.                                                             *
 16 // * for the full disclaimer and the limitatio << 
 17 // *                                               15 // *                                                                  *
 18 // * This  code  implementation is the result  <<  16 // * This  code  implementation is the  intellectual property  of the *
 19 // * technical work of the GEANT4 collaboratio <<  17 // * GEANT4 collaboration.                                            *
 20 // * By using,  copying,  modifying or  distri <<  18 // * By copying,  distributing  or modifying the Program (or any work *
 21 // * any work based  on the software)  you  ag <<  19 // * based  on  the Program)  you indicate  your  acceptance of  this *
 22 // * use  in  resulting  scientific  publicati <<  20 // * statement, and all its terms.                                    *
 23 // * acceptance of all terms of the Geant4 Sof << 
 24 // *******************************************     21 // ********************************************************************
 25 //                                                 22 //
 26 //                                                 23 //
                                                   >>  24 // $Id: G4PhysicalVolumeModel.cc,v 1.20 2001/08/24 20:34:25 johna Exp $
                                                   >>  25 // GEANT4 tag $Name: geant4-04-00 $
 27 //                                                 26 //
 28 //                                                 27 // 
 29 // John Allison  31st December 1997.               28 // John Allison  31st December 1997.
 30 // Model for physical volumes.                     29 // Model for physical volumes.
 31                                                    30 
 32 #include "G4PhysicalVolumeModel.hh"                31 #include "G4PhysicalVolumeModel.hh"
 33                                                    32 
                                                   >>  33 #include "G4ModelingParameters.hh"
 34 #include "G4VGraphicsScene.hh"                     34 #include "G4VGraphicsScene.hh"
 35 #include "G4VPhysicalVolume.hh"                    35 #include "G4VPhysicalVolume.hh"
 36 #include "G4PhysicalVolumeStore.hh"            << 
 37 #include "G4VPVParameterisation.hh"                36 #include "G4VPVParameterisation.hh"
 38 #include "G4LogicalVolume.hh"                      37 #include "G4LogicalVolume.hh"
 39 #include "G4VSolid.hh"                             38 #include "G4VSolid.hh"
 40 #include "G4SubtractionSolid.hh"               << 
 41 #include "G4IntersectionSolid.hh"              << 
 42 #include "G4Material.hh"                           39 #include "G4Material.hh"
 43 #include "G4VisAttributes.hh"                      40 #include "G4VisAttributes.hh"
 44 #include "G4BoundingExtentScene.hh"            <<  41 #include "G4BoundingSphereScene.hh"
                                                   >>  42 #include "G4PhysicalVolumeSearchScene.hh"
 45 #include "G4TransportationManager.hh"              43 #include "G4TransportationManager.hh"
 46 #include "G4Polyhedron.hh"                     << 
 47 #include "HepPolyhedronProcessor.h"            << 
 48 #include "G4AttDefStore.hh"                    << 
 49 #include "G4AttDef.hh"                         << 
 50 #include "G4AttValue.hh"                       << 
 51 #include "G4UnitsTable.hh"                     << 
 52 #include "G4Vector3D.hh"                       << 
 53 #include "G4Mesh.hh"                           << 
 54                                                    44 
 55 #include <sstream>                             <<  45 #include "g4std/strstream"
 56 #include <iomanip>                             << 
 57                                                << 
 58 #define G4warn G4cout                          << 
 59                                                    46 
 60 G4PhysicalVolumeModel::G4PhysicalVolumeModel       47 G4PhysicalVolumeModel::G4PhysicalVolumeModel
 61 (G4VPhysicalVolume*            pVPV            <<  48 (G4VPhysicalVolume*          pVPV,
 62  , G4int                       requestedDepth  <<  49  G4int                       requestedDepth,
 63  , const G4Transform3D&        modelTransform  <<  50  const G4Transform3D& modelTransformation,
 64  , const G4ModelingParameters* pMP             <<  51  const G4ModelingParameters* pMP,
 65  , G4bool                      useFullExtent   <<  52  G4bool useFullExtent):
 66  , const std::vector<G4PhysicalVolumeNodeID>&  <<  53   G4VModel        (modelTransformation, pMP),
 67 : G4VModel           (pMP)                     <<  54   fpTopPV         (pVPV),
 68 , fpTopPV            (pVPV)                    <<  55   fTopPVName      (pVPV -> GetName ()),
 69 , fTopPVCopyNo       (pVPV? pVPV->GetCopyNo(): <<  56   fTopPVCopyNo    (pVPV -> GetCopyNo ()),
 70 , fRequestedDepth    (requestedDepth)          <<  57   fRequestedDepth (requestedDepth),
 71 , fUseFullExtent     (useFullExtent)           <<  58   fUseFullExtent  (useFullExtent),
 72 , fTransform         (modelTransform)          <<  59   fCurrentDepth   (0),
 73 , fCurrentDepth      (0)                       <<  60   fpCurrentPV     (0),
 74 , fpCurrentPV        (fpTopPV)                 <<  61   fpCurrentLV     (0),
 75 , fCurrentPVCopyNo   (fpTopPV? fpTopPV->GetCop <<  62   fCurtailDescent (false),
 76 , fpCurrentLV        (fpTopPV? fpTopPV->GetLog <<  63   fpCurrentDepth  (0),
 77 , fpCurrentMaterial  (fpCurrentLV? fpCurrentLV <<  64   fppCurrentPV    (0),
 78 , fCurrentTransform  (modelTransform)          <<  65   fppCurrentLV    (0)
 79 , fBaseFullPVPath    (baseFullPVPath)          <<  66 {
 80 , fFullPVPath        (fBaseFullPVPath)         <<  67   const int len = 8; char a [len];
 81 , fAbort             (false)                   <<  68   G4std::ostrstream o (a, len); o.seekp (G4std::ios::beg);
 82 , fCurtailDescent    (false)                   <<  69   o << fpTopPV -> GetCopyNo () << G4std::ends;
 83 , fpClippingSolid    (0)                       <<  70   fGlobalTag = fpTopPV -> GetName () + "." + a;
 84 , fClippingMode      (subtraction)             <<  71   fGlobalDescription = "G4PhysicalVolumeModel " + fGlobalTag;
 85 , fNClippers         (0)                       << 
 86 , fTotalTouchables   (0)                       << 
 87 {                                              << 
 88   fType = "G4PhysicalVolumeModel";             << 
 89                                                << 
 90   if (!fpTopPV) {                              << 
 91                                                << 
 92     // In some circumstances creating an "empt << 
 93     // allowed, so I have supressed the G4Exce << 
 94     // be a problem we might have to re-instat << 
 95     // be used except by visualisation experts << 
 96     // where it is used simply to get a list o << 
 97     //    G4Exception                          << 
 98     //    ("G4PhysicalVolumeModel::G4PhysicalV << 
 99     //     "modeling0010", FatalException, "Nu << 
100                                                << 
101     fTopPVName = "NULL";                       << 
102     fGlobalTag = "Empty";                      << 
103     fGlobalDescription = "G4PhysicalVolumeMode << 
104                                                << 
105   } else {                                     << 
106                                                << 
107     fTopPVName = fpTopPV -> GetName ();        << 
108     std::ostringstream oss;                    << 
109     oss << fpTopPV->GetName() << ':' << fpTopP << 
110     << " BasePath:" << fBaseFullPVPath;        << 
111     fGlobalTag = oss.str();                    << 
112     fGlobalDescription = "G4PhysicalVolumeMode << 
113     CalculateExtent ();                        << 
114   }                                            << 
115 }                                              << 
116                                                    72 
117 G4PhysicalVolumeModel::~G4PhysicalVolumeModel  <<  73   CalculateExtent ();
118 {                                              << 
119   delete fpClippingSolid;                      << 
120 }                                                  74 }
121                                                    75 
122 G4ModelingParameters::PVNameCopyNoPath G4Physi <<  76 G4PhysicalVolumeModel::~G4PhysicalVolumeModel () {}
123 (const std::vector<G4PhysicalVolumeNodeID>& pa << 
124 {                                              << 
125   G4ModelingParameters::PVNameCopyNoPath PVNam << 
126   for (const auto& node: path) {               << 
127     PVNameCopyNoPath.push_back                 << 
128     (G4ModelingParameters::PVNameCopyNo        << 
129      (node.GetPhysicalVolume()->GetName(),node << 
130   }                                            << 
131   return PVNameCopyNoPath;                     << 
132 }                                              << 
133                                                    77 
134 G4String G4PhysicalVolumeModel::GetPVNamePathS <<  78 void G4PhysicalVolumeModel::CalculateExtent () {
135 (const std::vector<G4PhysicalVolumeNodeID>& pa << 
136 // Converts to path string, e.g., " World 0 En << 
137 // Note leading space character.               << 
138 {                                              << 
139   std::ostringstream oss;                      << 
140   oss << path;                                 << 
141   return oss.str();                            << 
142 }                                              << 
143                                                << 
144 void G4PhysicalVolumeModel::CalculateExtent () << 
145 {                                              << 
146   // To handle paramaterisations, set copy num << 
147   // to get extent right                       << 
148   G4VPVParameterisation* pP = fpTopPV -> GetPa << 
149   if (pP) {                                    << 
150     fpTopPV -> SetCopyNo (fTopPVCopyNo);       << 
151     G4VSolid* solid = pP -> ComputeSolid (fTop << 
152     solid -> ComputeDimensions (pP, fTopPVCopy << 
153   }                                            << 
154   if (fUseFullExtent) {                            79   if (fUseFullExtent) {
155     fExtent = fpTopPV -> GetLogicalVolume () -     80     fExtent = fpTopPV -> GetLogicalVolume () -> GetSolid () -> GetExtent ();
156   } else {                                     <<  81   }
157     // Calculate extent of *drawn* volumes, i. <<  82   else {
158     // invisible volumes, by traversing the wh <<  83     G4BoundingSphereScene bsScene(this);
159     // this physical volume.                   << 
160     G4BoundingExtentScene beScene(this);       << 
161     const G4int tempRequestedDepth = fRequeste << 
162     const G4Transform3D tempTransform = fTrans << 
163     const G4ModelingParameters* tempMP = fpMP;     84     const G4ModelingParameters* tempMP = fpMP;
164     fRequestedDepth = -1;  // Always search to << 
165     fTransform = G4Transform3D();  // Extent i << 
166     G4ModelingParameters mParams                   85     G4ModelingParameters mParams
167       (0,      // No default vis attributes ne <<  86       (0,      // No default vis attributes.
168        G4ModelingParameters::wf,  // wireframe <<  87        G4ModelingParameters::wireframe,
169        true,   // Global culling.                  88        true,   // Global culling.
170        true,   // Cull invisible volumes.          89        true,   // Cull invisible volumes.
171        false,  // Density culling.                 90        false,  // Density culling.
172        0.,     // Density (not relevant if den     91        0.,     // Density (not relevant if density culling false).
173        true,   // Cull daughters of opaque mot     92        true,   // Cull daughters of opaque mothers.
174        24);    // No of sides (not relevant fo <<  93        24,     // No of sides (not relevant for this operation).
175     mParams.SetSpecialMeshRendering(true);  // <<  94        true,   // View geometry.
                                                   >>  95        false,  // View hits - not relevant for physical volume model.
                                                   >>  96        false); // View digis - not relevant for physical volume model.
176     fpMP = &mParams;                               97     fpMP = &mParams;
177     DescribeYourselfTo (beScene);              <<  98     DescribeYourselfTo (bsScene);
178     fExtent = beScene.GetBoundingExtent();     <<  99     fExtent = bsScene.GetBoundingSphereExtent ();
179     fpMP = tempMP;                                100     fpMP = tempMP;
180     fTransform = tempTransform;                << 
181     fRequestedDepth = tempRequestedDepth;      << 
182   }                                               101   }
183   G4double radius = fExtent.GetExtentRadius(); << 
184   if (radius < 0.) {  // Nothing in the scene  << 
185     fExtent = fpTopPV -> GetLogicalVolume () - << 
186   }                                            << 
187   fExtent.Transform(fTransform);               << 
188 }                                                 102 }
189                                                   103 
190 void G4PhysicalVolumeModel::DescribeYourselfTo    104 void G4PhysicalVolumeModel::DescribeYourselfTo
191 (G4VGraphicsScene& sceneHandler)               << 105 (G4VGraphicsScene& sceneHandler) {
192 {                                              << 
193   if (!fpTopPV) {                              << 
194     G4Exception                                << 
195     ("G4PhysicalVolumeModel::DescribeYourselfT << 
196      "modeling0012", FatalException, "No model << 
197     return;  // Should never reach here, but k << 
198   }                                            << 
199                                                   106 
200   if (!fpMP) {                                 << 107   if (fpMP && fpMP -> IsViewGeom ()) {
201     G4Exception                                << 
202     ("G4PhysicalVolumeModel::DescribeYourselfT << 
203      "modeling0013", FatalException, "No model << 
204     return;  // Should never reach here, but k << 
205   }                                            << 
206                                                   108 
207   fNClippers = 0;                              << 109     sceneHandler.EstablishSpecials (*this);
208   G4DisplacedSolid* pSectionSolid = fpMP->GetS << 110     // See .hh file for explanation of this mechanism.
209   G4DisplacedSolid* pCutawaySolid = fpMP->GetC << 
210   if (fpClippingSolid) fNClippers++;           << 
211   if (pSectionSolid)   fNClippers++;           << 
212   if (pCutawaySolid)   fNClippers++;           << 
213   if (fNClippers > 1) {                        << 
214     G4ExceptionDescription ed;                 << 
215     ed << "More than one solid cutter/clipper: << 
216     if (fpClippingSolid) ed << "\nclipper in f << 
217     if (pSectionSolid)   ed << "\nsectioner in << 
218     if (pCutawaySolid)   ed << "\ncutaway in f << 
219     G4Exception("G4PhysicalVolumeModel::Descri << 
220   }                                            << 
221                                                   111 
222   G4Transform3D startingTransformation = fTran << 112     fCurrentDepth = 0;
                                                   >> 113     // Store in working space (via pointer to working space).
                                                   >> 114     if (fpCurrentDepth) *fpCurrentDepth = fCurrentDepth;
223                                                   115 
224   fNTouchables.clear();  // Keeps count of tou << 116     G4Transform3D startingTransformation = fTransform;
225                                                   117 
226   VisitGeometryAndGetVisReps                   << 118     VisitGeometryAndGetVisReps (fpTopPV,
227     (fpTopPV,                                  << 119         fRequestedDepth,
228      fRequestedDepth,                          << 120         startingTransformation,
229      startingTransformation,                   << 121         sceneHandler);
230      sceneHandler);                            << 122 
231                                                << 123     // Clear current data and working space (via pointers to working space).
232   fTotalTouchables = 0;                        << 124     fCurrentDepth = 0;
233   for (const auto& entry : fNTouchables) {     << 125     fpCurrentPV   = 0;
234     fTotalTouchables += entry.second;          << 126     fpCurrentLV   = 0;
235   }                                            << 127     if (fpCurrentDepth) *fpCurrentDepth = fCurrentDepth;
                                                   >> 128     if (fppCurrentPV)   *fppCurrentPV   = fpCurrentPV;
                                                   >> 129     if (fppCurrentLV)   *fppCurrentLV   = fpCurrentLV;
236                                                   130 
237   // Reset or clear data...                    << 131     sceneHandler.DecommissionSpecials (*this);
238   fCurrentDepth     = 0;                       << 132 
239   fpCurrentPV       = fpTopPV;                 << 133     // Clear pointers to working space.
240   fCurrentPVCopyNo  = fpTopPV->GetCopyNo();    << 134     fpCurrentDepth = 0;
241   fpCurrentLV       = fpTopPV->GetLogicalVolum << 135     fppCurrentPV   = 0;
242   fpCurrentMaterial = fpCurrentLV? fpCurrentLV << 136     fppCurrentLV   = 0;
243   fFullPVPath       = fBaseFullPVPath;         << 137   }
244   fDrawnPVPath.clear();                        << 
245   fAbort            = false;                   << 
246   fCurtailDescent   = false;                   << 
247 }                                                 138 }
248                                                   139 
249 G4String G4PhysicalVolumeModel::GetCurrentTag  << 140 G4String G4PhysicalVolumeModel::GetCurrentTag () const {
250 {                                              << 141   const int len = 8; char a [len];
                                                   >> 142   G4std::ostrstream o (a, len); o.seekp (G4std::ios::beg);
251   if (fpCurrentPV) {                              143   if (fpCurrentPV) {
252     std::ostringstream o;                      << 144     o << fpCurrentPV -> GetCopyNo () << G4std::ends;
253     o << fpCurrentPV -> GetCopyNo ();          << 145     return fpCurrentPV -> GetName () + "." + a;
254     return fpCurrentPV -> GetName () + ":" + o << 
255   }                                               146   }
256   else {                                          147   else {
257     return "WARNING: NO CURRENT VOLUME - globa    148     return "WARNING: NO CURRENT VOLUME - global tag is " + fGlobalTag;
258   }                                               149   }
259 }                                                 150 }
260                                                   151 
261 G4String G4PhysicalVolumeModel::GetCurrentDesc << 152 G4String G4PhysicalVolumeModel::GetCurrentDescription () const {
262 {                                              << 
263   return "G4PhysicalVolumeModel " + GetCurrent    153   return "G4PhysicalVolumeModel " + GetCurrentTag ();
264 }                                                 154 }
265                                                   155 
                                                   >> 156 void G4PhysicalVolumeModel::DefinePointersToWorkingSpace
                                                   >> 157 (G4int*              pCurrentDepth,
                                                   >> 158  G4VPhysicalVolume** ppCurrentPV,
                                                   >> 159  G4LogicalVolume**   ppCurrentLV) {
                                                   >> 160   fpCurrentDepth = pCurrentDepth;
                                                   >> 161   fppCurrentPV   = ppCurrentPV;
                                                   >> 162   fppCurrentLV   = ppCurrentLV;
                                                   >> 163 }
                                                   >> 164 
266 void G4PhysicalVolumeModel::VisitGeometryAndGe    165 void G4PhysicalVolumeModel::VisitGeometryAndGetVisReps
267 (G4VPhysicalVolume* pVPV,                         166 (G4VPhysicalVolume* pVPV,
268  G4int requestedDepth,                            167  G4int requestedDepth,
269  const G4Transform3D& theAT,                      168  const G4Transform3D& theAT,
270  G4VGraphicsScene& sceneHandler)               << 169  G4VGraphicsScene& sceneHandler) {
271 {                                              << 170 
272   // Visits geometry structure to a given dept    171   // Visits geometry structure to a given depth (requestedDepth), starting
273   //   at given physical volume with given sta    172   //   at given physical volume with given starting transformation and
274   //   describes volumes to the scene handler.    173   //   describes volumes to the scene handler.
275   // requestedDepth < 0 (default) implies full    174   // requestedDepth < 0 (default) implies full visit.
276   // theAT is the Accumulated Transformation.     175   // theAT is the Accumulated Transformation.
277                                                   176 
278   // Find corresponding logical volume and (la    177   // Find corresponding logical volume and (later) solid, storing in
279   // local variables to preserve re-entrancy.     178   // local variables to preserve re-entrancy.
280   G4LogicalVolume* pLV  = pVPV -> GetLogicalVo    179   G4LogicalVolume* pLV  = pVPV -> GetLogicalVolume ();
281   G4VSolid* pSol = nullptr;                    << 180 
282   G4Material* pMaterial = nullptr;             << 181   G4VSolid* pSol;
                                                   >> 182   G4Material* pMaterial;
283                                                   183 
284   if (!(pVPV -> IsReplicated ())) {               184   if (!(pVPV -> IsReplicated ())) {
285     // Non-replicated physical volume.            185     // Non-replicated physical volume.
286     pSol = pLV -> GetSolid ();                    186     pSol = pLV -> GetSolid ();
287     pMaterial = pLV -> GetMaterial ();            187     pMaterial = pLV -> GetMaterial ();
288     DescribeAndDescend (pVPV, requestedDepth,     188     DescribeAndDescend (pVPV, requestedDepth, pLV, pSol, pMaterial,
289       theAT, sceneHandler);                       189       theAT, sceneHandler);
290   }                                               190   }
291   else {                                          191   else {
292     // Replicated or parametrised physical vol    192     // Replicated or parametrised physical volume.
293     EAxis axis;                                   193     EAxis axis;
294     G4int nReplicas;                              194     G4int nReplicas;
295     G4double width;                               195     G4double width;
296     G4double offset;                              196     G4double offset;
297     G4bool consuming;                             197     G4bool consuming;
298     pVPV -> GetReplicationData (axis, nReplica    198     pVPV -> GetReplicationData (axis, nReplicas, width,  offset, consuming);
299     G4int nBegin = 0;                          << 
300     G4int nEnd = nReplicas;                    << 
301     if (fCurrentDepth == 0) { // i.e., top vol << 
302       nBegin = fTopPVCopyNo;  // Describe only << 
303       nEnd = nBegin + 1;      // specified by  << 
304     }                                          << 
305     G4VPVParameterisation* pP = pVPV -> GetPar    199     G4VPVParameterisation* pP = pVPV -> GetParameterisation ();
306     if (pP) {  // Parametrised volume.            200     if (pP) {  // Parametrised volume.
307       for (int n = nBegin; n < nEnd; n++) {    << 201       for (int n = 0; n < nReplicas; n++) {
308         pSol = pP -> ComputeSolid (n, pVPV);   << 202   pSol = pP -> ComputeSolid (n, pVPV);
309         pP -> ComputeTransformation (n, pVPV); << 203   pMaterial = pP -> ComputeMaterial (n, pVPV);
310         pSol -> ComputeDimensions (pP, n, pVPV << 204   pP -> ComputeTransformation (n, pVPV);
311         pVPV -> SetCopyNo (n);                 << 205   pSol -> ComputeDimensions (pP, n, pVPV);
312         fCurrentPVCopyNo = n;                  << 206   // pVPV -> SetCopyNo (n);  // Uncertain of effect of this.
313         // Create a touchable of current paren << 207   DescribeAndDescend (pVPV, requestedDepth, pLV, pSol, pMaterial,
314         // fFullPVPath has not been updated ye << 208           theAT, sceneHandler);
315         // corresponds to the parent.          << 
316         G4PhysicalVolumeModelTouchable parentT << 
317         pMaterial = pP -> ComputeMaterial (n,  << 
318         DescribeAndDescend (pVPV, requestedDep << 
319                             theAT, sceneHandle << 
320       }                                           209       }
321     }                                             210     }
322     else {  // Plain replicated volume.  From     211     else {  // Plain replicated volume.  From geometry_guide.txt...
323       // The replica's positions are claculate    212       // The replica's positions are claculated by means of a linear formula.
324       // Replication may occur along:             213       // Replication may occur along:
325       //                                          214       // 
326       // o Cartesian axes (kXAxis,kYAxis,kZAxi    215       // o Cartesian axes (kXAxis,kYAxis,kZAxis)
327       //                                          216       // 
328       //   The replications, of specified widt    217       //   The replications, of specified width have coordinates of
329       //   form (-width*(nReplicas-1)*0.5+n*wi    218       //   form (-width*(nReplicas-1)*0.5+n*width,0,0) where n=0.. nReplicas-1
330       //   for the case of kXAxis, and are unr    219       //   for the case of kXAxis, and are unrotated.
331       //                                          220       // 
332       // o Radial axis (cylindrical polar) (kR    221       // o Radial axis (cylindrical polar) (kRho)
333       //                                          222       // 
334       //   The replications are cons/tubs sect    223       //   The replications are cons/tubs sections, centred on the origin
335       //   and are unrotated.                     224       //   and are unrotated.
336       //   They have radii of width*n+offset t    225       //   They have radii of width*n+offset to width*(n+1)+offset
337       //                      where n=0..nRepl    226       //                      where n=0..nReplicas-1
338       //                                          227       // 
339       // o Phi axis (cylindrical polar) (kPhi)    228       // o Phi axis (cylindrical polar) (kPhi)
340       //   The replications are `phi sections'    229       //   The replications are `phi sections' or wedges, and of cons/tubs form
341       //   They have phi of offset+n*width to     230       //   They have phi of offset+n*width to offset+(n+1)*width where
342       //   n=0..nReplicas-1                       231       //   n=0..nReplicas-1
343       //                                          232       // 
344       pSol = pLV -> GetSolid ();               << 
345       pMaterial = pLV -> GetMaterial ();       << 
346       G4ThreeVector originalTranslation = pVPV    233       G4ThreeVector originalTranslation = pVPV -> GetTranslation ();
347       G4RotationMatrix* pOriginalRotation = pV    234       G4RotationMatrix* pOriginalRotation = pVPV -> GetRotation ();
348       G4double originalRMin = 0., originalRMax << 235       for (int n = 0; n < nReplicas; n++) {
349       if (axis == kRho && pSol->GetEntityType( << 236   G4ThreeVector translation;  // Null.
350         originalRMin = ((G4Tubs*)pSol)->GetInn << 237   G4RotationMatrix rotation;  // Null - life long enough for visualizing.
351         originalRMax = ((G4Tubs*)pSol)->GetOut << 238   G4RotationMatrix* pRotation = 0;
352       }                                        << 239   switch (axis) {
353       G4bool visualisable = true;              << 240   default:
354       for (int n = nBegin; n < nEnd; n++) {    << 241   case kXAxis:
355         G4ThreeVector translation;  // Identit << 242     translation = G4ThreeVector (-width*(nReplicas-1)*0.5+n*width,0,0);
356         G4RotationMatrix rotation;  // Identit << 243     break;
357         G4RotationMatrix* pRotation = 0;       << 244   case kYAxis:
358         switch (axis) {                        << 245     translation = G4ThreeVector (0,-width*(nReplicas-1)*0.5+n*width,0);
359           default:                             << 246     break;
360           case kXAxis:                         << 247   case kZAxis:
361             translation = G4ThreeVector (-widt << 248     translation = G4ThreeVector (0,0,-width*(nReplicas-1)*0.5+n*width);
362             break;                             << 249     break;
363           case kYAxis:                         << 250   case kRho:
364             translation = G4ThreeVector (0,-wi << 251     G4cout <<
365             break;                             << 252       "G4PhysicalVolumeModel::VisitGeometryAndGetVisReps: WARNING:"
366           case kZAxis:                         << 253       "\n  built-in replicated volumes replicated in radius are not yet"
367             translation = G4ThreeVector (0,0,- << 254       "\n  properly visualizable."
368             break;                             << 255          << G4endl;
369           case kRho:                           << 256     break;
370             if (pSol->GetEntityType() == "G4Tu << 257   case kPhi:
371               ((G4Tubs*)pSol)->SetInnerRadius( << 258     rotation.rotateZ (-(offset+(n+0.5)*width));
372               ((G4Tubs*)pSol)->SetOuterRadius( << 259     // Minus Sign because for the physical volume we need the
373             } else {                           << 260     // coordinate system rotation.
374               if (fpMP->IsWarning())           << 261     pRotation = &rotation;
375                 G4warn <<                      << 262     break;
376                 "G4PhysicalVolumeModel::VisitG << 263   } 
377                 "\n  built-in replicated volum << 264   pVPV -> SetTranslation (translation);
378                 << pSol->GetEntityType() <<    << 265   pVPV -> SetRotation    (pRotation);
379                 "-type\n  solids (your solid \ << 266   // pVPV -> SetCopyNo (n); // Has no effect and might even be
380                 << pSol->GetName() <<          << 267   // dangerous.
381                 "\") are not visualisable."    << 268   pSol = pLV -> GetSolid ();
382                 << G4endl;                     << 269   pMaterial = pLV -> GetMaterial ();
383               visualisable = false;            << 270   DescribeAndDescend (pVPV, requestedDepth, pLV, pSol, pMaterial,
384             }                                  << 271           theAT, sceneHandler);
385             break;                             << 
386           case kPhi:                           << 
387             rotation.rotateZ (-(offset+(n+0.5) << 
388             // Minus Sign because for the phys << 
389             // coordinate system rotation.     << 
390             pRotation = &rotation;             << 
391             break;                             << 
392         }                                      << 
393         pVPV -> SetTranslation (translation);  << 
394         pVPV -> SetRotation    (pRotation);    << 
395         pVPV -> SetCopyNo (n);                 << 
396         fCurrentPVCopyNo = n;                  << 
397         if (visualisable) {                    << 
398           DescribeAndDescend (pVPV, requestedD << 
399                               theAT, sceneHand << 
400         }                                      << 
401       }                                           272       }
402       // Restore originals...                     273       // Restore originals...
403       pVPV -> SetTranslation (originalTranslat    274       pVPV -> SetTranslation (originalTranslation);
404       pVPV -> SetRotation    (pOriginalRotatio    275       pVPV -> SetRotation    (pOriginalRotation);
405       if (axis == kRho && pSol->GetEntityType( << 
406         ((G4Tubs*)pSol)->SetInnerRadius(origin << 
407         ((G4Tubs*)pSol)->SetOuterRadius(origin << 
408       }                                        << 
409     }                                             276     }
410   }                                               277   }
                                                   >> 278 
                                                   >> 279   return;
411 }                                                 280 }
412                                                   281 
413 void G4PhysicalVolumeModel::DescribeAndDescend    282 void G4PhysicalVolumeModel::DescribeAndDescend
414 (G4VPhysicalVolume* pVPV,                         283 (G4VPhysicalVolume* pVPV,
415  G4int requestedDepth,                            284  G4int requestedDepth,
416  G4LogicalVolume* pLV,                            285  G4LogicalVolume* pLV,
417  G4VSolid* pSol,                                  286  G4VSolid* pSol,
418  G4Material* pMaterial,                        << 287  const G4Material* pMaterial,
419  const G4Transform3D& theAT,                      288  const G4Transform3D& theAT,
420  G4VGraphicsScene& sceneHandler)               << 289  G4VGraphicsScene& sceneHandler) {
421 {                                              << 290 
422   // Maintain useful data members...           << 291   // Maintain data members and store in working space (via pointers to
                                                   >> 292   // working space).
                                                   >> 293   if (fpCurrentDepth) *fpCurrentDepth = fCurrentDepth;
423   fpCurrentPV = pVPV;                             294   fpCurrentPV = pVPV;
424   fCurrentPVCopyNo = pVPV->GetCopyNo();        << 
425   fpCurrentLV = pLV;                              295   fpCurrentLV = pLV;
426   fpCurrentMaterial = pMaterial;               << 296   if (fppCurrentPV) *fppCurrentPV = fpCurrentPV;
                                                   >> 297   if (fppCurrentLV) *fppCurrentLV = fpCurrentLV;
427                                                   298 
428   // Create a nodeID for use below - note the  << 299   const HepRotation* pObjectRotation = pVPV -> GetObjectRotation ();
429   G4int copyNo = fpCurrentPV->GetCopyNo();     << 300   const Hep3Vector&  translation     = pVPV -> GetTranslation ();
430   auto nodeID = G4PhysicalVolumeNodeID         << 301   G4Transform3D theLT (G4Transform3D (*pObjectRotation, translation));
431   (fpCurrentPV,copyNo,fCurrentDepth,fCurrentTr << 
432                                                << 
433   // Update full path of physical volumes...   << 
434   fFullPVPath.push_back(nodeID);               << 
435                                                << 
436   const G4RotationMatrix objectRotation = pVPV << 
437   const G4ThreeVector&  translation     = pVPV << 
438   G4Transform3D theLT (G4Transform3D (objectRo << 
439                                                   302 
440   // Compute the accumulated transformation...    303   // Compute the accumulated transformation...
441   // Note that top volume's transformation rel    304   // Note that top volume's transformation relative to the world
442   // coordinate system is specified in theAT =    305   // coordinate system is specified in theAT == startingTransformation
443   // = fTransform (see DescribeYourselfTo), so    306   // = fTransform (see DescribeYourselfTo), so first time through the
444   // volume's own transformation, which is onl    307   // volume's own transformation, which is only relative to its
445   // mother, i.e., not relative to the world c    308   // mother, i.e., not relative to the world coordinate system, should
446   // not be accumulated.                          309   // not be accumulated.
447   G4Transform3D theNewAT (theAT);                 310   G4Transform3D theNewAT (theAT);
448   if (fCurrentDepth != 0) theNewAT = theAT * t    311   if (fCurrentDepth != 0) theNewAT = theAT * theLT;
449   fCurrentTransform = theNewAT;                << 
450                                                   312 
451   const G4VisAttributes* pVisAttribs = pLV->Ge << 313   /********************************************************
452   //  If the volume does not have any vis attr << 314   G4cout << "G4PhysicalVolumeModel::DescribeAndDescend: "
453   G4VisAttributes* tempVisAtts = nullptr;      << 315    << pVPV -> GetName () << "." << pVPV -> GetCopyNo ();
454   if (!pVisAttribs) {                          << 316   G4cout << "\n  theAT: ";
455     if (fpMP->GetDefaultVisAttributes()) {     << 317   G4cout << "\n    Rotation: ";
456       tempVisAtts = new G4VisAttributes(*fpMP- << 318   HepRotation rotation = theAT.getRotation ();
457     } else {                                   << 319   G4cout << rotation.thetaX() << ", "
458       tempVisAtts = new G4VisAttributes;       << 320    << rotation.phiX() << ", "
459     }                                          << 321    << rotation.thetaY() << ", "
460     // The user may request /vis/viewer/set/co << 322    << rotation.phiY() << ", "
461     if (fpMP->GetCBDAlgorithmNumber() == 1) {  << 323    << rotation.thetaZ() << ", "
462       // Algorithm 1: 3 parameters: Simple rai << 324    << rotation.phiZ();
463       if (fpMP->GetCBDParameters().size() != 3 << 325   G4cout << "\n    Translation: " << theAT.getTranslation();
464         G4Exception("G4PhysicalVolumeModelTouc << 326   G4cout << "\n  theNewAT: ";
465                     "modeling0014",            << 327   G4cout << "\n    Rotation: ";
466                     FatalErrorInArgument,      << 328   rotation = theNewAT.getRotation ();
467                     "Algorithm-parameter misma << 329   G4cout << rotation.thetaX() << ", "
468       } else {                                 << 330    << rotation.phiX() << ", "
469         const G4double d = pMaterial? pMateria << 331    << rotation.thetaY() << ", "
470         const G4double d0 = fpMP->GetCBDParame << 332    << rotation.phiY() << ", "
471         const G4double d1 = fpMP->GetCBDParame << 333    << rotation.thetaZ() << ", "
472         const G4double d2 = fpMP->GetCBDParame << 334    << rotation.phiZ();
473         if (d < d0) { // Density < d0 is invis << 335   G4cout << "\n    Translation: " << theNewAT.getTranslation();
474           tempVisAtts->SetVisibility(false);   << 336   G4cout << G4endl;
475         } else { // Intermediate densities are << 337   **********************************************************/
476           G4double red, green, blue;           << 
477           if (d < d1) {                        << 
478             red = (d1-d)/(d1-d0); green = (d-d << 
479           } else if (d < d2) {                 << 
480             red = 0.; green = (d2-d)/(d2-d1);  << 
481           } else {  // Density >= d2 is blue.  << 
482             red = 0.; green = 0.; blue = 1.;   << 
483           }                                    << 
484           tempVisAtts->SetColour(G4Colour(red, << 
485         }                                      << 
486       }                                        << 
487     } else if (fpMP->GetCBDAlgorithmNumber() = << 
488       // Algorithm 2                           << 
489       // ...etc.                               << 
490     }                                          << 
491     pVisAttribs = tempVisAtts;                 << 
492   }                                            << 
493   // From here, can assume pVisAttribs is a va << 
494   // because PreAddSolid needs a vis attribute << 
495                                                << 
496   // Check if vis attributes are to be modifie << 
497   const auto& vams = fpMP->GetVisAttributesMod << 
498   if (vams.size()) {                           << 
499     // OK, we have some VAMs (Vis Attributes M << 
500     for (const auto& vam: vams) {              << 
501       const auto& vamPath = vam.GetPVNameCopyN << 
502       if (vamPath.size() == fFullPVPath.size() << 
503         // OK, we have a size match.           << 
504         // Check the volume name/copy number p << 
505         auto iVAMNameCopyNo = vamPath.begin(); << 
506         auto iPVNodeId = fFullPVPath.begin();  << 
507         for (; iVAMNameCopyNo != vamPath.end() << 
508           if (!(                               << 
509                 iVAMNameCopyNo->GetName() ==   << 
510                 iPVNodeId->GetPhysicalVolume() << 
511                 iVAMNameCopyNo->GetCopyNo() == << 
512                 iPVNodeId->GetPhysicalVolume() << 
513                 )) {                           << 
514             // This path element does NOT matc << 
515             break;                             << 
516           }                                    << 
517         }                                      << 
518         if (iVAMNameCopyNo == vamPath.end()) { << 
519           // OK, the paths match (the above lo << 
520           // Create a vis atts object for the  << 
521           // It is static so that we may retur << 
522           static G4VisAttributes modifiedVisAt << 
523           // Initialise it with the current vi << 
524           modifiedVisAtts = *pVisAttribs;      << 
525           pVisAttribs = &modifiedVisAtts;      << 
526           const G4VisAttributes& transVisAtts  << 
527           switch (vam.GetVisAttributesSignifie << 
528             case G4ModelingParameters::VASVisi << 
529               modifiedVisAtts.SetVisibility(tr << 
530               break;                           << 
531             case G4ModelingParameters::VASDaug << 
532               modifiedVisAtts.SetDaughtersInvi << 
533               (transVisAtts.IsDaughtersInvisib << 
534               break;                           << 
535             case G4ModelingParameters::VASColo << 
536               modifiedVisAtts.SetColour(transV << 
537               break;                           << 
538             case G4ModelingParameters::VASLine << 
539               modifiedVisAtts.SetLineStyle(tra << 
540               break;                           << 
541             case G4ModelingParameters::VASLine << 
542               modifiedVisAtts.SetLineWidth(tra << 
543               break;                           << 
544             case G4ModelingParameters::VASForc << 
545               if (transVisAtts.IsForceDrawingS << 
546                 if (transVisAtts.GetForcedDraw << 
547                     G4VisAttributes::wireframe << 
548                   modifiedVisAtts.SetForceWire << 
549                 }                              << 
550               }                                << 
551               break;                           << 
552             case G4ModelingParameters::VASForc << 
553               if (transVisAtts.IsForceDrawingS << 
554                 if (transVisAtts.GetForcedDraw << 
555                     G4VisAttributes::solid) {  << 
556                   modifiedVisAtts.SetForceSoli << 
557                 }                              << 
558               }                                << 
559               break;                           << 
560             case G4ModelingParameters::VASForc << 
561               if (transVisAtts.IsForceDrawingS << 
562                 if (transVisAtts.GetForcedDraw << 
563                     G4VisAttributes::cloud) {  << 
564                   modifiedVisAtts.SetForceClou << 
565                 }                              << 
566               }                                << 
567               break;                           << 
568             case G4ModelingParameters::VASForc << 
569               modifiedVisAtts.SetForceNumberOf << 
570               (transVisAtts.GetForcedNumberOfC << 
571               break;                           << 
572             case G4ModelingParameters::VASForc << 
573               if (transVisAtts.IsForceAuxEdgeV << 
574                 modifiedVisAtts.SetForceAuxEdg << 
575                 (transVisAtts.IsForcedAuxEdgeV << 
576               }                                << 
577               break;                           << 
578             case G4ModelingParameters::VASForc << 
579               modifiedVisAtts.SetForceLineSegm << 
580               (transVisAtts.GetForcedLineSegme << 
581               break;                           << 
582           }                                    << 
583         }                                      << 
584       }                                        << 
585     }                                          << 
586   }                                            << 
587                                                << 
588   // Check for special mesh rendering          << 
589   if (fpMP->IsSpecialMeshRendering()) {        << 
590     G4bool potentialG4Mesh = false;            << 
591     if (fpMP->GetSpecialMeshVolumes().empty()) << 
592       // No volumes specified - all are potent << 
593       potentialG4Mesh = true;                  << 
594     } else {                                   << 
595       // Name and (optionally) copy number of  << 
596       for (const auto& pvNameCopyNo: fpMP->Get << 
597         if (pVPV->GetName() == pvNameCopyNo.Ge << 
598           // We have a name match              << 
599           if (pvNameCopyNo.GetCopyNo() < 0) {  << 
600             // Any copy number is OK           << 
601             potentialG4Mesh = true;            << 
602           } else {                             << 
603             if (pVPV->GetCopyNo() == pvNameCop << 
604               // We have a name and copy numbe << 
605               potentialG4Mesh = true;          << 
606             }                                  << 
607           }                                    << 
608         }                                      << 
609       }                                        << 
610     }                                          << 
611     if (potentialG4Mesh) {                     << 
612       // Create - or at least attempt to creat << 
613       // out of this pVPV the type will be "in << 
614       G4Mesh mesh(pVPV,theNewAT);              << 
615       if (mesh.GetMeshType() != G4Mesh::invali << 
616         // Create "artificial" nodeID to repre << 
617         G4int artCopyNo = 0;                   << 
618         auto artPV = mesh.GetParameterisedVolu << 
619         auto artDepth = fCurrentDepth + 1;     << 
620         auto artNodeID = G4PhysicalVolumeNodeI << 
621         fFullPVPath.push_back(artNodeID);      << 
622         fDrawnPVPath.push_back(artNodeID);     << 
623         sceneHandler.AddCompound(mesh);        << 
624         fFullPVPath.pop_back();                << 
625         fDrawnPVPath.pop_back();               << 
626         delete tempVisAtts;  // Needs cleaning << 
627         return;  // Mesh found and processed - << 
628       }  // else continue processing           << 
629     }                                          << 
630   }                                            << 
631                                                << 
632   // Make decision to draw...                  << 
633   G4bool thisToBeDrawn = true;                 << 
634                                                << 
635   // There are various reasons why this volume << 
636   // might not be drawn...                     << 
637   G4bool culling = fpMP->IsCulling();          << 
638   G4bool cullingInvisible = fpMP->IsCullingInv << 
639   G4bool markedVisible                         << 
640   = pVisAttribs->IsVisible() && pVisAttribs->G << 
641   G4bool cullingLowDensity = fpMP->IsDensityCu << 
642   G4double density = pMaterial? pMaterial->Get << 
643   G4double densityCut = fpMP -> GetVisibleDens << 
644                                                << 
645   // 1) Global culling is on....               << 
646   if (culling) {                               << 
647     // 2) Culling of invisible volumes is on.. << 
648     if (cullingInvisible) {                    << 
649       // 3) ...and the volume is marked not vi << 
650       if (!markedVisible) thisToBeDrawn = fals << 
651     }                                          << 
652     // 4) Or culling of low density volumes is << 
653     if (cullingLowDensity) {                   << 
654       // 5) ...and density is less than cut va << 
655       if (density < densityCut) thisToBeDrawn  << 
656     }                                          << 
657   }                                            << 
658   // 6) The user has asked for all further tra << 
659   if (fAbort) thisToBeDrawn = false;           << 
660                                                << 
661   // Set "drawn" flag (it was true by default) << 
662   nodeID.SetDrawn(thisToBeDrawn);              << 
663                                                   338 
                                                   >> 339   // Make decision to Draw.
                                                   >> 340   G4bool thisToBeDrawn = !IsThisCulled (pLV, pMaterial);
664   if (thisToBeDrawn) {                            341   if (thisToBeDrawn) {
665                                                << 342     const G4VisAttributes* pVisAttribs = pLV -> GetVisAttributes ();
666     // Update path of drawn physical volumes.. << 343     if (!pVisAttribs) pVisAttribs = fpMP -> GetDefaultVisAttributes ();
667     fDrawnPVPath.push_back(nodeID);            << 
668                                                << 
669     if (fpMP->IsExplode() && fDrawnPVPath.size << 
670       // For top-level drawn volumes, explode  << 
671       G4Transform3D centering = G4Translate3D( << 
672       G4Transform3D centred = centering.invers << 
673       G4Scale3D oldScale;                      << 
674       G4Rotate3D oldRotation;                  << 
675       G4Translate3D oldTranslation;            << 
676       centred.getDecomposition(oldScale, oldRo << 
677       G4double explodeFactor = fpMP->GetExplod << 
678       G4Translate3D newTranslation =           << 
679   G4Translate3D(explodeFactor * oldTranslation << 
680           explodeFactor * oldTranslation.dy(), << 
681           explodeFactor * oldTranslation.dz()) << 
682       theNewAT = centering * newTranslation *  << 
683     }                                          << 
684                                                << 
685     auto fullDepth = fCurrentDepth + (G4int)fB << 
686     fNTouchables[fullDepth]++;  // Increment f << 
687                                                << 
688     DescribeSolid (theNewAT, pSol, pVisAttribs    344     DescribeSolid (theNewAT, pSol, pVisAttribs, sceneHandler);
689                                                << 
690   }                                               345   }
691                                                   346 
692   // Make decision to draw daughters, if any.  << 347   if (fCurtailDescent) {
693   // reasons why daughters might not be drawn. << 348     fCurtailDescent = false;
694                                                << 349     // Reset for normal descending of next volume at this level.
695   // First, reasons that do not depend on cull << 350     return;
696   G4int nDaughters = (G4int)pLV->GetNoDaughter << 351   }
697   G4bool daughtersToBeDrawn = true;            << 352 
698   // 1) There are no daughters...              << 353   // First check if mother covers...
699   if (!nDaughters) daughtersToBeDrawn = false; << 354 
700   // 2) We are at the limit if requested depth << 355   // This is only effective in surface drawing style, and then only if
701   else if (requestedDepth == 0) daughtersToBeD << 356   // the volumes are visible and opaque, and then only if no sections
702   // 3) The user has asked for all further tra << 357   // or cutways are in operation.
703   else if (fAbort) daughtersToBeDrawn = false; << 358   G4bool cullDaughter = thisToBeDrawn && IsDaughterCulled (pLV);
704   // 4) The user has asked that the descent be << 359   if (!cullDaughter) {
705   else if (fCurtailDescent) daughtersToBeDrawn << 360     // OK, now let's check for daughters...
706                                                << 361     if (requestedDepth != 0) {
707   // Now, reasons that depend on culling polic << 362       int nDaughters = pLV -> GetNoDaughters ();
708   else {                                       << 363       if (nDaughters) {
709     G4bool daughtersInvisible = pVisAttribs->I << 364   for (int iDaughter = 0; iDaughter < nDaughters; iDaughter++) {
710     // Culling of covered daughters request.   << 365     G4VPhysicalVolume* pVPV = pLV -> GetDaughter (iDaughter);
711     // G4VSceneHandler::CreateModelingParamete << 366     // Descend the geometry structure recursively...
712     // parameters...                           << 367     fCurrentDepth++;
713     G4bool cullingCovered = fpMP->IsCullingCov << 368     VisitGeometryAndGetVisReps
714     G4bool surfaceDrawing =                    << 369       (pVPV, requestedDepth - 1, theNewAT, sceneHandler);
715       fpMP->GetDrawingStyle() == G4ModelingPar << 370     fCurrentDepth--;
716       fpMP->GetDrawingStyle() == G4ModelingPar << 
717     if (pVisAttribs->IsForceDrawingStyle()) {  << 
718       switch (pVisAttribs->GetForcedDrawingSty << 
719       default:                                 << 
720       case G4VisAttributes::wireframe: surface << 
721       case G4VisAttributes::solid: surfaceDraw << 
722       }                                        << 
723     }                                          << 
724     G4bool opaque = pVisAttribs->GetColour().G << 
725     // 5) Global culling is on....             << 
726     if (culling) {                             << 
727       // 6) ..and culling of invisible volumes << 
728       if (cullingInvisible) {                  << 
729   // 7) ...and the mother requests daughters i << 
730   if (daughtersInvisible) daughtersToBeDrawn = << 
731       }                                        << 
732       // 8) Or culling of covered daughters is << 
733       if (cullingCovered) {                    << 
734   // 9) ...and surface drawing is operating... << 
735   if (surfaceDrawing) {                        << 
736     // 10) ...but only if mother is visible... << 
737     if (thisToBeDrawn) {                       << 
738       // 11) ...and opaque...                  << 
739         if (opaque) daughtersToBeDrawn = false << 
740     }                                          << 
741   }                                               371   }
742       }                                           372       }
743     }                                             373     }
744   }                                               374   }
745                                                << 
746   if (daughtersToBeDrawn) {                    << 
747     for (G4int iDaughter = 0; iDaughter < nDau << 
748       // Store daughter pVPV in local variable << 
749       G4VPhysicalVolume* pDaughterVPV = pLV -> << 
750       // Descend the geometry structure recurs << 
751       fCurrentDepth++;                         << 
752       VisitGeometryAndGetVisReps               << 
753   (pDaughterVPV, requestedDepth - 1, theNewAT, << 
754       fCurrentDepth--;                         << 
755     }                                          << 
756   }                                            << 
757                                                << 
758   // Clean up                                  << 
759   delete tempVisAtts;                          << 
760                                                << 
761   // Reset for normal descending of next volum << 
762   fCurtailDescent = false;                     << 
763                                                << 
764   // Pop item from paths physical volumes...   << 
765   fFullPVPath.pop_back();                      << 
766   if (thisToBeDrawn) {                         << 
767     fDrawnPVPath.pop_back();                   << 
768   }                                            << 
769 }                                              << 
770                                                << 
771 namespace                                      << 
772 {                                              << 
773   G4bool SubtractionBoundingLimits(const G4VSo << 
774   {                                            << 
775     // Algorithm from G4SubtractionSolid::Boun << 
776     // Since it is unclear how the shape of th << 
777     // after subtraction, just return its orig << 
778     G4ThreeVector pMin, pMax;                  << 
779     const auto& pSolA = target;                << 
780     pSolA->BoundingLimits(pMin,pMax);          << 
781     // Check correctness of the bounding box   << 
782     if (pMin.x() >= pMax.x() || pMin.y() >= pM << 
783       // Bad bounding box (min >= max)         << 
784       // This signifies a subtraction of non-i << 
785       return false;                            << 
786     }                                          << 
787     return true;                               << 
788   }                                            << 
789                                                << 
790   G4bool IntersectionBoundingLimits(const G4VS << 
791   {                                            << 
792     // Algorithm from G4IntersectionSolid::Bou << 
793     G4ThreeVector pMin, pMax;                  << 
794     G4ThreeVector minA,maxA, minB,maxB;        << 
795     const auto& pSolA = target;                << 
796     const auto& pSolB = intersector;           << 
797     pSolA->BoundingLimits(minA,maxA);          << 
798     pSolB->BoundingLimits(minB,maxB);          << 
799     pMin.set(std::max(minA.x(),minB.x()),      << 
800              std::max(minA.y(),minB.y()),      << 
801              std::max(minA.z(),minB.z()));     << 
802     pMax.set(std::min(maxA.x(),maxB.x()),      << 
803              std::min(maxA.y(),maxB.y()),      << 
804              std::min(maxA.z(),maxB.z()));     << 
805     if (pMin.x() >= pMax.x() || pMin.y() >= pM << 
806       // Bad bounding box (min >= max)         << 
807       // This signifies a subtraction of non-i << 
808       return false;                            << 
809     }                                          << 
810     return true;                               << 
811   }                                            << 
812 }                                                 375 }
813                                                   376 
814 void G4PhysicalVolumeModel::DescribeSolid         377 void G4PhysicalVolumeModel::DescribeSolid
815 (const G4Transform3D& theAT,                      378 (const G4Transform3D& theAT,
816  G4VSolid* pSol,                                  379  G4VSolid* pSol,
817  const G4VisAttributes* pVisAttribs,              380  const G4VisAttributes* pVisAttribs,
818  G4VGraphicsScene& sceneHandler)               << 381  G4VGraphicsScene& sceneHandler) {
819 {                                              << 382   sceneHandler.PreAddThis (theAT, *pVisAttribs);
820   G4DisplacedSolid* pSectionSolid = fpMP->GetS << 383   pSol -> DescribeYourselfTo (sceneHandler);
821   G4DisplacedSolid* pCutawaySolid = fpMP->GetC << 384   sceneHandler.PostAddThis ();
822                                                << 385 }
823   if (fNClippers <= 0 || fNClippers > 1) {     << 386 
824                                                << 387 G4bool G4PhysicalVolumeModel::IsThisCulled (const G4LogicalVolume* pLV,
825     // Normal case - no clipping, etc. - or, i << 388               const G4Material* pMaterial) {
826     sceneHandler.PreAddSolid (theAT, *pVisAttr << 389   // If true, cull, i.e., do not Draw.
827     pSol -> DescribeYourselfTo (sceneHandler); << 390   G4double density = 0.;
828     sceneHandler.PostAddSolid ();              << 391   if (pMaterial) density = pMaterial -> GetDensity ();
829                                                << 392   const G4VisAttributes* pVisAttribs = pLV -> GetVisAttributes ();
830   } else {  // fNClippers == 1                 << 393   if (!pVisAttribs) pVisAttribs = fpMP -> GetDefaultVisAttributes ();
831                                                << 394   if (fpMP) {
832     G4VSolid*         pResultantSolid = nullpt << 395     return
833     G4DisplacedSolid* pDisplacedSolid = nullpt << 396       fpMP -> IsCulling () &&       // Global culling flag.
834                                                << 397       (   
835     if (fpClippingSolid) {                     << 398        // Invisible volumes...
836       pDisplacedSolid = new G4DisplacedSolid(" << 399        (fpMP -> IsCullingInvisible () &&
837       switch (fClippingMode) {                 << 400   !(pVisAttribs ? pVisAttribs -> IsVisible () : true)) ||
838         case subtraction:                      << 401 
839           if (SubtractionBoundingLimits(pSol)) << 402        // Low density volumes...
840             pResultantSolid = new G4Subtractio << 403        (fpMP -> IsDensityCulling () &&
841             ("subtracted_clipped_solid", pSol, << 404   (density < fpMP -> GetVisibleDensity ()))
842           }                                    << 405        )
843           break;                               << 406       ;
844         case intersection:                     << 
845           if (IntersectionBoundingLimits(pSol, << 
846             pResultantSolid = new G4Intersecti << 
847             ("intersected_clipped_solid", pSol << 
848           }                                    << 
849           break;                               << 
850       }                                        << 
851                                                << 
852     } else if (pSectionSolid) {                << 
853       pDisplacedSolid = new G4DisplacedSolid(" << 
854       if (IntersectionBoundingLimits(pSol, pDi << 
855         pResultantSolid = new G4IntersectionSo << 
856       }                                        << 
857                                                << 
858     } else if (pCutawaySolid) {                << 
859       pDisplacedSolid = new G4DisplacedSolid(" << 
860       switch (fpMP->GetCutawayMode()) {        << 
861         case G4ModelingParameters::cutawayUnio << 
862           if (SubtractionBoundingLimits(pSol)) << 
863             pResultantSolid = new G4Subtractio << 
864           }                                    << 
865           break;                               << 
866         case G4ModelingParameters::cutawayInte << 
867           if (IntersectionBoundingLimits(pSol, << 
868             pResultantSolid = new G4Intersecti << 
869           }                                    << 
870           break;                               << 
871       }                                        << 
872     }                                          << 
873                                                << 
874     if (pResultantSolid) {                     << 
875       sceneHandler.PreAddSolid (theAT, *pVisAt << 
876       pResultantSolid -> DescribeYourselfTo (s << 
877       sceneHandler.PostAddSolid ();            << 
878     }                                          << 
879                                                << 
880     delete pResultantSolid;                    << 
881     delete pDisplacedSolid;                    << 
882   }                                               407   }
883 }                                              << 408   else {
884                                                << 
885 G4bool G4PhysicalVolumeModel::Validate (G4bool << 
886 {                                              << 
887 // Not easy to see how to validate this sort o << 
888 // a check that a volume of the same name (fTo << 
889 // the geometry tree but under some circumstan << 
890 // time. Instead, let us simply check that the << 
891 // physical volume store.                      << 
892   const auto& pvStore = G4PhysicalVolumeStore: << 
893   auto iterator = find(pvStore->begin(),pvStor << 
894   if (iterator == pvStore->end()) {            << 
895     if (warn) {                                << 
896       G4ExceptionDescription ed;               << 
897       ed << "Attempt to validate a volume that << 
898       G4Exception("G4PhysicalVolumeModel::Vali << 
899     }                                          << 
900     return false;                                 409     return false;
901   } else {                                     << 
902     return true;                               << 
903   }                                            << 
904 }                                              << 
905                                                << 
906 const std::map<G4String,G4AttDef>* G4PhysicalV << 
907 {                                              << 
908     G4bool isNew;                              << 
909     std::map<G4String,G4AttDef>* store         << 
910       = G4AttDefStore::GetInstance("G4Physical << 
911     if (isNew) {                               << 
912       (*store)["PVPath"] =                     << 
913       G4AttDef("PVPath","Physical Volume Path" << 
914       (*store)["BasePVPath"] =                 << 
915       G4AttDef("BasePVPath","Base Physical Vol << 
916       (*store)["LVol"] =                       << 
917       G4AttDef("LVol","Logical Volume","Physic << 
918       (*store)["Solid"] =                      << 
919       G4AttDef("Solid","Solid Name","Physics", << 
920       (*store)["EType"] =                      << 
921       G4AttDef("EType","Entity Type","Physics" << 
922       (*store)["DmpSol"] =                     << 
923       G4AttDef("DmpSol","Dump of Solid propert << 
924       (*store)["LocalTrans"] =                 << 
925       G4AttDef("LocalTrans","Local transformat << 
926       (*store)["LocalExtent"] =                << 
927       G4AttDef("LocalExtent","Local extent of  << 
928       (*store)["GlobalTrans"] =                << 
929       G4AttDef("GlobalTrans","Global transform << 
930       (*store)["GlobalExtent"] =               << 
931       G4AttDef("GlobalExtent","Global extent o << 
932       (*store)["Material"] =                   << 
933       G4AttDef("Material","Material Name","Phy << 
934       (*store)["Density"] =                    << 
935       G4AttDef("Density","Material Density","P << 
936       (*store)["State"] =                      << 
937       G4AttDef("State","Material State (enum u << 
938       (*store)["Radlen"] =                     << 
939       G4AttDef("Radlen","Material Radiation Le << 
940       (*store)["Region"] =                     << 
941       G4AttDef("Region","Cuts Region","Physics << 
942       (*store)["RootRegion"] =                 << 
943       G4AttDef("RootRegion","Root Region (0/1  << 
944     }                                          << 
945   return store;                                << 
946 }                                              << 
947                                                << 
948 static std::ostream& operator<< (std::ostream& << 
949 {                                              << 
950   using namespace std;                         << 
951                                                << 
952   G4Scale3D sc;                                << 
953   G4Rotate3D r;                                << 
954   G4Translate3D tl;                            << 
955   t.getDecomposition(sc, r, tl);               << 
956                                                << 
957   const int w = 10;                            << 
958                                                << 
959   // Transformation itself                     << 
960   o << setw(w) << t.xx() << setw(w) << t.xy()  << 
961   o << setw(w) << t.yx() << setw(w) << t.yy()  << 
962   o << setw(w) << t.zx() << setw(w) << t.zy()  << 
963                                                << 
964   // Translation                               << 
965   o << "= translation:" << endl;               << 
966   o << setw(w) << tl.dx() << setw(w) << tl.dy( << 
967                                                << 
968   // Rotation                                  << 
969   o << "* rotation:" << endl;                  << 
970   o << setw(w) << r.xx() << setw(w) << r.xy()  << 
971   o << setw(w) << r.yx() << setw(w) << r.yy()  << 
972   o << setw(w) << r.zx() << setw(w) << r.zy()  << 
973                                                << 
974   // Scale                                     << 
975   o << "* scale:" << endl;                     << 
976   o << setw(w) << sc.xx() << setw(w) << sc.yy( << 
977                                                << 
978   // Transformed axes                          << 
979   o << "Transformed axes:" << endl;            << 
980   o << "x': " << r * G4Vector3D(1., 0., 0.) << << 
981   o << "y': " << r * G4Vector3D(0., 1., 0.) << << 
982   o << "z': " << r * G4Vector3D(0., 0., 1.) << << 
983                                                << 
984   return o;                                    << 
985 }                                              << 
986                                                << 
987 std::vector<G4AttValue>* G4PhysicalVolumeModel << 
988 {                                              << 
989   std::vector<G4AttValue>* values = new std::v << 
990                                                << 
991   if (!fpCurrentLV) {                          << 
992      G4Exception                               << 
993         ("G4PhysicalVolumeModel::CreateCurrent << 
994          "modeling0004",                       << 
995          JustWarning,                          << 
996          "Current logical volume not defined." << 
997      return values;                            << 
998   }                                               410   }
999                                                << 
1000   std::ostringstream oss; oss << fFullPVPath; << 
1001   values->push_back(G4AttValue("PVPath", oss. << 
1002                                               << 
1003   oss.str(""); oss << fBaseFullPVPath;        << 
1004   values->push_back(G4AttValue("BasePVPath",  << 
1005                                               << 
1006   values->push_back(G4AttValue("LVol", fpCurr << 
1007   G4VSolid* pSol = fpCurrentLV->GetSolid();   << 
1008                                               << 
1009   values->push_back(G4AttValue("Solid", pSol- << 
1010                                               << 
1011   values->push_back(G4AttValue("EType", pSol- << 
1012                                               << 
1013   oss.str(""); oss << '\n' << *pSol;          << 
1014   values->push_back(G4AttValue("DmpSol", oss. << 
1015                                               << 
1016   const G4RotationMatrix localRotation = fpCu << 
1017   const G4ThreeVector& localTranslation = fpC << 
1018   oss.str(""); oss << '\n' << G4Transform3D(l << 
1019   values->push_back(G4AttValue("LocalTrans",  << 
1020                                               << 
1021   oss.str(""); oss << '\n' << pSol->GetExtent << 
1022   values->push_back(G4AttValue("LocalExtent", << 
1023                                               << 
1024   oss.str(""); oss << '\n' << fCurrentTransfo << 
1025   values->push_back(G4AttValue("GlobalTrans", << 
1026                                               << 
1027   oss.str(""); oss << '\n' << (pSol->GetExten << 
1028   values->push_back(G4AttValue("GlobalExtent" << 
1029                                               << 
1030   G4String matName = fpCurrentMaterial? fpCur << 
1031   values->push_back(G4AttValue("Material", ma << 
1032                                               << 
1033   G4double matDensity = fpCurrentMaterial? fp << 
1034   values->push_back(G4AttValue("Density", G4B << 
1035                                               << 
1036   G4State matState = fpCurrentMaterial? fpCur << 
1037   oss.str(""); oss << matState;               << 
1038   values->push_back(G4AttValue("State", oss.s << 
1039                                               << 
1040   G4double matRadlen = fpCurrentMaterial? fpC << 
1041   values->push_back(G4AttValue("Radlen", G4Be << 
1042                                               << 
1043   G4Region* region = fpCurrentLV->GetRegion() << 
1044   G4String regionName = region? region->GetNa << 
1045   values->push_back(G4AttValue("Region", regi << 
1046                                               << 
1047   oss.str(""); oss << fpCurrentLV->IsRootRegi << 
1048   values->push_back(G4AttValue("RootRegion",  << 
1049                                               << 
1050   return values;                              << 
1051 }                                                411 }
1052                                                  412 
1053 G4bool G4PhysicalVolumeModel::G4PhysicalVolum << 413 G4bool G4PhysicalVolumeModel::IsDaughterCulled
1054   (const G4PhysicalVolumeModel::G4PhysicalVol << 414 (const G4LogicalVolume* pMotherLV) {
1055 {                                             << 415   // If true, cull, i.e., do not Draw.
1056   if (fpPV < right.fpPV) return true;         << 416   const G4VisAttributes* pVisAttribs = pMotherLV -> GetVisAttributes ();
1057   if (fpPV == right.fpPV) {                   << 417   if (!pVisAttribs) pVisAttribs = fpMP -> GetDefaultVisAttributes ();
1058     if (fCopyNo < right.fCopyNo) return true; << 418   if (fpMP) {
1059     if (fCopyNo == right.fCopyNo)             << 419     return
1060       return fNonCulledDepth < right.fNonCull << 420       fpMP -> IsCulling ()           // Global culling flag.
                                                   >> 421       &&
                                                   >> 422       (
                                                   >> 423        // Does mother request daughters not to be drawn?
                                                   >> 424        (pVisAttribs ? pVisAttribs -> IsDaughtersInvisible () : false)
                                                   >> 425        ||
                                                   >> 426        (
                                                   >> 427   // Global covered daughter flag.  This is affected by drawing
                                                   >> 428   // style, etc.  The enforcing of this is done in
                                                   >> 429   // G4VScene::CreateModelingParameters ()
                                                   >> 430   fpMP -> IsCullingCovered ()
                                                   >> 431   &&
                                                   >> 432   // Cull only if mother is visible...
                                                   >> 433   (pVisAttribs ? pVisAttribs -> IsVisible () : true)
                                                   >> 434   // &&
                                                   >> 435   // true // ...and opaque (transparency parameter not yet implemented).
                                                   >> 436   )
                                                   >> 437        )
                                                   >> 438       ;
1061   }                                              439   }
1062   return false;                               << 440   else {
1063 }                                             << 441     return false;
1064                                               << 
1065 G4bool G4PhysicalVolumeModel::G4PhysicalVolum << 
1066   (const G4PhysicalVolumeModel::G4PhysicalVol << 
1067 {                                             << 
1068   if (fpPV            != right.fpPV ||        << 
1069       fCopyNo         != right.fCopyNo ||     << 
1070       fNonCulledDepth != right.fNonCulledDept << 
1071       fTransform      != right.fTransform ||  << 
1072       fDrawn          != right.fDrawn) return << 
1073   return false;                               << 
1074 }                                             << 
1075                                               << 
1076 std::ostream& operator<<                      << 
1077   (std::ostream& os, const G4PhysicalVolumeMo << 
1078 {                                             << 
1079   G4VPhysicalVolume* pPV = node.GetPhysicalVo << 
1080   if (pPV) {                                  << 
1081     os << pPV->GetName()                      << 
1082        << ' ' << node.GetCopyNo()             << 
1083 //       << '[' << node.GetNonCulledDepth() < << 
1084 //       << ':' << node.GetTransform()        << 
1085     ;                                         << 
1086 //    os << " (";                             << 
1087 //    if (!node.GetDrawn()) os << "not ";     << 
1088 //    os << "drawn)";                         << 
1089   } else {                                    << 
1090     os << " (Null PV node)";                  << 
1091   }                                              442   }
1092   return os;                                  << 
1093 }                                                443 }
1094                                                  444 
1095 std::ostream& operator<<                      << 445 G4bool G4PhysicalVolumeModel::Validate (G4bool warn) {
1096 (std::ostream& os, const std::vector<G4Physic << 446   G4VPhysicalVolume* world =
1097 {                                             << 447     G4TransportationManager::GetTransportationManager ()
1098   if (path.empty()) {                         << 448     -> GetNavigatorForTracking () -> GetWorldVolume ();
1099     os << " TOP";                             << 449   // The idea now is to seek a PV with the same name and copy no
1100   } else {                                    << 450   // in the hope it's the same one!!
1101     for (const auto& nodeID: path) {          << 451   if (warn) {
1102       os << ' ' << nodeID;                    << 452     G4cout << "G4PhysicalVolumeModel::Validate() called." << G4endl;
                                                   >> 453   }
                                                   >> 454   G4PhysicalVolumeSearchScene searchScene (fTopPVName, fTopPVCopyNo);
                                                   >> 455   G4PhysicalVolumeModel searchModel (world);
                                                   >> 456   G4ModelingParameters mp;  // Default modeling parameters for this search.
                                                   >> 457   searchModel.SetModelingParameters (&mp);
                                                   >> 458   searchModel.DescribeYourselfTo (searchScene);
                                                   >> 459   G4VPhysicalVolume* foundVolume = searchScene.GetFoundVolume ();
                                                   >> 460   if (foundVolume) {
                                                   >> 461     if (warn) {
                                                   >> 462       G4cout << "  Volume of the same name and copy number (\""
                                                   >> 463        << fTopPVName << "\", copy " << fTopPVCopyNo
                                                   >> 464        << ") still exists and is being used."
                                                   >> 465   "\n  Be warned that this does not necessarily guarantee it's the same"
                                                   >> 466   "\n  volume you originally specified in /vis/scene/add/."
                                                   >> 467        << G4endl;
1103     }                                            468     }
                                                   >> 469     fpTopPV = foundVolume;
                                                   >> 470     CalculateExtent ();
                                                   >> 471     return true;
1104   }                                              472   }
1105   return os;                                  << 473   else {
1106 }                                             << 474     if (warn) {
1107                                               << 475       G4cout << "  A volume of the same name and copy number (\""
1108 G4PhysicalVolumeModel::G4PhysicalVolumeModelT << 476        << fTopPVName << "\", copy " << fTopPVCopyNo
1109 (const std::vector<G4PhysicalVolumeNodeID>& f << 477        << ") no longer exists."
1110   fFullPVPath(fullPVPath) {}                  << 478        << G4endl;
1111                                               << 479     }
1112 const G4ThreeVector& G4PhysicalVolumeModel::G << 480     return false;
1113 {                                             << 
1114   size_t i = fFullPVPath.size() - depth - 1;  << 
1115   if (i >= fFullPVPath.size()) {              << 
1116     G4Exception("G4PhysicalVolumeModelTouchab << 
1117     "modeling0005",                           << 
1118     FatalErrorInArgument,                     << 
1119     "Index out of range. Asking for non-exist << 
1120   }                                           << 
1121   static G4ThreeVector tempTranslation;       << 
1122   tempTranslation = fFullPVPath[i].GetTransfo << 
1123   return tempTranslation;                     << 
1124 }                                             << 
1125                                               << 
1126 const G4RotationMatrix* G4PhysicalVolumeModel << 
1127 {                                             << 
1128   size_t i = fFullPVPath.size() - depth - 1;  << 
1129   if (i >= fFullPVPath.size()) {              << 
1130     G4Exception("G4PhysicalVolumeModelTouchab << 
1131     "modeling0006",                           << 
1132     FatalErrorInArgument,                     << 
1133     "Index out of range. Asking for non-exist << 
1134   }                                           << 
1135   static G4RotationMatrix tempRotation;       << 
1136   tempRotation = fFullPVPath[i].GetTransform( << 
1137   return &tempRotation;                       << 
1138 }                                             << 
1139                                               << 
1140 G4VPhysicalVolume* G4PhysicalVolumeModel::G4P << 
1141 {                                             << 
1142   size_t i = fFullPVPath.size() - depth - 1;  << 
1143   if (i >= fFullPVPath.size()) {              << 
1144     G4Exception("G4PhysicalVolumeModelTouchab << 
1145     "modeling0007",                           << 
1146     FatalErrorInArgument,                     << 
1147     "Index out of range. Asking for non-exist << 
1148   }                                           << 
1149   return fFullPVPath[i].GetPhysicalVolume();  << 
1150 }                                             << 
1151                                               << 
1152 G4VSolid* G4PhysicalVolumeModel::G4PhysicalVo << 
1153 {                                             << 
1154   size_t i = fFullPVPath.size() - depth - 1;  << 
1155   if (i >= fFullPVPath.size()) {              << 
1156     G4Exception("G4PhysicalVolumeModelTouchab << 
1157     "modeling0008",                           << 
1158     FatalErrorInArgument,                     << 
1159     "Index out of range. Asking for non-exist << 
1160   }                                           << 
1161   return fFullPVPath[i].GetPhysicalVolume()-> << 
1162 }                                             << 
1163                                               << 
1164 G4int G4PhysicalVolumeModel::G4PhysicalVolume << 
1165 {                                             << 
1166   size_t i = fFullPVPath.size() - depth - 1;  << 
1167   if (i >= fFullPVPath.size()) {              << 
1168     G4Exception("G4PhysicalVolumeModelTouchab << 
1169     "modeling0009",                           << 
1170     FatalErrorInArgument,                     << 
1171     "Index out of range. Asking for non-exist << 
1172   }                                              481   }
1173   return fFullPVPath[i].GetCopyNo();          << 
1174 }                                                482 }
1175                                                  483