Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/visualization/management/src/G4VSceneHandler.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/management/src/G4VSceneHandler.cc (Version 11.3.0) and /visualization/management/src/G4VSceneHandler.cc (Version 10.5.p1)


  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 //                                                 27 //
 28 //                                                 28 // 
 29 // John Allison  19th July 1996                    29 // John Allison  19th July 1996
 30 // Abstract interface class for graphics scene     30 // Abstract interface class for graphics scenes.
 31                                                    31 
 32 #include "G4VSceneHandler.hh"                      32 #include "G4VSceneHandler.hh"
 33                                                    33 
 34 #include "G4ios.hh"                                34 #include "G4ios.hh"
 35 #include <sstream>                                 35 #include <sstream>
 36                                                    36 
 37 #include "G4VisManager.hh"                         37 #include "G4VisManager.hh"
 38 #include "G4VGraphicsSystem.hh"                    38 #include "G4VGraphicsSystem.hh"
 39 #include "G4VViewer.hh"                            39 #include "G4VViewer.hh"
 40 #include "G4VSolid.hh"                             40 #include "G4VSolid.hh"
 41 #include "G4RotationMatrix.hh"                     41 #include "G4RotationMatrix.hh"
 42 #include "G4ThreeVector.hh"                        42 #include "G4ThreeVector.hh"
 43 #include "G4VPhysicalVolume.hh"                    43 #include "G4VPhysicalVolume.hh"
 44 #include "G4Material.hh"                           44 #include "G4Material.hh"
 45 #include "G4Polyline.hh"                           45 #include "G4Polyline.hh"
                                                   >>  46 #include "G4Scale.hh"
 46 #include "G4Text.hh"                               47 #include "G4Text.hh"
 47 #include "G4Circle.hh"                             48 #include "G4Circle.hh"
 48 #include "G4Square.hh"                             49 #include "G4Square.hh"
 49 #include "G4Polymarker.hh"                         50 #include "G4Polymarker.hh"
 50 #include "G4Polyhedron.hh"                         51 #include "G4Polyhedron.hh"
 51 #include "G4Visible.hh"                            52 #include "G4Visible.hh"
 52 #include "G4VisAttributes.hh"                      53 #include "G4VisAttributes.hh"
 53 #include "G4VModel.hh"                             54 #include "G4VModel.hh"
 54 #include "G4TrajectoriesModel.hh"                  55 #include "G4TrajectoriesModel.hh"
 55 #include "G4Box.hh"                                56 #include "G4Box.hh"
 56 #include "G4Cons.hh"                               57 #include "G4Cons.hh"
 57 #include "G4Orb.hh"                                58 #include "G4Orb.hh"
 58 #include "G4Para.hh"                               59 #include "G4Para.hh"
 59 #include "G4Sphere.hh"                             60 #include "G4Sphere.hh"
 60 #include "G4Torus.hh"                              61 #include "G4Torus.hh"
 61 #include "G4Trap.hh"                               62 #include "G4Trap.hh"
 62 #include "G4Trd.hh"                                63 #include "G4Trd.hh"
 63 #include "G4Tubs.hh"                               64 #include "G4Tubs.hh"
 64 #include "G4Ellipsoid.hh"                          65 #include "G4Ellipsoid.hh"
 65 #include "G4Polycone.hh"                           66 #include "G4Polycone.hh"
 66 #include "G4Polyhedra.hh"                          67 #include "G4Polyhedra.hh"
 67 #include "G4Tet.hh"                            << 
 68 #include "G4DisplacedSolid.hh"                     68 #include "G4DisplacedSolid.hh"
 69 #include "G4UnionSolid.hh"                     << 
 70 #include "G4IntersectionSolid.hh"              << 
 71 #include "G4SubtractionSolid.hh"               << 
 72 #include "G4LogicalVolume.hh"                      69 #include "G4LogicalVolume.hh"
 73 #include "G4PhysicalVolumeModel.hh"                70 #include "G4PhysicalVolumeModel.hh"
 74 #include "G4ModelingParameters.hh"                 71 #include "G4ModelingParameters.hh"
 75 #include "G4VTrajectory.hh"                        72 #include "G4VTrajectory.hh"
 76 #include "G4VTrajectoryPoint.hh"                   73 #include "G4VTrajectoryPoint.hh"
 77 #include "G4HitsModel.hh"                          74 #include "G4HitsModel.hh"
 78 #include "G4VHit.hh"                               75 #include "G4VHit.hh"
 79 #include "G4VDigi.hh"                              76 #include "G4VDigi.hh"
 80 #include "G4ScoringManager.hh"                     77 #include "G4ScoringManager.hh"
 81 #include "G4VScoringMesh.hh"                   << 
 82 #include "G4Mesh.hh"                           << 
 83 #include "G4DefaultLinearColorMap.hh"              78 #include "G4DefaultLinearColorMap.hh"
 84 #include "G4QuickRand.hh"                      <<  79 #include "Randomize.hh"
 85 #include "G4StateManager.hh"                       80 #include "G4StateManager.hh"
 86 #include "G4RunManager.hh"                         81 #include "G4RunManager.hh"
 87 #include "G4RunManagerFactory.hh"              <<  82 #ifdef G4MULTITHREADED
                                                   >>  83 #include "G4MTRunManager.hh"
                                                   >>  84 #endif
 88 #include "G4Run.hh"                                85 #include "G4Run.hh"
 89 #include "G4Transform3D.hh"                        86 #include "G4Transform3D.hh"
 90 #include "G4AttHolder.hh"                          87 #include "G4AttHolder.hh"
 91 #include "G4AttDef.hh"                             88 #include "G4AttDef.hh"
 92 #include "G4SceneTreeItem.hh"                  << 
 93 #include "G4VVisCommand.hh"                        89 #include "G4VVisCommand.hh"
 94 #include "G4PhysicalConstants.hh"                  90 #include "G4PhysicalConstants.hh"
 95 #include "G4SystemOfUnits.hh"                      91 #include "G4SystemOfUnits.hh"
 96                                                    92 
 97 #define G4warn G4cout                          << 
 98                                                << 
 99 G4VSceneHandler::G4VSceneHandler (G4VGraphicsS     93 G4VSceneHandler::G4VSceneHandler (G4VGraphicsSystem& system, G4int id, const G4String& name):
100   fSystem                (system),                 94   fSystem                (system),
101   fSceneHandlerId        (id),                     95   fSceneHandlerId        (id),
102   fViewCount             (0),                      96   fViewCount             (0),
103   fpViewer               (0),                      97   fpViewer               (0),
104   fpScene                (0),                      98   fpScene                (0),
105   fMarkForClearingTransientStore (true),  // R     99   fMarkForClearingTransientStore (true),  // Ready for first
106             // ClearTransientStoreIfMarked(),     100             // ClearTransientStoreIfMarked(),
107             // e.g., at end of run (see           101             // e.g., at end of run (see
108             // G4VisManager.cc).                  102             // G4VisManager.cc).
109   fReadyForTransients    (true),  // Only fals    103   fReadyForTransients    (true),  // Only false while processing scene.
110   fProcessingSolid       (false),                 104   fProcessingSolid       (false),
111   fProcessing2D          (false),                 105   fProcessing2D          (false),
112   fpModel                (0),                     106   fpModel                (0),
113   fNestingDepth          (0),                     107   fNestingDepth          (0),
114   fpVisAttribs           (0)                      108   fpVisAttribs           (0)
115 {                                                 109 {
116   G4VisManager* pVMan = G4VisManager::GetInsta    110   G4VisManager* pVMan = G4VisManager::GetInstance ();
117   fpScene = pVMan -> GetCurrentScene ();          111   fpScene = pVMan -> GetCurrentScene ();
118   if (name == "") {                               112   if (name == "") {
119     std::ostringstream ost;                       113     std::ostringstream ost;
120     ost << fSystem.GetName () << '-' << fScene    114     ost << fSystem.GetName () << '-' << fSceneHandlerId;
121     fName = ost.str();                            115     fName = ost.str();
122   }                                               116   }
123   else {                                          117   else {
124     fName = name;                                 118     fName = name;
125   }                                               119   }
126   fTransientsDrawnThisEvent = pVMan->GetTransi    120   fTransientsDrawnThisEvent = pVMan->GetTransientsDrawnThisEvent();
127   fTransientsDrawnThisRun = pVMan->GetTransien    121   fTransientsDrawnThisRun = pVMan->GetTransientsDrawnThisRun();
128 }                                                 122 }
129                                                   123 
130 G4VSceneHandler::~G4VSceneHandler () {            124 G4VSceneHandler::~G4VSceneHandler () {
131   G4VViewer* last;                                125   G4VViewer* last;
132   while( ! fViewerList.empty() ) {                126   while( ! fViewerList.empty() ) {
133     last = fViewerList.back();                    127     last = fViewerList.back();
134     fViewerList.pop_back();                       128     fViewerList.pop_back();
135     delete last;                                  129     delete last;
136   }                                               130   }
137 }                                                 131 }
138                                                   132 
139 const G4VisExtent& G4VSceneHandler::GetExtent(    133 const G4VisExtent& G4VSceneHandler::GetExtent() const
140 {                                                 134 {
141   if (fpScene) {                                  135   if (fpScene) {
142     return fpScene->GetExtent();                  136     return fpScene->GetExtent();
143   } else {                                        137   } else {
144     static const G4VisExtent defaultExtent = G    138     static const G4VisExtent defaultExtent = G4VisExtent();
145     return defaultExtent;                         139     return defaultExtent;
146   }                                               140   }
147 }                                                 141 }
148                                                   142 
149 void G4VSceneHandler::PreAddSolid (const G4Tra    143 void G4VSceneHandler::PreAddSolid (const G4Transform3D& objectTransformation,
150            const G4VisAttributes& visAttribs)     144            const G4VisAttributes& visAttribs) {
151   fObjectTransformation = objectTransformation    145   fObjectTransformation = objectTransformation;
152   fpVisAttribs = &visAttribs;                     146   fpVisAttribs = &visAttribs;
153   fProcessingSolid = true;                        147   fProcessingSolid = true;
154 }                                                 148 }
155                                                   149 
156 void G4VSceneHandler::PostAddSolid () {           150 void G4VSceneHandler::PostAddSolid () {
157   fpVisAttribs = 0;                               151   fpVisAttribs = 0;
158   fProcessingSolid = false;                       152   fProcessingSolid = false;
159   if (fReadyForTransients) {                      153   if (fReadyForTransients) {
160     fTransientsDrawnThisEvent = true;             154     fTransientsDrawnThisEvent = true;
161     fTransientsDrawnThisRun = true;               155     fTransientsDrawnThisRun = true;
162   }                                               156   }
163 }                                                 157 }
164                                                   158 
165 void G4VSceneHandler::BeginPrimitives             159 void G4VSceneHandler::BeginPrimitives
166 (const G4Transform3D& objectTransformation) {     160 (const G4Transform3D& objectTransformation) {
167   //static G4int count = 0;                       161   //static G4int count = 0;
168   //G4cout << "G4VSceneHandler::BeginPrimitive    162   //G4cout << "G4VSceneHandler::BeginPrimitives: " << count++ << G4endl;
169   fNestingDepth++;                                163   fNestingDepth++;
170   if (fNestingDepth > 1)                          164   if (fNestingDepth > 1)
171     G4Exception                                   165     G4Exception
172       ("G4VSceneHandler::BeginPrimitives",        166       ("G4VSceneHandler::BeginPrimitives",
173        "visman0101", FatalException,              167        "visman0101", FatalException,
174        "Nesting detected. It is illegal to nes    168        "Nesting detected. It is illegal to nest Begin/EndPrimitives.");
175   fObjectTransformation = objectTransformation    169   fObjectTransformation = objectTransformation;
176 }                                                 170 }
177                                                   171 
178 void G4VSceneHandler::EndPrimitives () {          172 void G4VSceneHandler::EndPrimitives () {
179   if (fNestingDepth <= 0)                         173   if (fNestingDepth <= 0)
180     G4Exception("G4VSceneHandler::EndPrimitive    174     G4Exception("G4VSceneHandler::EndPrimitives",
181     "visman0102", FatalException, "Nesting err    175     "visman0102", FatalException, "Nesting error.");
182   fNestingDepth--;                                176   fNestingDepth--;
183   if (fReadyForTransients) {                      177   if (fReadyForTransients) {
184     fTransientsDrawnThisEvent = true;             178     fTransientsDrawnThisEvent = true;
185     fTransientsDrawnThisRun = true;               179     fTransientsDrawnThisRun = true;
186   }                                               180   }
187 }                                                 181 }
188                                                   182 
189 void G4VSceneHandler::BeginPrimitives2D           183 void G4VSceneHandler::BeginPrimitives2D
190 (const G4Transform3D& objectTransformation) {     184 (const G4Transform3D& objectTransformation) {
191   fNestingDepth++;                                185   fNestingDepth++;
192   if (fNestingDepth > 1)                          186   if (fNestingDepth > 1)
193     G4Exception                                   187     G4Exception
194       ("G4VSceneHandler::BeginPrimitives2D",      188       ("G4VSceneHandler::BeginPrimitives2D",
195        "visman0103", FatalException,              189        "visman0103", FatalException,
196        "Nesting detected. It is illegal to nes    190        "Nesting detected. It is illegal to nest Begin/EndPrimitives.");
197   fObjectTransformation = objectTransformation    191   fObjectTransformation = objectTransformation;
198   fProcessing2D = true;                           192   fProcessing2D = true;
199 }                                                 193 }
200                                                   194 
201 void G4VSceneHandler::EndPrimitives2D () {        195 void G4VSceneHandler::EndPrimitives2D () {
202   if (fNestingDepth <= 0)                         196   if (fNestingDepth <= 0)
203     G4Exception("G4VSceneHandler::EndPrimitive    197     G4Exception("G4VSceneHandler::EndPrimitives2D",
204     "visman0104", FatalException, "Nesting err    198     "visman0104", FatalException, "Nesting error.");
205   fNestingDepth--;                                199   fNestingDepth--;
206   if (fReadyForTransients) {                      200   if (fReadyForTransients) {
207     fTransientsDrawnThisEvent = true;             201     fTransientsDrawnThisEvent = true;
208     fTransientsDrawnThisRun = true;               202     fTransientsDrawnThisRun = true;
209   }                                               203   }
210   fProcessing2D = false;                          204   fProcessing2D = false;
211 }                                                 205 }
212                                                   206 
213 void G4VSceneHandler::BeginModeling () {          207 void G4VSceneHandler::BeginModeling () {
214 }                                                 208 }
215                                                   209 
216 void G4VSceneHandler::EndModeling ()              210 void G4VSceneHandler::EndModeling ()
217 {                                                 211 {
218   fpModel = 0;                                    212   fpModel = 0;
219 }                                                 213 }
220                                                   214 
221 void G4VSceneHandler::ClearStore () {}            215 void G4VSceneHandler::ClearStore () {}
222                                                   216 
223 void G4VSceneHandler::ClearTransientStore () {    217 void G4VSceneHandler::ClearTransientStore () {}
224                                                   218 
225 template <class T> void G4VSceneHandler::AddSo    219 template <class T> void G4VSceneHandler::AddSolidT
226 (const T& solid)                                  220 (const T& solid)
227 {                                                 221 {
228   // Get and check applicable vis attributes.     222   // Get and check applicable vis attributes.
229   fpVisAttribs = fpViewer->GetApplicableVisAtt    223   fpVisAttribs = fpViewer->GetApplicableVisAttributes(fpVisAttribs);
230   RequestPrimitives (solid);                      224   RequestPrimitives (solid);
231 }                                                 225 }
232                                                   226 
233 template <class T> void G4VSceneHandler::AddSo    227 template <class T> void G4VSceneHandler::AddSolidWithAuxiliaryEdges
234 (const T& solid)                                  228 (const T& solid)
235 {                                                 229 {
236   // Get and check applicable vis attributes.     230   // Get and check applicable vis attributes.
237   fpVisAttribs = fpViewer->GetApplicableVisAtt    231   fpVisAttribs = fpViewer->GetApplicableVisAttributes(fpVisAttribs);
238   // Draw with auxiliary edges unless otherwis    232   // Draw with auxiliary edges unless otherwise specified.
239   if (!fpVisAttribs->IsForceAuxEdgeVisible())     233   if (!fpVisAttribs->IsForceAuxEdgeVisible()) {
240     // Create a vis atts object for the modifi    234     // Create a vis atts object for the modified vis atts.
241     // It is static so that we may return a re    235     // It is static so that we may return a reliable pointer to it.
242     static G4VisAttributes visAttsWithAuxEdges    236     static G4VisAttributes visAttsWithAuxEdges;
243     // Initialise it with the current vis atts    237     // Initialise it with the current vis atts and reset the pointer.
244     visAttsWithAuxEdges = *fpVisAttribs;          238     visAttsWithAuxEdges = *fpVisAttribs;
245     // Force auxiliary edges visible.             239     // Force auxiliary edges visible.
246     visAttsWithAuxEdges.SetForceAuxEdgeVisible    240     visAttsWithAuxEdges.SetForceAuxEdgeVisible();
247     fpVisAttribs = &visAttsWithAuxEdges;          241     fpVisAttribs = &visAttsWithAuxEdges;
248   }                                               242   }
249   RequestPrimitives (solid);                      243   RequestPrimitives (solid);
250 }                                                 244 }
251                                                   245 
252 void G4VSceneHandler::AddSolid (const G4Box& b    246 void G4VSceneHandler::AddSolid (const G4Box& box) {
253   AddSolidT (box);                                247   AddSolidT (box);
254   // If your graphics system is sophisticated     248   // If your graphics system is sophisticated enough to handle a
255   //  particular solid shape as a primitive, i    249   //  particular solid shape as a primitive, in your derived class write a
256   //  function to override this.                  250   //  function to override this.
257   // Your function might look like this...        251   // Your function might look like this...
258   // void G4MySceneHandler::AddSolid (const G4    252   // void G4MySceneHandler::AddSolid (const G4Box& box) {
259   // Get and check applicable vis attributes.     253   // Get and check applicable vis attributes.
260   //   fpVisAttribs = fpViewer->GetApplicableV    254   //   fpVisAttribs = fpViewer->GetApplicableVisAttributes(fpVisAttribs);
261   // Do not draw if not visible.                  255   // Do not draw if not visible.
262   //   if (fpVisAttribs->IsVisible()) {           256   //   if (fpVisAttribs->IsVisible()) {
263   //   Get parameters of appropriate object, e    257   //   Get parameters of appropriate object, e.g.:
264   //     G4double dx = box.GetXHalfLength ();     258   //     G4double dx = box.GetXHalfLength ();
265   //     G4double dy = box.GetYHalfLength ();     259   //     G4double dy = box.GetYHalfLength ();
266   //     G4double dz = box.GetZHalfLength ();     260   //     G4double dz = box.GetZHalfLength ();
267   //     ...                                      261   //     ...
268   //     and Draw or Store in your display Lis    262   //     and Draw or Store in your display List.
269 }                                                 263 }
270                                                   264 
271 void G4VSceneHandler::AddSolid (const G4Cons&     265 void G4VSceneHandler::AddSolid (const G4Cons& cons) {
272   AddSolidT (cons);                               266   AddSolidT (cons);
273 }                                                 267 }
274                                                   268 
275 void G4VSceneHandler::AddSolid (const G4Orb& o    269 void G4VSceneHandler::AddSolid (const G4Orb& orb) {
276   AddSolidWithAuxiliaryEdges (orb);               270   AddSolidWithAuxiliaryEdges (orb);
277 }                                                 271 }
278                                                   272 
279 void G4VSceneHandler::AddSolid (const G4Para&     273 void G4VSceneHandler::AddSolid (const G4Para& para) {
280   AddSolidT (para);                               274   AddSolidT (para);
281 }                                                 275 }
282                                                   276 
283 void G4VSceneHandler::AddSolid (const G4Sphere    277 void G4VSceneHandler::AddSolid (const G4Sphere& sphere) {
284   AddSolidWithAuxiliaryEdges (sphere);            278   AddSolidWithAuxiliaryEdges (sphere);
285 }                                                 279 }
286                                                   280 
287 void G4VSceneHandler::AddSolid (const G4Torus&    281 void G4VSceneHandler::AddSolid (const G4Torus& torus) {
288   AddSolidWithAuxiliaryEdges (torus);             282   AddSolidWithAuxiliaryEdges (torus);
289 }                                                 283 }
290                                                   284 
291 void G4VSceneHandler::AddSolid (const G4Trap&     285 void G4VSceneHandler::AddSolid (const G4Trap& trap) {
292   AddSolidT (trap);                               286   AddSolidT (trap);
293 }                                                 287 }
294                                                   288 
295 void G4VSceneHandler::AddSolid (const G4Trd& t    289 void G4VSceneHandler::AddSolid (const G4Trd& trd) {
296   AddSolidT (trd);                                290   AddSolidT (trd);
297 }                                                 291 }
298                                                   292 
299 void G4VSceneHandler::AddSolid (const G4Tubs&     293 void G4VSceneHandler::AddSolid (const G4Tubs& tubs) {
300   AddSolidT (tubs);                               294   AddSolidT (tubs);
301 }                                                 295 }
302                                                   296 
303 void G4VSceneHandler::AddSolid (const G4Ellips    297 void G4VSceneHandler::AddSolid (const G4Ellipsoid& ellipsoid) {
304   AddSolidWithAuxiliaryEdges (ellipsoid);         298   AddSolidWithAuxiliaryEdges (ellipsoid);
305 }                                                 299 }
306                                                   300 
307 void G4VSceneHandler::AddSolid (const G4Polyco    301 void G4VSceneHandler::AddSolid (const G4Polycone& polycone) {
308   AddSolidT (polycone);                           302   AddSolidT (polycone);
309 }                                                 303 }
310                                                   304 
311 void G4VSceneHandler::AddSolid (const G4Polyhe    305 void G4VSceneHandler::AddSolid (const G4Polyhedra& polyhedra) {
312   AddSolidT (polyhedra);                          306   AddSolidT (polyhedra);
313 }                                                 307 }
314                                                   308 
315 void G4VSceneHandler::AddSolid (const G4Tessel << 
316   AddSolidT (tess);                            << 
317 }                                              << 
318                                                << 
319 void G4VSceneHandler::AddSolid (const G4VSolid    309 void G4VSceneHandler::AddSolid (const G4VSolid& solid) {
320   AddSolidT (solid);                              310   AddSolidT (solid);
321 }                                                 311 }
322                                                   312 
323 void G4VSceneHandler::AddCompound (const G4VTr    313 void G4VSceneHandler::AddCompound (const G4VTrajectory& traj) {
324   G4TrajectoriesModel* trajectoriesModel =        314   G4TrajectoriesModel* trajectoriesModel =
325     dynamic_cast<G4TrajectoriesModel*>(fpModel    315     dynamic_cast<G4TrajectoriesModel*>(fpModel);
326   if (trajectoriesModel)                          316   if (trajectoriesModel)
327     traj.DrawTrajectory();                        317     traj.DrawTrajectory();
328   else {                                          318   else {
329     G4Exception                                   319     G4Exception
330     ("G4VSceneHandler::AddCompound(const G4VTr    320     ("G4VSceneHandler::AddCompound(const G4VTrajectory&)",
331      "visman0105", FatalException, "Not a G4Tr    321      "visman0105", FatalException, "Not a G4TrajectoriesModel.");
332   }                                               322   }
333 }                                                 323 }
334                                                   324 
335 void G4VSceneHandler::AddCompound (const G4VHi    325 void G4VSceneHandler::AddCompound (const G4VHit& hit) {
336   // Cast away const because Draw is non-const    326   // Cast away const because Draw is non-const!!!!
337   const_cast<G4VHit&>(hit).Draw();                327   const_cast<G4VHit&>(hit).Draw();
338 }                                                 328 }
339                                                   329 
340 void G4VSceneHandler::AddCompound (const G4VDi    330 void G4VSceneHandler::AddCompound (const G4VDigi& digi) {
341   // Cast away const because Draw is non-const    331   // Cast away const because Draw is non-const!!!!
342   const_cast<G4VDigi&>(digi).Draw();              332   const_cast<G4VDigi&>(digi).Draw();
343 }                                                 333 }
344                                                   334 
345 void G4VSceneHandler::AddCompound (const G4THi    335 void G4VSceneHandler::AddCompound (const G4THitsMap<G4double>& hits) {
346   using MeshScoreMap = G4VScoringMesh::MeshSco << 
347   //G4cout << "AddCompound: hits: " << &hits <    336   //G4cout << "AddCompound: hits: " << &hits << G4endl;
348   G4bool scoreMapHits = false;                    337   G4bool scoreMapHits = false;
349   G4ScoringManager* scoringManager = G4Scoring    338   G4ScoringManager* scoringManager = G4ScoringManager::GetScoringManagerIfExist();
350   if (scoringManager) {                           339   if (scoringManager) {
351     std::size_t nMeshes = scoringManager->GetN << 340     size_t nMeshes = scoringManager->GetNumberOfMesh();
352     for (std::size_t iMesh = 0; iMesh < nMeshe << 341     for (size_t iMesh = 0; iMesh < nMeshes; ++iMesh) {
353       G4VScoringMesh* mesh = scoringManager->G << 342       G4VScoringMesh* mesh = scoringManager->GetMesh(iMesh);
354       if (mesh && mesh->IsActive()) {             343       if (mesh && mesh->IsActive()) {
355   MeshScoreMap scoreMap = mesh->GetScoreMap();    344   MeshScoreMap scoreMap = mesh->GetScoreMap();
356         const G4String& mapNam = const_cast<G4    345         const G4String& mapNam = const_cast<G4THitsMap<G4double>&>(hits).GetName();
357   for(MeshScoreMap::const_iterator i = scoreMa << 346   for(MeshScoreMap::const_iterator i = scoreMap.begin();
358       i != scoreMap.cend(); ++i) {             << 347       i != scoreMap.end(); ++i) {
359     const G4String& scoreMapName = i->first;      348     const G4String& scoreMapName = i->first;
360     if (scoreMapName == mapNam) {                 349     if (scoreMapName == mapNam) {
361       G4DefaultLinearColorMap colorMap("G4VSce    350       G4DefaultLinearColorMap colorMap("G4VSceneHandlerColorMap");
362       scoreMapHits = true;                        351       scoreMapHits = true;
363       mesh->DrawMesh(scoreMapName, &colorMap);    352       mesh->DrawMesh(scoreMapName, &colorMap);
364     }                                             353     }
365   }                                               354   }
366       }                                           355       }
367     }                                             356     }
368   }                                               357   }
369   if (scoreMapHits) {                             358   if (scoreMapHits) {
370     static G4bool first = true;                   359     static G4bool first = true;
371     if (first) {                                  360     if (first) {
372       first = false;                              361       first = false;
373       G4cout <<                                   362       G4cout <<
374   "Scoring map drawn with default parameters."    363   "Scoring map drawn with default parameters."
375   "\n  To get gMocren file for gMocren browser    364   "\n  To get gMocren file for gMocren browser:"
376   "\n    /vis/open gMocrenFile"                   365   "\n    /vis/open gMocrenFile"
377   "\n    /vis/viewer/flush"                       366   "\n    /vis/viewer/flush"
378   "\n  Many other options available with /scor    367   "\n  Many other options available with /score/draw... commands."
379   "\n  You might want to \"/vis/viewer/set/aut    368   "\n  You might want to \"/vis/viewer/set/autoRefresh false\"."
380        << G4endl;                                 369        << G4endl;
381     }                                             370     }
382   } else {  // Not score map hits.  Just call     371   } else {  // Not score map hits.  Just call DrawAllHits.
383     // Cast away const because DrawAllHits is     372     // Cast away const because DrawAllHits is non-const!!!!
384     const_cast<G4THitsMap<G4double>&>(hits).Dr    373     const_cast<G4THitsMap<G4double>&>(hits).DrawAllHits();
385   }                                               374   }
386 }                                                 375 }
387                                                   376 
388 void G4VSceneHandler::AddCompound (const G4THi    377 void G4VSceneHandler::AddCompound (const G4THitsMap<G4StatDouble>& hits) {
389   using MeshScoreMap = G4VScoringMesh::MeshSco << 
390   //G4cout << "AddCompound: hits: " << &hits <    378   //G4cout << "AddCompound: hits: " << &hits << G4endl;
391   G4bool scoreMapHits = false;                    379   G4bool scoreMapHits = false;
392   G4ScoringManager* scoringManager = G4Scoring    380   G4ScoringManager* scoringManager = G4ScoringManager::GetScoringManagerIfExist();
393   if (scoringManager) {                           381   if (scoringManager) {
394     std::size_t nMeshes = scoringManager->GetN << 382     size_t nMeshes = scoringManager->GetNumberOfMesh();
395     for (std::size_t iMesh = 0; iMesh < nMeshe << 383     for (size_t iMesh = 0; iMesh < nMeshes; ++iMesh) {
396       G4VScoringMesh* mesh = scoringManager->G << 384       G4VScoringMesh* mesh = scoringManager->GetMesh(iMesh);
397       if (mesh && mesh->IsActive()) {             385       if (mesh && mesh->IsActive()) {
398   MeshScoreMap scoreMap = mesh->GetScoreMap();    386   MeshScoreMap scoreMap = mesh->GetScoreMap();
399   for(MeshScoreMap::const_iterator i = scoreMa << 387   for(MeshScoreMap::const_iterator i = scoreMap.begin();
400       i != scoreMap.cend(); ++i) {             << 388       i != scoreMap.end(); ++i) {
401     const G4String& scoreMapName = i->first;      389     const G4String& scoreMapName = i->first;
402     const G4THitsMap<G4StatDouble>* foundHits     390     const G4THitsMap<G4StatDouble>* foundHits = i->second;
403     if (foundHits == &hits) {                     391     if (foundHits == &hits) {
404       G4DefaultLinearColorMap colorMap("G4VSce    392       G4DefaultLinearColorMap colorMap("G4VSceneHandlerColorMap");
405       scoreMapHits = true;                        393       scoreMapHits = true;
406       mesh->DrawMesh(scoreMapName, &colorMap);    394       mesh->DrawMesh(scoreMapName, &colorMap);
407     }                                             395     }
408   }                                               396   }
409       }                                           397       }
410     }                                             398     }
411   }                                               399   }
412   if (scoreMapHits) {                             400   if (scoreMapHits) {
413     static G4bool first = true;                   401     static G4bool first = true;
414     if (first) {                                  402     if (first) {
415       first = false;                              403       first = false;
416       G4cout <<                                   404       G4cout <<
417   "Scoring map drawn with default parameters."    405   "Scoring map drawn with default parameters."
418   "\n  To get gMocren file for gMocren browser    406   "\n  To get gMocren file for gMocren browser:"
419   "\n    /vis/open gMocrenFile"                   407   "\n    /vis/open gMocrenFile"
420   "\n    /vis/viewer/flush"                       408   "\n    /vis/viewer/flush"
421   "\n  Many other options available with /scor    409   "\n  Many other options available with /score/draw... commands."
422   "\n  You might want to \"/vis/viewer/set/aut    410   "\n  You might want to \"/vis/viewer/set/autoRefresh false\"."
423        << G4endl;                                 411        << G4endl;
424     }                                             412     }
425   } else {  // Not score map hits.  Just call     413   } else {  // Not score map hits.  Just call DrawAllHits.
426     // Cast away const because DrawAllHits is     414     // Cast away const because DrawAllHits is non-const!!!!
427     const_cast<G4THitsMap<G4StatDouble>&>(hits    415     const_cast<G4THitsMap<G4StatDouble>&>(hits).DrawAllHits();
428   }                                               416   }
429 }                                                 417 }
430                                                   418 
431 void G4VSceneHandler::AddCompound(const G4Mesh << 
432 {                                              << 
433   G4warn <<                                    << 
434   "There has been an attempt to draw a mesh wi << 
435   << fpViewer->GetViewParameters().GetSpecialM << 
436   << "\":\n" << mesh                           << 
437   << "but it is not of a recognised type or is << 
438   "\nby the current graphics driver. Instead w << 
439   "\ncontainer \"" << mesh.GetContainerVolume( << 
440   << G4endl;                                   << 
441   const auto& pv = mesh.GetContainerVolume();  << 
442   const auto& lv = pv->GetLogicalVolume();     << 
443   const auto& solid = lv->GetSolid();          << 
444   const auto& transform = mesh.GetTransform(); << 
445   // Make sure container is visible            << 
446   G4VisAttributes tmpVisAtts;  // Visible, whi << 
447   const auto& saveVisAtts = lv->GetVisAttribut << 
448   if (saveVisAtts) {                           << 
449     tmpVisAtts = *saveVisAtts;                 << 
450     tmpVisAtts.SetVisibility(true);            << 
451     auto colour = saveVisAtts->GetColour();    << 
452     colour.SetAlpha(1.);                       << 
453     tmpVisAtts.SetColour(colour);              << 
454   }                                            << 
455   // Draw container                            << 
456   PreAddSolid(transform,tmpVisAtts);           << 
457   solid->DescribeYourselfTo(*this);            << 
458   PostAddSolid();                              << 
459   // Restore vis attributes                    << 
460   lv->SetVisAttributes(saveVisAtts);           << 
461 }                                              << 
462                                                << 
463 void G4VSceneHandler::AddViewerToList (G4VView    419 void G4VSceneHandler::AddViewerToList (G4VViewer* pViewer) {
464   fViewerList.push_back (pViewer);                420   fViewerList.push_back (pViewer);
465 }                                                 421 }
466                                                   422 
                                                   >> 423 void G4VSceneHandler::AddPrimitive (const G4Scale& scale) {
                                                   >> 424 
                                                   >> 425   const G4double margin(0.01);
                                                   >> 426   // Fractional margin - ensures scale is comfortably inside viewing
                                                   >> 427   // volume.
                                                   >> 428   const G4double oneMinusMargin (1. - margin);
                                                   >> 429 
                                                   >> 430   const G4VisExtent& sceneExtent = fpScene->GetExtent();
                                                   >> 431 
                                                   >> 432   // Useful constants...
                                                   >> 433   const G4double length(scale.GetLength());
                                                   >> 434   const G4double halfLength(length / 2.);
                                                   >> 435   const G4double tickLength(length / 20.);
                                                   >> 436   const G4double piBy2(halfpi);
                                                   >> 437 
                                                   >> 438   // Get size of scene...
                                                   >> 439   const G4double xmin = sceneExtent.GetXmin();
                                                   >> 440   const G4double xmax = sceneExtent.GetXmax();
                                                   >> 441   const G4double ymin = sceneExtent.GetYmin();
                                                   >> 442   const G4double ymax = sceneExtent.GetYmax();
                                                   >> 443   const G4double zmin = sceneExtent.GetZmin();
                                                   >> 444   const G4double zmax = sceneExtent.GetZmax();
                                                   >> 445 
                                                   >> 446   // Create (empty) polylines having the same vis attributes...
                                                   >> 447   G4Polyline scaleLine, tick11, tick12, tick21, tick22;
                                                   >> 448   G4VisAttributes visAtts(*scale.GetVisAttributes());  // Long enough life.
                                                   >> 449   scaleLine.SetVisAttributes(&visAtts);
                                                   >> 450   tick11.SetVisAttributes(&visAtts);
                                                   >> 451   tick12.SetVisAttributes(&visAtts);
                                                   >> 452   tick21.SetVisAttributes(&visAtts);
                                                   >> 453   tick22.SetVisAttributes(&visAtts);
                                                   >> 454 
                                                   >> 455   // Add points to the polylines to represent an scale parallel to the
                                                   >> 456   // x-axis centred on the origin...
                                                   >> 457   G4Point3D r1(G4Point3D(-halfLength, 0., 0.));
                                                   >> 458   G4Point3D r2(G4Point3D( halfLength, 0., 0.));
                                                   >> 459   scaleLine.push_back(r1);
                                                   >> 460   scaleLine.push_back(r2);
                                                   >> 461   G4Point3D ticky(0., tickLength, 0.);
                                                   >> 462   G4Point3D tickz(0., 0., tickLength);
                                                   >> 463   tick11.push_back(r1 + ticky);
                                                   >> 464   tick11.push_back(r1 - ticky);
                                                   >> 465   tick12.push_back(r1 + tickz);
                                                   >> 466   tick12.push_back(r1 - tickz);
                                                   >> 467   tick21.push_back(r2 + ticky);
                                                   >> 468   tick21.push_back(r2 - ticky);
                                                   >> 469   tick22.push_back(r2 + tickz);
                                                   >> 470   tick22.push_back(r2 - tickz);
                                                   >> 471   G4Point3D textPosition(0., tickLength, 0.);
                                                   >> 472 
                                                   >> 473   // Transform appropriately...
                                                   >> 474 
                                                   >> 475   G4Transform3D transformation;
                                                   >> 476   if (scale.GetAutoPlacing()) {
                                                   >> 477     G4Transform3D rotation;
                                                   >> 478     switch (scale.GetDirection()) {
                                                   >> 479     case G4Scale::x:
                                                   >> 480       break;
                                                   >> 481     case G4Scale::y:
                                                   >> 482       rotation = G4RotateZ3D(piBy2);
                                                   >> 483       break;
                                                   >> 484     case G4Scale::z:
                                                   >> 485       rotation = G4RotateY3D(piBy2);
                                                   >> 486       break;
                                                   >> 487     }
                                                   >> 488     G4double sxmid;
                                                   >> 489     G4double symid;
                                                   >> 490     G4double szmid;
                                                   >> 491     sxmid = xmin + oneMinusMargin * (xmax - xmin);
                                                   >> 492     symid = ymin + margin * (ymax - ymin);
                                                   >> 493     szmid = zmin + oneMinusMargin * (zmax - zmin);
                                                   >> 494     switch (scale.GetDirection()) {
                                                   >> 495     case G4Scale::x:
                                                   >> 496       sxmid -= halfLength;
                                                   >> 497       break;
                                                   >> 498     case G4Scale::y:
                                                   >> 499       symid += halfLength;
                                                   >> 500       break;
                                                   >> 501     case G4Scale::z:
                                                   >> 502       szmid -= halfLength;
                                                   >> 503       break;
                                                   >> 504     }
                                                   >> 505     G4Translate3D translation(sxmid, symid, szmid);
                                                   >> 506     transformation = translation * rotation;
                                                   >> 507   } else {
                                                   >> 508     if (fpModel) transformation = fpModel->GetTransformation();
                                                   >> 509   }
                                                   >> 510 
                                                   >> 511   // Draw...
                                                   >> 512   // We would like to call BeginPrimitives(transformation) here but
                                                   >> 513   // calling BeginPrimitives from within an AddPrimitive is not
                                                   >> 514   // allowed!  So we have to do our own transformation...
                                                   >> 515   AddPrimitive(scaleLine.transform(transformation));
                                                   >> 516   AddPrimitive(tick11.transform(transformation));
                                                   >> 517   AddPrimitive(tick12.transform(transformation));
                                                   >> 518   AddPrimitive(tick21.transform(transformation));
                                                   >> 519   AddPrimitive(tick22.transform(transformation));
                                                   >> 520   G4Text text(scale.GetAnnotation(),textPosition.transform(transformation));
                                                   >> 521   G4VisAttributes va(G4VVisCommand::GetCurrentTextColour());
                                                   >> 522   text.SetVisAttributes(va);
                                                   >> 523   text.SetScreenSize(scale.GetAnnotationSize());
                                                   >> 524   AddPrimitive(text);
                                                   >> 525 }
                                                   >> 526 
467 void G4VSceneHandler::AddPrimitive (const G4Po    527 void G4VSceneHandler::AddPrimitive (const G4Polymarker& polymarker) {
468   switch (polymarker.GetMarkerType()) {           528   switch (polymarker.GetMarkerType()) {
469     default:                                   << 529   default:
470     case G4Polymarker::dots:                   << 530   case G4Polymarker::dots:
471     {                                             531     {
472       G4Circle dot (polymarker);               << 532       for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) {
473       dot.SetWorldSize  (0.);                  << 533   G4Circle dot (polymarker);
474       dot.SetScreenSize (0.1);  // Very small  << 
475       for (std::size_t iPoint = 0; iPoint < po << 
476         dot.SetPosition (polymarker[iPoint]);     534         dot.SetPosition (polymarker[iPoint]);
477         AddPrimitive (dot);                    << 535   dot.SetWorldSize  (0.);
                                                   >> 536   dot.SetScreenSize (0.1);  // Very small circle.
                                                   >> 537   AddPrimitive (dot);
478       }                                           538       }
479     }                                             539     }
480       break;                                   << 540     break;
481     case G4Polymarker::circles:                << 541   case G4Polymarker::circles:
482     {                                             542     {
483       G4Circle circle (polymarker);  // Defaul << 543       for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) {
484       for (std::size_t iPoint = 0; iPoint < po << 544   G4Circle circle (polymarker);
485         circle.SetPosition (polymarker[iPoint] << 545   circle.SetPosition (polymarker[iPoint]);
486         AddPrimitive (circle);                 << 546   AddPrimitive (circle);
487       }                                           547       }
488     }                                             548     }
489       break;                                   << 549     break;
490     case G4Polymarker::squares:                << 550   case G4Polymarker::squares:
491     {                                             551     {
492       G4Square square (polymarker);  // Defaul << 552       for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) {
493       for (std::size_t iPoint = 0; iPoint < po << 553   G4Square square (polymarker);
494         square.SetPosition (polymarker[iPoint] << 554   square.SetPosition (polymarker[iPoint]);
495         AddPrimitive (square);                 << 555   AddPrimitive (square);
496       }                                           556       }
497     }                                             557     }
498       break;                                   << 558     break;
499   }                                               559   }
500 }                                                 560 }
501                                                   561 
502 void G4VSceneHandler::RemoveViewerFromList (G4    562 void G4VSceneHandler::RemoveViewerFromList (G4VViewer* pViewer) {
503   fViewerList.remove(pViewer);  // Does nothin << 563   fViewerList.remove(pViewer);
504   // And reset current viewer                  << 
505   auto visManager = G4VisManager::GetInstance( << 
506   visManager->SetCurrentViewer(nullptr);       << 
507 }                                              << 
508                                                << 
509                                                << 
510 void G4VSceneHandler::AddPrimitive (const G4Pl << 
511   G4warn << "WARNING: Plotter not implemented  << 
512   G4warn << "  Open a plotter-aware graphics s << 
513   G4warn << "  /vis/scene/removeModel Plotter" << 
514 }                                                 564 }
515                                                   565 
516 void G4VSceneHandler::SetScene (G4Scene* pScen    566 void G4VSceneHandler::SetScene (G4Scene* pScene) {
517   fpScene = pScene;                               567   fpScene = pScene;
518   // Notify all viewers that a kernel visit is    568   // Notify all viewers that a kernel visit is required.
519   G4ViewerListIterator i;                         569   G4ViewerListIterator i;
520   for (i = fViewerList.begin(); i != fViewerLi    570   for (i = fViewerList.begin(); i != fViewerList.end(); i++) {
521     (*i) -> SetNeedKernelVisit (true);            571     (*i) -> SetNeedKernelVisit (true);
522   }                                               572   }
523 }                                                 573 }
524                                                   574 
525 void G4VSceneHandler::RequestPrimitives (const << 575 void G4VSceneHandler::RequestPrimitives (const G4VSolid& solid) {
526 {                                              << 576   G4Polyhedron::SetNumberOfRotationSteps (GetNoOfSides (fpVisAttribs));
527   // Sometimes solids that have no substance g << 577   G4Polyhedron* pPolyhedron = solid.GetPolyhedron ();
528   // be part of the geometry tree but have bee << 578   G4Polyhedron::ResetNumberOfRotationSteps ();
529   // example by a Boolean subtraction in which << 579   if (pPolyhedron) {
530   // is entirely inside the subtractor or an i << 580     pPolyhedron -> SetVisAttributes (fpVisAttribs);
531   // the original volume is entirely outside t << 581     BeginPrimitives (fObjectTransformation);
532   // The problem is that the Boolean Processor << 582     AddPrimitive (*pPolyhedron);
533   // polyhedron in these cases (IMHO it should << 583     EndPrimitives ();
534   // workaround is to return before the damage << 
535   // Algorithm by Evgueni Tcherniaev           << 
536   auto pSolid = &solid;                        << 
537   auto pBooleanSolid = dynamic_cast<const G4Bo << 
538   if (pBooleanSolid) {                         << 
539     G4ThreeVector bmin, bmax;                  << 
540     pBooleanSolid->BoundingLimits(bmin, bmax); << 
541     G4bool isGood = false;                     << 
542     if (dynamic_cast<const G4SubtractionSolid* << 
543       auto ptrB = pBooleanSolid->GetConstituen << 
544       for (G4int i=0; i<10; ++i) {             << 
545         G4double x = bmin.x() + (bmax.x() - bm << 
546         G4double y = bmin.y() + (bmax.y() - bm << 
547         G4double z = bmin.z() + (bmax.z() - bm << 
548         if (ptrB->Inside(G4ThreeVector(x,y,bmi << 
549         if (ptrB->Inside(G4ThreeVector(x,y,bma << 
550         if (ptrB->Inside(G4ThreeVector(x,bmin. << 
551         if (ptrB->Inside(G4ThreeVector(x,bmax. << 
552         if (ptrB->Inside(G4ThreeVector(bmin.x( << 
553         if (ptrB->Inside(G4ThreeVector(bmax.x( << 
554       }                                        << 
555     } else if (dynamic_cast<const G4Intersecti << 
556       auto ptrB = pBooleanSolid->GetConstituen << 
557       for (G4int i=0; i<10; ++i) {             << 
558         G4double x = bmin.x() + (bmax.x() - bm << 
559         G4double y = bmin.y() + (bmax.y() - bm << 
560         G4double z = bmin.z() + (bmax.z() - bm << 
561         if (ptrB->Inside(G4ThreeVector(x,y,bmi << 
562         if (ptrB->Inside(G4ThreeVector(x,y,bma << 
563         if (ptrB->Inside(G4ThreeVector(x,bmin. << 
564         if (ptrB->Inside(G4ThreeVector(x,bmax. << 
565         if (ptrB->Inside(G4ThreeVector(bmin.x( << 
566         if (ptrB->Inside(G4ThreeVector(bmax.x( << 
567       }                                        << 
568     }                                          << 
569     if (!isGood)                               << 
570     {                                          << 
571       for (G4int i=0; i<10000; ++i) {          << 
572         G4double x = bmin.x() + (bmax.x() - bm << 
573         G4double y = bmin.y() + (bmax.y() - bm << 
574         G4double z = bmin.z() + (bmax.z() - bm << 
575         if (pBooleanSolid->Inside(G4ThreeVecto << 
576       }                                        << 
577     }                                          << 
578     if (!isGood) return;                       << 
579   }                                               584   }
580                                                << 585   else {
581   const G4ViewParameters::DrawingStyle style = << 586     G4VisManager::Verbosity verbosity = G4VisManager::GetVerbosity();
582   const G4ViewParameters& vp = fpViewer->GetVi << 587     if (verbosity >= G4VisManager::errors) {
583                                                << 588       G4cerr <<
584   switch (style) {                             << 589       "ERROR: G4VSceneHandler::RequestPrimitives"
585     default:                                   << 590       "\n  Polyhedron not available for " << solid.GetName () <<
586     case G4ViewParameters::wireframe:          << 591       "\n  Touchable path: ";
587     case G4ViewParameters::hlr:                << 592       G4PhysicalVolumeModel* pPVModel = dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
588     case G4ViewParameters::hsr:                << 593       if (pPVModel) {
589     case G4ViewParameters::hlhsr:              << 594         G4cerr << pPVModel->GetFullPVPath();
590     {                                          << 595       }
591       // Use polyhedral representation         << 596       static G4bool explanation = false;
592       G4Polyhedron::SetNumberOfRotationSteps ( << 597       if (!explanation) {
593       G4Polyhedron* pPolyhedron = solid.GetPol << 598         explanation = true;
594       G4Polyhedron::ResetNumberOfRotationSteps << 599         G4cerr <<
595       if (pPolyhedron) {                       << 600         "\n  This means it cannot be visualized on most systems (try RayTracer)."
596         pPolyhedron -> SetVisAttributes (fpVis << 601         "\n  1) The solid may not have implemented the CreatePolyhedron method."
597         BeginPrimitives (fObjectTransformation << 602         "\n  2) For Boolean solids, the BooleanProcessor, which attempts to create"
598         AddPrimitive (*pPolyhedron);           << 603         "\n     the resultant polyhedron, may have failed.";
599         EndPrimitives ();                      << 
600         break;                                 << 
601       } else {  // Print warnings and drop thr << 
602         G4VisManager::Verbosity verbosity = G4 << 
603         auto pPVModel = dynamic_cast<G4Physica << 
604         if (pPVModel) {                        << 
605           auto problematicVolume = pPVModel->G << 
606           if (fProblematicVolumes.find(problem << 
607             fProblematicVolumes[problematicVol << 
608             if (verbosity >= G4VisManager::err << 
609               G4warn <<                        << 
610               "ERROR: G4VSceneHandler::Request << 
611               "\n  Polyhedron not available fo << 
612               G4warn << "\n  Touchable path: " << 
613               static G4bool explanation = fals << 
614               if (!explanation) {              << 
615                 explanation = true;            << 
616                 G4warn <<                      << 
617                 "\n  This means it cannot be v << 
618                 "\n  1) The solid may not have << 
619                 "\n  2) For Boolean solids, th << 
620                 "\n     the resultant polyhedr << 
621                 "\n  Try RayTracer. It uses Ge << 
622               }                                << 
623             }                                  << 
624             G4warn << "\n  Drawing solid with  << 
625             G4warn << G4endl;                  << 
626           }                                    << 
627         }                                      << 
628       }                                        << 
629     }                                          << 
630       [[fallthrough]];                         << 
631                                                << 
632     case G4ViewParameters::cloud:              << 
633     {                                          << 
634       // Form solid out of cloud of dots on su << 
635       G4Polymarker dots;                       << 
636       // Note: OpenGL has a fast implementatio << 
637       // to build a polymarker rather than add << 
638       // And anyway, in Qt, in the latter case << 
639       // entry, something we would want to avo << 
640       dots.SetVisAttributes(fpVisAttribs);     << 
641       dots.SetMarkerType(G4Polymarker::dots);  << 
642       dots.SetSize(G4VMarker::screen,1.);      << 
643       G4int numberOfCloudPoints = GetNumberOfC << 
644       if (numberOfCloudPoints <= 0) numberOfCl << 
645       for (G4int i = 0; i < numberOfCloudPoint << 
646   G4ThreeVector p = solid.GetPointOnSurface(); << 
647   dots.push_back(p);                           << 
648       }                                           604       }
649       BeginPrimitives (fObjectTransformation); << 605       G4cerr << G4endl;
650       AddPrimitive(dots);                      << 
651       EndPrimitives ();                        << 
652       break;                                   << 
653     }                                             606     }
654   }                                               607   }
655 }                                                 608 }
656                                                   609 
657 //namespace {                                  << 610 void G4VSceneHandler::ProcessScene () {
658 //  void DrawExtent(const G4VModel* pModel)    << 
659 //  {                                          << 
660 //    // Show extent boxes - debug only, OGLSX << 
661 //    if (pModel->GetExtent() != G4VisExtent:: << 
662 //      const auto& extent = pModel->GetExtent << 
663 //      const auto& centre = extent.GetExtentC << 
664 //      const auto& position = G4Translate3D(c << 
665 //      const auto& dx = (extent.GetXmax()-ext << 
666 //      const auto& dy = (extent.GetYmax()-ext << 
667 //      const auto& dz = (extent.GetZmax()-ext << 
668 //      auto visAtts = G4VisAttributes();      << 
669 //      visAtts.SetForceWireframe();           << 
670 //      G4Box extentBox("Extent",dx,dy,dz);    << 
671 //      G4VisManager::GetInstance()->Draw(exte << 
672 //    }                                        << 
673 //  }                                          << 
674 //}                                            << 
675                                                   611 
676 void G4VSceneHandler::ProcessScene()           << 
677 {                                              << 
678   // Assumes graphics database store has alrea    612   // Assumes graphics database store has already been cleared if
679   // relevant for the particular scene handler    613   // relevant for the particular scene handler.
680                                                   614 
681   if(!fpScene)                                 << 615   if (!fpScene) return;
682     return;                                    << 
683                                                   616 
684   if(fpScene->GetExtent() == G4VisExtent::GetN << 617   if (fpScene->GetExtent() == G4VisExtent::GetNullExtent()) {
685   {                                            << 618     G4Exception
686     G4Exception("G4VSceneHandler::ProcessScene << 619     ("G4VSceneHandler::ProcessScene",
687                 "The scene has no extent.");   << 620      "visman0106", JustWarning,
                                                   >> 621      "The scene has no extent.");
688   }                                               622   }
689                                                   623 
690   G4VisManager* visManager = G4VisManager::Get    624   G4VisManager* visManager = G4VisManager::GetInstance();
691                                                   625 
692   if(!visManager->GetConcreteInstance())       << 626   if (!visManager->GetConcreteInstance()) return;
693     return;                                    << 
694                                                   627 
695   G4VisManager::Verbosity verbosity = visManag    628   G4VisManager::Verbosity verbosity = visManager->GetVerbosity();
696                                                   629 
697   fReadyForTransients = false;                    630   fReadyForTransients = false;
698                                                   631 
699   // Reset fMarkForClearingTransientStore. (Le    632   // Reset fMarkForClearingTransientStore. (Leaving
700   // fMarkForClearingTransientStore true cause    633   // fMarkForClearingTransientStore true causes problems with
701   // recomputing transients below.)  Restore i    634   // recomputing transients below.)  Restore it again at end...
702   G4bool tmpMarkForClearingTransientStore = fM    635   G4bool tmpMarkForClearingTransientStore = fMarkForClearingTransientStore;
703   fMarkForClearingTransientStore          = fa << 636   fMarkForClearingTransientStore = false;
704                                                   637 
705   // Traverse geometry tree and send drawing p    638   // Traverse geometry tree and send drawing primitives to window(s).
706                                                   639 
707   const std::vector<G4Scene::Model>& runDurati    640   const std::vector<G4Scene::Model>& runDurationModelList =
708     fpScene->GetRunDurationModelList();        << 641     fpScene -> GetRunDurationModelList ();
709                                                   642 
710   if(runDurationModelList.size()) {            << 643   if (runDurationModelList.size ()) {
711     if(verbosity >= G4VisManager::confirmation << 644     if (verbosity >= G4VisManager::confirmations) {
712       G4cout << "Traversing scene data..." <<     645       G4cout << "Traversing scene data..." << G4endl;
713       static G4int first = true;               << 
714       if (first) {                             << 
715         first = false;                         << 
716         G4cout <<                              << 
717         "(This could happen more than once - i << 
718         "\nper rebuild, for opaque, transparen << 
719         << G4endl;                             << 
720       }                                        << 
721     }                                             646     }
722                                                   647 
723     // Reset visibility of all objects to fals << 648     BeginModeling ();
724     fpViewer->AccessSceneTree().ResetVisibilit << 
725                                                << 
726     BeginModeling();                           << 
727                                                   649 
728     // Create modeling parameters from view pa    650     // Create modeling parameters from view parameters...
729     G4ModelingParameters* pMP = CreateModeling << 651     G4ModelingParameters* pMP = CreateModelingParameters ();
730                                                   652 
731     for(std::size_t i = 0; i < runDurationMode << 653     for (size_t i = 0; i < runDurationModelList.size (); i++) {
732       if(runDurationModelList[i].fActive) {    << 654       if (runDurationModelList[i].fActive) {
733         fpModel = runDurationModelList[i].fpMo    655         fpModel = runDurationModelList[i].fpModel;
734         fpModel->SetModelingParameters(pMP);   << 656   // Note: this is not the place to take action on
735                                                << 657   // pModel->GetTransformation().  The model must take care of
736         // Describe to the current scene handl << 658   // this in pModel->DescribeYourselfTo(*this).  See, for example,
737         fpModel->DescribeYourselfTo(*this);    << 659   // G4PhysicalVolumeModel and /vis/scene/add/logo.
738                                                << 660   fpModel -> SetModelingParameters (pMP);
739         // To see the extents of each model re << 661   fpModel -> DescribeYourselfTo (*this);
740         // uncomment the next line and DrawExt << 662   fpModel -> SetModelingParameters (0);
741         // DrawExtent(fpModel);                << 
742                                                << 
743         // Enter models in the scene tree. The << 
744         // the model to the scene tree, i.e.,  << 
745         fpViewer->InsertModelInSceneTree(fpMod << 
746         auto pPVModel = dynamic_cast<G4Physica << 
747         if (pPVModel) {                        << 
748           G4VViewer::SceneTreeScene sceneTreeS << 
749           fpModel->DescribeYourselfTo(sceneTre << 
750         }                                      << 
751                                                << 
752         // Reset modeling parameters pointer   << 
753         fpModel->SetModelingParameters(0);     << 
754       }                                           663       }
755     }                                             664     }
756                                                   665 
757     fpModel = 0;                                  666     fpModel = 0;
758     delete pMP;                                   667     delete pMP;
759                                                   668 
760     EndModeling();                             << 669     EndModeling ();
761   }                                            << 
762                                                << 
763   // Some printing                             << 
764   if(verbosity >= G4VisManager::confirmations) << 
765     for (const auto& model: runDurationModelLi << 
766       if (model.fActive) {                     << 
767         auto pvModel = dynamic_cast<G4Physical << 
768         if (pvModel) {                         << 
769           G4int nTouchables = 0;               << 
770           G4cout << "Numbers of touchables by  << 
771           << pvModel->GetGlobalDescription() < << 
772           for (const auto& dn : pvModel->GetNu << 
773             G4cout << "\n  Depth " << dn.first << 
774             nTouchables += dn.second;          << 
775           }                                    << 
776           G4cout << "\n  Total number of touch << 
777         }                                      << 
778       }                                        << 
779     }                                          << 
780                                                << 
781     if (fProblematicVolumes.size() > 0) {      << 
782       G4cout << "Problematic volumes:";        << 
783       for (const auto& prob: fProblematicVolum << 
784         G4cout << "\n  " << prob.first->GetNam << 
785       }                                        << 
786       G4cout << G4endl;                        << 
787     }                                          << 
788   }                                               670   }
789                                                   671 
790   fReadyForTransients = true;                     672   fReadyForTransients = true;
791                                                   673 
792   // Refresh event from end-of-event model lis    674   // Refresh event from end-of-event model list.
793   // Allow only in Idle or GeomClosed state...    675   // Allow only in Idle or GeomClosed state...
794   G4StateManager* stateManager = G4StateManage    676   G4StateManager* stateManager = G4StateManager::GetStateManager();
795   G4ApplicationState state     = stateManager- << 677   G4ApplicationState state = stateManager->GetCurrentState();
796   if(state == G4State_Idle || state == G4State << 678   if (state == G4State_Idle || state == G4State_GeomClosed) {
797   {                                            << 679 
798     visManager->SetEventRefreshing(true);         680     visManager->SetEventRefreshing(true);
799                                                   681 
800     if(visManager->GetRequestedEvent())        << 682     if (visManager->GetRequestedEvent()) {
801     {                                          << 
802       DrawEvent(visManager->GetRequestedEvent(    683       DrawEvent(visManager->GetRequestedEvent());
803     }                                          << 
804     else                                       << 
805     {                                          << 
806       G4RunManager* runManager = G4RunManagerF << 
807       if(runManager)                           << 
808       {                                        << 
809         const G4Run* run = runManager->GetCurr << 
810         // Draw a null event in order to pick  << 
811         if (run == nullptr) DrawEvent(0);      << 
812         const std::vector<const G4Event*>* eve << 
813           run ? run->GetEventVector() : 0;     << 
814         std::size_t nKeptEvents = 0;           << 
815         if(events)                             << 
816           nKeptEvents = events->size();        << 
817         if(nKeptEvents)                        << 
818         {                                      << 
819           if(fpScene->GetRefreshAtEndOfEvent() << 
820           {                                    << 
821             if(verbosity >= G4VisManager::conf << 
822             {                                  << 
823               G4cout << "Refreshing event..."  << 
824             }                                  << 
825             const G4Event* event = 0;          << 
826             if(events && events->size())       << 
827               event = events->back();          << 
828             if(event)                          << 
829               DrawEvent(event);                << 
830           }                                    << 
831           else                                 << 
832           {  // Accumulating events.           << 
833                                                   684 
834             if(verbosity >= G4VisManager::conf << 685     } else {
835             {                                  << 
836               G4cout << "Refreshing events in  << 
837             }                                  << 
838             for(const auto& event : *events)   << 
839             {                                  << 
840               if(event)                        << 
841                 DrawEvent(event);              << 
842             }                                  << 
843                                                   686 
844             if(!fpScene->GetRefreshAtEndOfRun( << 687       G4RunManager* runManager = G4RunManager::GetRunManager();
845             {                                  << 688 #ifdef G4MULTITHREADED
846               if(verbosity >= G4VisManager::wa << 689       if(G4Threading::IsMultithreadedApplication())
847               {                                << 690       { runManager = G4MTRunManager::GetMasterRunManager(); }
848                 G4warn << "WARNING: Cannot ref << 691 #endif
849                           "\n  than one runs.  << 692       if (runManager) {
850                        << G4endl;              << 693   const G4Run* run = runManager->GetCurrentRun();
851               }                                << 694         const std::vector<const G4Event*>* events =
                                                   >> 695     run? run->GetEventVector(): 0;
                                                   >> 696   size_t nKeptEvents = 0;
                                                   >> 697   if (events) nKeptEvents = events->size();
                                                   >> 698   if (nKeptEvents) {
                                                   >> 699 
                                                   >> 700     if (fpScene->GetRefreshAtEndOfEvent()) {
                                                   >> 701 
                                                   >> 702       if (verbosity >= G4VisManager::confirmations) {
                                                   >> 703         G4cout << "Refreshing event..." << G4endl;
                                                   >> 704       }
                                                   >> 705       const G4Event* event = 0;
                                                   >> 706       if (events && events->size()) event = events->back();
                                                   >> 707       if (event) DrawEvent(event);
                                                   >> 708 
                                                   >> 709     } else {  // Accumulating events.
                                                   >> 710 
                                                   >> 711       if (verbosity >= G4VisManager::confirmations) {
                                                   >> 712         G4cout << "Refreshing events in run..." << G4endl;
                                                   >> 713       }
                                                   >> 714             for (const auto& event: *events) {
                                                   >> 715               if (event) DrawEvent(event);
852             }                                     716             }
853           }                                    << 717 
854         }                                      << 718       if (!fpScene->GetRefreshAtEndOfRun()) {
                                                   >> 719         if (verbosity >= G4VisManager::warnings) {
                                                   >> 720     G4cout <<
                                                   >> 721       "WARNING: Cannot refresh events accumulated over more"
                                                   >> 722       "\n  than one runs.  Refreshed just the last run."
                                                   >> 723            << G4endl;
                                                   >> 724         }
                                                   >> 725       }
                                                   >> 726     }
                                                   >> 727   }
855       }                                           728       }
856     }                                             729     }
857     visManager->SetEventRefreshing(false);        730     visManager->SetEventRefreshing(false);
858   }                                               731   }
859                                                   732 
860   // Refresh end-of-run model list.               733   // Refresh end-of-run model list.
861   // Allow only in Idle or GeomClosed state...    734   // Allow only in Idle or GeomClosed state...
862   if(state == G4State_Idle || state == G4State << 735   if (state == G4State_Idle || state == G4State_GeomClosed) {
863   {                                            << 
864     DrawEndOfRunModels();                         736     DrawEndOfRunModels();
865   }                                               737   }
866                                                   738 
867   fMarkForClearingTransientStore = tmpMarkForC    739   fMarkForClearingTransientStore = tmpMarkForClearingTransientStore;
868 }                                                 740 }
869                                                   741 
870 void G4VSceneHandler::DrawEvent(const G4Event*    742 void G4VSceneHandler::DrawEvent(const G4Event* event)
871 {                                                 743 {
872   if(!fpViewer->ReadyToDraw()) return;         << 
873   const std::vector<G4Scene::Model>& EOEModelL    744   const std::vector<G4Scene::Model>& EOEModelList =
874     fpScene -> GetEndOfEventModelList ();         745     fpScene -> GetEndOfEventModelList ();
875   std::size_t nModels = EOEModelList.size();   << 746   size_t nModels = EOEModelList.size();
876   if (nModels) {                                  747   if (nModels) {
877     G4ModelingParameters* pMP = CreateModeling    748     G4ModelingParameters* pMP = CreateModelingParameters();
878     pMP->SetEvent(event);                         749     pMP->SetEvent(event);
879     for (std::size_t i = 0; i < nModels; ++i)  << 750     for (size_t i = 0; i < nModels; i++) {
880       if (EOEModelList[i].fActive) {              751       if (EOEModelList[i].fActive) {
881         fpModel = EOEModelList[i].fpModel;     << 752   fpModel = EOEModelList[i].fpModel;
882         fpModel -> SetModelingParameters(pMP); << 753   fpModel -> SetModelingParameters(pMP);
883                                                << 754   fpModel -> DescribeYourselfTo (*this);
884         // Describe to the current scene handl << 755   fpModel -> SetModelingParameters(0);
885         fpModel -> DescribeYourselfTo (*this); << 
886                                                << 
887         // Enter models in the scene tree      << 
888         fpViewer->InsertModelInSceneTree(fpMod << 
889                                                << 
890         // Reset modeling parameters pointer   << 
891         fpModel -> SetModelingParameters(0);   << 
892       }                                           756       }
893     }                                             757     }
894     fpModel = 0;                                  758     fpModel = 0;
895     delete pMP;                                   759     delete pMP;
896   }                                               760   }
897 }                                                 761 }
898                                                   762 
899 void G4VSceneHandler::DrawEndOfRunModels()        763 void G4VSceneHandler::DrawEndOfRunModels()
900 {                                                 764 {
901   if(!fpViewer->ReadyToDraw()) return;         << 
902   const std::vector<G4Scene::Model>& EORModelL    765   const std::vector<G4Scene::Model>& EORModelList =
903     fpScene -> GetEndOfRunModelList ();           766     fpScene -> GetEndOfRunModelList ();
904   std::size_t nModels = EORModelList.size();   << 767   size_t nModels = EORModelList.size();
905   if (nModels) {                                  768   if (nModels) {
906     G4ModelingParameters* pMP = CreateModeling    769     G4ModelingParameters* pMP = CreateModelingParameters();
907     pMP->SetEvent(0);                             770     pMP->SetEvent(0);
908     for (std::size_t i = 0; i < nModels; ++i)  << 771     for (size_t i = 0; i < nModels; i++) {
909       if (EORModelList[i].fActive) {              772       if (EORModelList[i].fActive) {
910         fpModel = EORModelList[i].fpModel;        773         fpModel = EORModelList[i].fpModel;
911         fpModel -> SetModelingParameters(pMP); << 774   fpModel -> SetModelingParameters(pMP);
912                                                << 775   fpModel -> DescribeYourselfTo (*this);
913         // Describe to the current scene handl << 776   fpModel -> SetModelingParameters(0);
914         fpModel -> DescribeYourselfTo (*this); << 
915                                                << 
916         // Enter models in the scene tree      << 
917         fpViewer->InsertModelInSceneTree(fpMod << 
918                                                << 
919         // Reset modeling parameters pointer   << 
920         fpModel -> SetModelingParameters(0);   << 
921       }                                           777       }
922     }                                             778     }
923     fpModel = 0;                                  779     fpModel = 0;
924     delete pMP;                                   780     delete pMP;
925   }                                               781   }
926 }                                                 782 }
927                                                   783 
928 G4ModelingParameters* G4VSceneHandler::CreateM    784 G4ModelingParameters* G4VSceneHandler::CreateModelingParameters ()
929 {                                                 785 {
930   // Create modeling parameters from View Para    786   // Create modeling parameters from View Parameters...
931   if (!fpViewer) return NULL;                     787   if (!fpViewer) return NULL;
932                                                   788 
933   const G4ViewParameters& vp = fpViewer -> Get    789   const G4ViewParameters& vp = fpViewer -> GetViewParameters ();
934                                                   790 
935   // Convert drawing styles...                    791   // Convert drawing styles...
936   G4ModelingParameters::DrawingStyle modelDraw    792   G4ModelingParameters::DrawingStyle modelDrawingStyle =
937   G4ModelingParameters::wf;                    << 793     G4ModelingParameters::wf;
938   switch (vp.GetDrawingStyle ()) {                794   switch (vp.GetDrawingStyle ()) {
939     default:                                   << 795   default:
940     case G4ViewParameters::wireframe:          << 796   case G4ViewParameters::wireframe:
941       modelDrawingStyle = G4ModelingParameters << 797     modelDrawingStyle = G4ModelingParameters::wf;
942       break;                                   << 798     break;
943     case G4ViewParameters::hlr:                << 799   case G4ViewParameters::hlr:
944       modelDrawingStyle = G4ModelingParameters << 800     modelDrawingStyle = G4ModelingParameters::hlr;
945       break;                                   << 801     break;
946     case G4ViewParameters::hsr:                << 802   case G4ViewParameters::hsr:
947       modelDrawingStyle = G4ModelingParameters << 803     modelDrawingStyle = G4ModelingParameters::hsr;
948       break;                                   << 804     break;
949     case G4ViewParameters::hlhsr:              << 805   case G4ViewParameters::hlhsr:
950       modelDrawingStyle = G4ModelingParameters << 806     modelDrawingStyle = G4ModelingParameters::hlhsr;
951       break;                                   << 807     break;
952     case G4ViewParameters::cloud:              << 
953       modelDrawingStyle = G4ModelingParameters << 
954       break;                                   << 
955   }                                               808   }
956                                                   809 
957   // Decide if covered daughters are really to    810   // Decide if covered daughters are really to be culled...
958   G4bool reallyCullCovered =                      811   G4bool reallyCullCovered =
959     vp.IsCullingCovered()   // Culling daughte    812     vp.IsCullingCovered()   // Culling daughters depends also on...
960     && !vp.IsSection ()     // Sections (DCUT)    813     && !vp.IsSection ()     // Sections (DCUT) not requested.
961     && !vp.IsCutaway ()     // Cutaways not re    814     && !vp.IsCutaway ()     // Cutaways not requested.
962     ;                                             815     ;
963                                                   816 
964   G4ModelingParameters* pModelingParams = new     817   G4ModelingParameters* pModelingParams = new G4ModelingParameters
965     (vp.GetDefaultVisAttributes (),               818     (vp.GetDefaultVisAttributes (),
966      modelDrawingStyle,                           819      modelDrawingStyle,
967      vp.IsCulling (),                             820      vp.IsCulling (),
968      vp.IsCullingInvisible (),                    821      vp.IsCullingInvisible (),
969      vp.IsDensityCulling (),                      822      vp.IsDensityCulling (),
970      vp.GetVisibleDensity (),                     823      vp.GetVisibleDensity (),
971      reallyCullCovered,                           824      reallyCullCovered,
972      vp.GetNoOfSides ()                           825      vp.GetNoOfSides ()
973      );                                           826      );
974                                                   827 
975   pModelingParams->SetNumberOfCloudPoints(vp.G << 
976   pModelingParams->SetWarning                     828   pModelingParams->SetWarning
977     (G4VisManager::GetVerbosity() >= G4VisMana    829     (G4VisManager::GetVerbosity() >= G4VisManager::warnings);
978                                                   830 
979   pModelingParams->SetCBDAlgorithmNumber(vp.Ge    831   pModelingParams->SetCBDAlgorithmNumber(vp.GetCBDAlgorithmNumber());
980   pModelingParams->SetCBDParameters(vp.GetCBDP    832   pModelingParams->SetCBDParameters(vp.GetCBDParameters());
981                                                   833 
982   pModelingParams->SetExplodeFactor(vp.GetExpl    834   pModelingParams->SetExplodeFactor(vp.GetExplodeFactor());
983   pModelingParams->SetExplodeCentre(vp.GetExpl    835   pModelingParams->SetExplodeCentre(vp.GetExplodeCentre());
984                                                   836 
985   pModelingParams->SetSectionSolid(CreateSecti    837   pModelingParams->SetSectionSolid(CreateSectionSolid());
986                                                << 
987   if (vp.GetCutawayMode() == G4ViewParameters: << 
988     pModelingParams->SetCutawayMode(G4Modeling << 
989   } else if (vp.GetCutawayMode() == G4ViewPara << 
990     pModelingParams->SetCutawayMode(G4Modeling << 
991   }                                            << 
992                                                << 
993   pModelingParams->SetCutawaySolid(CreateCutaw    838   pModelingParams->SetCutawaySolid(CreateCutawaySolid());
994   // The polyhedron objects are deleted in the    839   // The polyhedron objects are deleted in the modeling parameters destructor.
995                                                   840   
996   pModelingParams->SetVisAttributesModifiers(v    841   pModelingParams->SetVisAttributesModifiers(vp.GetVisAttributesModifiers());
997                                                   842 
998   pModelingParams->SetSpecialMeshRendering(vp. << 
999   pModelingParams->SetSpecialMeshVolumes(vp.Ge << 
1000                                               << 
1001   return pModelingParams;                        843   return pModelingParams;
1002 }                                                844 }
1003                                                  845 
1004 G4DisplacedSolid* G4VSceneHandler::CreateSect << 846 G4VSolid* G4VSceneHandler::CreateSectionSolid()
1005 {                                                847 {
1006   G4DisplacedSolid* sectioner = 0;            << 848   G4VSolid* sectioner = 0;
1007                                               << 
1008   const G4ViewParameters& vp = fpViewer->GetV    849   const G4ViewParameters& vp = fpViewer->GetViewParameters();
1009   if (vp.IsSection () ) {                        850   if (vp.IsSection () ) {
1010                                               << 
1011     G4double radius = fpScene->GetExtent().Ge    851     G4double radius = fpScene->GetExtent().GetExtentRadius();
1012     G4double safe = radius + fpScene->GetExte    852     G4double safe = radius + fpScene->GetExtent().GetExtentCentre().mag();
1013     G4VSolid* sectionBox =                       853     G4VSolid* sectionBox =
1014       new G4Box("_sectioner", safe, safe, 1.e << 854       new G4Box("_sectioner", safe, safe, 1.e-5 * radius);  // Thin in z-plane.
1015                                               << 
1016     const G4Plane3D& sp = vp.GetSectionPlane     855     const G4Plane3D& sp = vp.GetSectionPlane ();
1017     G4ThreeVector normal = sp.normal();       << 856     G4double a = sp.a();
1018     G4Transform3D requiredTransform = G4Trans << 857     G4double b = sp.b();
1019     G4Rotate3D(G4ThreeVector(0,0,1), G4ThreeV << 858     G4double c = sp.c();
1020                                               << 859     G4double d = sp.d();
                                                   >> 860     G4Transform3D transform = G4TranslateZ3D(-d);
                                                   >> 861     const G4Normal3D normal(a,b,c);
                                                   >> 862     if (normal != G4Normal3D(0,0,1)) {
                                                   >> 863       const G4double angle = std::acos(normal.dot(G4Normal3D(0,0,1)));
                                                   >> 864       const G4Vector3D axis = G4Normal3D(0,0,1).cross(normal);
                                                   >> 865       transform = G4Rotate3D(angle, axis) * transform;
                                                   >> 866     }
1021     sectioner = new G4DisplacedSolid             867     sectioner = new G4DisplacedSolid
1022     ("_displaced_sectioning_box", sectionBox, << 868       ("_displaced_sectioning_box", sectionBox, transform);
1023   }                                              869   }
1024                                               << 
1025   return sectioner;                              870   return sectioner;
1026 }                                                871 }
1027                                                  872 
1028 G4DisplacedSolid* G4VSceneHandler::CreateCuta << 873 G4VSolid* G4VSceneHandler::CreateCutawaySolid()
1029 {                                                874 {
1030   const auto& vp = fpViewer->GetViewParameter << 875   // To be reviewed.
1031   const auto& nPlanes = vp.GetCutawayPlanes() << 876   return 0;
1032                                               << 877   /*** An alternative way of getting a cutaway is to use
1033   if (nPlanes == 0) return nullptr;           << 878   Command /vis/scene/add/volume
1034                                               << 879   Guidance :
1035   std::vector<G4DisplacedSolid*> cutaway_soli << 880   Adds a physical volume to current scene, with optional clipping volume.
1036                                               << 881   If physical-volume-name is "world" (the default), the top of the
1037   G4double radius = fpScene->GetExtent().GetE << 882   main geometry tree (material world) is added.  If "worlds", the
1038   G4double safe = radius + fpScene->GetExtent << 883   top of all worlds - material world and parallel worlds, if any - are
1039   auto cutawayBox = new G4Box("_cutaway_box", << 884     added.  Otherwise a search of all worlds is made, taking the first
1040                                               << 885     matching occurence only.  To see a representation of the geometry
1041   // if (vp.GetCutawayMode() == G4ViewParamet << 886     hierarchy of the worlds, try "/vis/drawTree [worlds]" or one of the
1042   // the intersection of displaced cutaway bo << 887     driver/browser combinations that have the required functionality, e.g., HepRep.
1043   // positive values a*x+b*y+c*z+d>0, so we h << 888     If clip-volume-type is specified, the subsequent parameters are used to
1044   // "back to front". The parameter "cutawayU << 889     to define a clipping volume.  For example,
1045   // that remain *after* cutaway", because we << 890     "/vis/scene/add/volume ! ! ! -box km 0 1 0 1 0 1" will draw the world
1046   // a "union" of what remains by superimposi << 891     with the positive octant cut away.  (If the Boolean Processor issues
1047   // and G4OpenGLImmediate/StoredViewer::Proc << 892     warnings try replacing 0 by 0.000000001 or something.)
1048   // that is the intersection of inverted cut << 893     If clip-volume-type is prepended with '-', the clip-volume is subtracted
1049                                               << 894     (cutaway). (This is the default if there is no prepended character.)
1050   // Conversely, if (vp.GetCutawayMode() == G << 895     If '*' is prepended, the intersection of the physical-volume and the
1051   // create an intersector that is the inters << 896     clip-volume is made. (You can make a section/DCUT with a thin box, for
1052                                               << 897     example).
1053   for (size_t plane_no = 0; plane_no < nPlane << 898     For "box", the parameters are xmin,xmax,ymin,ymax,zmin,zmax.
1054   {                                           << 899     Only "box" is programmed at present.
1055     const G4Plane3D& sp = vp.GetCutawayPlanes << 900    ***/
1056     G4Transform3D requiredTransform;          << 
1057     G4ThreeVector normal;                     << 
1058     switch (vp.GetCutawayMode()) {            << 
1059       case G4ViewParameters::cutawayUnion:    << 
1060         normal = -sp.normal();  // Invert nor << 
1061         requiredTransform = G4Translate3D(nor << 
1062         G4Rotate3D(G4ThreeVector(0,0,1), G4Th << 
1063         break;                                << 
1064       case G4ViewParameters::cutawayIntersect << 
1065         normal = sp.normal();                 << 
1066         requiredTransform = G4Translate3D(nor << 
1067         G4Rotate3D(G4ThreeVector(0,0,1), G4Th << 
1068         break;                                << 
1069     }                                         << 
1070     cutaway_solids.push_back                  << 
1071     (new G4DisplacedSolid("_displaced_cutaway << 
1072   }                                           << 
1073                                               << 
1074   if (nPlanes == 1) return (G4DisplacedSolid* << 
1075                                               << 
1076   G4IntersectionSolid *union2 = nullptr, *uni << 
1077   G4IntersectionSolid *intersection2 = nullpt << 
1078   switch (vp.GetCutawayMode()) {              << 
1079                                               << 
1080     case G4ViewParameters::cutawayUnion:      << 
1081       // Here we make a subtractor of interse << 
1082       union2 = new G4IntersectionSolid("_unio << 
1083       if (nPlanes == 2) return (G4DisplacedSo << 
1084       else if (nPlanes == 3) {                << 
1085         union3 = new G4IntersectionSolid("_un << 
1086         return (G4DisplacedSolid*)union3;     << 
1087       }                                       << 
1088       break;                                  << 
1089                                               << 
1090     case G4ViewParameters::cutawayIntersectio << 
1091       // And here we make an intersector of i << 
1092       intersection2                           << 
1093       = new G4IntersectionSolid("_intersectio << 
1094       if (nPlanes == 2) return (G4DisplacedSo << 
1095       else if (nPlanes == 3) {                << 
1096         intersection3                         << 
1097         = new G4IntersectionSolid("_intersect << 
1098         return (G4DisplacedSolid*)intersectio << 
1099       }                                       << 
1100       break;                                  << 
1101   }                                           << 
1102                                               << 
1103   G4Exception("G4VSceneHandler::CreateCutaway << 
1104               "Not programmed for more than 3 << 
1105   return nullptr;                             << 
1106 }                                                901 }
1107                                                  902 
1108 void G4VSceneHandler::LoadAtts(const G4Visibl    903 void G4VSceneHandler::LoadAtts(const G4Visible& visible, G4AttHolder* holder)
1109 {                                                904 {
1110   // Load G4Atts from G4VisAttributes, if any    905   // Load G4Atts from G4VisAttributes, if any...
1111   const G4VisAttributes* va = visible.GetVisA    906   const G4VisAttributes* va = visible.GetVisAttributes();
1112   if (va) {                                      907   if (va) {
1113     const std::map<G4String,G4AttDef>* vaDefs    908     const std::map<G4String,G4AttDef>* vaDefs =
1114       va->GetAttDefs();                          909       va->GetAttDefs();
1115     if (vaDefs) {                                910     if (vaDefs) {
1116       holder->AddAtts(visible.GetVisAttribute    911       holder->AddAtts(visible.GetVisAttributes()->CreateAttValues(), vaDefs);
1117     }                                            912     }
1118   }                                              913   }
1119                                                  914 
1120   G4PhysicalVolumeModel* pPVModel =              915   G4PhysicalVolumeModel* pPVModel =
1121     dynamic_cast<G4PhysicalVolumeModel*>(fpMo    916     dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
1122   if (pPVModel) {                                917   if (pPVModel) {
1123     // Load G4Atts from G4PhysicalVolumeModel    918     // Load G4Atts from G4PhysicalVolumeModel...
1124     const std::map<G4String,G4AttDef>* pvDefs    919     const std::map<G4String,G4AttDef>* pvDefs = pPVModel->GetAttDefs();
1125     if (pvDefs) {                                920     if (pvDefs) {
1126       holder->AddAtts(pPVModel->CreateCurrent    921       holder->AddAtts(pPVModel->CreateCurrentAttValues(), pvDefs);
1127     }                                            922     }
1128   }                                              923   }
1129                                                  924 
1130   G4TrajectoriesModel* trajModel = dynamic_ca    925   G4TrajectoriesModel* trajModel = dynamic_cast<G4TrajectoriesModel*>(fpModel);
1131   if (trajModel) {                               926   if (trajModel) {
1132     // Load G4Atts from trajectory model...      927     // Load G4Atts from trajectory model...
1133     const std::map<G4String,G4AttDef>* trajMo    928     const std::map<G4String,G4AttDef>* trajModelDefs = trajModel->GetAttDefs();
1134     if (trajModelDefs) {                         929     if (trajModelDefs) {
1135       holder->AddAtts(trajModel->CreateCurren    930       holder->AddAtts(trajModel->CreateCurrentAttValues(), trajModelDefs);
1136     }                                            931     }
1137     // Load G4Atts from trajectory...            932     // Load G4Atts from trajectory...
1138     const G4VTrajectory* traj = trajModel->Ge    933     const G4VTrajectory* traj = trajModel->GetCurrentTrajectory();
1139     if (traj) {                                  934     if (traj) {
1140       const std::map<G4String,G4AttDef>* traj    935       const std::map<G4String,G4AttDef>* trajDefs = traj->GetAttDefs();
1141       if (trajDefs) {                            936       if (trajDefs) {
1142         holder->AddAtts(traj->CreateAttValues    937         holder->AddAtts(traj->CreateAttValues(), trajDefs);
1143       }                                          938       }
1144       G4int nPoints = traj->GetPointEntries()    939       G4int nPoints = traj->GetPointEntries();
1145       for (G4int i = 0; i < nPoints; ++i) {      940       for (G4int i = 0; i < nPoints; ++i) {
1146         G4VTrajectoryPoint* trajPoint = traj-    941         G4VTrajectoryPoint* trajPoint = traj->GetPoint(i);
1147         if (trajPoint) {                         942         if (trajPoint) {
1148           const std::map<G4String,G4AttDef>*     943           const std::map<G4String,G4AttDef>* pointDefs = trajPoint->GetAttDefs();
1149           if (pointDefs) {                       944           if (pointDefs) {
1150             holder->AddAtts(trajPoint->Create    945             holder->AddAtts(trajPoint->CreateAttValues(), pointDefs);
1151           }                                      946           }
1152         }                                        947         }
1153       }                                          948       }
1154     }                                            949     }
1155   }                                              950   }
1156                                                  951 
1157   G4HitsModel* hitsModel = dynamic_cast<G4Hit    952   G4HitsModel* hitsModel = dynamic_cast<G4HitsModel*>(fpModel);
1158   if (hitsModel) {                               953   if (hitsModel) {
1159     // Load G4Atts from hit...                   954     // Load G4Atts from hit...
1160     const G4VHit* hit = hitsModel->GetCurrent    955     const G4VHit* hit = hitsModel->GetCurrentHit();
1161     const std::map<G4String,G4AttDef>* hitsDe    956     const std::map<G4String,G4AttDef>* hitsDefs = hit->GetAttDefs();
1162     if (hitsDefs) {                              957     if (hitsDefs) {
1163       holder->AddAtts(hit->CreateAttValues(),    958       holder->AddAtts(hit->CreateAttValues(), hitsDefs);
1164     }                                            959     }
1165   }                                              960   }
1166 }                                                961 }
1167                                                  962 
1168 const G4Colour& G4VSceneHandler::GetColour () << 
1169   fpVisAttribs = fpViewer->GetApplicableVisAt << 
1170   const G4Colour& colour = fpVisAttribs -> Ge << 
1171   return colour;                              << 
1172 }                                             << 
1173                                               << 
1174 const G4Colour& G4VSceneHandler::GetColour (c << 
1175   auto pVA = visible.GetVisAttributes();      << 
1176   if (!pVA) pVA = fpViewer->GetViewParameters << 
1177   return pVA->GetColour();                    << 
1178 }                                             << 
1179                                               << 
1180 const G4Colour& G4VSceneHandler::GetTextColou    963 const G4Colour& G4VSceneHandler::GetTextColour (const G4Text& text) {
1181   auto pVA = text.GetVisAttributes();         << 964   const G4VisAttributes* pVA = text.GetVisAttributes ();
1182   if (!pVA) pVA = fpViewer->GetViewParameters << 965   if (!pVA) {
1183   return pVA->GetColour();                    << 966     return G4VVisCommand::GetCurrentTextColour();
                                                   >> 967   }
                                                   >> 968   const G4Colour& colour = pVA -> GetColour ();
                                                   >> 969   return colour;
1184 }                                                970 }
1185                                                  971 
1186 G4double G4VSceneHandler::GetLineWidth(const     972 G4double G4VSceneHandler::GetLineWidth(const G4VisAttributes* pVisAttribs)
1187 {                                                973 {
1188   G4double lineWidth = pVisAttribs->GetLineWi    974   G4double lineWidth = pVisAttribs->GetLineWidth();
1189   if (lineWidth < 1.) lineWidth = 1.;            975   if (lineWidth < 1.) lineWidth = 1.;
1190   lineWidth *= fpViewer -> GetViewParameters(    976   lineWidth *= fpViewer -> GetViewParameters().GetGlobalLineWidthScale();
1191   if (lineWidth < 1.) lineWidth = 1.;            977   if (lineWidth < 1.) lineWidth = 1.;
1192   return lineWidth;                              978   return lineWidth;
1193 }                                                979 }
1194                                                  980 
1195 G4ViewParameters::DrawingStyle G4VSceneHandle    981 G4ViewParameters::DrawingStyle G4VSceneHandler::GetDrawingStyle
1196 (const G4VisAttributes* pVisAttribs) {           982 (const G4VisAttributes* pVisAttribs) {
1197   // Drawing style is normally determined by     983   // Drawing style is normally determined by the view parameters, but
1198   // it can be overriddden by the ForceDrawin    984   // it can be overriddden by the ForceDrawingStyle flag in the vis
1199   // attributes.                                 985   // attributes.
1200   const G4ViewParameters& vp = fpViewer->GetV << 986   G4ViewParameters::DrawingStyle style = 
1201   const G4ViewParameters::DrawingStyle viewer << 987     fpViewer->GetViewParameters().GetDrawingStyle();
1202   G4ViewParameters::DrawingStyle resultantSty << 
1203   if (pVisAttribs -> IsForceDrawingStyle ())     988   if (pVisAttribs -> IsForceDrawingStyle ()) {
1204     G4VisAttributes::ForcedDrawingStyle force    989     G4VisAttributes::ForcedDrawingStyle forcedStyle =
1205     pVisAttribs -> GetForcedDrawingStyle ();  << 990       pVisAttribs -> GetForcedDrawingStyle ();
1206     // This is complicated because if hidden     991     // This is complicated because if hidden line and surface removal
1207     // has been requested we wish to preserve    992     // has been requested we wish to preserve this sometimes.
1208     switch (forcedStyle) {                       993     switch (forcedStyle) {
1209       case (G4VisAttributes::solid):          << 994     case (G4VisAttributes::solid):
1210         switch (viewerStyle) {                << 995       switch (style) {
1211           case (G4ViewParameters::hlr):       << 996       case (G4ViewParameters::hlr):
1212             resultantStyle = G4ViewParameters << 997   style = G4ViewParameters::hlhsr;
1213             break;                            << 998   break;
1214           case (G4ViewParameters::wireframe): << 999       case (G4ViewParameters::wireframe):
1215             resultantStyle = G4ViewParameters << 1000   style = G4ViewParameters::hsr;
1216             break;                            << 1001   break;
1217           case (G4ViewParameters::cloud):     << 1002       case (G4ViewParameters::hlhsr):
1218             resultantStyle = G4ViewParameters << 1003       case (G4ViewParameters::hsr):
1219             break;                            << 
1220           case (G4ViewParameters::hlhsr):     << 
1221           case (G4ViewParameters::hsr):       << 
1222             break;                            << 
1223         }                                     << 
1224         break;                                << 
1225       case (G4VisAttributes::cloud):          << 
1226         resultantStyle = G4ViewParameters::cl << 
1227         break;                                << 
1228       case (G4VisAttributes::wireframe):      << 
1229       default:                                   1004       default:
1230         // But if forced style is wireframe,  << 1005   break;
1231         // main uses is in displaying the con << 1006       } 
1232         // solid and their surfaces overlap w << 1007       break;
1233         // solid, making a mess if hlr is spe << 1008     case (G4VisAttributes::wireframe):
1234         resultantStyle = G4ViewParameters::wi << 1009     default:
1235         break;                                << 1010       // But if forced style is wireframe, do it, because one of its
1236     }                                         << 1011       // main uses is in displaying the consituent solids of a Boolean
1237   }                                           << 1012       // solid and their surfaces overlap with the resulting Booean
1238   return resultantStyle;                      << 1013       // solid, making a mess if hlr is specified.
1239 }                                             << 1014       style = G4ViewParameters::wireframe;
1240                                               << 1015       break;
1241 G4int G4VSceneHandler::GetNumberOfCloudPoints << 1016     }
1242 (const G4VisAttributes* pVisAttribs) const {  << 
1243   // Returns no of cloud points from current  << 
1244   // has forced through the vis attributes, t << 
1245   // current view parameter.                  << 
1246   G4int numberOfCloudPoints = fpViewer->GetVi << 
1247   if (pVisAttribs -> IsForceDrawingStyle() && << 
1248       pVisAttribs -> GetForcedDrawingStyle()  << 
1249       pVisAttribs -> GetForcedNumberOfCloudPo << 
1250     numberOfCloudPoints = pVisAttribs -> GetF << 
1251   }                                              1017   }
1252   return numberOfCloudPoints;                 << 1018   return style;
1253 }                                                1019 }
1254                                                  1020 
1255 G4bool G4VSceneHandler::GetAuxEdgeVisible (co    1021 G4bool G4VSceneHandler::GetAuxEdgeVisible (const G4VisAttributes* pVisAttribs) {
1256   G4bool isAuxEdgeVisible = fpViewer->GetView    1022   G4bool isAuxEdgeVisible = fpViewer->GetViewParameters().IsAuxEdgeVisible ();
1257   if (pVisAttribs -> IsForceAuxEdgeVisible())    1023   if (pVisAttribs -> IsForceAuxEdgeVisible()) {
1258     isAuxEdgeVisible = pVisAttribs->IsForcedA    1024     isAuxEdgeVisible = pVisAttribs->IsForcedAuxEdgeVisible();
1259   }                                              1025   }
1260   return isAuxEdgeVisible;                       1026   return isAuxEdgeVisible;
1261 }                                                1027 }
1262                                                  1028 
1263 G4double G4VSceneHandler::GetMarkerSize          1029 G4double G4VSceneHandler::GetMarkerSize
1264 (const G4VMarker& marker,                        1030 (const G4VMarker& marker, 
1265  G4VSceneHandler::MarkerSizeType& markerSizeT    1031  G4VSceneHandler::MarkerSizeType& markerSizeType)
1266 {                                                1032 {
1267   G4bool userSpecified = marker.GetWorldSize(    1033   G4bool userSpecified = marker.GetWorldSize() || marker.GetScreenSize();
1268   const G4VMarker& defaultMarker =               1034   const G4VMarker& defaultMarker =
1269     fpViewer -> GetViewParameters().GetDefaul    1035     fpViewer -> GetViewParameters().GetDefaultMarker();
1270   G4double size = userSpecified ?                1036   G4double size = userSpecified ?
1271     marker.GetWorldSize() : defaultMarker.Get    1037     marker.GetWorldSize() : defaultMarker.GetWorldSize();
1272   if (size) {                                    1038   if (size) {
1273     // Draw in world coordinates.                1039     // Draw in world coordinates.
1274     markerSizeType = world;                      1040     markerSizeType = world;
1275   }                                              1041   }
1276   else {                                         1042   else {
1277     size = userSpecified ?                       1043     size = userSpecified ?
1278       marker.GetScreenSize() : defaultMarker.    1044       marker.GetScreenSize() : defaultMarker.GetScreenSize();
1279     // Draw in screen coordinates.               1045     // Draw in screen coordinates.
1280     markerSizeType = screen;                     1046     markerSizeType = screen;
1281   }                                              1047   }
1282   size *= fpViewer -> GetViewParameters().Get    1048   size *= fpViewer -> GetViewParameters().GetGlobalMarkerScale();
1283   if (markerSizeType == screen && size < 1.)     1049   if (markerSizeType == screen && size < 1.) size = 1.;
1284   return size;                                   1050   return size;
1285 }                                                1051 }
1286                                                  1052 
1287 G4int G4VSceneHandler::GetNoOfSides(const G4V    1053 G4int G4VSceneHandler::GetNoOfSides(const G4VisAttributes* pVisAttribs)
1288 {                                                1054 {
1289   // No. of sides (lines segments per circle)    1055   // No. of sides (lines segments per circle) is normally determined
1290   // by the view parameters, but it can be ov    1056   // by the view parameters, but it can be overriddden by the
1291   // ForceLineSegmentsPerCircle in the vis at    1057   // ForceLineSegmentsPerCircle in the vis attributes.
1292   G4int lineSegmentsPerCircle = fpViewer->Get    1058   G4int lineSegmentsPerCircle = fpViewer->GetViewParameters().GetNoOfSides();
1293   if (pVisAttribs) {                             1059   if (pVisAttribs) {
1294     if (pVisAttribs->IsForceLineSegmentsPerCi    1060     if (pVisAttribs->IsForceLineSegmentsPerCircle())
1295       lineSegmentsPerCircle = pVisAttribs->Ge    1061       lineSegmentsPerCircle = pVisAttribs->GetForcedLineSegmentsPerCircle();
1296     if (lineSegmentsPerCircle < pVisAttribs->    1062     if (lineSegmentsPerCircle < pVisAttribs->GetMinLineSegmentsPerCircle()) {
1297       lineSegmentsPerCircle = pVisAttribs->Ge    1063       lineSegmentsPerCircle = pVisAttribs->GetMinLineSegmentsPerCircle();
1298       G4warn <<                               << 1064       G4cout <<
1299   "G4VSceneHandler::GetNoOfSides: attempt to     1065   "G4VSceneHandler::GetNoOfSides: attempt to set the"
1300   "\nnumber of line segments per circle < " < << 1066   "\nnumber of line segements per circle < " << lineSegmentsPerCircle
1301        << "; forced to " << pVisAttribs->GetM    1067        << "; forced to " << pVisAttribs->GetMinLineSegmentsPerCircle() << G4endl;
1302     }                                            1068     }
1303   }                                              1069   }
1304   return lineSegmentsPerCircle;                  1070   return lineSegmentsPerCircle;
1305 }                                                1071 }
1306                                                  1072 
1307 std::ostream& operator << (std::ostream& os,     1073 std::ostream& operator << (std::ostream& os, const G4VSceneHandler& sh) {
1308                                                  1074 
1309   os << "Scene handler " << sh.fName << " has    1075   os << "Scene handler " << sh.fName << " has "
1310      << sh.fViewerList.size () << " viewer(s)    1076      << sh.fViewerList.size () << " viewer(s):";
1311   for (std::size_t i = 0; i < sh.fViewerList. << 1077   for (size_t i = 0; i < sh.fViewerList.size (); i++) {
1312     os << "\n  " << *(sh.fViewerList [i]);       1078     os << "\n  " << *(sh.fViewerList [i]);
1313   }                                              1079   }
1314                                                  1080 
1315   if (sh.fpScene) {                              1081   if (sh.fpScene) {
1316     os << "\n  " << *sh.fpScene;                 1082     os << "\n  " << *sh.fpScene;
1317   }                                              1083   }
1318   else {                                         1084   else {
1319     os << "\n  This scene handler currently h    1085     os << "\n  This scene handler currently has no scene.";
1320   }                                              1086   }
1321                                                  1087 
1322   return os;                                     1088   return os;
1323 }                                             << 
1324                                               << 
1325 void G4VSceneHandler::PseudoSceneFor3DRectMes << 
1326   if (fpPVModel->GetCurrentDepth() == fpMesh- << 
1327     const auto& material = fpPVModel->GetCurr << 
1328     const auto& name = material? material->Ge << 
1329     const auto& pVisAtts = fpPVModel->GetCurr << 
1330     // Get position in world coordinates      << 
1331     // As a parameterisation the box is trans << 
1332     // and its centre, originally by definiti << 
1333     const G4ThreeVector& position = fpCurrent << 
1334     fPositionByMaterial.insert(std::make_pair << 
1335     if (fNameAndVisAttsByMaterial.find(materi << 
1336       // Store name and vis attributes of fir << 
1337       fNameAndVisAttsByMaterial[material] = N << 
1338   }                                           << 
1339 }                                             << 
1340                                               << 
1341 void G4VSceneHandler::PseudoSceneForTetVertic << 
1342   if (fpPVModel->GetCurrentDepth() == fpMesh- << 
1343     // Need to know it's a tet !!!! or implem << 
1344     try {                                     << 
1345       const auto& tet = dynamic_cast<const G4 << 
1346       const auto& material = fpPVModel->GetCu << 
1347       const auto& name = material? material-> << 
1348       const auto& pVisAtts = fpPVModel->GetCu << 
1349       // Transform into world coordinates if  << 
1350       if (fpCurrentObjectTransformation->xx() << 
1351           fpCurrentObjectTransformation->yy() << 
1352           fpCurrentObjectTransformation->zz() << 
1353         const auto& vertices = tet.GetVertice << 
1354         fVerticesByMaterial.insert(std::make_ << 
1355       } else {                                << 
1356         auto vertices = tet.GetVertices();    << 
1357         for (auto&& vertex: vertices) {       << 
1358           vertex = G4Point3D(vertex).transfor << 
1359         }                                     << 
1360         fVerticesByMaterial.insert(std::make_ << 
1361       }                                       << 
1362       if (fNameAndVisAttsByMaterial.find(mate << 
1363         // Store name and vis attributes of f << 
1364         fNameAndVisAttsByMaterial[material] = << 
1365     }                                         << 
1366     catch (const std::bad_cast&) {            << 
1367       G4ExceptionDescription ed;              << 
1368       ed << "Called for a mesh that is not a  << 
1369       G4Exception("PseudoSceneForTetVertices" << 
1370     }                                         << 
1371   }                                           << 
1372 }                                             << 
1373                                               << 
1374 void G4VSceneHandler::StandardSpecialMeshRend << 
1375 // Standard way of special mesh rendering.    << 
1376 // MySceneHandler::AddCompound(const G4Mesh&  << 
1377 // appropriate or implement its own special m << 
1378 {                                             << 
1379   G4bool implemented = false;                 << 
1380   switch (mesh.GetMeshType()) {               << 
1381     case G4Mesh::rectangle: [[fallthrough]];  << 
1382     case G4Mesh::nested3DRectangular:         << 
1383       switch (fpViewer->GetViewParameters().G << 
1384         case G4ViewParameters::meshAsDefault: << 
1385           [[fallthrough]];                    << 
1386         case G4ViewParameters::meshAsDots:    << 
1387           Draw3DRectMeshAsDots(mesh);  // Rec << 
1388           implemented = true;                 << 
1389           break;                              << 
1390         case G4ViewParameters::meshAsSurfaces << 
1391           Draw3DRectMeshAsSurfaces(mesh);  // << 
1392           implemented = true;                 << 
1393           break;                              << 
1394       }                                       << 
1395       break;                                  << 
1396     case G4Mesh::tetrahedron:                 << 
1397       switch (fpViewer->GetViewParameters().G << 
1398         case G4ViewParameters::meshAsDefault: << 
1399           [[fallthrough]];                    << 
1400         case G4ViewParameters::meshAsDots:    << 
1401           DrawTetMeshAsDots(mesh);  // Tetrah << 
1402           implemented = true;                 << 
1403           break;                              << 
1404         case G4ViewParameters::meshAsSurfaces << 
1405           DrawTetMeshAsSurfaces(mesh);  // Te << 
1406           implemented = true;                 << 
1407           break;                              << 
1408       }                                       << 
1409       break;                                  << 
1410     case G4Mesh::cylinder: [[fallthrough]];   << 
1411     case G4Mesh::sphere: [[fallthrough]];     << 
1412     case G4Mesh::invalid: break;              << 
1413   }                                           << 
1414   if (implemented) {                          << 
1415     // Draw container if not marked invisible << 
1416     auto container = mesh.GetContainerVolume( << 
1417     auto containerLogical = container->GetLog << 
1418     auto containerVisAtts = containerLogical- << 
1419     if (containerVisAtts == nullptr || contai << 
1420       auto solid = containerLogical->GetSolid << 
1421       auto polyhedron = solid->GetPolyhedron( << 
1422       // Always draw as wireframe             << 
1423       G4VisAttributes tmpVisAtts;             << 
1424       if (containerVisAtts != nullptr) tmpVis << 
1425       tmpVisAtts.SetForceWireframe();         << 
1426       polyhedron->SetVisAttributes(tmpVisAtts << 
1427       BeginPrimitives(mesh.GetTransform());   << 
1428       AddPrimitive(*polyhedron);              << 
1429       EndPrimitives();                        << 
1430     }                                         << 
1431   } else {                                    << 
1432     // Invoke base class function             << 
1433     G4VSceneHandler::AddCompound(mesh);       << 
1434   }                                           << 
1435   return;                                     << 
1436 }                                             << 
1437                                               << 
1438 void G4VSceneHandler::Draw3DRectMeshAsDots(co << 
1439 // For a rectangular 3-D mesh, draw as colour << 
1440 // one dot randomly placed in each visible me << 
1441 {                                             << 
1442   // Check                                    << 
1443   if (mesh.GetMeshType() != G4Mesh::rectangle << 
1444       mesh.GetMeshType() != G4Mesh::nested3DR << 
1445     G4ExceptionDescription ed;                << 
1446     ed << "Called with a mesh that is not rec << 
1447     G4Exception("G4VSceneHandler::Draw3DRectM << 
1448     return;                                   << 
1449   }                                           << 
1450                                               << 
1451   static G4bool firstPrint = true;            << 
1452   const auto& verbosity = G4VisManager::GetVe << 
1453   G4bool print = firstPrint && verbosity >= G << 
1454   if (print) {                                << 
1455     G4cout                                    << 
1456     << "Special case drawing of 3D rectangula << 
1457     << '\n' << mesh                           << 
1458     << G4endl;                                << 
1459   }                                           << 
1460                                               << 
1461   const auto& container = mesh.GetContainerVo << 
1462                                               << 
1463   // This map is static so that once filled i << 
1464   static std::map<G4String,std::map<const G4M << 
1465   auto& dotsByMaterial = dotsByMaterialAndMes << 
1466                                               << 
1467   // Fill map if not already filled           << 
1468   if (dotsByMaterial.empty()) {               << 
1469                                               << 
1470     // Get positions and material one cell at << 
1471     // The pseudo scene allows a "private" de << 
1472     // Instantiate a temporary G4PhysicalVolu << 
1473     G4ModelingParameters tmpMP;               << 
1474     tmpMP.SetCulling(true);  // This avoids d << 
1475     tmpMP.SetCullingInvisible(true);  // ...  << 
1476     const G4bool useFullExtent = true;  // To << 
1477     G4PhysicalVolumeModel tmpPVModel          << 
1478     (container,                               << 
1479      G4PhysicalVolumeModel::UNLIMITED,        << 
1480      G4Transform3D(),  // so that positions a << 
1481      &tmpMP,                                  << 
1482      useFullExtent);                          << 
1483     // Accumulate information in temporary ma << 
1484     std::multimap<const G4Material*,const G4T << 
1485     std::map<const G4Material*,G4VSceneHandle << 
1486     // Instantiate the pseudo scene           << 
1487     PseudoSceneFor3DRectMeshPositions pseudoS << 
1488     (&tmpPVModel,&mesh,positionByMaterial,nam << 
1489     // Make private descent into the paramete << 
1490     tmpPVModel.DescribeYourselfTo(pseudoScene << 
1491     // Now we have a map of positions by mate << 
1492     // Also a map of name and colour by mater << 
1493                                               << 
1494     const auto& prms = mesh.GetThreeDRectPara << 
1495     const auto& halfX = prms.fHalfX;          << 
1496     const auto& halfY = prms.fHalfY;          << 
1497     const auto& halfZ = prms.fHalfZ;          << 
1498                                               << 
1499     // Fill the permanent (static) map of dot << 
1500     G4int nDotsTotal = 0;                     << 
1501     for (const auto& entry: nameAndVisAttsByM << 
1502       G4int nDots = 0;                        << 
1503       const auto& material = entry.first;     << 
1504       const auto& nameAndVisAtts = nameAndVis << 
1505       const auto& name = nameAndVisAtts.fName << 
1506       const auto& visAtts = nameAndVisAtts.fV << 
1507       G4Polymarker dots;                      << 
1508       dots.SetInfo(name);                     << 
1509       dots.SetVisAttributes(visAtts);         << 
1510       dots.SetMarkerType(G4Polymarker::dots); << 
1511       dots.SetSize(G4VMarker::screen,1.);     << 
1512       // Enter empty polymarker into the map  << 
1513       dotsByMaterial[material] = dots;        << 
1514       // Now fill it in situ                  << 
1515       auto& dotsInMap = dotsByMaterial[materi << 
1516       const auto& range = positionByMaterial. << 
1517       for (auto posByMat = range.first; posBy << 
1518         dotsInMap.push_back(GetPointInBox(pos << 
1519         ++nDots;                              << 
1520       }                                       << 
1521                                               << 
1522       if (print) {                            << 
1523         G4cout                                << 
1524         << std::setw(30) << std::left << name << 
1525         << ": " << std::setw(7) << nDots << " << 
1526         << ": colour " << std::fixed << std:: << 
1527         << visAtts.GetColour() << std::defaul << 
1528         << G4endl;                            << 
1529       }                                       << 
1530                                               << 
1531       nDotsTotal += nDots;                    << 
1532     }                                         << 
1533                                               << 
1534     if (print) {                              << 
1535       G4cout << "Total number of dots: " << n << 
1536     }                                         << 
1537   }                                           << 
1538                                               << 
1539   // Some subsequent expressions apply only t << 
1540   auto pPVModel = dynamic_cast<G4PhysicalVolu << 
1541                                               << 
1542   G4String parameterisationName;              << 
1543   if (pPVModel) {                             << 
1544     parameterisationName = pPVModel->GetFullP << 
1545   }                                           << 
1546                                               << 
1547   // Draw the dots by material                << 
1548   // Ensure they are "hidden", i.e., use the  << 
1549   auto keepVP = fpViewer->GetViewParameters() << 
1550   auto vp = fpViewer->GetViewParameters();    << 
1551   vp.SetMarkerHidden();                       << 
1552   fpViewer->SetViewParameters(vp);            << 
1553   // Now we transform to world coordinates    << 
1554   BeginPrimitives (mesh.GetTransform());      << 
1555   for (const auto& entry: dotsByMaterial) {   << 
1556     const auto& dots = entry.second;          << 
1557     // The current "leaf" node in the PVPath  << 
1558     // been converted into polymarkers by mat << 
1559     // its name to that of the material (whos << 
1560     // so that its appearance in the scene tr << 
1561     // an appropriate name and its visibility << 
1562     if (pPVModel) {                           << 
1563       const auto& fullPVPath = pPVModel->GetF << 
1564       auto leafPV = fullPVPath.back().GetPhys << 
1565       leafPV->SetName(dots.GetInfo());        << 
1566     }                                         << 
1567     // Add dots to the scene                  << 
1568     AddPrimitive(dots);                       << 
1569   }                                           << 
1570   EndPrimitives ();                           << 
1571   // Restore view parameters                  << 
1572   fpViewer->SetViewParameters(keepVP);        << 
1573   // Restore parameterisation name            << 
1574   if (pPVModel) {                             << 
1575     pPVModel->GetFullPVPath().back().GetPhysi << 
1576   }                                           << 
1577                                               << 
1578   firstPrint = false;                         << 
1579   return;                                     << 
1580 }                                             << 
1581                                               << 
1582 void G4VSceneHandler::Draw3DRectMeshAsSurface << 
1583 // For a rectangular 3-D mesh, draw as surfac << 
1584 // with inner shared faces removed.           << 
1585 {                                             << 
1586   // Check                                    << 
1587   if (mesh.GetMeshType() != G4Mesh::rectangle << 
1588       mesh.GetMeshType() != G4Mesh::nested3DR << 
1589     G4ExceptionDescription ed;                << 
1590     ed << "Called with a mesh that is not rec << 
1591     G4Exception("G4VSceneHandler::Draw3DRectM << 
1592     return;                                   << 
1593   }                                           << 
1594                                               << 
1595   static G4bool firstPrint = true;            << 
1596   const auto& verbosity = G4VisManager::GetVe << 
1597   G4bool print = firstPrint && verbosity >= G << 
1598   if (print) {                                << 
1599     G4cout                                    << 
1600     << "Special case drawing of 3D rectangula << 
1601     << '\n' << mesh                           << 
1602     << G4endl;                                << 
1603   }                                           << 
1604                                               << 
1605   const auto& container = mesh.GetContainerVo << 
1606                                               << 
1607   // This map is static so that once filled i << 
1608   static std::map<G4String,std::map<const G4M << 
1609   auto& boxesByMaterial = boxesByMaterialAndM << 
1610                                               << 
1611   // Fill map if not already filled           << 
1612   if (boxesByMaterial.empty()) {              << 
1613                                               << 
1614     // Get positions and material one cell at << 
1615     // The pseudo scene allows a "private" de << 
1616     // Instantiate a temporary G4PhysicalVolu << 
1617     G4ModelingParameters tmpMP;               << 
1618     tmpMP.SetCulling(true);  // This avoids d << 
1619     tmpMP.SetCullingInvisible(true);  // ...  << 
1620     const G4bool useFullExtent = true;  // To << 
1621     G4PhysicalVolumeModel tmpPVModel          << 
1622     (container,                               << 
1623      G4PhysicalVolumeModel::UNLIMITED,        << 
1624      G4Transform3D(),  // so that positions a << 
1625      &tmpMP,                                  << 
1626      useFullExtent);                          << 
1627     // Accumulate information in temporary ma << 
1628     std::multimap<const G4Material*,const G4T << 
1629     std::map<const G4Material*,G4VSceneHandle << 
1630     // Instantiate the pseudo scene           << 
1631     PseudoSceneFor3DRectMeshPositions pseudoS << 
1632     (&tmpPVModel,&mesh,positionByMaterial,nam << 
1633     // Make private descent into the paramete << 
1634     tmpPVModel.DescribeYourselfTo(pseudoScene << 
1635     // Now we have a map of positions by mate << 
1636     // Also a map of name and colour by mater << 
1637                                               << 
1638     const auto& prms = mesh.GetThreeDRectPara << 
1639     const auto& sizeX = 2.*prms.fHalfX;       << 
1640     const auto& sizeY = 2.*prms.fHalfY;       << 
1641     const auto& sizeZ = 2.*prms.fHalfZ;       << 
1642                                               << 
1643     // Fill the permanent (static) map of box << 
1644     G4int nBoxesTotal = 0, nFacetsTotal = 0;  << 
1645     for (const auto& entry: nameAndVisAttsByM << 
1646       G4int nBoxes = 0;                       << 
1647       const auto& material = entry.first;     << 
1648       const auto& nameAndVisAtts = nameAndVis << 
1649       const auto& name = nameAndVisAtts.fName << 
1650       const auto& visAtts = nameAndVisAtts.fV << 
1651       // Transfer positions into a vector rea << 
1652       std::vector<G4ThreeVector> positionsFor << 
1653       const auto& range = positionByMaterial. << 
1654       for (auto posByMat = range.first; posBy << 
1655         const auto& position = posByMat->seco << 
1656         positionsForPolyhedron.push_back(posi << 
1657         ++nBoxes;                             << 
1658       }                                       << 
1659       // The polyhedron will be in local coor << 
1660       // Add an empty place-holder to the map << 
1661       auto& polyhedron = boxesByMaterial[mate << 
1662       // Replace with the desired polyhedron  << 
1663       polyhedron = G4PolyhedronBoxMesh(sizeX, << 
1664       polyhedron.SetVisAttributes(visAtts);   << 
1665       polyhedron.SetInfo(name);               << 
1666                                               << 
1667       if (print) {                            << 
1668         G4cout                                << 
1669         << std::setw(30) << std::left << name << 
1670         << ": " << std::setw(7) << nBoxes <<  << 
1671         << " (" << std::setw(7) << 6*nBoxes < << 
1672         << ": reduced to " << std::setw(7) << << 
1673         << std::setw(2) << std::fixed << std: << 
1674         << "%): colour " << std::fixed << std << 
1675         << visAtts.GetColour() << std::defaul << 
1676         << G4endl;                            << 
1677       }                                       << 
1678                                               << 
1679       nBoxesTotal += nBoxes;                  << 
1680       nFacetsTotal += polyhedron.GetNoFacets( << 
1681     }                                         << 
1682                                               << 
1683     if (print) {                              << 
1684       G4cout << "Total number of boxes: " <<  << 
1685       << ": reduced to " << nFacetsTotal << " << 
1686       << std::setw(2) << std::fixed << std::s << 
1687       << G4endl;                              << 
1688     }                                         << 
1689   }                                           << 
1690                                               << 
1691   // Some subsequent expressions apply only t << 
1692   auto pPVModel = dynamic_cast<G4PhysicalVolu << 
1693                                               << 
1694   G4String parameterisationName;              << 
1695   if (pPVModel) {                             << 
1696     parameterisationName = pPVModel->GetFullP << 
1697   }                                           << 
1698                                               << 
1699   // Draw the boxes by material               << 
1700   // Now we transform to world coordinates    << 
1701   BeginPrimitives (mesh.GetTransform());      << 
1702   for (const auto& entry: boxesByMaterial) {  << 
1703     const auto& poly = entry.second;          << 
1704     // The current "leaf" node in the PVPath  << 
1705     // been converted into polyhedra by mater << 
1706     // its name to that of the material (whos << 
1707     // so that its appearance in the scene tr << 
1708     // an appropriate name and its visibility << 
1709     if (pPVModel) {                           << 
1710       const auto& fullPVPath = pPVModel->GetF << 
1711       auto leafPV = fullPVPath.back().GetPhys << 
1712       leafPV->SetName(poly.GetInfo());        << 
1713     }                                         << 
1714     AddPrimitive(poly);                       << 
1715   }                                           << 
1716   EndPrimitives ();                           << 
1717   // Restore parameterisation name            << 
1718   if (pPVModel) {                             << 
1719     pPVModel->GetFullPVPath().back().GetPhysi << 
1720   }                                           << 
1721                                               << 
1722   firstPrint = false;                         << 
1723   return;                                     << 
1724 }                                             << 
1725                                               << 
1726 void G4VSceneHandler::DrawTetMeshAsDots(const << 
1727 // For a tetrahedron mesh, draw as coloured d << 
1728 // one dot randomly placed in each visible me << 
1729 {                                             << 
1730   // Check                                    << 
1731   if (mesh.GetMeshType() != G4Mesh::tetrahedr << 
1732     G4ExceptionDescription ed;                << 
1733     ed << "Called with mesh that is not a tet << 
1734     G4Exception("G4VSceneHandler::DrawTetMesh << 
1735     return;                                   << 
1736   }                                           << 
1737                                               << 
1738   static G4bool firstPrint = true;            << 
1739   const auto& verbosity = G4VisManager::GetVe << 
1740   G4bool print = firstPrint && verbosity >= G << 
1741                                               << 
1742   if (print) {                                << 
1743     G4cout                                    << 
1744     << "Special case drawing of tetrahedron m << 
1745     << '\n' << mesh                           << 
1746     << G4endl;                                << 
1747   }                                           << 
1748                                               << 
1749   const auto& container = mesh.GetContainerVo << 
1750                                               << 
1751   // This map is static so that once filled i << 
1752   static std::map<G4String,std::map<const G4M << 
1753   auto& dotsByMaterial = dotsByMaterialAndMes << 
1754                                               << 
1755   // Fill map if not already filled           << 
1756   if (dotsByMaterial.empty()) {               << 
1757                                               << 
1758     // Get vertices and colour one cell at a  << 
1759     // The pseudo scene allows a "private" de << 
1760     // Instantiate a temporary G4PhysicalVolu << 
1761     G4ModelingParameters tmpMP;               << 
1762     tmpMP.SetCulling(true);  // This avoids d << 
1763     tmpMP.SetCullingInvisible(true);  // ...  << 
1764     const G4bool useFullExtent = true;  // To << 
1765     G4PhysicalVolumeModel tmpPVModel          << 
1766     (container,                               << 
1767      G4PhysicalVolumeModel::UNLIMITED,        << 
1768      G4Transform3D(),  // so that positions a << 
1769      &tmpMP,                                  << 
1770      useFullExtent);                          << 
1771     // Accumulate information in temporary ma << 
1772     std::multimap<const G4Material*,std::vect << 
1773     std::map<const G4Material*,G4VSceneHandle << 
1774     // Instantiate a pseudo scene             << 
1775     PseudoSceneForTetVertices pseudoScene     << 
1776     (&tmpPVModel,&mesh,verticesByMaterial,nam << 
1777     // Make private descent into the paramete << 
1778     tmpPVModel.DescribeYourselfTo(pseudoScene << 
1779     // Now we have a map of vertices by mater << 
1780     // Also a map of name and colour by mater << 
1781                                               << 
1782     // Fill the permanent (static) map of dot << 
1783     G4int nDotsTotal = 0;                     << 
1784     for (const auto& entry: nameAndVisAttsByM << 
1785       G4int nDots = 0;                        << 
1786       const auto& material = entry.first;     << 
1787       const auto& nameAndVisAtts = nameAndVis << 
1788       const auto& name = nameAndVisAtts.fName << 
1789       const auto& visAtts = nameAndVisAtts.fV << 
1790       G4Polymarker dots;                      << 
1791       dots.SetVisAttributes(visAtts);         << 
1792       dots.SetMarkerType(G4Polymarker::dots); << 
1793       dots.SetSize(G4VMarker::screen,1.);     << 
1794       dots.SetInfo(name);                     << 
1795       // Enter empty polymarker into the map  << 
1796       dotsByMaterial[material] = dots;        << 
1797       // Now fill it in situ                  << 
1798       auto& dotsInMap = dotsByMaterial[materi << 
1799       const auto& range = verticesByMaterial. << 
1800       for (auto vByMat = range.first; vByMat  << 
1801         dotsInMap.push_back(GetPointInTet(vBy << 
1802         ++nDots;                              << 
1803       }                                       << 
1804                                               << 
1805       if (print) {                            << 
1806         G4cout                                << 
1807         << std::setw(30) << std::left << name << 
1808         << ": " << std::setw(7) << nDots << " << 
1809         << ": colour " << std::fixed << std:: << 
1810         << visAtts.GetColour() << std::defaul << 
1811         << G4endl;                            << 
1812       }                                       << 
1813                                               << 
1814       nDotsTotal += nDots;                    << 
1815     }                                         << 
1816                                               << 
1817     if (print) {                              << 
1818       G4cout << "Total number of dots: " << n << 
1819     }                                         << 
1820   }                                           << 
1821                                               << 
1822   // Some subsequent expressions apply only t << 
1823   auto pPVModel = dynamic_cast<G4PhysicalVolu << 
1824                                               << 
1825   G4String parameterisationName;              << 
1826   if (pPVModel) {                             << 
1827     parameterisationName = pPVModel->GetFullP << 
1828   }                                           << 
1829                                               << 
1830   // Draw the dots by material                << 
1831   // Ensure they are "hidden", i.e., use the  << 
1832   auto keepVP = fpViewer->GetViewParameters() << 
1833   auto vp = fpViewer->GetViewParameters();    << 
1834   vp.SetMarkerHidden();                       << 
1835   fpViewer->SetViewParameters(vp);            << 
1836                                               << 
1837   // Now we transform to world coordinates    << 
1838   BeginPrimitives (mesh.GetTransform());      << 
1839   for (const auto& entry: dotsByMaterial) {   << 
1840     const auto& dots = entry.second;          << 
1841     // The current "leaf" node in the PVPath  << 
1842     // been converted into polymarkers by mat << 
1843     // its name to that of the material (whos << 
1844     // so that its appearance in the scene tr << 
1845     // an appropriate name and its visibility << 
1846     if (pPVModel) {                           << 
1847       const auto& fullPVPath = pPVModel->GetF << 
1848       auto leafPV = fullPVPath.back().GetPhys << 
1849       leafPV->SetName(dots.GetInfo());        << 
1850     }                                         << 
1851     AddPrimitive(dots);                       << 
1852   }                                           << 
1853   EndPrimitives ();                           << 
1854                                               << 
1855   // Restore view parameters                  << 
1856   fpViewer->SetViewParameters(keepVP);        << 
1857   // Restore parameterisation name            << 
1858   if (pPVModel) {                             << 
1859     pPVModel->GetFullPVPath().back().GetPhysi << 
1860   }                                           << 
1861                                               << 
1862   firstPrint = false;                         << 
1863   return;                                     << 
1864 }                                             << 
1865                                               << 
1866 void G4VSceneHandler::DrawTetMeshAsSurfaces(c << 
1867 // For a tetrahedron mesh, draw as surfaces b << 
1868 // with inner shared faces removed.           << 
1869 {                                             << 
1870   // Check                                    << 
1871   if (mesh.GetMeshType() != G4Mesh::tetrahedr << 
1872     G4ExceptionDescription ed;                << 
1873     ed << "Called with mesh that is not a tet << 
1874     G4Exception("G4VSceneHandler::DrawTetMesh << 
1875     return;                                   << 
1876   }                                           << 
1877                                               << 
1878   static G4bool firstPrint = true;            << 
1879   const auto& verbosity = G4VisManager::GetVe << 
1880   G4bool print = firstPrint && verbosity >= G << 
1881                                               << 
1882   if (print) {                                << 
1883     G4cout                                    << 
1884     << "Special case drawing of tetrahedron m << 
1885     << '\n' << mesh                           << 
1886     << G4endl;                                << 
1887   }                                           << 
1888                                               << 
1889   // This map is static so that once filled i << 
1890   static std::map<G4String,std::map<const G4M << 
1891   auto& surfacesByMaterial = surfacesByMateri << 
1892                                               << 
1893   // Fill map if not already filled           << 
1894   if (surfacesByMaterial.empty()) {           << 
1895                                               << 
1896     // Get vertices and colour one cell at a  << 
1897     // The pseudo scene allows a "private" de << 
1898     // Instantiate a temporary G4PhysicalVolu << 
1899     G4ModelingParameters tmpMP;               << 
1900     tmpMP.SetCulling(true);  // This avoids d << 
1901     tmpMP.SetCullingInvisible(true);  // ...  << 
1902     const G4bool useFullExtent = true;  // To << 
1903     G4PhysicalVolumeModel tmpPVModel          << 
1904     (mesh.GetContainerVolume(),               << 
1905      G4PhysicalVolumeModel::UNLIMITED,        << 
1906      G4Transform3D(),  // so that positions a << 
1907      &tmpMP,                                  << 
1908      useFullExtent);                          << 
1909     // Accumulate information in temporary ma << 
1910     std::multimap<const G4Material*,std::vect << 
1911     std::map<const G4Material*,G4VSceneHandle << 
1912     // Instantiate a pseudo scene             << 
1913     PseudoSceneForTetVertices pseudoScene     << 
1914     (&tmpPVModel,&mesh,verticesByMaterial,nam << 
1915     // Make private descent into the paramete << 
1916     tmpPVModel.DescribeYourselfTo(pseudoScene << 
1917     // Now we have a map of vertices by mater << 
1918     // Also a map of name and colour by mater << 
1919                                               << 
1920     // Fill the permanent (static) map of sur << 
1921     G4int nTetsTotal = 0, nFacetsTotal = 0;   << 
1922     for (const auto& entry: nameAndVisAttsByM << 
1923       G4int nTets = 0;                        << 
1924       const auto& material = entry.first;     << 
1925       const auto& nameAndVisAtts = nameAndVis << 
1926       const auto& name = nameAndVisAtts.fName << 
1927       const auto& visAtts = nameAndVisAtts.fV << 
1928       // Transfer vertices into a vector read << 
1929       std::vector<G4ThreeVector> verticesForP << 
1930       const auto& range = verticesByMaterial. << 
1931       for (auto vByMat = range.first; vByMat  << 
1932         const std::vector<G4ThreeVector>& ver << 
1933         for (const auto& vertex: vertices)    << 
1934           verticesForPolyhedron.push_back(ver << 
1935         ++nTets;                              << 
1936       }                                       << 
1937       // The polyhedron will be in local coor << 
1938       // Add an empty place-holder to the map << 
1939       auto& polyhedron = surfacesByMaterial[m << 
1940       // Replace with the desired polyhedron  << 
1941       polyhedron = G4PolyhedronTetMesh(vertic << 
1942       polyhedron.SetVisAttributes(visAtts);   << 
1943       polyhedron.SetInfo(name);               << 
1944                                               << 
1945       if (print) {                            << 
1946         G4cout                                << 
1947         << std::setw(30) << std::left << name << 
1948         << ": " << std::setw(7) << nTets << " << 
1949         << " (" << std::setw(7) << 4*nTets << << 
1950         << ": reduced to " << std::setw(7) << << 
1951         << std::setw(2) << std::fixed << std: << 
1952         << "%): colour " << std::fixed << std << 
1953         << visAtts.GetColour() << std::defaul << 
1954         << G4endl;                            << 
1955      }                                        << 
1956                                               << 
1957       nTetsTotal += nTets;                    << 
1958       nFacetsTotal += polyhedron.GetNoFacets( << 
1959     }                                         << 
1960                                               << 
1961     if (print) {                              << 
1962       G4cout << "Total number of tetrahedra:  << 
1963       << ": reduced to " << nFacetsTotal << " << 
1964       << std::setw(2) << std::fixed << std::s << 
1965       << G4endl;                              << 
1966     }                                         << 
1967   }                                           << 
1968                                               << 
1969   // Some subsequent expressions apply only t << 
1970   auto pPVModel = dynamic_cast<G4PhysicalVolu << 
1971                                               << 
1972   G4String parameterisationName;              << 
1973   if (pPVModel) {                             << 
1974     parameterisationName = pPVModel->GetFullP << 
1975   }                                           << 
1976                                               << 
1977   // Draw the surfaces by material            << 
1978   // Now we transform to world coordinates    << 
1979   BeginPrimitives (mesh.GetTransform());      << 
1980   for (const auto& entry: surfacesByMaterial) << 
1981     const auto& poly = entry.second;          << 
1982     // The current "leaf" node in the PVPath  << 
1983     // been converted into polyhedra by mater << 
1984     // its name to that of the material (whos << 
1985     // so that its appearance in the scene tr << 
1986     // an appropriate name and its visibility << 
1987     if (pPVModel) {                           << 
1988       const auto& fullPVPath = pPVModel->GetF << 
1989       auto leafPV = fullPVPath.back().GetPhys << 
1990       leafPV->SetName(poly.GetInfo());        << 
1991     }                                         << 
1992     AddPrimitive(poly);                       << 
1993   }                                           << 
1994   EndPrimitives ();                           << 
1995                                               << 
1996   // Restore parameterisation name            << 
1997   if (pPVModel) {                             << 
1998     pPVModel->GetFullPVPath().back().GetPhysi << 
1999   }                                           << 
2000                                               << 
2001   firstPrint = false;                         << 
2002   return;                                     << 
2003 }                                             << 
2004                                               << 
2005 G4ThreeVector                                 << 
2006 G4VSceneHandler::GetPointInBox(const G4ThreeV << 
2007                                G4double halfX << 
2008                                G4double halfY << 
2009                                G4double halfZ << 
2010 {                                             << 
2011   G4double x = pos.getX() + (2.*G4QuickRand() << 
2012   G4double y = pos.getY() + (2.*G4QuickRand() << 
2013   G4double z = pos.getZ() + (2.*G4QuickRand() << 
2014   return G4ThreeVector(x, y, z);              << 
2015 }                                             << 
2016                                               << 
2017 G4ThreeVector                                 << 
2018 G4VSceneHandler::GetPointInTet(const std::vec << 
2019 {                                             << 
2020   G4double p = G4QuickRand();                 << 
2021   G4double q = G4QuickRand();                 << 
2022   G4double r = G4QuickRand();                 << 
2023   if (p + q > 1.)                             << 
2024   {                                           << 
2025     p = 1. - p;                               << 
2026     q = 1. - q;                               << 
2027   }                                           << 
2028   if (q + r > 1.)                             << 
2029   {                                           << 
2030     G4double tmp = r;                         << 
2031     r = 1. - p - q;                           << 
2032     q = 1. - tmp;                             << 
2033   }                                           << 
2034   else if (p + q + r > 1.)                    << 
2035   {                                           << 
2036     G4double tmp = r;                         << 
2037     r = p + q + r - 1.;                       << 
2038     p = 1. - q - tmp;                         << 
2039   }                                           << 
2040   G4double a = 1. - p - q - r;                << 
2041   return vertices[0]*a + vertices[1]*p + vert << 
2042 }                                                1089 }
2043                                                  1090