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 11.0.p3,)


** Warning: Cannot open xref database.

  1 //                                                  1 
  2 // *******************************************    
  3 // * License and Disclaimer                       
  4 // *                                              
  5 // * The  Geant4 software  is  copyright of th    
  6 // * the Geant4 Collaboration.  It is provided    
  7 // * conditions of the Geant4 Software License    
  8 // * LICENSE and available at  http://cern.ch/    
  9 // * include a list of copyright holders.         
 10 // *                                              
 11 // * Neither the authors of this software syst    
 12 // * institutes,nor the agencies providing fin    
 13 // * work  make  any representation or  warran    
 14 // * regarding  this  software system or assum    
 15 // * use.  Please see the license in the file     
 16 // * for the full disclaimer and the limitatio    
 17 // *                                              
 18 // * This  code  implementation is the result     
 19 // * technical work of the GEANT4 collaboratio    
 20 // * By using,  copying,  modifying or  distri    
 21 // * any work based  on the software)  you  ag    
 22 // * use  in  resulting  scientific  publicati    
 23 // * acceptance of all terms of the Geant4 Sof    
 24 // *******************************************    
 25 //                                                
 26 //                                                
 27 //                                                
 28 //                                                
 29 // John Allison  19th July 1996                   
 30 // Abstract interface class for graphics scene    
 31                                                   
 32 #include "G4VSceneHandler.hh"                     
 33                                                   
 34 #include "G4ios.hh"                               
 35 #include <sstream>                                
 36                                                   
 37 #include "G4VisManager.hh"                        
 38 #include "G4VGraphicsSystem.hh"                   
 39 #include "G4VViewer.hh"                           
 40 #include "G4VSolid.hh"                            
 41 #include "G4RotationMatrix.hh"                    
 42 #include "G4ThreeVector.hh"                       
 43 #include "G4VPhysicalVolume.hh"                   
 44 #include "G4Material.hh"                          
 45 #include "G4Polyline.hh"                          
 46 #include "G4Text.hh"                              
 47 #include "G4Circle.hh"                            
 48 #include "G4Square.hh"                            
 49 #include "G4Polymarker.hh"                        
 50 #include "G4Polyhedron.hh"                        
 51 #include "G4Visible.hh"                           
 52 #include "G4VisAttributes.hh"                     
 53 #include "G4VModel.hh"                            
 54 #include "G4TrajectoriesModel.hh"                 
 55 #include "G4Box.hh"                               
 56 #include "G4Cons.hh"                              
 57 #include "G4Orb.hh"                               
 58 #include "G4Para.hh"                              
 59 #include "G4Sphere.hh"                            
 60 #include "G4Torus.hh"                             
 61 #include "G4Trap.hh"                              
 62 #include "G4Trd.hh"                               
 63 #include "G4Tubs.hh"                              
 64 #include "G4Ellipsoid.hh"                         
 65 #include "G4Polycone.hh"                          
 66 #include "G4Polyhedra.hh"                         
 67 #include "G4Tet.hh"                               
 68 #include "G4DisplacedSolid.hh"                    
 69 #include "G4UnionSolid.hh"                        
 70 #include "G4IntersectionSolid.hh"                 
 71 #include "G4SubtractionSolid.hh"                  
 72 #include "G4LogicalVolume.hh"                     
 73 #include "G4PhysicalVolumeModel.hh"               
 74 #include "G4ModelingParameters.hh"                
 75 #include "G4VTrajectory.hh"                       
 76 #include "G4VTrajectoryPoint.hh"                  
 77 #include "G4HitsModel.hh"                         
 78 #include "G4VHit.hh"                              
 79 #include "G4VDigi.hh"                             
 80 #include "G4ScoringManager.hh"                    
 81 #include "G4VScoringMesh.hh"                      
 82 #include "G4Mesh.hh"                              
 83 #include "G4DefaultLinearColorMap.hh"             
 84 #include "G4QuickRand.hh"                         
 85 #include "G4StateManager.hh"                      
 86 #include "G4RunManager.hh"                        
 87 #include "G4RunManagerFactory.hh"                 
 88 #include "G4Run.hh"                               
 89 #include "G4Transform3D.hh"                       
 90 #include "G4AttHolder.hh"                         
 91 #include "G4AttDef.hh"                            
 92 #include "G4SceneTreeItem.hh"                     
 93 #include "G4VVisCommand.hh"                       
 94 #include "G4PhysicalConstants.hh"                 
 95 #include "G4SystemOfUnits.hh"                     
 96                                                   
 97 #define G4warn G4cout                             
 98                                                   
 99 G4VSceneHandler::G4VSceneHandler (G4VGraphicsS    
100   fSystem                (system),                
101   fSceneHandlerId        (id),                    
102   fViewCount             (0),                     
103   fpViewer               (0),                     
104   fpScene                (0),                     
105   fMarkForClearingTransientStore (true),  // R    
106             // ClearTransientStoreIfMarked(),     
107             // e.g., at end of run (see           
108             // G4VisManager.cc).                  
109   fReadyForTransients    (true),  // Only fals    
110   fProcessingSolid       (false),                 
111   fProcessing2D          (false),                 
112   fpModel                (0),                     
113   fNestingDepth          (0),                     
114   fpVisAttribs           (0)                      
115 {                                                 
116   G4VisManager* pVMan = G4VisManager::GetInsta    
117   fpScene = pVMan -> GetCurrentScene ();          
118   if (name == "") {                               
119     std::ostringstream ost;                       
120     ost << fSystem.GetName () << '-' << fScene    
121     fName = ost.str();                            
122   }                                               
123   else {                                          
124     fName = name;                                 
125   }                                               
126   fTransientsDrawnThisEvent = pVMan->GetTransi    
127   fTransientsDrawnThisRun = pVMan->GetTransien    
128 }                                                 
129                                                   
130 G4VSceneHandler::~G4VSceneHandler () {            
131   G4VViewer* last;                                
132   while( ! fViewerList.empty() ) {                
133     last = fViewerList.back();                    
134     fViewerList.pop_back();                       
135     delete last;                                  
136   }                                               
137 }                                                 
138                                                   
139 const G4VisExtent& G4VSceneHandler::GetExtent(    
140 {                                                 
141   if (fpScene) {                                  
142     return fpScene->GetExtent();                  
143   } else {                                        
144     static const G4VisExtent defaultExtent = G    
145     return defaultExtent;                         
146   }                                               
147 }                                                 
148                                                   
149 void G4VSceneHandler::PreAddSolid (const G4Tra    
150            const G4VisAttributes& visAttribs)     
151   fObjectTransformation = objectTransformation    
152   fpVisAttribs = &visAttribs;                     
153   fProcessingSolid = true;                        
154 }                                                 
155                                                   
156 void G4VSceneHandler::PostAddSolid () {           
157   fpVisAttribs = 0;                               
158   fProcessingSolid = false;                       
159   if (fReadyForTransients) {                      
160     fTransientsDrawnThisEvent = true;             
161     fTransientsDrawnThisRun = true;               
162   }                                               
163 }                                                 
164                                                   
165 void G4VSceneHandler::BeginPrimitives             
166 (const G4Transform3D& objectTransformation) {     
167   //static G4int count = 0;                       
168   //G4cout << "G4VSceneHandler::BeginPrimitive    
169   fNestingDepth++;                                
170   if (fNestingDepth > 1)                          
171     G4Exception                                   
172       ("G4VSceneHandler::BeginPrimitives",        
173        "visman0101", FatalException,              
174        "Nesting detected. It is illegal to nes    
175   fObjectTransformation = objectTransformation    
176 }                                                 
177                                                   
178 void G4VSceneHandler::EndPrimitives () {          
179   if (fNestingDepth <= 0)                         
180     G4Exception("G4VSceneHandler::EndPrimitive    
181     "visman0102", FatalException, "Nesting err    
182   fNestingDepth--;                                
183   if (fReadyForTransients) {                      
184     fTransientsDrawnThisEvent = true;             
185     fTransientsDrawnThisRun = true;               
186   }                                               
187 }                                                 
188                                                   
189 void G4VSceneHandler::BeginPrimitives2D           
190 (const G4Transform3D& objectTransformation) {     
191   fNestingDepth++;                                
192   if (fNestingDepth > 1)                          
193     G4Exception                                   
194       ("G4VSceneHandler::BeginPrimitives2D",      
195        "visman0103", FatalException,              
196        "Nesting detected. It is illegal to nes    
197   fObjectTransformation = objectTransformation    
198   fProcessing2D = true;                           
199 }                                                 
200                                                   
201 void G4VSceneHandler::EndPrimitives2D () {        
202   if (fNestingDepth <= 0)                         
203     G4Exception("G4VSceneHandler::EndPrimitive    
204     "visman0104", FatalException, "Nesting err    
205   fNestingDepth--;                                
206   if (fReadyForTransients) {                      
207     fTransientsDrawnThisEvent = true;             
208     fTransientsDrawnThisRun = true;               
209   }                                               
210   fProcessing2D = false;                          
211 }                                                 
212                                                   
213 void G4VSceneHandler::BeginModeling () {          
214 }                                                 
215                                                   
216 void G4VSceneHandler::EndModeling ()              
217 {                                                 
218   fpModel = 0;                                    
219 }                                                 
220                                                   
221 void G4VSceneHandler::ClearStore () {}            
222                                                   
223 void G4VSceneHandler::ClearTransientStore () {    
224                                                   
225 template <class T> void G4VSceneHandler::AddSo    
226 (const T& solid)                                  
227 {                                                 
228   // Get and check applicable vis attributes.     
229   fpVisAttribs = fpViewer->GetApplicableVisAtt    
230   RequestPrimitives (solid);                      
231 }                                                 
232                                                   
233 template <class T> void G4VSceneHandler::AddSo    
234 (const T& solid)                                  
235 {                                                 
236   // Get and check applicable vis attributes.     
237   fpVisAttribs = fpViewer->GetApplicableVisAtt    
238   // Draw with auxiliary edges unless otherwis    
239   if (!fpVisAttribs->IsForceAuxEdgeVisible())     
240     // Create a vis atts object for the modifi    
241     // It is static so that we may return a re    
242     static G4VisAttributes visAttsWithAuxEdges    
243     // Initialise it with the current vis atts    
244     visAttsWithAuxEdges = *fpVisAttribs;          
245     // Force auxiliary edges visible.             
246     visAttsWithAuxEdges.SetForceAuxEdgeVisible    
247     fpVisAttribs = &visAttsWithAuxEdges;          
248   }                                               
249   RequestPrimitives (solid);                      
250 }                                                 
251                                                   
252 void G4VSceneHandler::AddSolid (const G4Box& b    
253   AddSolidT (box);                                
254   // If your graphics system is sophisticated     
255   //  particular solid shape as a primitive, i    
256   //  function to override this.                  
257   // Your function might look like this...        
258   // void G4MySceneHandler::AddSolid (const G4    
259   // Get and check applicable vis attributes.     
260   //   fpVisAttribs = fpViewer->GetApplicableV    
261   // Do not draw if not visible.                  
262   //   if (fpVisAttribs->IsVisible()) {           
263   //   Get parameters of appropriate object, e    
264   //     G4double dx = box.GetXHalfLength ();     
265   //     G4double dy = box.GetYHalfLength ();     
266   //     G4double dz = box.GetZHalfLength ();     
267   //     ...                                      
268   //     and Draw or Store in your display Lis    
269 }                                                 
270                                                   
271 void G4VSceneHandler::AddSolid (const G4Cons&     
272   AddSolidT (cons);                               
273 }                                                 
274                                                   
275 void G4VSceneHandler::AddSolid (const G4Orb& o    
276   AddSolidWithAuxiliaryEdges (orb);               
277 }                                                 
278                                                   
279 void G4VSceneHandler::AddSolid (const G4Para&     
280   AddSolidT (para);                               
281 }                                                 
282                                                   
283 void G4VSceneHandler::AddSolid (const G4Sphere    
284   AddSolidWithAuxiliaryEdges (sphere);            
285 }                                                 
286                                                   
287 void G4VSceneHandler::AddSolid (const G4Torus&    
288   AddSolidWithAuxiliaryEdges (torus);             
289 }                                                 
290                                                   
291 void G4VSceneHandler::AddSolid (const G4Trap&     
292   AddSolidT (trap);                               
293 }                                                 
294                                                   
295 void G4VSceneHandler::AddSolid (const G4Trd& t    
296   AddSolidT (trd);                                
297 }                                                 
298                                                   
299 void G4VSceneHandler::AddSolid (const G4Tubs&     
300   AddSolidT (tubs);                               
301 }                                                 
302                                                   
303 void G4VSceneHandler::AddSolid (const G4Ellips    
304   AddSolidWithAuxiliaryEdges (ellipsoid);         
305 }                                                 
306                                                   
307 void G4VSceneHandler::AddSolid (const G4Polyco    
308   AddSolidT (polycone);                           
309 }                                                 
310                                                   
311 void G4VSceneHandler::AddSolid (const G4Polyhe    
312   AddSolidT (polyhedra);                          
313 }                                                 
314                                                   
315 void G4VSceneHandler::AddSolid (const G4Tessel    
316   AddSolidT (tess);                               
317 }                                                 
318                                                   
319 void G4VSceneHandler::AddSolid (const G4VSolid    
320   AddSolidT (solid);                              
321 }                                                 
322                                                   
323 void G4VSceneHandler::AddCompound (const G4VTr    
324   G4TrajectoriesModel* trajectoriesModel =        
325     dynamic_cast<G4TrajectoriesModel*>(fpModel    
326   if (trajectoriesModel)                          
327     traj.DrawTrajectory();                        
328   else {                                          
329     G4Exception                                   
330     ("G4VSceneHandler::AddCompound(const G4VTr    
331      "visman0105", FatalException, "Not a G4Tr    
332   }                                               
333 }                                                 
334                                                   
335 void G4VSceneHandler::AddCompound (const G4VHi    
336   // Cast away const because Draw is non-const    
337   const_cast<G4VHit&>(hit).Draw();                
338 }                                                 
339                                                   
340 void G4VSceneHandler::AddCompound (const G4VDi    
341   // Cast away const because Draw is non-const    
342   const_cast<G4VDigi&>(digi).Draw();              
343 }                                                 
344                                                   
345 void G4VSceneHandler::AddCompound (const G4THi    
346   using MeshScoreMap = G4VScoringMesh::MeshSco    
347   //G4cout << "AddCompound: hits: " << &hits <    
348   G4bool scoreMapHits = false;                    
349   G4ScoringManager* scoringManager = G4Scoring    
350   if (scoringManager) {                           
351     std::size_t nMeshes = scoringManager->GetN    
352     for (std::size_t iMesh = 0; iMesh < nMeshe    
353       G4VScoringMesh* mesh = scoringManager->G    
354       if (mesh && mesh->IsActive()) {             
355   MeshScoreMap scoreMap = mesh->GetScoreMap();    
356         const G4String& mapNam = const_cast<G4    
357   for(MeshScoreMap::const_iterator i = scoreMa    
358       i != scoreMap.cend(); ++i) {                
359     const G4String& scoreMapName = i->first;      
360     if (scoreMapName == mapNam) {                 
361       G4DefaultLinearColorMap colorMap("G4VSce    
362       scoreMapHits = true;                        
363       mesh->DrawMesh(scoreMapName, &colorMap);    
364     }                                             
365   }                                               
366       }                                           
367     }                                             
368   }                                               
369   if (scoreMapHits) {                             
370     static G4bool first = true;                   
371     if (first) {                                  
372       first = false;                              
373       G4cout <<                                   
374   "Scoring map drawn with default parameters."    
375   "\n  To get gMocren file for gMocren browser    
376   "\n    /vis/open gMocrenFile"                   
377   "\n    /vis/viewer/flush"                       
378   "\n  Many other options available with /scor    
379   "\n  You might want to \"/vis/viewer/set/aut    
380        << G4endl;                                 
381     }                                             
382   } else {  // Not score map hits.  Just call     
383     // Cast away const because DrawAllHits is     
384     const_cast<G4THitsMap<G4double>&>(hits).Dr    
385   }                                               
386 }                                                 
387                                                   
388 void G4VSceneHandler::AddCompound (const G4THi    
389   using MeshScoreMap = G4VScoringMesh::MeshSco    
390   //G4cout << "AddCompound: hits: " << &hits <    
391   G4bool scoreMapHits = false;                    
392   G4ScoringManager* scoringManager = G4Scoring    
393   if (scoringManager) {                           
394     std::size_t nMeshes = scoringManager->GetN    
395     for (std::size_t iMesh = 0; iMesh < nMeshe    
396       G4VScoringMesh* mesh = scoringManager->G    
397       if (mesh && mesh->IsActive()) {             
398   MeshScoreMap scoreMap = mesh->GetScoreMap();    
399   for(MeshScoreMap::const_iterator i = scoreMa    
400       i != scoreMap.cend(); ++i) {                
401     const G4String& scoreMapName = i->first;      
402     const G4THitsMap<G4StatDouble>* foundHits     
403     if (foundHits == &hits) {                     
404       G4DefaultLinearColorMap colorMap("G4VSce    
405       scoreMapHits = true;                        
406       mesh->DrawMesh(scoreMapName, &colorMap);    
407     }                                             
408   }                                               
409       }                                           
410     }                                             
411   }                                               
412   if (scoreMapHits) {                             
413     static G4bool first = true;                   
414     if (first) {                                  
415       first = false;                              
416       G4cout <<                                   
417   "Scoring map drawn with default parameters."    
418   "\n  To get gMocren file for gMocren browser    
419   "\n    /vis/open gMocrenFile"                   
420   "\n    /vis/viewer/flush"                       
421   "\n  Many other options available with /scor    
422   "\n  You might want to \"/vis/viewer/set/aut    
423        << G4endl;                                 
424     }                                             
425   } else {  // Not score map hits.  Just call     
426     // Cast away const because DrawAllHits is     
427     const_cast<G4THitsMap<G4StatDouble>&>(hits    
428   }                                               
429 }                                                 
430                                                   
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    
464   fViewerList.push_back (pViewer);                
465 }                                                 
466                                                   
467 void G4VSceneHandler::AddPrimitive (const G4Po    
468   switch (polymarker.GetMarkerType()) {           
469     default:                                      
470     case G4Polymarker::dots:                      
471     {                                             
472       G4Circle dot (polymarker);                  
473       dot.SetWorldSize  (0.);                     
474       dot.SetScreenSize (0.1);  // Very small     
475       for (std::size_t iPoint = 0; iPoint < po    
476         dot.SetPosition (polymarker[iPoint]);     
477         AddPrimitive (dot);                       
478       }                                           
479     }                                             
480       break;                                      
481     case G4Polymarker::circles:                   
482     {                                             
483       G4Circle circle (polymarker);  // Defaul    
484       for (std::size_t iPoint = 0; iPoint < po    
485         circle.SetPosition (polymarker[iPoint]    
486         AddPrimitive (circle);                    
487       }                                           
488     }                                             
489       break;                                      
490     case G4Polymarker::squares:                   
491     {                                             
492       G4Square square (polymarker);  // Defaul    
493       for (std::size_t iPoint = 0; iPoint < po    
494         square.SetPosition (polymarker[iPoint]    
495         AddPrimitive (square);                    
496       }                                           
497     }                                             
498       break;                                      
499   }                                               
500 }                                                 
501                                                   
502 void G4VSceneHandler::RemoveViewerFromList (G4    
503   fViewerList.remove(pViewer);  // Does nothin    
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 }                                                 
515                                                   
516 void G4VSceneHandler::SetScene (G4Scene* pScen    
517   fpScene = pScene;                               
518   // Notify all viewers that a kernel visit is    
519   G4ViewerListIterator i;                         
520   for (i = fViewerList.begin(); i != fViewerLi    
521     (*i) -> SetNeedKernelVisit (true);            
522   }                                               
523 }                                                 
524                                                   
525 void G4VSceneHandler::RequestPrimitives (const    
526 {                                                 
527   // Sometimes solids that have no substance g    
528   // be part of the geometry tree but have bee    
529   // example by a Boolean subtraction in which    
530   // is entirely inside the subtractor or an i    
531   // the original volume is entirely outside t    
532   // The problem is that the Boolean Processor    
533   // polyhedron in these cases (IMHO it should    
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   }                                               
580                                                   
581   const G4ViewParameters::DrawingStyle style =    
582   const G4ViewParameters& vp = fpViewer->GetVi    
583                                                   
584   switch (style) {                                
585     default:                                      
586     case G4ViewParameters::wireframe:             
587     case G4ViewParameters::hlr:                   
588     case G4ViewParameters::hsr:                   
589     case G4ViewParameters::hlhsr:                 
590     {                                             
591       // Use polyhedral representation            
592       G4Polyhedron::SetNumberOfRotationSteps (    
593       G4Polyhedron* pPolyhedron = solid.GetPol    
594       G4Polyhedron::ResetNumberOfRotationSteps    
595       if (pPolyhedron) {                          
596         pPolyhedron -> SetVisAttributes (fpVis    
597         BeginPrimitives (fObjectTransformation    
598         AddPrimitive (*pPolyhedron);              
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       }                                           
649       BeginPrimitives (fObjectTransformation);    
650       AddPrimitive(dots);                         
651       EndPrimitives ();                           
652       break;                                      
653     }                                             
654   }                                               
655 }                                                 
656                                                   
657 //namespace {                                     
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                                                   
676 void G4VSceneHandler::ProcessScene()              
677 {                                                 
678   // Assumes graphics database store has alrea    
679   // relevant for the particular scene handler    
680                                                   
681   if(!fpScene)                                    
682     return;                                       
683                                                   
684   if(fpScene->GetExtent() == G4VisExtent::GetN    
685   {                                               
686     G4Exception("G4VSceneHandler::ProcessScene    
687                 "The scene has no extent.");      
688   }                                               
689                                                   
690   G4VisManager* visManager = G4VisManager::Get    
691                                                   
692   if(!visManager->GetConcreteInstance())          
693     return;                                       
694                                                   
695   G4VisManager::Verbosity verbosity = visManag    
696                                                   
697   fReadyForTransients = false;                    
698                                                   
699   // Reset fMarkForClearingTransientStore. (Le    
700   // fMarkForClearingTransientStore true cause    
701   // recomputing transients below.)  Restore i    
702   G4bool tmpMarkForClearingTransientStore = fM    
703   fMarkForClearingTransientStore          = fa    
704                                                   
705   // Traverse geometry tree and send drawing p    
706                                                   
707   const std::vector<G4Scene::Model>& runDurati    
708     fpScene->GetRunDurationModelList();           
709                                                   
710   if(runDurationModelList.size()) {               
711     if(verbosity >= G4VisManager::confirmation    
712       G4cout << "Traversing scene data..." <<     
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     }                                             
722                                                   
723     // Reset visibility of all objects to fals    
724     fpViewer->AccessSceneTree().ResetVisibilit    
725                                                   
726     BeginModeling();                              
727                                                   
728     // Create modeling parameters from view pa    
729     G4ModelingParameters* pMP = CreateModeling    
730                                                   
731     for(std::size_t i = 0; i < runDurationMode    
732       if(runDurationModelList[i].fActive) {       
733         fpModel = runDurationModelList[i].fpMo    
734         fpModel->SetModelingParameters(pMP);      
735                                                   
736         // Describe to the current scene handl    
737         fpModel->DescribeYourselfTo(*this);       
738                                                   
739         // To see the extents of each model re    
740         // uncomment the next line and DrawExt    
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       }                                           
755     }                                             
756                                                   
757     fpModel = 0;                                  
758     delete pMP;                                   
759                                                   
760     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   }                                               
789                                                   
790   fReadyForTransients = true;                     
791                                                   
792   // Refresh event from end-of-event model lis    
793   // Allow only in Idle or GeomClosed state...    
794   G4StateManager* stateManager = G4StateManage    
795   G4ApplicationState state     = stateManager-    
796   if(state == G4State_Idle || state == G4State    
797   {                                               
798     visManager->SetEventRefreshing(true);         
799                                                   
800     if(visManager->GetRequestedEvent())           
801     {                                             
802       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                                                   
834             if(verbosity >= G4VisManager::conf    
835             {                                     
836               G4cout << "Refreshing events in     
837             }                                     
838             for(const auto& event : *events)      
839             {                                     
840               if(event)                           
841                 DrawEvent(event);                 
842             }                                     
843                                                   
844             if(!fpScene->GetRefreshAtEndOfRun(    
845             {                                     
846               if(verbosity >= G4VisManager::wa    
847               {                                   
848                 G4warn << "WARNING: Cannot ref    
849                           "\n  than one runs.     
850                        << G4endl;                 
851               }                                   
852             }                                     
853           }                                       
854         }                                         
855       }                                           
856     }                                             
857     visManager->SetEventRefreshing(false);        
858   }                                               
859                                                   
860   // Refresh end-of-run model list.               
861   // Allow only in Idle or GeomClosed state...    
862   if(state == G4State_Idle || state == G4State    
863   {                                               
864     DrawEndOfRunModels();                         
865   }                                               
866                                                   
867   fMarkForClearingTransientStore = tmpMarkForC    
868 }                                                 
869                                                   
870 void G4VSceneHandler::DrawEvent(const G4Event*    
871 {                                                 
872   if(!fpViewer->ReadyToDraw()) return;            
873   const std::vector<G4Scene::Model>& EOEModelL    
874     fpScene -> GetEndOfEventModelList ();         
875   std::size_t nModels = EOEModelList.size();      
876   if (nModels) {                                  
877     G4ModelingParameters* pMP = CreateModeling    
878     pMP->SetEvent(event);                         
879     for (std::size_t i = 0; i < nModels; ++i)     
880       if (EOEModelList[i].fActive) {              
881         fpModel = EOEModelList[i].fpModel;        
882         fpModel -> SetModelingParameters(pMP);    
883                                                   
884         // Describe to the current scene handl    
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       }                                           
893     }                                             
894     fpModel = 0;                                  
895     delete pMP;                                   
896   }                                               
897 }                                                 
898                                                   
899 void G4VSceneHandler::DrawEndOfRunModels()        
900 {                                                 
901   if(!fpViewer->ReadyToDraw()) return;            
902   const std::vector<G4Scene::Model>& EORModelL    
903     fpScene -> GetEndOfRunModelList ();           
904   std::size_t nModels = EORModelList.size();      
905   if (nModels) {                                  
906     G4ModelingParameters* pMP = CreateModeling    
907     pMP->SetEvent(0);                             
908     for (std::size_t i = 0; i < nModels; ++i)     
909       if (EORModelList[i].fActive) {              
910         fpModel = EORModelList[i].fpModel;        
911         fpModel -> SetModelingParameters(pMP);    
912                                                   
913         // Describe to the current scene handl    
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       }                                           
922     }                                             
923     fpModel = 0;                                  
924     delete pMP;                                   
925   }                                               
926 }                                                 
927                                                   
928 G4ModelingParameters* G4VSceneHandler::CreateM    
929 {                                                 
930   // Create modeling parameters from View Para    
931   if (!fpViewer) return NULL;                     
932                                                   
933   const G4ViewParameters& vp = fpViewer -> Get    
934                                                   
935   // Convert drawing styles...                    
936   G4ModelingParameters::DrawingStyle modelDraw    
937   G4ModelingParameters::wf;                       
938   switch (vp.GetDrawingStyle ()) {                
939     default:                                      
940     case G4ViewParameters::wireframe:             
941       modelDrawingStyle = G4ModelingParameters    
942       break;                                      
943     case G4ViewParameters::hlr:                   
944       modelDrawingStyle = G4ModelingParameters    
945       break;                                      
946     case G4ViewParameters::hsr:                   
947       modelDrawingStyle = G4ModelingParameters    
948       break;                                      
949     case G4ViewParameters::hlhsr:                 
950       modelDrawingStyle = G4ModelingParameters    
951       break;                                      
952     case G4ViewParameters::cloud:                 
953       modelDrawingStyle = G4ModelingParameters    
954       break;                                      
955   }                                               
956                                                   
957   // Decide if covered daughters are really to    
958   G4bool reallyCullCovered =                      
959     vp.IsCullingCovered()   // Culling daughte    
960     && !vp.IsSection ()     // Sections (DCUT)    
961     && !vp.IsCutaway ()     // Cutaways not re    
962     ;                                             
963                                                   
964   G4ModelingParameters* pModelingParams = new     
965     (vp.GetDefaultVisAttributes (),               
966      modelDrawingStyle,                           
967      vp.IsCulling (),                             
968      vp.IsCullingInvisible (),                    
969      vp.IsDensityCulling (),                      
970      vp.GetVisibleDensity (),                     
971      reallyCullCovered,                           
972      vp.GetNoOfSides ()                           
973      );                                           
974                                                   
975   pModelingParams->SetNumberOfCloudPoints(vp.G    
976   pModelingParams->SetWarning                     
977     (G4VisManager::GetVerbosity() >= G4VisMana    
978                                                   
979   pModelingParams->SetCBDAlgorithmNumber(vp.Ge    
980   pModelingParams->SetCBDParameters(vp.GetCBDP    
981                                                   
982   pModelingParams->SetExplodeFactor(vp.GetExpl    
983   pModelingParams->SetExplodeCentre(vp.GetExpl    
984                                                   
985   pModelingParams->SetSectionSolid(CreateSecti    
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    
994   // The polyhedron objects are deleted in the    
995                                                   
996   pModelingParams->SetVisAttributesModifiers(v    
997                                                   
998   pModelingParams->SetSpecialMeshRendering(vp.    
999   pModelingParams->SetSpecialMeshVolumes(vp.Ge    
1000                                                  
1001   return pModelingParams;                        
1002 }                                                
1003                                                  
1004 G4DisplacedSolid* G4VSceneHandler::CreateSect    
1005 {                                                
1006   G4DisplacedSolid* sectioner = 0;               
1007                                                  
1008   const G4ViewParameters& vp = fpViewer->GetV    
1009   if (vp.IsSection () ) {                        
1010                                                  
1011     G4double radius = fpScene->GetExtent().Ge    
1012     G4double safe = radius + fpScene->GetExte    
1013     G4VSolid* sectionBox =                       
1014       new G4Box("_sectioner", safe, safe, 1.e    
1015                                                  
1016     const G4Plane3D& sp = vp.GetSectionPlane     
1017     G4ThreeVector normal = sp.normal();          
1018     G4Transform3D requiredTransform = G4Trans    
1019     G4Rotate3D(G4ThreeVector(0,0,1), G4ThreeV    
1020                                                  
1021     sectioner = new G4DisplacedSolid             
1022     ("_displaced_sectioning_box", sectionBox,    
1023   }                                              
1024                                                  
1025   return sectioner;                              
1026 }                                                
1027                                                  
1028 G4DisplacedSolid* G4VSceneHandler::CreateCuta    
1029 {                                                
1030   const auto& vp = fpViewer->GetViewParameter    
1031   const auto& nPlanes = vp.GetCutawayPlanes()    
1032                                                  
1033   if (nPlanes == 0) return nullptr;              
1034                                                  
1035   std::vector<G4DisplacedSolid*> cutaway_soli    
1036                                                  
1037   G4double radius = fpScene->GetExtent().GetE    
1038   G4double safe = radius + fpScene->GetExtent    
1039   auto cutawayBox = new G4Box("_cutaway_box",    
1040                                                  
1041   // if (vp.GetCutawayMode() == G4ViewParamet    
1042   // the intersection of displaced cutaway bo    
1043   // positive values a*x+b*y+c*z+d>0, so we h    
1044   // "back to front". The parameter "cutawayU    
1045   // that remain *after* cutaway", because we    
1046   // a "union" of what remains by superimposi    
1047   // and G4OpenGLImmediate/StoredViewer::Proc    
1048   // that is the intersection of inverted cut    
1049                                                  
1050   // Conversely, if (vp.GetCutawayMode() == G    
1051   // create an intersector that is the inters    
1052                                                  
1053   for (size_t plane_no = 0; plane_no < nPlane    
1054   {                                              
1055     const G4Plane3D& sp = vp.GetCutawayPlanes    
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 }                                                
1107                                                  
1108 void G4VSceneHandler::LoadAtts(const G4Visibl    
1109 {                                                
1110   // Load G4Atts from G4VisAttributes, if any    
1111   const G4VisAttributes* va = visible.GetVisA    
1112   if (va) {                                      
1113     const std::map<G4String,G4AttDef>* vaDefs    
1114       va->GetAttDefs();                          
1115     if (vaDefs) {                                
1116       holder->AddAtts(visible.GetVisAttribute    
1117     }                                            
1118   }                                              
1119                                                  
1120   G4PhysicalVolumeModel* pPVModel =              
1121     dynamic_cast<G4PhysicalVolumeModel*>(fpMo    
1122   if (pPVModel) {                                
1123     // Load G4Atts from G4PhysicalVolumeModel    
1124     const std::map<G4String,G4AttDef>* pvDefs    
1125     if (pvDefs) {                                
1126       holder->AddAtts(pPVModel->CreateCurrent    
1127     }                                            
1128   }                                              
1129                                                  
1130   G4TrajectoriesModel* trajModel = dynamic_ca    
1131   if (trajModel) {                               
1132     // Load G4Atts from trajectory model...      
1133     const std::map<G4String,G4AttDef>* trajMo    
1134     if (trajModelDefs) {                         
1135       holder->AddAtts(trajModel->CreateCurren    
1136     }                                            
1137     // Load G4Atts from trajectory...            
1138     const G4VTrajectory* traj = trajModel->Ge    
1139     if (traj) {                                  
1140       const std::map<G4String,G4AttDef>* traj    
1141       if (trajDefs) {                            
1142         holder->AddAtts(traj->CreateAttValues    
1143       }                                          
1144       G4int nPoints = traj->GetPointEntries()    
1145       for (G4int i = 0; i < nPoints; ++i) {      
1146         G4VTrajectoryPoint* trajPoint = traj-    
1147         if (trajPoint) {                         
1148           const std::map<G4String,G4AttDef>*     
1149           if (pointDefs) {                       
1150             holder->AddAtts(trajPoint->Create    
1151           }                                      
1152         }                                        
1153       }                                          
1154     }                                            
1155   }                                              
1156                                                  
1157   G4HitsModel* hitsModel = dynamic_cast<G4Hit    
1158   if (hitsModel) {                               
1159     // Load G4Atts from hit...                   
1160     const G4VHit* hit = hitsModel->GetCurrent    
1161     const std::map<G4String,G4AttDef>* hitsDe    
1162     if (hitsDefs) {                              
1163       holder->AddAtts(hit->CreateAttValues(),    
1164     }                                            
1165   }                                              
1166 }                                                
1167                                                  
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    
1181   auto pVA = text.GetVisAttributes();            
1182   if (!pVA) pVA = fpViewer->GetViewParameters    
1183   return pVA->GetColour();                       
1184 }                                                
1185                                                  
1186 G4double G4VSceneHandler::GetLineWidth(const     
1187 {                                                
1188   G4double lineWidth = pVisAttribs->GetLineWi    
1189   if (lineWidth < 1.) lineWidth = 1.;            
1190   lineWidth *= fpViewer -> GetViewParameters(    
1191   if (lineWidth < 1.) lineWidth = 1.;            
1192   return lineWidth;                              
1193 }                                                
1194                                                  
1195 G4ViewParameters::DrawingStyle G4VSceneHandle    
1196 (const G4VisAttributes* pVisAttribs) {           
1197   // Drawing style is normally determined by     
1198   // it can be overriddden by the ForceDrawin    
1199   // attributes.                                 
1200   const G4ViewParameters& vp = fpViewer->GetV    
1201   const G4ViewParameters::DrawingStyle viewer    
1202   G4ViewParameters::DrawingStyle resultantSty    
1203   if (pVisAttribs -> IsForceDrawingStyle ())     
1204     G4VisAttributes::ForcedDrawingStyle force    
1205     pVisAttribs -> GetForcedDrawingStyle ();     
1206     // This is complicated because if hidden     
1207     // has been requested we wish to preserve    
1208     switch (forcedStyle) {                       
1209       case (G4VisAttributes::solid):             
1210         switch (viewerStyle) {                   
1211           case (G4ViewParameters::hlr):          
1212             resultantStyle = G4ViewParameters    
1213             break;                               
1214           case (G4ViewParameters::wireframe):    
1215             resultantStyle = G4ViewParameters    
1216             break;                               
1217           case (G4ViewParameters::cloud):        
1218             resultantStyle = G4ViewParameters    
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:                                   
1230         // But if forced style is wireframe,     
1231         // main uses is in displaying the con    
1232         // solid and their surfaces overlap w    
1233         // solid, making a mess if hlr is spe    
1234         resultantStyle = G4ViewParameters::wi    
1235         break;                                   
1236     }                                            
1237   }                                              
1238   return resultantStyle;                         
1239 }                                                
1240                                                  
1241 G4int G4VSceneHandler::GetNumberOfCloudPoints    
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   }                                              
1252   return numberOfCloudPoints;                    
1253 }                                                
1254                                                  
1255 G4bool G4VSceneHandler::GetAuxEdgeVisible (co    
1256   G4bool isAuxEdgeVisible = fpViewer->GetView    
1257   if (pVisAttribs -> IsForceAuxEdgeVisible())    
1258     isAuxEdgeVisible = pVisAttribs->IsForcedA    
1259   }                                              
1260   return isAuxEdgeVisible;                       
1261 }                                                
1262                                                  
1263 G4double G4VSceneHandler::GetMarkerSize          
1264 (const G4VMarker& marker,                        
1265  G4VSceneHandler::MarkerSizeType& markerSizeT    
1266 {                                                
1267   G4bool userSpecified = marker.GetWorldSize(    
1268   const G4VMarker& defaultMarker =               
1269     fpViewer -> GetViewParameters().GetDefaul    
1270   G4double size = userSpecified ?                
1271     marker.GetWorldSize() : defaultMarker.Get    
1272   if (size) {                                    
1273     // Draw in world coordinates.                
1274     markerSizeType = world;                      
1275   }                                              
1276   else {                                         
1277     size = userSpecified ?                       
1278       marker.GetScreenSize() : defaultMarker.    
1279     // Draw in screen coordinates.               
1280     markerSizeType = screen;                     
1281   }                                              
1282   size *= fpViewer -> GetViewParameters().Get    
1283   if (markerSizeType == screen && size < 1.)     
1284   return size;                                   
1285 }                                                
1286                                                  
1287 G4int G4VSceneHandler::GetNoOfSides(const G4V    
1288 {                                                
1289   // No. of sides (lines segments per circle)    
1290   // by the view parameters, but it can be ov    
1291   // ForceLineSegmentsPerCircle in the vis at    
1292   G4int lineSegmentsPerCircle = fpViewer->Get    
1293   if (pVisAttribs) {                             
1294     if (pVisAttribs->IsForceLineSegmentsPerCi    
1295       lineSegmentsPerCircle = pVisAttribs->Ge    
1296     if (lineSegmentsPerCircle < pVisAttribs->    
1297       lineSegmentsPerCircle = pVisAttribs->Ge    
1298       G4warn <<                                  
1299   "G4VSceneHandler::GetNoOfSides: attempt to     
1300   "\nnumber of line segments per circle < " <    
1301        << "; forced to " << pVisAttribs->GetM    
1302     }                                            
1303   }                                              
1304   return lineSegmentsPerCircle;                  
1305 }                                                
1306                                                  
1307 std::ostream& operator << (std::ostream& os,     
1308                                                  
1309   os << "Scene handler " << sh.fName << " has    
1310      << sh.fViewerList.size () << " viewer(s)    
1311   for (std::size_t i = 0; i < sh.fViewerList.    
1312     os << "\n  " << *(sh.fViewerList [i]);       
1313   }                                              
1314                                                  
1315   if (sh.fpScene) {                              
1316     os << "\n  " << *sh.fpScene;                 
1317   }                                              
1318   else {                                         
1319     os << "\n  This scene handler currently h    
1320   }                                              
1321                                                  
1322   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 }                                                
2043