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 10.1)


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