Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/visualization/management/src/G4VisManager.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 ]

  1 //
  2 // ********************************************************************
  3 // * License and Disclaimer                                           *
  4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.                             *
 10 // *                                                                  *
 11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                                                  *
 18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // ********************************************************************
 25 //
 26 //
 27 // 
 28 // GEANT4 Visualization Manager - John Allison 02/Jan/1996.
 29 // Michael Kelsey  31 Jan 2019 -- Add new command for electric field
 30 
 31 #include "G4VisManager.hh"
 32 
 33 #include "G4VisCommands.hh"
 34 #include "G4VisCommandsCompound.hh"
 35 #include "G4VisCommandsGeometry.hh"
 36 #include "G4VisCommandsGeometrySet.hh"
 37 #include "G4VisCommandsMultithreading.hh"
 38 #include "G4VisCommandsSet.hh"
 39 #include "G4VisCommandsScene.hh"
 40 #include "G4VisCommandsSceneAdd.hh"
 41 #include "G4VisCommandsPlotter.hh"
 42 #include "G4VisCommandsSceneHandler.hh"
 43 #include "G4VisCommandsTouchable.hh"
 44 #include "G4VisCommandsTouchableSet.hh"
 45 #include "G4VisCommandsViewer.hh"
 46 #include "G4VisCommandsViewerDefault.hh"
 47 #include "G4VisCommandsViewerSet.hh"
 48 #include "G4UImanager.hh"
 49 #include "G4VisStateDependent.hh"
 50 #include "G4UIdirectory.hh"
 51 #include "G4VGraphicsSystem.hh"
 52 #include "G4VSceneHandler.hh"
 53 #include "G4VViewer.hh"
 54 #include "G4VPhysicalVolume.hh"
 55 #include "G4LogicalVolume.hh"
 56 #include "G4VSolid.hh"
 57 #include "G4Vector3D.hh"
 58 #include "G4Point3D.hh"
 59 #include "G4RotationMatrix.hh"
 60 #include "G4Polyline.hh"
 61 #include "G4Polyhedron.hh"
 62 #include "G4NullModel.hh"
 63 #include "G4ModelingParameters.hh"
 64 #include "G4TransportationManager.hh"
 65 #include "G4VisCommandModelCreate.hh"
 66 #include "G4VisCommandsListManager.hh"
 67 #include "G4VisModelManager.hh"
 68 #include "G4VModelFactory.hh"
 69 #include "G4VisFilterManager.hh"
 70 #include "G4VTrajectoryModel.hh"
 71 #include "G4TrajectoryDrawByCharge.hh"
 72 #include "Randomize.hh"
 73 #include "G4RunManager.hh"
 74 #include "G4RunManagerFactory.hh"
 75 #include "G4EventManager.hh"
 76 #include "G4Run.hh"
 77 #include "G4Event.hh"
 78 #include <map>
 79 #include <set>
 80 #include <vector>
 81 #include <sstream>
 82 
 83 #ifdef G4MULTITHREADED
 84 #  include "G4Threading.hh"
 85 #  include "G4AutoLock.hh"
 86 #  include "G4GeometryWorkspace.hh" // no_geant4_module_check(!G4MULTITHREADED)
 87 #  include "G4SolidsWorkspace.hh"
 88 #  include <deque>
 89 #  include <typeinfo>
 90 #  include <chrono>
 91 #  include <thread>
 92 #endif
 93 
 94 #define G4warn G4cout
 95 
 96 G4VisManager* G4VisManager::fpInstance = 0;
 97 
 98 G4VisManager::Verbosity G4VisManager::fVerbosity = G4VisManager::warnings;
 99 
100 G4VisManager::G4VisManager (const G4String& verbosityString)
101 : fVerbose         (1)
102 , fDefaultGraphicsSystemName("OGL")          // Override in G4VisExecutive
103 , fDefaultXGeometryString   ("600x600-0+0")  // Override in G4VisExecutive
104 , fDefaultGraphicsSystemBasis ("G4VisManager initialisation")
105 , fDefaultXGeometryStringBasis("G4VisManager initialisation")
106 , fInitialised     (false)
107 , fpGraphicsSystem (0)
108 , fpScene          (0)
109 , fpSceneHandler   (0)
110 , fpViewer         (0)
111 , fpStateDependent (0)
112 , fEventRefreshing          (false)
113 , fTransientsDrawnThisRun   (false)
114 , fTransientsDrawnThisEvent (false)
115 , fNoOfEventsDrawnThisRun   (0)
116 , fNKeepRequests            (0)
117 , fEventKeepingSuspended    (false)
118 , fDrawEventOnlyIfToBeKept  (false)
119 , fpRequestedEvent          (0)
120 , fReviewingKeptEvents      (false)
121 , fAbortReviewKeptEvents    (false)
122 , fReviewingPlots           (false)
123 , fAbortReviewPlots         (false)
124 , fIsDrawGroup              (false)
125 , fDrawGroupNestingDepth    (0)
126 , fIgnoreStateChanges       (false)
127 #ifdef G4MULTITHREADED
128 , fMaxEventQueueSize        (100)
129 , fWaitOnEventQueueFull     (true)
130 #endif
131 // All other objects use default constructors.
132 {
133   fpTrajDrawModelMgr = new G4VisModelManager<G4VTrajectoryModel>("/vis/modeling/trajectories");
134   fpTrajFilterMgr = new G4VisFilterManager<G4VTrajectory>("/vis/filtering/trajectories");
135   fpHitFilterMgr = new G4VisFilterManager<G4VHit>("/vis/filtering/hits");
136   fpDigiFilterMgr = new G4VisFilterManager<G4VDigi>("/vis/filtering/digi");
137 
138   VerbosityGuidanceStrings.push_back
139     ("Simple graded message scheme - digit or string (1st character defines):");
140   VerbosityGuidanceStrings.push_back
141     ("  0) quiet,         // Nothing is printed.");
142   VerbosityGuidanceStrings.push_back
143     ("  1) startup,       // Startup and endup messages are printed...");
144   VerbosityGuidanceStrings.push_back
145     ("  2) errors,        // ...and errors...");
146   VerbosityGuidanceStrings.push_back
147     ("  3) warnings,      // ...and warnings...");
148   VerbosityGuidanceStrings.push_back
149     ("  4) confirmations, // ...and confirming messages...");
150   VerbosityGuidanceStrings.push_back
151     ("  5) parameters,    // ...and parameters of scenes and views...");
152   VerbosityGuidanceStrings.push_back
153     ("  6) all            // ...and everything available.");
154 
155   if (fpInstance) {
156     G4Exception
157       ("G4VisManager::G4VisManager",
158        "visman0001", FatalException,
159        "Attempt to Construct more than one VisManager");
160   }
161 
162   fpInstance = this;
163   SetConcreteInstance(this);
164 
165   fpStateDependent = new G4VisStateDependent (this);
166   // No need to delete this; G4StateManager does this.
167 
168   fVerbosity = GetVerbosityValue(verbosityString);
169   if (fVerbosity >= startup) {
170       G4cout
171   << "Visualization Manager instantiating with verbosity \""
172   << VerbosityString(fVerbosity)
173   << "\"..." << G4endl;
174   }
175 
176   // Note: The specific graphics systems must be instantiated in a
177   // higher level library to avoid circular dependencies.  Also,
178   // some specifically need additional external libararies that the
179   // user must supply.  Therefore we ask the user to implement
180   // RegisterGraphicsSystems() and RegisterModelFactories()
181   // in a subclass.  We have to wait for the subclass to instantiate
182   // so RegisterGraphicsSystems() cannot be called from this
183   // constructor; it is called from Initialise().  So we ask the
184   // user:
185   //   (a) to write a subclass and implement  RegisterGraphicsSystems()
186   //       and RegisterModelFactories().  See
187   //       visualization/include/G4VisExecutive.hh/icc as an example.
188   //   (b) instantiate the subclass.
189   //   (c) invoke the Initialise() method of the subclass.
190   // For example:
191   //   ...
192   //   // Instantiate and initialise Visualization Manager.
193   //   G4VisManager* visManager = new G4VisExecutive;
194   //   visManager -> SetVerboseLevel (Verbose);
195   //   visManager -> Initialise ();
196   //   // (Don't forget to delete visManager;)
197   //   ...
198 
199   // Make top level command directory...
200   // vis commands should *not* be broadcast to workers
201   G4bool propagateToWorkers;
202   auto directory = new G4UIdirectory ("/vis/",propagateToWorkers=false);
203   directory -> SetGuidance ("Visualization commands.");
204   // Request commands in name order
205   directory -> Sort();  // Ordering propagates to sub-directories
206   fDirectoryList.push_back (directory);
207 
208   // Instantiate *basic* top level commands so that they can be used
209   // immediately after instantiation of the vis manager.  Other top
210   // level and lower level commands are instantiated later in
211   // RegisterMessengers.
212   G4VVisCommand::SetVisManager (this);  // Sets shared pointer
213   RegisterMessenger(new G4VisCommandVerbose);
214   RegisterMessenger(new G4VisCommandInitialize);
215 }
216 
217 G4VisManager::~G4VisManager()
218 {
219   G4UImanager* UImanager = G4UImanager::GetUIpointer();
220   UImanager->SetCoutDestination(nullptr);
221   std::size_t i;
222   for (i = 0; i < fSceneList.size (); ++i) {
223     delete fSceneList[i];
224   }
225   for (i = 0; i < fAvailableSceneHandlers.size (); ++i) {
226   if (fAvailableSceneHandlers[i] != NULL) {
227     delete fAvailableSceneHandlers[i];
228   }
229   }
230   for (i = 0; i < fAvailableGraphicsSystems.size (); ++i) {
231     if (fAvailableGraphicsSystems[i]) {
232       delete fAvailableGraphicsSystems[i];
233     }
234   }
235   if (fVerbosity >= startup) {
236     G4cout << "Graphics systems deleted." << G4endl;
237     G4cout << "Visualization Manager deleting..." << G4endl;
238   }
239   for (i = 0; i < fMessengerList.size (); ++i) {
240     delete fMessengerList[i];
241   }
242   for (i = 0; i < fDirectoryList.size (); ++i) {
243     delete fDirectoryList[i];
244   }
245 
246   delete fpDigiFilterMgr;
247   delete fpHitFilterMgr;
248   delete fpTrajFilterMgr;
249   delete fpTrajDrawModelMgr;
250   fpInstance = 0;
251 }
252 
253 G4VisManager* G4VisManager::GetInstance () {
254   if (!fpInstance) {
255     G4Exception
256       ("G4VisManager::GetInstance",
257        "visman0002", FatalException, "VisManager not yet instantiated");
258   }
259   return fpInstance;
260 }
261 
262 void G4VisManager::Initialise () {
263 
264   if (fInitialised && fVerbosity >= warnings) {
265     G4warn << "WARNING: G4VisManager::Initialise: already initialised."
266      << G4endl;
267     return;
268   }
269 
270   if (fVerbosity >= startup) {
271     G4cout << "Visualization Manager initialising..." << G4endl;
272   }
273 
274   if (fVerbosity >= parameters) {
275     G4cout <<
276       "\nYou have instantiated your own Visualization Manager, inheriting"
277       "\n  G4VisManager and implementing RegisterGraphicsSystems(), in which"
278       "\n  you should, normally, instantiate drivers which do not need"
279       "\n  external packages or libraries, and, optionally, drivers under"
280       "\n  control of environment variables."
281       "\n  Also you should implement RegisterModelFactories()."
282       "\n  See visualization/management/include/G4VisExecutive.hh/icc, for example."
283       "\n  In your main() you will have something like:"
284       "\n    G4VisManager* visManager = new G4VisExecutive;"
285       "\n    visManager -> SetVerboseLevel (Verbose);"
286       "\n    visManager -> Initialize ();"
287       "\n  (Don't forget to delete visManager;)"
288       "\n"
289    << G4endl;
290   }
291 
292   if (fVerbosity >= startup) {
293     G4cout << "Registering graphics systems..." << G4endl;
294   }
295 
296   RegisterGraphicsSystems ();
297 
298   if (fVerbosity >= startup) {
299     G4cout <<
300       "\nYou have successfully registered the following graphics systems."
301    << G4endl;
302     PrintAvailableGraphicsSystems (fVerbosity);
303     G4cout << G4endl;
304   }
305 
306   // Make command directories for commands instantiated in the
307   // modeling subcategory...
308   G4UIcommand* directory;
309   directory = new G4UIdirectory ("/vis/modeling/");
310   directory -> SetGuidance ("Modeling commands.");
311   fDirectoryList.push_back (directory);
312   directory = new G4UIdirectory ("/vis/modeling/trajectories/");
313   directory -> SetGuidance ("Trajectory model commands.");
314   fDirectoryList.push_back (directory);
315   directory = new G4UIdirectory ("/vis/modeling/trajectories/create/");
316   directory -> SetGuidance ("Create trajectory models and messengers.");
317   fDirectoryList.push_back (directory);
318 
319   // Filtering command directory
320   directory = new G4UIdirectory ("/vis/filtering/");
321   directory -> SetGuidance ("Filtering commands.");
322   fDirectoryList.push_back (directory);
323   directory = new G4UIdirectory ("/vis/filtering/trajectories/");
324   directory -> SetGuidance ("Trajectory filtering commands.");
325   fDirectoryList.push_back (directory);
326   directory = new G4UIdirectory ("/vis/filtering/trajectories/create/");
327   directory -> SetGuidance ("Create trajectory filters and messengers.");
328   fDirectoryList.push_back (directory);
329   directory = new G4UIdirectory ("/vis/filtering/hits/");
330   directory -> SetGuidance ("Hit filtering commands.");
331   fDirectoryList.push_back (directory);
332   directory = new G4UIdirectory ("/vis/filtering/hits/create/");
333   directory -> SetGuidance ("Create hit filters and messengers.");
334   fDirectoryList.push_back (directory);
335   directory = new G4UIdirectory ("/vis/filtering/digi/");
336   directory -> SetGuidance ("Digi filtering commands.");
337   fDirectoryList.push_back (directory);
338   directory = new G4UIdirectory ("/vis/filtering/digi/create/");
339   directory -> SetGuidance ("Create digi filters and messengers.");
340   fDirectoryList.push_back (directory);
341 
342   RegisterMessengers ();
343 
344   if (fVerbosity >= startup) {
345     G4cout << "Registering model factories..." << G4endl;
346   }
347 
348   RegisterModelFactories();
349 
350   if (fVerbosity >= startup) {
351     G4cout <<
352       "\nYou have successfully registered the following model factories."
353      << G4endl;
354     PrintAvailableModels (fVerbosity);
355     G4cout << G4endl;
356   }
357 
358   if (fVerbosity >= startup) {
359     PrintAvailableUserVisActions (fVerbosity);
360     G4cout << G4endl;
361   }
362 
363   InitialiseG4ColourMap();
364 
365   if (fVerbosity >= startup) {
366     G4cout <<
367     "Some /vis commands (optionally) take a string to specify colour."
368     "\n\"/vis/list\" to see available colours."
369     << G4endl;
370   }
371 
372   fInitialised = true;
373 }
374 
375 void G4VisManager::InitialiseG4ColourMap() const
376 {
377   G4Colour::InitialiseColourMap();  // Initialises (if not already initialised)
378 
379   // our forever 65 named colors taken long time ago from X11.
380   // Extracted from g4tools/include/tools/colors
381   // Copyright (C) 2010, Guy Barrand. All rights reserved.
382   // See the file tools.license for terms.
383 
384 #define TOOLS_COLORS_STAT(name,r,g,b) \
385 G4Colour::AddToMap(#name, G4Colour(r,g,b));
386 
387   //0-9
388   TOOLS_COLORS_STAT(aquamarine,0.496101F,0.996109F,0.828138F)
389   TOOLS_COLORS_STAT(mediumaquamarine,0.398444F,0.800793F,0.664073F)
390   //  TOOLS_COLORS_STAT(black,0,0,0) (already defined)
391   //  TOOLS_COLORS_STAT(blue,0,0,1) (already defined)
392   TOOLS_COLORS_STAT(cadetblue,0.371099F,0.617197F,0.62501F)
393   TOOLS_COLORS_STAT(cornflowerblue,0.390631F,0.58204F,0.925795F)
394   TOOLS_COLORS_STAT(darkslateblue,0.281254F,0.238285F,0.542977F)
395   TOOLS_COLORS_STAT(lightblue,0.675792F,0.843763F,0.898451F)
396   TOOLS_COLORS_STAT(lightsteelblue,0.68751F,0.765637F,0.867201F)
397   TOOLS_COLORS_STAT(mediumblue,0,0,0.800793F)
398 
399   //10-19
400   TOOLS_COLORS_STAT(mediumslateblue,0.480476F,0.406256F,0.929702F)
401   TOOLS_COLORS_STAT(midnightblue,0.0976577F,0.0976577F,0.437507F)
402   TOOLS_COLORS_STAT(navyblue,0,0,0.500008F)
403   TOOLS_COLORS_STAT(navy,0,0,0.500008F)
404   TOOLS_COLORS_STAT(skyblue,0.527352F,0.8047F,0.917983F)
405   TOOLS_COLORS_STAT(slateblue,0.414069F,0.351568F,0.800793F)
406   TOOLS_COLORS_STAT(steelblue,0.273442F,0.50782F,0.703136F)
407   TOOLS_COLORS_STAT(coral,0.996109F,0.496101F,0.312505F)
408   //  TOOLS_COLORS_STAT(cyan,0,1,1) (already defined)
409   TOOLS_COLORS_STAT(firebrick,0.695323F,0.132815F,0.132815F)
410 
411   //20-29
412   //  TOOLS_COLORS_STAT(brown,0.644541F,0.164065F,0.164065F) (already defined)
413   TOOLS_COLORS_STAT(gold,0.996109F,0.839857F,0)
414   TOOLS_COLORS_STAT(goldenrod,0.851575F,0.644541F,0.125002F)
415   //  TOOLS_COLORS_STAT(green,0,1,0) (already defined)
416   TOOLS_COLORS_STAT(darkgreen,0,0.390631F,0)
417   TOOLS_COLORS_STAT(darkolivegreen,0.332036F,0.417975F,0.183597F)
418   TOOLS_COLORS_STAT(forestgreen,0.132815F,0.542977F,0.132815F)
419   TOOLS_COLORS_STAT(limegreen,0.195315F,0.800793F,0.195315F)
420   TOOLS_COLORS_STAT(mediumseagreen,0.234379F,0.699229F,0.441413F)
421   TOOLS_COLORS_STAT(mediumspringgreen,0,0.976577F,0.601572F)
422 
423   //30-39
424   TOOLS_COLORS_STAT(palegreen,0.593759F,0.980484F,0.593759F)
425   TOOLS_COLORS_STAT(seagreen,0.17969F,0.542977F,0.339849F)
426   TOOLS_COLORS_STAT(springgreen,0,0.996109F,0.496101F)
427   TOOLS_COLORS_STAT(yellowgreen,0.601572F,0.800793F,0.195315F)
428   TOOLS_COLORS_STAT(darkslategrey,0.183597F,0.308598F,0.308598F)
429   TOOLS_COLORS_STAT(dimgrey,0.410163F,0.410163F,0.410163F)
430   TOOLS_COLORS_STAT(lightgrey,0.824231F,0.824231F,0.824231F)
431   //  TOOLS_COLORS_STAT(grey,0.750011F,0.750011F,0.750011F) (already defined)
432   TOOLS_COLORS_STAT(khaki,0.937514F,0.898451F,0.546883F)
433   //  TOOLS_COLORS_STAT(magenta,1,0,1) (already defined)
434 
435   //40-49
436   TOOLS_COLORS_STAT(maroon,0.68751F,0.187503F,0.375006F)
437   TOOLS_COLORS_STAT(orange,0.996109F,0.644541F,0)
438   TOOLS_COLORS_STAT(orchid,0.851575F,0.437507F,0.83595F)
439   TOOLS_COLORS_STAT(darkorchid,0.597665F,0.195315F,0.796887F)
440   TOOLS_COLORS_STAT(mediumorchid,0.726574F,0.332036F,0.824231F)
441   TOOLS_COLORS_STAT(pink,0.996109F,0.750011F,0.792981F)
442   TOOLS_COLORS_STAT(plum,0.863294F,0.62501F,0.863294F)
443   //  TOOLS_COLORS_STAT(red,1,0,0) (already defined)
444   TOOLS_COLORS_STAT(indianred,0.800793F,0.35938F,0.35938F)
445   TOOLS_COLORS_STAT(mediumvioletred,0.777356F,0.0820325F,0.519539F)
446 
447   //50-59
448   TOOLS_COLORS_STAT(orangered,0.996109F,0.269535F,0)
449   TOOLS_COLORS_STAT(violetred,0.812512F,0.125002F,0.562509F)
450   TOOLS_COLORS_STAT(salmon,0.976577F,0.500008F,0.445319F)
451   TOOLS_COLORS_STAT(sienna,0.62501F,0.320317F,0.175784F)
452   TOOLS_COLORS_STAT(tan,0.820325F,0.703136F,0.546883F)
453   TOOLS_COLORS_STAT(thistle,0.843763F,0.746105F,0.843763F)
454   TOOLS_COLORS_STAT(turquoise,0.250004F,0.875013F,0.812512F)
455   TOOLS_COLORS_STAT(darkturquoise,0,0.8047F,0.816419F)
456   TOOLS_COLORS_STAT(mediumturquoise,0.281254F,0.816419F,0.796887F)
457   TOOLS_COLORS_STAT(violet,0.929702F,0.50782F,0.929702F)
458 
459   //60-64
460   TOOLS_COLORS_STAT(blueviolet,0.539071F,0.167971F,0.882826F)
461   TOOLS_COLORS_STAT(wheat,0.957046F,0.867201F,0.699229F)
462   //  TOOLS_COLORS_STAT(white,1,1,1) (already defined)
463   //  TOOLS_COLORS_STAT(yellow,1,1,0) (already defined)
464   TOOLS_COLORS_STAT(greenyellow,0.675792F,0.996109F,0.18359F)
465 
466 #undef TOOLS_COLORS_STAT
467 }
468 
469 void G4VisManager::RegisterMessengers () {
470   
471   // Instantiate individual messengers/commands (often - but not
472   // always - one command per messenger).
473   
474   G4UIcommand* directory;
475   
476   directory = new G4UIdirectory ("/vis/geometry/");
477   directory -> SetGuidance("Operations on vis attributes of Geant4 geometry.");
478   fDirectoryList.push_back (directory);
479   RegisterMessenger(new G4VisCommandGeometryList);
480   RegisterMessenger(new G4VisCommandGeometryRestore);
481   
482   directory = new G4UIdirectory ("/vis/geometry/set/");
483   directory -> SetGuidance("Set vis attributes of Geant4 geometry.");
484   fDirectoryList.push_back (directory);
485   RegisterMessenger(new G4VisCommandGeometrySetColour);
486   RegisterMessenger(new G4VisCommandGeometrySetDaughtersInvisible);
487   RegisterMessenger(new G4VisCommandGeometrySetLineStyle);
488   RegisterMessenger(new G4VisCommandGeometrySetLineWidth);
489   RegisterMessenger(new G4VisCommandGeometrySetForceAuxEdgeVisible);
490   RegisterMessenger(new G4VisCommandGeometrySetForceCloud);
491   RegisterMessenger(new G4VisCommandGeometrySetForceLineSegmentsPerCircle);
492   RegisterMessenger(new G4VisCommandGeometrySetForceSolid);
493   RegisterMessenger(new G4VisCommandGeometrySetForceWireframe);
494   RegisterMessenger(new G4VisCommandGeometrySetVisibility);
495   
496 #ifdef G4MULTITHREADED
497   directory = new G4UIdirectory ("/vis/multithreading/");
498   directory -> SetGuidance("Commands unique to multithreading mode.");
499   fDirectoryList.push_back (directory);
500   RegisterMessenger(new G4VisCommandMultithreadingActionOnEventQueueFull);
501   RegisterMessenger(new G4VisCommandMultithreadingMaxEventQueueSize);
502 #endif
503 
504   directory = new G4UIdirectory ("/vis/set/");
505   directory -> SetGuidance
506     ("Set quantities for use in future commands where appropriate.");
507   fDirectoryList.push_back (directory);
508   RegisterMessenger(new G4VisCommandSetArrow3DLineSegmentsPerCircle);
509   RegisterMessenger(new G4VisCommandSetColour);
510   RegisterMessenger(new G4VisCommandSetExtentForField);
511   RegisterMessenger(new G4VisCommandSetLineWidth);
512   RegisterMessenger(new G4VisCommandSetTextColour);
513   RegisterMessenger(new G4VisCommandSetTextLayout);
514   RegisterMessenger(new G4VisCommandSetTextSize);
515   RegisterMessenger(new G4VisCommandSetTouchable);
516   RegisterMessenger(new G4VisCommandSetVolumeForField);
517 
518   directory = new G4UIdirectory ("/vis/scene/");
519   directory -> SetGuidance ("Operations on Geant4 scenes.");
520   fDirectoryList.push_back (directory);
521   RegisterMessenger(new G4VisCommandSceneActivateModel);
522   RegisterMessenger(new G4VisCommandSceneCreate);
523   RegisterMessenger(new G4VisCommandSceneEndOfEventAction);
524   RegisterMessenger(new G4VisCommandSceneEndOfRunAction);
525   RegisterMessenger(new G4VisCommandSceneList);
526   RegisterMessenger(new G4VisCommandSceneNotifyHandlers);
527   RegisterMessenger(new G4VisCommandSceneRemoveModel);
528   RegisterMessenger(new G4VisCommandSceneSelect);
529   RegisterMessenger(new G4VisCommandSceneShowExtents);
530 
531   directory = new G4UIdirectory ("/vis/scene/add/");
532   directory -> SetGuidance ("Add model to current scene.");
533   fDirectoryList.push_back (directory);
534   RegisterMessenger(new G4VisCommandSceneAddArrow);
535   RegisterMessenger(new G4VisCommandSceneAddArrow2D);
536   RegisterMessenger(new G4VisCommandSceneAddAxes);
537   RegisterMessenger(new G4VisCommandSceneAddDate);
538   RegisterMessenger(new G4VisCommandSceneAddDigis);
539   RegisterMessenger(new G4VisCommandSceneAddEventID);
540   RegisterMessenger(new G4VisCommandSceneAddExtent);
541   RegisterMessenger(new G4VisCommandSceneAddElectricField);
542   RegisterMessenger(new G4VisCommandSceneAddFrame);
543   RegisterMessenger(new G4VisCommandSceneAddGPS);
544   RegisterMessenger(new G4VisCommandSceneAddHits);
545   RegisterMessenger(new G4VisCommandSceneAddLine);
546   RegisterMessenger(new G4VisCommandSceneAddLine2D);
547   RegisterMessenger(new G4VisCommandSceneAddLocalAxes);
548   RegisterMessenger(new G4VisCommandSceneAddLogicalVolume);
549   RegisterMessenger(new G4VisCommandSceneAddLogo);
550   RegisterMessenger(new G4VisCommandSceneAddLogo2D);
551   RegisterMessenger(new G4VisCommandSceneAddMagneticField);
552   RegisterMessenger(new G4VisCommandSceneAddPlotter);
553   RegisterMessenger(new G4VisCommandSceneAddPSHits);
554   RegisterMessenger(new G4VisCommandSceneAddScale);
555   RegisterMessenger(new G4VisCommandSceneAddText);
556   RegisterMessenger(new G4VisCommandSceneAddText2D);
557   RegisterMessenger(new G4VisCommandSceneAddTrajectories);
558   RegisterMessenger(new G4VisCommandSceneAddUserAction);
559   RegisterMessenger(new G4VisCommandSceneAddVolume);
560   
561   RegisterMessenger(new G4VisCommandPlotterCreate);
562   RegisterMessenger(new G4VisCommandPlotterSetLayout);
563   RegisterMessenger(new G4VisCommandPlotterAddStyle);
564   RegisterMessenger(new G4VisCommandPlotterAddRegionStyle);
565   RegisterMessenger(new G4VisCommandPlotterAddRegionParameter);
566   RegisterMessenger(new G4VisCommandPlotterClear);
567   RegisterMessenger(new G4VisCommandPlotterClearRegion);
568   RegisterMessenger(new G4VisCommandPlotterList);
569   RegisterMessenger(new G4VisCommandPlotterAddRegionH1);
570   RegisterMessenger(new G4VisCommandPlotterAddRegionH2);
571   
572   directory = new G4UIdirectory ("/vis/sceneHandler/");
573   directory -> SetGuidance ("Operations on Geant4 scene handlers.");
574   fDirectoryList.push_back (directory);
575   RegisterMessenger(new G4VisCommandSceneHandlerAttach);
576   RegisterMessenger(new G4VisCommandSceneHandlerCreate);
577   RegisterMessenger(new G4VisCommandSceneHandlerList);
578   RegisterMessenger(new G4VisCommandSceneHandlerSelect);
579   
580   directory = new G4UIdirectory ("/vis/touchable/");
581   directory -> SetGuidance ("Operations on touchables.");
582   fDirectoryList.push_back (directory);
583   RegisterMessenger(new G4VisCommandsTouchable);
584   
585   directory = new G4UIdirectory ("/vis/touchable/set/");
586   directory -> SetGuidance ("Set vis attributes of current touchable.");
587   fDirectoryList.push_back (directory);
588   RegisterMessenger(new G4VisCommandsTouchableSet);
589 
590   directory = new G4UIdirectory ("/vis/viewer/");
591   directory -> SetGuidance ("Operations on Geant4 viewers.");
592   fDirectoryList.push_back (directory);
593   RegisterMessenger(new G4VisCommandViewerAddCutawayPlane);
594   RegisterMessenger(new G4VisCommandViewerCentreOn);
595   RegisterMessenger(new G4VisCommandViewerChangeCutawayPlane);
596   RegisterMessenger(new G4VisCommandViewerClear);
597   RegisterMessenger(new G4VisCommandViewerClearCutawayPlanes);
598   RegisterMessenger(new G4VisCommandViewerClearTransients);
599   RegisterMessenger(new G4VisCommandViewerClearVisAttributesModifiers);
600   RegisterMessenger(new G4VisCommandViewerClone);
601   RegisterMessenger(new G4VisCommandViewerColourByDensity);
602   RegisterMessenger(new G4VisCommandViewerCopyViewFrom);
603   RegisterMessenger(new G4VisCommandViewerCreate);
604   RegisterMessenger(new G4VisCommandViewerDolly);
605   RegisterMessenger(new G4VisCommandViewerFlush);
606   RegisterMessenger(new G4VisCommandViewerInterpolate);
607   RegisterMessenger(new G4VisCommandViewerList);
608   RegisterMessenger(new G4VisCommandViewerPan);
609   RegisterMessenger(new G4VisCommandViewerRebuild);
610   RegisterMessenger(new G4VisCommandViewerRefresh);
611   RegisterMessenger(new G4VisCommandViewerReset);
612   RegisterMessenger(new G4VisCommandViewerResetCameraParameters);
613   RegisterMessenger(new G4VisCommandViewerSave);
614   RegisterMessenger(new G4VisCommandViewerScale);
615   RegisterMessenger(new G4VisCommandViewerSelect);
616   RegisterMessenger(new G4VisCommandViewerUpdate);
617   RegisterMessenger(new G4VisCommandViewerZoom);
618   
619   directory = new G4UIdirectory ("/vis/viewer/default/");
620   directory -> SetGuidance("Set default values for future viewers.");
621   fDirectoryList.push_back (directory);
622   RegisterMessenger(new G4VisCommandViewerDefaultHiddenEdge);
623   RegisterMessenger(new G4VisCommandViewerDefaultStyle);
624   
625   directory = new G4UIdirectory ("/vis/viewer/set/");
626   directory -> SetGuidance ("Set view parameters of current viewer.");
627   fDirectoryList.push_back (directory);
628   RegisterMessenger(new G4VisCommandsViewerSet);
629   
630   // *Basic* top level commands were instantiated in the constructor
631   // so that they can be used immediately after instantiation of the
632   // vis manager.  Other top level commands, including "compound commands"
633   // (i.e., commands that invoke other commands) are instantiated here.
634 
635   RegisterMessenger(new G4VisCommandAbortReviewKeptEvents);
636   RegisterMessenger(new G4VisCommandAbortReviewPlots);
637   RegisterMessenger(new G4VisCommandDrawOnlyToBeKeptEvents);
638   RegisterMessenger(new G4VisCommandDrawTree);
639   RegisterMessenger(new G4VisCommandDrawView);
640   RegisterMessenger(new G4VisCommandDrawLogicalVolume);
641   RegisterMessenger(new G4VisCommandDrawVolume);
642   RegisterMessenger(new G4VisCommandEnable);
643   RegisterMessenger(new G4VisCommandList);
644   RegisterMessenger(new G4VisCommandOpen);
645   RegisterMessenger(new G4VisCommandPlot);
646   RegisterMessenger(new G4VisCommandReviewKeptEvents);
647   RegisterMessenger(new G4VisCommandReviewPlots);
648   RegisterMessenger(new G4VisCommandSpecify);
649 
650   // List manager commands
651   RegisterMessenger(new G4VisCommandListManagerList< G4VisModelManager<G4VTrajectoryModel> >
652         (fpTrajDrawModelMgr, fpTrajDrawModelMgr->Placement()));
653   RegisterMessenger(new G4VisCommandListManagerSelect< G4VisModelManager<G4VTrajectoryModel> >
654         (fpTrajDrawModelMgr, fpTrajDrawModelMgr->Placement()));
655   
656   // Trajectory filter manager commands
657   RegisterMessenger(new G4VisCommandListManagerList< G4VisFilterManager<G4VTrajectory> >
658                     (fpTrajFilterMgr, fpTrajFilterMgr->Placement()));
659   RegisterMessenger(new G4VisCommandManagerMode< G4VisFilterManager<G4VTrajectory> >
660                     (fpTrajFilterMgr, fpTrajFilterMgr->Placement()));
661   
662   // Hit filter manager commands
663   RegisterMessenger(new G4VisCommandListManagerList< G4VisFilterManager<G4VHit> >
664                     (fpHitFilterMgr, fpHitFilterMgr->Placement()));
665   RegisterMessenger(new G4VisCommandManagerMode< G4VisFilterManager<G4VHit> >
666                     (fpHitFilterMgr, fpHitFilterMgr->Placement()));
667   
668   // Digi filter manager commands
669   RegisterMessenger(new G4VisCommandListManagerList< G4VisFilterManager<G4VDigi> >
670                     (fpDigiFilterMgr, fpDigiFilterMgr->Placement()));
671   RegisterMessenger(new G4VisCommandManagerMode< G4VisFilterManager<G4VDigi> >
672                     (fpDigiFilterMgr, fpDigiFilterMgr->Placement()));
673 }
674 
675 #include <tools/histo/h1d>
676 #include <tools/histo/h2d>
677 
678 namespace {
679   struct PlotResults {
680     std::size_t fNumberOfPlots = 0;
681     std::size_t fTotalEntries = 0;
682   };
683   template <typename HT>  // tools::histo::h1d, etc
684   PlotResults ResultsOfHnPlots(const G4String& plotType) {  // h1, etc.
685     PlotResults plotResults;
686     auto ui = G4UImanager::GetUIpointer();
687     auto keepControlVerbose = ui->GetVerboseLevel();
688     ui->SetVerboseLevel(0);
689     auto status = ui->ApplyCommand("/analysis/" + plotType + "/getVector");
690     ui->SetVerboseLevel(keepControlVerbose);
691     if(status==G4UIcommandStatus::fCommandSucceeded) {
692       G4String hexString = ui->GetCurrentValues(G4String("/analysis/" + plotType + "/getVector"));
693       if(hexString.size()) {
694         void* ptr; std::istringstream is(hexString); is >> ptr;
695         auto vectorOfPlots = (const std::vector<HT*>*)ptr;
696         for (std::size_t i = 0; i < vectorOfPlots->size(); ++i) {
697           auto plot = (*vectorOfPlots)[i];
698           if (plot == nullptr) continue;  // Ignore deleted plots
699           ++plotResults.fNumberOfPlots;
700           plotResults.fTotalEntries += plot->entries();
701         }
702       }
703     }
704     return plotResults;
705   }
706   void PrintListOfPlots() {
707     std::size_t numberOfPlots = 0;
708     std::size_t numberOfEntries = 0;
709     PlotResults h1results = ResultsOfHnPlots<tools::histo::h1d>("h1");
710     numberOfPlots += h1results.fNumberOfPlots;
711     numberOfEntries += h1results.fTotalEntries;
712     PlotResults h2results = ResultsOfHnPlots<tools::histo::h2d>("h2");
713     numberOfPlots += h2results.fNumberOfPlots;
714     numberOfEntries += h2results.fTotalEntries;
715     if (numberOfPlots > 0) {
716       G4warn << "There are histograms that can be viewed with visualization:";
717       if (h1results.fNumberOfPlots > 0) {
718         G4warn << "\n  " << h1results.fNumberOfPlots << " h1 histograms(s)";
719       }
720       if (h2results.fNumberOfPlots > 0) {
721         G4warn << "\n  " << h2results.fNumberOfPlots << " h2 histograms(s)";
722       }
723       G4warn
724       << "\n  List them with \"/analysis/list\"."
725       << "\n  View them immediately with \"/vis/plot\" or \"/vis/reviewPlots\"."
726       << G4endl;
727       if (numberOfEntries == 0) {
728         G4warn <<
729         "  But...there are no entries. To make your histograms available for"
730         "\n  plotting in this UI session, use CloseFile(false) in your"
731         "\n  EndOfRunAction and Reset() in your BeginOfRunAction."
732         << G4endl;
733       }
734     }
735   }
736 }
737 
738 void G4VisManager::Enable() {
739   if (IsValidView ()) {
740     SetConcreteInstance(this);
741     if (fVerbosity >= confirmations) {
742       G4cout << "G4VisManager::Enable: visualization enabled." << G4endl;
743     }
744     if (fVerbosity >= warnings) {
745       std::size_t nKeptEvents = 0;
746       const G4Run* run = G4RunManager::GetRunManager()->GetCurrentRun();
747       if (run) nKeptEvents = run->GetEventVector()->size();
748       G4String isare("are"),plural("s");
749       if (nKeptEvents == 1) {isare = "is"; plural = "";}
750       G4cout <<
751       "There " << isare << ' ' << nKeptEvents << " kept event" << plural << '.'
752       << G4endl;
753       if (nKeptEvents > 0) {
754         G4cout <<
755   "  \"/vis/reviewKeptEvents\" to review one by one."
756   "\n  To see accumulated, \"/vis/enable\", then \"/vis/viewer/flush\" or \"/vis/viewer/rebuild\"."
757         << G4endl;
758       }
759       PrintListOfPlots();
760     }
761   }
762   else {
763     if (fVerbosity >= warnings) {
764       G4warn <<
765   "G4VisManager::Enable: WARNING: visualization remains disabled for"
766   "\n  above reasons.  Rectifying with valid vis commands will"
767   "\n  automatically enable."
768        << G4endl;
769     }
770   }
771 }
772 
773 void G4VisManager::Disable() {
774   SetConcreteInstance(0);
775   if (fVerbosity >= confirmations) {
776     G4cout <<
777     "G4VisManager::Disable: visualization disabled."
778     "\n  The pointer returned by GetConcreteInstance will be zero."
779     "\n  Note that it will become enabled after some valid vis commands."
780      << G4endl;
781   }
782   if (fVerbosity >= warnings) {
783     G4int currentTrajectoryType =
784     G4RunManagerKernel::GetRunManagerKernel()->GetTrackingManager()->GetStoreTrajectory();
785     if (currentTrajectoryType > 0) {
786     G4warn <<
787       "You may wish to disable trajectory production too:"
788       "\n  \"/tracking/storeTrajectory 0\""
789       "\nbut don't forget to re-enable with"
790       "\n  \"/vis/enable\""
791       "\n  \"/tracking/storeTrajectory " << currentTrajectoryType
792       << "\"\n  and maybe \"/vis/viewer/rebuild\""
793       << G4endl;
794     }
795   }
796 }
797 
798 const G4GraphicsSystemList& G4VisManager::GetAvailableGraphicsSystems () {
799   std::size_t nSystems = fAvailableGraphicsSystems.size ();
800   if (nSystems == 0) {
801     if (fVerbosity >= warnings) {
802       G4warn << "G4VisManager::GetAvailableGraphicsSystems: WARNING: no"
803   "\n graphics system available!"
804   "\n  1) Did you have environment variables G4VIS_BUILD_xxxx_DRIVER set"
805   "\n     when you compiled/built the visualization code?"
806   "\n  2) Did you instantiate your own Visualization Manager and forget"
807   "\n     to implement RegisterGraphicsSystems correctly?"
808   "\n  3) You can register your own graphics system, e.g.,"
809   "\n     visManager->RegisterGraphicsSystem(new MyGraphicsSystem);)"
810   "\n     after instantiating your vis manager and before"
811   "\n     visManager->Initialize()."
812        << G4endl;
813     }
814   }
815   return fAvailableGraphicsSystems;
816 }
817 
818 G4bool G4VisManager::RegisterGraphicsSystem (G4VGraphicsSystem* pSystem) {
819   G4bool happy = true;
820   if (pSystem) {
821     fAvailableGraphicsSystems.push_back (pSystem);
822     if (fVerbosity >= confirmations) {
823       G4cout << "G4VisManager::RegisterGraphicsSystem: "
824        << pSystem -> GetName ();
825       if (pSystem -> GetNickname () != "") {
826   G4cout << " (" << pSystem -> GetNickname () << ")";
827       }
828       G4cout << " registered." << G4endl;
829     }
830   }
831   else {
832     if (fVerbosity >= errors) {
833       G4warn << "G4VisManager::RegisterGraphicsSystem: null pointer!"
834        << G4endl;
835     }
836     happy=false;
837   }
838   return happy;
839 }
840 
841 const G4VTrajectoryModel*
842 G4VisManager::CurrentTrajDrawModel() const
843 {
844   assert (0 != fpTrajDrawModelMgr);
845 
846   const G4VTrajectoryModel* model = fpTrajDrawModelMgr->Current();
847 
848   if (0 == model) {
849     // No model was registered with the trajectory model manager.
850     // Use G4TrajectoryDrawByCharge as a fallback.
851     fpTrajDrawModelMgr->Register(new G4TrajectoryDrawByCharge("DefaultModel"));
852     if (fVerbosity >= warnings) {
853       G4warn<<"G4VisManager: Using G4TrajectoryDrawByCharge as fallback trajectory model."<<G4endl;
854       G4warn<<"See commands in /vis/modeling/trajectories/ for other options."<<G4endl;
855     }
856   }
857 
858   model = fpTrajDrawModelMgr->Current();
859   assert (0 != model); // Should definitely exist now
860 
861   return model;
862 }
863 
864 void G4VisManager::RegisterModel(G4VTrajectoryModel* model)
865 {
866   fpTrajDrawModelMgr->Register(model);
867 }
868 
869 void
870 G4VisManager::RegisterModelFactory(G4TrajDrawModelFactory* factory) 
871 {
872   fpTrajDrawModelMgr->Register(factory);
873 }
874 
875 void G4VisManager::RegisterModel(G4VFilter<G4VTrajectory>* model)
876 {
877   fpTrajFilterMgr->Register(model);
878 }
879 
880 void
881 G4VisManager::RegisterModelFactory(G4TrajFilterFactory* factory)
882 {
883   fpTrajFilterMgr->Register(factory);
884 }
885 
886 void G4VisManager::RegisterModel(G4VFilter<G4VHit>* model)
887 {
888   fpHitFilterMgr->Register(model);
889 }
890 
891 void
892 G4VisManager::RegisterModelFactory(G4HitFilterFactory* factory)
893 {
894   fpHitFilterMgr->Register(factory);
895 }
896 
897 void G4VisManager::RegisterModel(G4VFilter<G4VDigi>* model)
898 {
899   fpDigiFilterMgr->Register(model);
900 }
901 
902 void
903 G4VisManager::RegisterModelFactory(G4DigiFilterFactory* factory)
904 {
905   fpDigiFilterMgr->Register(factory);
906 }
907 
908 void G4VisManager::SelectTrajectoryModel(const G4String& model) 
909 {
910    fpTrajDrawModelMgr->SetCurrent(model);
911 }
912 
913 void G4VisManager::BeginDraw (const G4Transform3D& objectTransform)
914 {
915 #ifdef G4MULTITHREADED
916   if (G4Threading::IsWorkerThread()) return;
917 #endif
918   fDrawGroupNestingDepth++;
919   if (fDrawGroupNestingDepth > 1) {
920     G4Exception
921       ("G4VisManager::BeginDraw",
922        "visman0008", JustWarning,
923        "Nesting detected. It is illegal to nest Begin/EndDraw."
924        "\n Ignored");
925     return;
926   }
927   if (IsValidView ()) {
928     ClearTransientStoreIfMarked();
929     fpSceneHandler -> BeginPrimitives (objectTransform);
930     fIsDrawGroup = true;
931   }
932 }
933 
934 void G4VisManager::EndDraw ()
935 {
936 #ifdef G4MULTITHREADED
937   if (G4Threading::IsWorkerThread()) return;
938 #endif
939   fDrawGroupNestingDepth--;
940   if (fDrawGroupNestingDepth != 0) {
941     if (fDrawGroupNestingDepth < 0) fDrawGroupNestingDepth = 0;
942     return;
943   }
944   if (IsValidView ()) {
945     fpSceneHandler -> EndPrimitives ();
946   }
947   fIsDrawGroup = false;
948 }
949 
950 void G4VisManager::BeginDraw2D (const G4Transform3D& objectTransform)
951 {
952 #ifdef G4MULTITHREADED
953   if (G4Threading::IsWorkerThread()) return;
954 #endif
955   fDrawGroupNestingDepth++;
956   if (fDrawGroupNestingDepth > 1) {
957     G4Exception
958       ("G4VisManager::BeginDraw2D",
959        "visman0009", JustWarning,
960        "Nesting detected. It is illegal to nest Begin/EndDraw2D."
961        "\n Ignored");
962     return;
963   }
964   if (IsValidView ()) {
965     ClearTransientStoreIfMarked();
966     fpSceneHandler -> BeginPrimitives2D (objectTransform);
967     fIsDrawGroup = true;
968   }
969 }
970 
971 void G4VisManager::EndDraw2D ()
972 {
973 #ifdef G4MULTITHREADED
974   if (G4Threading::IsWorkerThread()) return;
975 #endif
976   fDrawGroupNestingDepth--;
977   if (fDrawGroupNestingDepth != 0) {
978     if (fDrawGroupNestingDepth < 0) fDrawGroupNestingDepth = 0;
979     return;
980   }
981   if (IsValidView ()) {
982     fpSceneHandler -> EndPrimitives2D ();
983   }
984   fIsDrawGroup = false;
985 }
986 
987 template <class T> void G4VisManager::DrawT
988 (const T& graphics_primitive, const G4Transform3D& objectTransform) {
989 #ifdef G4MULTITHREADED
990   if (G4Threading::IsWorkerThread()) return;
991 #endif
992   if (fIsDrawGroup) {
993     if (objectTransform != fpSceneHandler->GetObjectTransformation()) {
994       G4Exception
995   ("G4VSceneHandler::DrawT",
996    "visman0010", FatalException,
997    "Different transform detected in Begin/EndDraw group.");
998     }
999     fpSceneHandler -> AddPrimitive (graphics_primitive);
1000   } else {
1001     if (IsValidView ()) {
1002       ClearTransientStoreIfMarked();
1003       fpSceneHandler -> BeginPrimitives (objectTransform);
1004       fpSceneHandler -> AddPrimitive (graphics_primitive);
1005       fpSceneHandler -> EndPrimitives ();
1006     }
1007   }
1008 }
1009 
1010 template <class T> void G4VisManager::DrawT2D
1011 (const T& graphics_primitive, const G4Transform3D& objectTransform) {
1012 #ifdef G4MULTITHREADED
1013   if (G4Threading::IsWorkerThread()) return;
1014 #endif
1015   if (fIsDrawGroup) {
1016     if (objectTransform != fpSceneHandler->GetObjectTransformation()) {
1017       G4Exception
1018   ("G4VSceneHandler::DrawT",
1019    "visman0011", FatalException,
1020    "Different transform detected in Begin/EndDraw2D group.");
1021     }
1022     fpSceneHandler -> AddPrimitive (graphics_primitive);
1023   } else {
1024     if (IsValidView ()) {
1025       ClearTransientStoreIfMarked();
1026       fpSceneHandler -> BeginPrimitives2D (objectTransform);
1027       fpSceneHandler -> AddPrimitive (graphics_primitive);
1028       fpSceneHandler -> EndPrimitives2D ();
1029     }
1030   }
1031 }
1032 
1033 void G4VisManager::Draw (const G4Circle& circle,
1034        const G4Transform3D& objectTransform)
1035 {
1036   DrawT (circle, objectTransform);
1037 }
1038 
1039 void G4VisManager::Draw (const G4Polyhedron& polyhedron,
1040        const G4Transform3D& objectTransform)
1041 {
1042   DrawT (polyhedron, objectTransform);
1043 }
1044 
1045 void G4VisManager::Draw (const G4Polyline& line,
1046        const G4Transform3D& objectTransform)
1047 {
1048   DrawT (line, objectTransform);
1049 }
1050 
1051 void G4VisManager::Draw (const G4Polymarker& polymarker,
1052        const G4Transform3D& objectTransform)
1053 {
1054   DrawT (polymarker, objectTransform);
1055 }
1056 
1057 void G4VisManager::Draw (const G4Square& square,
1058        const G4Transform3D& objectTransform)
1059 {
1060   DrawT (square, objectTransform);
1061 }
1062 
1063 void G4VisManager::Draw (const G4Text& text,
1064        const G4Transform3D& objectTransform)
1065 {
1066   DrawT (text, objectTransform);
1067 }
1068 
1069 void G4VisManager::Draw2D (const G4Circle& circle,
1070          const G4Transform3D& objectTransform)
1071 {
1072   DrawT2D (circle, objectTransform);
1073 }
1074 
1075 void G4VisManager::Draw2D (const G4Polyhedron& polyhedron,
1076          const G4Transform3D& objectTransform)
1077 {
1078   DrawT2D (polyhedron, objectTransform);
1079 }
1080 
1081 void G4VisManager::Draw2D (const G4Polyline& line,
1082          const G4Transform3D& objectTransform)
1083 {
1084   DrawT2D (line, objectTransform);
1085 }
1086 
1087 void G4VisManager::Draw2D (const G4Polymarker& polymarker,
1088          const G4Transform3D& objectTransform)
1089 {
1090   DrawT2D (polymarker, objectTransform);
1091 }
1092 
1093 void G4VisManager::Draw2D (const G4Square& square,
1094          const G4Transform3D& objectTransform)
1095 {
1096   DrawT2D (square, objectTransform);
1097 }
1098 
1099 void G4VisManager::Draw2D (const G4Text& text,
1100          const G4Transform3D& objectTransform)
1101 {
1102   DrawT2D (text, objectTransform);
1103 }
1104 
1105 void G4VisManager::Draw (const G4VHit& hit) {
1106 #ifdef G4MULTITHREADED
1107   if (G4Threading::IsWorkerThread()) return;
1108 #endif
1109   if (fIsDrawGroup) {
1110     fpSceneHandler -> AddCompound (hit);
1111   } else {
1112     if (IsValidView ()) {
1113       ClearTransientStoreIfMarked();
1114       fpSceneHandler -> AddCompound (hit);
1115     }
1116   }
1117 }
1118 
1119 void G4VisManager::Draw (const G4VDigi& digi) {
1120 #ifdef G4MULTITHREADED
1121   if (G4Threading::IsWorkerThread()) return;
1122 #endif
1123   if (fIsDrawGroup) {
1124     fpSceneHandler -> AddCompound (digi);
1125   } else {
1126     if (IsValidView ()) {
1127       ClearTransientStoreIfMarked();
1128       fpSceneHandler -> AddCompound (digi);
1129     }
1130   }
1131 }
1132 
1133 void G4VisManager::Draw (const G4VTrajectory& traj) {
1134 #ifdef G4MULTITHREADED
1135   if (G4Threading::IsWorkerThread()) return;
1136 #endif
1137   // A trajectory needs a trajectories model to provide G4Atts, etc.
1138   static G4TrajectoriesModel trajectoriesModel;
1139   trajectoriesModel.SetCurrentTrajectory(&traj);
1140   G4RunManager* runManager = G4RunManagerFactory::GetMasterRunManager();
1141   const G4Run* currentRun  = runManager->GetCurrentRun();
1142   if (currentRun) {
1143     trajectoriesModel.SetRunID(currentRun->GetRunID());
1144   }
1145   const G4Event* currentEvent =
1146   G4EventManager::GetEventManager()->GetConstCurrentEvent();
1147   if (currentEvent) {
1148     trajectoriesModel.SetEventID(currentEvent->GetEventID());
1149   }
1150   if (fIsDrawGroup) {
1151     fpSceneHandler -> SetModel (&trajectoriesModel);
1152     fpSceneHandler -> AddCompound (traj);
1153     fpSceneHandler -> SetModel (0);
1154   } else {
1155     if (IsValidView ()) {
1156       ClearTransientStoreIfMarked();
1157       fpSceneHandler -> SetModel (&trajectoriesModel);
1158       fpSceneHandler -> AddCompound (traj);
1159       fpSceneHandler -> SetModel (0);
1160     }
1161   }
1162 }
1163 
1164 void G4VisManager::Draw (const G4LogicalVolume& logicalVol,
1165        const G4VisAttributes& attribs,
1166        const G4Transform3D& objectTransform) {
1167 #ifdef G4MULTITHREADED
1168   if (G4Threading::IsWorkerThread()) return;
1169 #endif
1170   // Find corresponding solid.
1171   G4VSolid* pSol = logicalVol.GetSolid ();
1172   Draw (*pSol, attribs, objectTransform);
1173 }
1174 
1175 void G4VisManager::Draw (const G4VSolid& solid,
1176        const G4VisAttributes& attribs,
1177        const G4Transform3D& objectTransform) {
1178 #ifdef G4MULTITHREADED
1179   if (G4Threading::IsWorkerThread()) return;
1180 #endif
1181   if (fIsDrawGroup) {
1182     fpSceneHandler -> PreAddSolid (objectTransform, attribs);
1183     solid.DescribeYourselfTo (*fpSceneHandler);
1184     fpSceneHandler -> PostAddSolid ();
1185   } else {
1186     if (IsValidView ()) {
1187       ClearTransientStoreIfMarked();
1188       fpSceneHandler -> PreAddSolid (objectTransform, attribs);
1189       solid.DescribeYourselfTo (*fpSceneHandler);
1190       fpSceneHandler -> PostAddSolid ();
1191     }
1192   }
1193 }
1194 
1195 void G4VisManager::Draw (const G4VPhysicalVolume& physicalVol,
1196        const G4VisAttributes& attribs,
1197        const G4Transform3D& objectTransform) {
1198 #ifdef G4MULTITHREADED
1199   if (G4Threading::IsWorkerThread()) return;
1200 #endif
1201   // Note: It is tempting to use a temporary model here, as for
1202   // trajectories, in order to get at the G4Atts of the physical
1203   // volume.  I tried it (JA).  But it's not easy to pass the
1204   // vis attributes.  Also other aspects of the model seem not to
1205   // be properly set up.  So, the idea has been abandoned for the time
1206   // being.  The model pointer will be null.  So when picking there
1207   // will be no G4Atts from this physical volume.
1208   //
1209   // If this is called from DrawHit, for example, the user may G4Atts to the
1210   // hit and these will be available with "/vis/scene/add/hits".
1211   //
1212   // Find corresponding logical volume and solid.
1213   G4LogicalVolume* pLV  = physicalVol.GetLogicalVolume ();
1214   G4VSolid*        pSol = pLV -> GetSolid ();
1215   Draw (*pSol, attribs, objectTransform);
1216 }
1217 
1218 void G4VisManager::DrawGeometry
1219 (G4VPhysicalVolume* v, const G4Transform3D& t)
1220 // Draws a geometry tree starting at the specified physical volume.
1221 {
1222   auto modelingParameters = fpSceneHandler->CreateModelingParameters();
1223   auto depth = G4PhysicalVolumeModel::UNLIMITED;
1224   const G4bool useFullExtent = true;
1225   G4PhysicalVolumeModel aPVModel(v,depth,t,modelingParameters,useFullExtent);
1226   aPVModel.DescribeYourselfTo(*fpSceneHandler);
1227   delete modelingParameters;
1228 }
1229 
1230 void G4VisManager::CreateSceneHandler (const G4String& name) {
1231   if (!fInitialised) Initialise ();
1232   if (fpGraphicsSystem) {
1233     G4VSceneHandler* pSceneHandler =
1234       fpGraphicsSystem -> CreateSceneHandler (name);
1235     if (pSceneHandler) {
1236       fAvailableSceneHandlers.push_back (pSceneHandler);
1237       fpSceneHandler = pSceneHandler;                         // Make current.
1238     }
1239     else {
1240       if (fVerbosity >= errors) {
1241   G4warn << "ERROR in G4VisManager::CreateSceneHandler during "
1242          << fpGraphicsSystem -> GetName ()
1243          << " scene handler creation.\n  No action taken."
1244          << G4endl;
1245       }
1246     }
1247   }
1248   else PrintInvalidPointers ();
1249 }
1250 
1251 void G4VisManager::CreateViewer
1252 (const G4String& name, const G4String& XGeometry)
1253 {
1254 
1255   if (!fInitialised) Initialise ();
1256 
1257   if (!fpSceneHandler) {
1258     PrintInvalidPointers ();
1259     return;
1260   }
1261 
1262   G4VViewer* p = fpGraphicsSystem -> CreateViewer (*fpSceneHandler, name);
1263 
1264   if (!p) {
1265     if (fVerbosity >= errors) {
1266       G4warn << "ERROR in G4VisManager::CreateViewer: null pointer during "
1267        << fpGraphicsSystem -> GetName ()
1268        << " viewer creation.\n  No action taken."
1269        << G4endl;
1270     }
1271     return;
1272   }
1273 
1274   if (p -> GetViewId() < 0) {
1275     if (fVerbosity >= errors) {
1276       G4warn << "ERROR in G4VisManager::CreateViewer during "
1277        << fpGraphicsSystem -> GetName ()
1278        << " viewer instantiation.\n  No action taken."
1279        << G4endl;
1280     }
1281     return;
1282   }
1283 
1284   // Viewer is created, now we can set geometry parameters
1285   // Before 12/2008, it was done in G4VViewer.cc but it did not have to be there!
1286     
1287   G4ViewParameters initialvp = p -> GetViewParameters();
1288   initialvp.SetXGeometryString(XGeometry); //parse string and store parameters
1289   p -> SetViewParameters(initialvp);
1290   p -> Initialise ();  // (Viewer itself may change view parameters further.)
1291   if (p -> GetViewId() < 0) {
1292     if (fVerbosity >= errors) {
1293       G4warn << "ERROR in G4VisManager::CreateViewer during "
1294        << fpGraphicsSystem -> GetName ()
1295        << " viewer initialisation.\n  No action taken."
1296        << G4endl;
1297     }
1298     return;
1299   }
1300 
1301   fpViewer = p;                             // Make current.
1302   fpSceneHandler -> AddViewerToList (fpViewer);
1303   fpSceneHandler -> SetCurrentViewer (fpViewer);
1304   if (fVerbosity >= confirmations) {
1305     G4cout << "G4VisManager::CreateViewer: new viewer created."
1306      << G4endl;
1307   }
1308 
1309   const G4ViewParameters& vp = fpViewer->GetViewParameters();
1310   if (fVerbosity >= parameters) {
1311     G4cout << " view parameters are:\n  " << vp << G4endl;
1312   }
1313 
1314   if (vp.IsCulling () && vp.IsCullingInvisible ()) {
1315     static G4bool warned = false;
1316     if (fVerbosity >= confirmations) {
1317       if (!warned) {
1318   G4cout <<
1319   "NOTE: objects with visibility flag set to \"false\""
1320   " will not be drawn!"
1321   "\n  \"/vis/viewer/set/culling global false\" to Draw such objects."
1322   "\n  Also see other \"/vis/viewer/set\" commands."
1323          << G4endl;
1324   warned = true;
1325       }
1326     }
1327   }
1328   if (vp.IsCullingCovered ()) {
1329     static G4bool warned = false;
1330     if (fVerbosity >= warnings) {
1331       if (!warned) {
1332   G4warn <<
1333   "WARNING: covered objects in solid mode will not be rendered!"
1334   "\n  \"/vis/viewer/set/culling coveredDaughters false\" to reverse this."
1335   "\n  Also see other \"/vis/viewer/set\" commands."
1336          << G4endl;
1337   warned = true;
1338       }
1339     }
1340   }
1341 }
1342 
1343 void G4VisManager::GeometryHasChanged () {
1344   if (fVerbosity >= confirmations) {
1345     G4cout << "G4VisManager::GeometryHasChanged() called." << G4endl;
1346   }
1347 
1348   // Change the world...
1349   G4VPhysicalVolume* pWorld =
1350     G4TransportationManager::GetTransportationManager ()
1351     -> GetNavigatorForTracking () -> GetWorldVolume ();
1352   if (!pWorld) {
1353     if (fVerbosity >= warnings) {
1354       G4warn << "WARNING: There is no world volume!" << G4endl;
1355     }
1356   }
1357 
1358   // Check scenes.
1359   G4SceneList& sceneList = fSceneList;
1360   std::size_t iScene, nScenes = sceneList.size ();
1361   for (iScene = 0; iScene < nScenes; ++iScene) {
1362     G4Scene* pScene = sceneList [iScene];
1363     std::vector<G4Scene::Model>& modelList = pScene -> SetRunDurationModelList ();
1364     if (modelList.size ()) {
1365       G4bool modelInvalid;
1366       do {  // Remove, if required, one at a time.
1367   modelInvalid = false;
1368   std::vector<G4Scene::Model>::iterator iterModel;
1369   for (iterModel = modelList.begin();
1370        iterModel != modelList.end();
1371        ++iterModel) {
1372     modelInvalid = !(iterModel->fpModel->Validate(fVerbosity>=warnings));
1373     if (modelInvalid) {
1374       // Model invalid - remove and break.
1375       if (fVerbosity >= warnings) {
1376         G4warn << "WARNING: Model \""
1377          << iterModel->fpModel->GetGlobalDescription ()
1378          <<
1379     "\" is no longer valid - being removed\n  from scene \""
1380          << pScene -> GetName () << "\""
1381          << G4endl;
1382       }
1383       modelList.erase (iterModel);
1384       break;
1385     }
1386   }
1387       } while (modelInvalid);
1388 
1389       if (modelList.size () == 0) {
1390   if (fVerbosity >= warnings) {
1391     G4warn << "WARNING: No run-duration models left in this scene \""
1392      << pScene -> GetName ()
1393      << "\"."
1394      << G4endl;
1395   }
1396         if (pWorld) {
1397           if (fVerbosity >= warnings) {
1398             G4warn << "  Adding current world to \""
1399             << pScene -> GetName ()
1400             << "\"."
1401             << G4endl;
1402           }
1403           pScene->AddRunDurationModel(new G4PhysicalVolumeModel(pWorld),fVerbosity>=warnings);
1404           // (The above includes a re-calculation of the extent.)
1405           G4UImanager::GetUIpointer () ->
1406           ApplyCommand (G4String("/vis/scene/notifyHandlers " + pScene->GetName()));
1407         }
1408       }
1409       else {
1410   pScene->CalculateExtent();  // Recalculate extent
1411   G4UImanager::GetUIpointer () ->
1412     ApplyCommand (G4String("/vis/scene/notifyHandlers " + pScene->GetName()));
1413       }
1414     }
1415   }
1416 
1417   // Check the manager's current scene...
1418   if (fpScene && fpScene -> GetRunDurationModelList ().size () == 0) {
1419     if (fVerbosity >= warnings) {
1420       G4warn << "WARNING: The current scene \""
1421        << fpScene -> GetName ()
1422        << "\" has no run duration models."
1423              << "\n  Use \"/vis/scene/add/volume\" or create a new scene."
1424        << G4endl;
1425     }
1426     // Clean up
1427     if (fpSceneHandler) {
1428       fpSceneHandler->ClearTransientStore();
1429       fpSceneHandler->ClearStore();
1430       if (fpViewer) {
1431         fpViewer->NeedKernelVisit();
1432         fpViewer->SetView();
1433         fpViewer->ClearView();
1434         fpViewer->FinishView();
1435       }
1436     }
1437   }
1438 }
1439 
1440 void G4VisManager::NotifyHandlers () {
1441 
1442   if (fVerbosity >= confirmations) {
1443     G4cout << "G4VisManager::NotifyHandler() called." << G4endl;
1444   }
1445 
1446   if (IsValidView()) {
1447 
1448     // Check scenes.
1449     G4SceneList& sceneList = fSceneList;
1450     std::size_t iScene, nScenes = sceneList.size ();
1451     for (iScene = 0; iScene < nScenes; ++iScene) {
1452       G4Scene* pScene = sceneList [iScene];
1453       std::vector<G4Scene::Model>& modelList = pScene -> SetRunDurationModelList ();
1454 
1455       if (modelList.size ()) {
1456         pScene->CalculateExtent();
1457         G4UImanager::GetUIpointer () ->
1458         ApplyCommand (G4String("/vis/scene/notifyHandlers " + pScene->GetName()));
1459       }
1460     }
1461 
1462     // Check the manager's current scene...
1463     if (fpScene && fpScene -> GetRunDurationModelList ().size () == 0) {
1464       if (fVerbosity >= warnings) {
1465         G4warn << "WARNING: The current scene \""
1466         << fpScene -> GetName ()
1467         << "\" has no run duration models."
1468         << "\n  Use \"/vis/scene/add/volume\" or create a new scene."
1469         << G4endl;
1470       }
1471       fpSceneHandler->ClearTransientStore();
1472       fpSceneHandler->ClearStore();
1473       fpViewer->NeedKernelVisit();
1474       fpViewer->SetView();
1475       fpViewer->ClearView();
1476       fpViewer->FinishView();
1477     }
1478   }
1479 }
1480 
1481 G4bool G4VisManager::FilterTrajectory(const G4VTrajectory& trajectory)
1482 {
1483   return fpTrajFilterMgr->Accept(trajectory);
1484 }   
1485 
1486 G4bool G4VisManager::FilterHit(const G4VHit& hit)
1487 {
1488   return fpHitFilterMgr->Accept(hit);
1489 }   
1490 
1491 G4bool G4VisManager::FilterDigi(const G4VDigi& digi)
1492 {
1493   return fpDigiFilterMgr->Accept(digi);
1494 }   
1495 
1496 void G4VisManager::DispatchToModel(const G4VTrajectory& trajectory)
1497 {
1498   G4bool visible(true);
1499 
1500   // See if trajectory passes filter
1501   G4bool passed = FilterTrajectory(trajectory);
1502 
1503   if (!passed) {
1504     // Draw invisible trajectory if trajectory failed filter and
1505     // are filtering in soft mode
1506     if (fpTrajFilterMgr->GetMode() == FilterMode::Soft) visible = false;
1507     else {return;}
1508   }
1509 
1510   // Go on to draw trajectory
1511   assert (0 != fpTrajDrawModelMgr);
1512 
1513   const G4VTrajectoryModel* trajectoryModel = CurrentTrajDrawModel();
1514 
1515   assert (0 != trajectoryModel); // Should exist
1516 
1517   if (IsValidView()) {
1518       trajectoryModel->Draw(trajectory, visible);
1519   }
1520 }
1521 
1522 void G4VisManager::RegisterRunDurationUserVisAction
1523 (const G4String& name,
1524  G4VUserVisAction* pVisAction,
1525  const G4VisExtent& extent) {
1526   fRunDurationUserVisActions.push_back(UserVisAction(name,pVisAction));
1527   if (extent.GetExtentRadius() > 0.) {
1528     fUserVisActionExtents[pVisAction] = extent;
1529   } else {
1530     if (fVerbosity >= warnings) {
1531       G4warn <<
1532   "WARNING: No extent set for user vis action \"" << name << "\"."
1533        << G4endl;
1534     }
1535   }
1536   if (fVerbosity >= confirmations) {
1537     G4cout
1538     << "Run duration user vis action \"" << name << "\" registered"
1539     << G4endl;
1540   }
1541 }
1542 
1543 void G4VisManager::RegisterEndOfEventUserVisAction
1544 (const G4String& name,
1545  G4VUserVisAction* pVisAction,
1546  const G4VisExtent& extent) {
1547   fEndOfEventUserVisActions.push_back(UserVisAction(name,pVisAction));
1548   if (extent.GetExtentRadius() > 0.) {
1549     fUserVisActionExtents[pVisAction] = extent;
1550   } else {
1551     if (fVerbosity >= warnings) {
1552       G4warn <<
1553   "WARNING: No extent set for user vis action \"" << name << "\"."
1554        << G4endl;
1555     }
1556   }
1557   if (fVerbosity >= confirmations) {
1558     G4cout
1559     << "End of event user vis action \"" << name << "\" registered"
1560     << G4endl;
1561   }
1562 }
1563 
1564 void G4VisManager::RegisterEndOfRunUserVisAction
1565 (const G4String& name,
1566  G4VUserVisAction* pVisAction,
1567  const G4VisExtent& extent) {
1568   fEndOfRunUserVisActions.push_back(UserVisAction(name,pVisAction));
1569   if (extent.GetExtentRadius() > 0.) {
1570     fUserVisActionExtents[pVisAction] = extent;
1571   } else {
1572     if (fVerbosity >= warnings) {
1573       G4warn <<
1574   "WARNING: No extent set for user vis action \"" << name << "\"."
1575        << G4endl;
1576     }
1577   }
1578   if (fVerbosity >= confirmations) {
1579     G4cout
1580     << "End of run user vis action \"" << name << "\" registered"
1581     << G4endl;
1582   }
1583 }
1584 
1585 void G4VisManager::SetCurrentScene (G4Scene* pScene) {
1586   if (pScene != fpScene) {
1587     // A change of scene.  Therefore reset transients drawn flags.  All
1588     // memory of previous transient proceessing thereby erased...
1589     ResetTransientsDrawnFlags();
1590   }
1591   fpScene = pScene;
1592 }
1593 
1594 void G4VisManager::SetCurrentGraphicsSystem (G4VGraphicsSystem* pSystem) {
1595   fpGraphicsSystem = pSystem;
1596   if (fVerbosity >= confirmations) {
1597     G4cout << "G4VisManager::SetCurrentGraphicsSystem: system now "
1598      << pSystem -> GetName () << G4endl;
1599   }
1600   // If current scene handler is of same graphics system, leave unchanged.
1601   // Else find the most recent scene handler of same graphics system.
1602   // Or clear pointers.
1603   if (!(fpSceneHandler && fpSceneHandler -> GetGraphicsSystem () == pSystem)) {
1604     const G4SceneHandlerList& sceneHandlerList = fAvailableSceneHandlers;
1605     G4int nSH = (G4int)sceneHandlerList.size ();  // No. of scene handlers.
1606     G4int iSH;
1607     for (iSH = nSH - 1; iSH >= 0; iSH--) {
1608       if (sceneHandlerList [iSH] -> GetGraphicsSystem () == pSystem) break;
1609     }
1610     if (iSH >= 0) {
1611       fpSceneHandler = sceneHandlerList [iSH];
1612       if (fVerbosity >= confirmations) {
1613   G4cout << "  Scene Handler now "
1614          << fpSceneHandler -> GetName () << G4endl;
1615       }
1616       if (fpScene != fpSceneHandler -> GetScene ()) {
1617   fpScene = fpSceneHandler -> GetScene ();
1618   if (fVerbosity >= confirmations) {
1619     G4cout << "  Scene now \""
1620      << fpScene -> GetName () << "\"" << G4endl;
1621   }
1622       }
1623       const G4ViewerList& viewerList = fpSceneHandler -> GetViewerList ();
1624       if (viewerList.size ()) {
1625   fpViewer = viewerList [0];
1626   if (fVerbosity >= confirmations) {
1627     G4cout << "  Viewer now " << fpViewer -> GetName () << G4endl;
1628   }
1629       }
1630       else {
1631   fpViewer = 0;
1632       }
1633     }
1634     else {
1635       fpSceneHandler = 0;
1636       fpViewer = 0;
1637     }
1638   }
1639 }
1640 
1641 void G4VisManager::SetCurrentSceneHandler (G4VSceneHandler* pSceneHandler) {
1642   fpSceneHandler = pSceneHandler;
1643   if (fVerbosity >= confirmations) {
1644     G4cout << "G4VisManager::SetCurrentSceneHandler: scene handler now \""
1645      << pSceneHandler -> GetName () << "\"" << G4endl;
1646   }
1647   if (fpScene != fpSceneHandler -> GetScene ()) {
1648     fpScene = fpSceneHandler -> GetScene ();
1649     if (fVerbosity >= confirmations) {
1650       G4cout << "  Scene now \""
1651        << fpScene -> GetName () << "\"" << G4endl;
1652     }
1653   }
1654   if (fpGraphicsSystem != pSceneHandler -> GetGraphicsSystem ()) {
1655     fpGraphicsSystem = pSceneHandler -> GetGraphicsSystem ();
1656     if (fVerbosity >= confirmations) {
1657       G4cout << "  Graphics system now \""
1658        << fpGraphicsSystem -> GetName () << "\"" << G4endl;
1659     }
1660   }
1661   const G4ViewerList& viewerList = fpSceneHandler -> GetViewerList ();
1662   std::size_t nViewers = viewerList.size ();
1663   if (nViewers) {
1664     std::size_t iViewer;
1665     for (iViewer = 0; iViewer < nViewers; ++iViewer) {
1666       if (fpViewer == viewerList [iViewer]) break;
1667     }
1668     if (iViewer >= nViewers) {
1669       fpViewer = viewerList [0];
1670       if (fVerbosity >= confirmations) {
1671   G4cout << "  Viewer now \"" << fpViewer -> GetName () << "\""
1672          << G4endl;
1673       }
1674     }
1675     if (!IsValidView ()) {
1676       if (fVerbosity >= warnings) {
1677   G4warn <<
1678   "WARNING: Problem setting scene handler - please report circumstances."
1679          << G4endl;
1680       }
1681     }
1682   }
1683   else {
1684     fpViewer = 0;
1685     if (fVerbosity >= warnings) {
1686       G4warn <<
1687   "WARNING: No viewers for this scene handler - please create one."
1688        << G4endl;
1689     }
1690   }
1691 }
1692 
1693 void G4VisManager::SetCurrentViewer (G4VViewer* pViewer) {
1694   fpViewer  = pViewer;
1695   if (fpViewer == nullptr) {
1696     if (fVerbosity >= confirmations) {
1697       G4cout << "G4VisManager::SetCurrentViewer: current viewer pointer zeroed "
1698       << G4endl;
1699     }
1700     return;
1701   }
1702   if (fVerbosity >= confirmations) {
1703     G4cout << "G4VisManager::SetCurrentViewer: viewer now "
1704      << pViewer -> GetName ()
1705      << G4endl;
1706   }
1707   fpSceneHandler = fpViewer -> GetSceneHandler ();
1708   if (!fpSceneHandler) {
1709     if (fVerbosity >= warnings) {
1710       G4warn <<
1711       "WARNING: No scene handler for this viewer - please create one."
1712       << G4endl;
1713     }
1714     return;
1715   }
1716   // JA: I don't think we need this. Setview will be called when needed.
1717   // fpViewer->SetView();
1718   fpSceneHandler -> SetCurrentViewer (pViewer);
1719   fpScene = fpSceneHandler -> GetScene ();
1720   fpGraphicsSystem = fpSceneHandler -> GetGraphicsSystem ();
1721   if (!IsValidView ()) {
1722     if (fVerbosity >= warnings) {
1723       G4warn <<
1724   "WARNING: Problem setting viewer - please report circumstances."
1725        << G4endl;
1726     }
1727   }
1728 }
1729 
1730 void G4VisManager::PrintAvailableGraphicsSystems
1731 (Verbosity verbosity, std::ostream& out) const
1732 {
1733   out << "Registered graphics systems are:\n";
1734   if (fAvailableGraphicsSystems.size ()) {
1735     for (const auto& gs: fAvailableGraphicsSystems) {
1736       const G4String& name = gs->GetName();
1737       const std::vector<G4String>& nicknames = gs->GetNicknames();
1738       if (verbosity <= warnings) {
1739         // Brief output
1740         out << "  " << name << " (";
1741         for (std::size_t i = 0; i < nicknames.size(); ++i) {
1742           if (i != 0) {
1743             out << ", ";
1744           }
1745           out << nicknames[i];
1746         }
1747         out << ')';
1748       } else {
1749         // Full output
1750         out << *gs;
1751       }
1752       out << std::endl;
1753     }
1754     out << "Default graphics system is: " << fDefaultGraphicsSystemName
1755     << " (based on " << fDefaultGraphicsSystemBasis << ")."
1756     << "\nDefault window size hint is: " << fDefaultXGeometryString
1757     << " (based on " << fDefaultXGeometryStringBasis << ")."
1758     << "\nNote: Parameters specified on the command line will override these defaults."
1759     << "\n      Use \"vis/open\" without parameters to get these defaults."
1760     << std::endl;
1761   } else {
1762     out << "  NONE!!!  None registered - yet!  Mmmmm!" << G4endl;
1763   }
1764 }
1765 
1766 void G4VisManager::PrintAvailableModels (Verbosity verbosity) const
1767 {
1768   {
1769     //fpTrajDrawModelMgr->Print(G4cout);
1770     G4cout << "Registered model factories:" << G4endl;
1771     const std::vector<G4VModelFactory<G4VTrajectoryModel>*>& factoryList =
1772       fpTrajDrawModelMgr->FactoryList();
1773     if (factoryList.empty()) G4cout << "  None" << G4endl;
1774     else {
1775       std::vector<G4VModelFactory<G4VTrajectoryModel>*>::const_iterator i;
1776       for (i = factoryList.begin(); i != factoryList.end(); ++i) {
1777         (*i)->Print(G4cout);
1778       }
1779     }
1780     G4cout << "\nRegistered models:" << G4endl;
1781     const G4VisListManager<G4VTrajectoryModel>* listManager =
1782       fpTrajDrawModelMgr->ListManager();
1783     const std::map<G4String, G4VTrajectoryModel*>& modelMap =
1784       listManager->Map();
1785     if (modelMap.empty()) G4cout << "  None" << G4endl;
1786     else {
1787       std::map<G4String, G4VTrajectoryModel*>::const_iterator i;
1788       for (i = modelMap.begin(); i != modelMap.end(); ++i) {
1789   G4cout << "  " << i->second->Name();
1790   if (i->second == listManager->Current()) G4cout << " (Current)";
1791   G4cout << G4endl;
1792   if (verbosity >= parameters) i->second->Print(G4cout);
1793       }
1794     }
1795   }
1796 
1797   G4cout << G4endl;
1798 
1799   {
1800     //fpTrajFilterMgr->Print(G4cout);
1801     G4cout << "Registered filter factories:" << G4endl;
1802     const std::vector<G4VModelFactory<G4VFilter<G4VTrajectory> >*>&
1803       factoryList = fpTrajFilterMgr->FactoryList();
1804     if (factoryList.empty()) G4cout << "  None" << G4endl;
1805     else {
1806       std::vector<G4VModelFactory<G4VFilter<G4VTrajectory> >*>::const_iterator i;
1807       for (i = factoryList.begin(); i != factoryList.end(); ++i) {
1808         (*i)->Print(G4cout);
1809       }
1810     }
1811 
1812     G4cout << "\nRegistered filters:" << G4endl;
1813     const std::vector<G4VFilter<G4VTrajectory>*>&
1814       filterList = fpTrajFilterMgr->FilterList();
1815     if (filterList.empty()) G4cout << "  None" << G4endl;
1816     else {
1817       std::vector<G4VFilter<G4VTrajectory>*>::const_iterator i;
1818       for (i = filterList.begin(); i != filterList.end(); ++i) {
1819   G4cout << "  " << (*i)->GetName() << G4endl;
1820   if (verbosity >= parameters) (*i)->PrintAll(G4cout);
1821       }
1822     }
1823   }
1824 }
1825 
1826 void G4VisManager::PrintAvailableUserVisActions (Verbosity) const
1827 {
1828   G4cout <<
1829     "You have successfully registered the following user vis actions."
1830    << G4endl;
1831   G4cout << "Run Duration User Vis Actions:";
1832   if (fRunDurationUserVisActions.empty()) G4cout << " none" << G4endl;
1833   else {
1834     G4cout << G4endl;
1835     for (std::size_t i = 0; i < fRunDurationUserVisActions.size(); ++i) {
1836       const G4String& name = fRunDurationUserVisActions[i].fName;
1837       G4cout << "  " << name << G4endl;
1838     }
1839   }
1840 
1841   G4cout << "End of Event User Vis Actions:";
1842   if (fEndOfEventUserVisActions.empty()) G4cout << " none" << G4endl;
1843   else {
1844     G4cout << G4endl;
1845     for (std::size_t i = 0; i < fEndOfEventUserVisActions.size(); ++i) {
1846       const G4String& name = fEndOfEventUserVisActions[i].fName;
1847       G4cout << "  " << name << G4endl;
1848     }
1849   }
1850 
1851   G4cout << "End of Run User Vis Actions:";
1852   if (fEndOfRunUserVisActions.empty()) G4cout << " none" << G4endl;
1853   else {
1854     G4cout << G4endl;
1855     for (std::size_t i = 0; i < fEndOfRunUserVisActions.size(); ++i) {
1856       const G4String& name = fEndOfRunUserVisActions[i].fName;
1857       G4cout << "  " << name << G4endl;
1858     }
1859   }
1860 }
1861 
1862 void G4VisManager::PrintAvailableColours (Verbosity) const {
1863   G4cout <<
1864     "Some /vis commands (optionally) take a string to specify colour."
1865     "\nAvailable colours:\n  ";
1866   const std::map<G4String, G4Colour>& map = G4Colour::GetMap();
1867   for (std::map<G4String, G4Colour>::const_iterator i = map.begin();
1868        i != map.end();) {
1869     G4cout << i->first;
1870     if (++i != map.end()) G4cout << ", ";
1871   }
1872   G4cout << G4endl;
1873 }
1874 
1875 void G4VisManager::PrintInvalidPointers () const {
1876   if (fVerbosity >= errors) {
1877     G4warn << "ERROR: G4VisManager::PrintInvalidPointers:";
1878     if (!fpGraphicsSystem) {
1879       G4warn << "\n null graphics system pointer.";
1880     }
1881     else {
1882       G4warn << "\n  Graphics system is " << fpGraphicsSystem -> GetName ()
1883        << " but:";
1884       if (!fpScene)
1885   G4warn <<
1886     "\n  Null scene pointer. Use \"/vis/drawVolume\" or"
1887     " \"/vis/scene/create\".";
1888       if (!fpSceneHandler)
1889   G4warn <<
1890     "\n  Null scene handler pointer. Use \"/vis/open\" or"
1891     " \"/vis/sceneHandler/create\".";
1892       if (!fpViewer )
1893   G4warn <<
1894     "\n  Null viewer pointer. Use \"/vis/viewer/create\".";
1895     }
1896     G4warn << G4endl;
1897   }
1898 }
1899 
1900 #ifdef G4MULTITHREADED
1901 
1902 namespace {
1903   G4bool mtRunInProgress = false;
1904   std::deque<const G4Event*> mtVisEventQueue;
1905   G4Thread* mtVisSubThread = 0;
1906   G4Mutex mtVisSubThreadMutex = G4MUTEX_INITIALIZER;
1907 }
1908 
1909 G4ThreadFunReturnType G4VisManager::G4VisSubThread(G4ThreadFunArgType p)
1910 {
1911   G4VisManager* pVisManager = (G4VisManager*)p;
1912   G4VSceneHandler* pSceneHandler = pVisManager->GetCurrentSceneHandler();
1913   if (!pSceneHandler) return 0;
1914   G4Scene* pScene = pSceneHandler->GetScene();
1915   if (!pScene) return 0;
1916   G4VViewer* pViewer = pVisManager->GetCurrentViewer();
1917   if (!pViewer) return 0;
1918 
1919   G4UImanager::GetUIpointer()->SetUpForSpecialThread("G4VIS");
1920 
1921   //  G4cout << "G4VisManager::G4VisSubThread: thread: "
1922   //  << G4Threading::G4GetThreadId() << std::endl;
1923 
1924   // Set up geometry and navigation for a thread
1925   G4GeometryWorkspace::GetPool()->CreateAndUseWorkspace();
1926   G4SolidsWorkspace::GetPool()->CreateAndUseWorkspace();
1927   G4Navigator* navigator = G4TransportationManager::GetTransportationManager()
1928                              ->GetNavigatorForTracking();
1929   navigator->SetWorldVolume(
1930     G4RunManagerFactory::GetMasterRunManagerKernel()->GetCurrentWorld());
1931 
1932   pViewer->SwitchToVisSubThread();
1933 
1934   while (true) {
1935 
1936     G4MUTEXLOCK(&mtVisSubThreadMutex);
1937     std::size_t eventQueueSize = mtVisEventQueue.size();
1938     G4MUTEXUNLOCK(&mtVisSubThreadMutex);
1939     // G4cout << "Event queue size (A): " << eventQueueSize << G4endl;
1940 
1941     while (eventQueueSize) {
1942 
1943       G4MUTEXLOCK(&mtVisSubThreadMutex);
1944       const G4Event* event = mtVisEventQueue.front();
1945       G4MUTEXUNLOCK(&mtVisSubThreadMutex);
1946       // G4int eventID = event->GetEventID();
1947       // G4cout
1948       //  << "G4VisManager::G4VisSubThread: Vis sub-thread: Dealing with event:
1949       //  "
1950       //  << eventID << G4endl;
1951 
1952       // Here comes the event drawing
1953       pVisManager->SetTransientsDrawnThisEvent(false);
1954       pSceneHandler->SetTransientsDrawnThisEvent(false);
1955 
1956       // We are about to draw the event (trajectories, etc.), but first we
1957       // have to clear the previous event(s) if necessary.  If this event
1958       // needs to be drawn afresh, e.g., the first event or any event when
1959       // "accumulate" is not requested, the old event has to be cleared.
1960       // We have postponed this so that, for normal viewers like OGL, the
1961       // previous event(s) stay on screen until this new event comes
1962       // along.  For a file-writing viewer the geometry has to be drawn.
1963       // See, for example, G4HepRepFileSceneHandler::ClearTransientStore.
1964       pVisManager->ClearTransientStoreIfMarked();
1965 
1966       // Now draw the event...
1967       pSceneHandler->DrawEvent(event);
1968       ++pVisManager->fNoOfEventsDrawnThisRun;
1969 
1970       if (pScene->GetRefreshAtEndOfEvent()) {
1971 
1972         // ShowView guarantees the view is flushed to the screen.  It also
1973         // triggers other features such picking (if enabled) and allows
1974         // file-writing viewers to close the file.
1975         pViewer->ShowView();
1976         pSceneHandler->SetMarkForClearingTransientStore(true);
1977 
1978       }
1979 
1980       // Testing.
1981       // std::this_thread::sleep_for(std::chrono::seconds(5));
1982 
1983       // Then pop and release event
1984       G4MUTEXLOCK(&mtVisSubThreadMutex);
1985       mtVisEventQueue.pop_front();
1986       event->PostProcessingFinished();
1987       eventQueueSize = mtVisEventQueue.size();
1988       G4MUTEXUNLOCK(&mtVisSubThreadMutex);
1989       // G4cout << "Event queue size (B): " << eventQueueSize << G4endl;
1990     }
1991 
1992     G4MUTEXLOCK(&mtVisSubThreadMutex);
1993     G4int runInProgress = mtRunInProgress;
1994     G4MUTEXUNLOCK(&mtVisSubThreadMutex);
1995     if (!runInProgress) {
1996       // EndOfRun on master thread has signalled end of run.  There is
1997       // nothing to draw so...
1998       break;
1999     }
2000 
2001     // Run still in progress but nothing to draw, so wait a while.
2002     std::this_thread::sleep_for(std::chrono::milliseconds(100));
2003   }
2004 
2005   // Inform viewer that we have finished all sub-thread drawing
2006   pViewer->DoneWithVisSubThread();
2007   pViewer->MovingToMasterThread();
2008   // G4cout << "G4VisManager::G4VisSubThread: Vis sub-thread: ending" << G4endl;
2009   return nullptr;
2010 }
2011 
2012 namespace {
2013   //  G4Mutex visBeginOfRunMutex = G4MUTEX_INITIALIZER;
2014   //  G4Mutex visBeginOfEventMutex = G4MUTEX_INITIALIZER;
2015   G4Mutex visEndOfEventMutex = G4MUTEX_INITIALIZER;
2016   //  G4Mutex visEndOfRunMutex = G4MUTEX_INITIALIZER;
2017 }
2018 
2019 #endif
2020 
2021 void G4VisManager::BeginOfRun ()
2022 {
2023   if (fIgnoreStateChanges) return;
2024 
2025 #ifdef G4MULTITHREADED
2026   if (G4Threading::IsWorkerThread()) return;
2027 #endif
2028   //  G4cout << "G4VisManager::BeginOfRun: thread: "
2029   //  << G4Threading::G4GetThreadId() << G4endl;
2030 
2031   G4RunManager* runManager = G4RunManagerFactory::GetMasterRunManager();
2032 
2033   // For a fake run...
2034   G4int nEventsToBeProcessed = runManager->GetNumberOfEventsToBeProcessed();
2035   if (nEventsToBeProcessed == 0) return;
2036 
2037   fNKeepRequests = 0;
2038   fEventKeepingSuspended = false;
2039   fTransientsDrawnThisRun = false;
2040   if (fpSceneHandler) fpSceneHandler->SetTransientsDrawnThisRun(false);
2041   fNoOfEventsDrawnThisRun = 0;
2042 
2043   // Check to see if the user has created a trajectory model. If not, create
2044   // a default one. To avoid code duplication the following function is used
2045   // and its result (a const G4VTrajectoryModel*) is thrown away at this point.
2046   // The function is called again later when needed.
2047   CurrentTrajDrawModel();
2048 
2049 #ifdef G4MULTITHREADED
2050 //   There is a static method G4Threading::IsMultithreadedApplication()
2051 //   that returns true only if G4MTRunManager is instantiated with MT
2052 //   installation. Thus method returns false if G4RunManager base class is
2053 //   instantiated even with the MT installation, or of course with sequential
2054 //   installation.
2055   if (G4Threading::IsMultithreadedApplication()) {
2056 
2057     // Inform viewer that we have finished all master thread drawing for now...
2058     if (fpViewer) fpViewer->DoneWithMasterThread();
2059 
2060     // Start vis sub-thread
2061 //    G4cout << "G4VisManager::BeginOfRun: Starting vis sub-thread" << G4endl;
2062     G4MUTEXLOCK(&mtVisSubThreadMutex);
2063     mtRunInProgress = true;
2064     G4MUTEXUNLOCK(&mtVisSubThreadMutex);
2065     mtVisSubThread = new G4Thread;
2066     // Launch vis thread
2067     G4THREADCREATE(mtVisSubThread,G4VisSubThread,this);
2068 
2069     // Tricky things for some viewers (e.g., Qt):
2070     // - Launch the vis thread
2071     // - Wait for the vis thread to set its QThread
2072     // - Then move current QOpenGL context (if Qt) to this Qthread
2073     // - Go ahead
2074     if (fpViewer) fpViewer->MovingToVisSubThread();
2075   }
2076 #endif
2077 }
2078 
2079 void G4VisManager::BeginOfEvent ()
2080 {
2081   if (fIgnoreStateChanges) return;
2082 
2083   if (!GetConcreteInstance()) return;
2084 
2085 //  G4cout << "G4VisManager::BeginOfEvent: thread: "
2086 //  << G4Threading::G4GetThreadId() << G4endl;
2087 
2088   // Some instructions that should NOT be in multithreaded version.
2089 #ifndef G4MULTITHREADED
2090   // These instructions are in G4VisSubThread for multithreading.
2091   fTransientsDrawnThisEvent = false;
2092   if (fpSceneHandler) fpSceneHandler->SetTransientsDrawnThisEvent(false);
2093 #endif
2094 }
2095 
2096 void G4VisManager::EndOfEvent ()
2097 {
2098   if (fIgnoreStateChanges) return;
2099 
2100   if (!GetConcreteInstance()) return;
2101 
2102 //  G4cout << "G4VisManager::EndOfEvent: thread: "
2103 //  << G4Threading::G4GetThreadId() << G4endl;
2104 
2105 #ifdef G4MULTITHREADED
2106   G4AutoLock al(&visEndOfEventMutex);
2107   // Testing.
2108 //  std::this_thread::sleep_for(std::chrono::seconds(5));
2109 #endif
2110 
2111   // Don't call IsValidView unless there is a scene handler.  This
2112   // avoids WARNING message at end of event and run when the user has
2113   // not instantiated a scene handler, e.g., in batch mode.
2114   G4bool valid = fpSceneHandler && IsValidView();
2115   if (!valid) return;
2116 
2117   G4RunManager* runManager = G4RunManagerFactory::GetMasterRunManager();
2118 
2119   const G4Run* currentRun = runManager->GetCurrentRun();
2120   if (!currentRun) return;
2121 
2122   // This gets the thread-local event manager
2123   G4EventManager* eventManager = G4EventManager::GetEventManager();
2124   const G4Event* currentEvent = eventManager->GetConstCurrentEvent();
2125   if (!currentEvent) return;
2126 
2127   // Discard event if fDrawEventOnlyIfToBeKept flag is set unless the
2128   // user has requested the event to be kept.
2129   if (fDrawEventOnlyIfToBeKept) {
2130     if (!currentEvent->ToBeKept()) return;
2131   }
2132 
2133   if (G4Threading::IsMultithreadedApplication()) {
2134 
2135 #ifdef G4MULTITHREADED
2136 
2137     // Wait if too many events in the queue.
2138     G4MUTEXLOCK(&mtVisSubThreadMutex);
2139     std::size_t eventQueueSize = mtVisEventQueue.size();
2140     G4MUTEXUNLOCK(&mtVisSubThreadMutex);
2141 //    G4cout << "Event queue size (1): " << eventQueueSize << G4endl;
2142 
2143     G4bool eventQueueFull = false;
2144     while (fMaxEventQueueSize > 0 && (G4int)eventQueueSize >= fMaxEventQueueSize) {
2145 
2146 //      G4cout << "Event queue size (2): " << eventQueueSize << G4endl;
2147       if (fWaitOnEventQueueFull) {
2148         static G4bool warned = false;
2149         if (!warned) {
2150           G4warn <<
2151           "WARNING: The number of events in the visualisation queue has exceeded"
2152           "\n  the maximum, "
2153           << fMaxEventQueueSize <<
2154           ".\n  If, during a multithreaded run, the simulation gets ahead of the"
2155           "\n  visualisation by more than this maximum, the simulation is delayed"
2156           "\n  until the vis sub-thread has drawn a few more events and removed them"
2157           "\n  from the queue.  You may change this maximum number of events with"
2158           "\n  \"/vis/multithreading/maxEventQueueSize <N>\", where N is the maximum"
2159           "\n  number you wish to allow.  N <= 0 means \"unlimited\"."
2160           "\n  Alternatively you may choose to discard events for drawing by setting"
2161           "\n  \"/vis/multithreading/actionOnEventQueueFull discard\"."
2162           "\n  To avoid visualisation altogether: \"/vis/disable\"."
2163           "\n  And maybe \"/tracking/storeTrajectories 0\"."
2164           << G4endl;
2165           warned = true;
2166         }
2167         //      G4cout << "Event queue size (3): " << eventQueueSize << G4endl;
2168         // Wait a while to give event drawing time to reduce the queue...
2169         std::this_thread::sleep_for(std::chrono::milliseconds(100));
2170         //      G4cout << "Event queue size (4): " << eventQueueSize << G4endl;
2171       } else {
2172         static G4bool warned = false;
2173         if (!warned) {
2174           G4warn <<
2175           "WARNING: The number of events in the visualisation queue has exceeded"
2176           "\n  the maximum, "
2177           << fMaxEventQueueSize <<
2178           ".\n  Some events have been discarded for drawing.  You may change this"
2179           "\n  behaviour with \"/vis/multithreading/actionOnEventQueueFull wait\"."
2180           "\n  To avoid visualisation altogether: \"/vis/disable\"."
2181           "\n  And maybe \"/tracking/storeTrajectories 0\"."
2182           << G4endl;
2183           warned = true;
2184         }
2185         eventQueueFull = true;  // Causes event to be discarded for drawing.
2186         break;
2187       }
2188 
2189       G4MUTEXLOCK(&mtVisSubThreadMutex);
2190       eventQueueSize = mtVisEventQueue.size();
2191       G4MUTEXUNLOCK(&mtVisSubThreadMutex);
2192     }
2193 
2194     if (!eventQueueFull) {
2195       G4MUTEXLOCK(&mtVisSubThreadMutex);
2196       // Keep event for processing and put event on vis event queue
2197       currentEvent->KeepForPostProcessing();
2198       if (fpScene->GetRefreshAtEndOfEvent()) {
2199         // Keep one event (cannot know which is last so any will do)
2200         if (fNKeepRequests == 0) {
2201           eventManager->KeepTheCurrentEvent();
2202           fNKeepRequests++;
2203         }
2204       }
2205       mtVisEventQueue.push_back(currentEvent);
2206       G4MUTEXUNLOCK(&mtVisSubThreadMutex);
2207     }
2208 
2209 //    G4MUTEXLOCK(&mtVisSubThreadMutex);
2210 //    G4int eQS = mtVisEventQueue.size();
2211 //    G4MUTEXUNLOCK(&mtVisSubThreadMutex);
2212 //    G4cout << "Event queue size (5): " << eQS << G4endl;
2213 
2214 #endif
2215 
2216   } else {
2217 
2218     // Sequential mode
2219 
2220     G4int nEventsToBeProcessed = 0;
2221     G4int nKeptEvents = 0;
2222     G4int eventID = -2;  // (If no run manager, triggers ShowView as normal.)
2223     if (currentRun) {
2224       nEventsToBeProcessed = runManager->GetNumberOfEventsToBeProcessed();
2225       eventID = currentEvent->GetEventID();
2226       const std::vector<const G4Event*>* events = currentRun->GetEventVector();
2227       if (events) nKeptEvents = (G4int)events->size();
2228     }
2229 
2230     // We are about to draw the event (trajectories, etc.), but first we
2231     // have to clear the previous event(s) if necessary.  If this event
2232     // needs to be drawn afresh, e.g., the first event or any event when
2233     // "accumulate" is not requested, the old event has to be cleared.
2234     // We have postponed this so that, for normal viewers like OGL, the
2235     // previous event(s) stay on screen until this new event comes
2236     // along.  For a file-writing viewer the geometry has to be drawn.
2237     // See, for example, G4HepRepFileSceneHandler::ClearTransientStore.
2238     ClearTransientStoreIfMarked();
2239 
2240     // Now draw the event...
2241     fpSceneHandler->DrawEvent(currentEvent);
2242     ++fNoOfEventsDrawnThisRun;
2243 
2244     if (fpScene->GetRefreshAtEndOfEvent()) {
2245 
2246       // Unless last event (in which case wait end of run)...
2247       if (eventID < nEventsToBeProcessed - 1) {
2248         // ShowView guarantees the view is flushed to the screen.  It also
2249         // triggers other features such picking (if enabled) and allows
2250         // file-writing viewers to close the file.
2251         fpViewer->ShowView();
2252       } else {  // Last event...
2253                 // Keep, but only if user has not kept any...
2254         if (nKeptEvents == 0) {
2255           eventManager->KeepTheCurrentEvent();
2256           fNKeepRequests++;
2257         }
2258       }
2259       fpSceneHandler->SetMarkForClearingTransientStore(true);
2260 
2261     }
2262   }
2263 
2264   // Both modes - sequential and MT
2265 
2266   if (!(fpScene->GetRefreshAtEndOfEvent())) {
2267 
2268     //  Accumulating events...
2269 
2270     G4int maxNumberOfKeptEvents = fpScene->GetMaxNumberOfKeptEvents();
2271 
2272     if (maxNumberOfKeptEvents >= 0 &&
2273         fNKeepRequests >= maxNumberOfKeptEvents) {
2274 
2275       fEventKeepingSuspended = true;
2276       static G4bool warned = false;
2277       if (!warned) {
2278         if (fVerbosity >= warnings) {
2279           G4warn <<
2280           "WARNING: G4VisManager::EndOfEvent: Automatic event keeping suspended."
2281           << G4endl;
2282           if (maxNumberOfKeptEvents > 0) {
2283             G4warn <<
2284             "\n  The number of events exceeds the maximum, "
2285             << maxNumberOfKeptEvents <<
2286             ", that may be kept by\n  the vis manager."
2287             << G4endl;
2288           }
2289         }
2290         warned = true;
2291       }
2292 
2293     } else if (maxNumberOfKeptEvents != 0) {
2294 
2295       // If not disabled nor suspended.
2296       if (GetConcreteInstance() && !fEventKeepingSuspended) {
2297 //        G4cout <<
2298 //        "Requesting keeping event " << currentEvent->GetEventID()
2299 //        << G4endl;
2300         eventManager->KeepTheCurrentEvent();
2301         fNKeepRequests++;
2302       }
2303     }
2304   }
2305 }
2306 
2307 void G4VisManager::EndOfRun ()
2308 {
2309   if (fIgnoreStateChanges) return;
2310 
2311 #ifdef G4MULTITHREADED
2312   if (G4Threading::IsWorkerThread()) return;
2313 #endif
2314 
2315   //  G4cout << "G4VisManager::EndOfRun: thread: "
2316   //  << G4Threading::G4GetThreadId() << G4endl;
2317 
2318   G4RunManager* runManager = G4RunManagerFactory::GetMasterRunManager();
2319 
2320   // For a fake run...
2321   G4int nEventsToBeProcessed = runManager->GetNumberOfEventsToBeProcessed();
2322   if (nEventsToBeProcessed == 0) return;
2323 
2324   const G4Run* currentRun = runManager->GetCurrentRun();
2325   if (!currentRun) return;
2326 
2327 #ifdef G4MULTITHREADED
2328   //  G4AutoLock al(&visEndOfRunMutex);  ???
2329   if (G4Threading::IsMultithreadedApplication()) {
2330     // Reset flag so that sub-thread exits when it has finished processing.
2331     G4MUTEXLOCK(&mtVisSubThreadMutex);
2332     mtRunInProgress = false;
2333     G4MUTEXUNLOCK(&mtVisSubThreadMutex);
2334     // Wait for sub-thread to finish.
2335     G4THREADJOIN(*mtVisSubThread);
2336     delete mtVisSubThread;
2337     if (fpViewer) fpViewer->SwitchToMasterThread();
2338   }
2339 #endif
2340 
2341 #ifdef G4MULTITHREADED
2342   // Print warning about discarded events, if any.
2343   // Don't call IsValidView unless there is a scene handler.  This
2344   // avoids WARNING message from IsValidView() when the user has
2345   // not instantiated a scene handler, e.g., in batch mode.
2346   if (fpSceneHandler && IsValidView()) {  // Events should have been drawn
2347     G4int noOfEventsRequested = runManager->GetNumberOfEventsToBeProcessed();
2348     if (fNoOfEventsDrawnThisRun != noOfEventsRequested) {
2349       if (!fWaitOnEventQueueFull && fVerbosity >= warnings) {
2350         G4warn
2351         << "WARNING: Number of events drawn this run, "
2352         << fNoOfEventsDrawnThisRun << ", is different to number requested, "
2353         << noOfEventsRequested <<
2354         ".\n  (This is because you requested \"/vis/multithreading/actionOnEventQueueFull discard\".)"
2355         << G4endl;
2356       }
2357     }
2358   }
2359 #endif
2360 
2361   G4int nKeptEvents = 0;
2362   const std::vector<const G4Event*>* events = currentRun->GetEventVector();
2363   if (events) nKeptEvents = (G4int)events->size();
2364   if (fVerbosity >= warnings && nKeptEvents > 0) {
2365     G4warn << nKeptEvents;
2366     if (nKeptEvents == 1) G4warn << " event has";
2367     else G4warn << " events have";
2368     G4warn << " been kept for refreshing and/or reviewing." << G4endl;
2369     if (nKeptEvents != fNKeepRequests) {
2370       G4warn << "  (Note: ";
2371       if (fNKeepRequests == 0) {
2372         G4warn << "No keep requests were";
2373       } else if (fNKeepRequests == 1) {
2374         G4warn << "1 keep request was";
2375       } else {
2376         G4warn << fNKeepRequests << " keep requests were";
2377       }
2378       G4warn << " made by the vis manager.";
2379       if (fNKeepRequests == 0) {
2380         G4warn <<
2381         "\n  The kept events are those you have asked to be kept in your user action(s).)";
2382       } else {
2383         G4warn <<
2384         "\n  The same or further events may have been kept by you in your user action(s).)";
2385       }
2386       G4warn << G4endl;
2387     }
2388     G4warn <<
2389   "  \"/vis/reviewKeptEvents\" to review one by one."
2390   "\n  To see accumulated, \"/vis/enable\", then \"/vis/viewer/flush\" or \"/vis/viewer/rebuild\"."
2391     << G4endl;
2392   }
2393 
2394   if (fVerbosity >= warnings) PrintListOfPlots();
2395 
2396   if (fEventKeepingSuspended && fVerbosity >= warnings) {
2397     G4warn <<
2398     "WARNING: G4VisManager::EndOfRun: Automatic event keeping was suspended."
2399     << G4endl;
2400     if (fpScene->GetMaxNumberOfKeptEvents() > 0) {
2401       G4warn <<
2402       "  The number of events in the run exceeded the maximum, "
2403       << fpScene->GetMaxNumberOfKeptEvents() <<
2404       ", that may be\n  kept by the vis manager." <<
2405       "\n  The number of events kept by the vis manager can be changed with"
2406       "\n  \"/vis/scene/endOfEventAction accumulate <N>\", where N is the"
2407       "\n  maximum number you wish to allow.  N < 0 means \"unlimited\"."
2408       << G4endl;
2409     }
2410   }
2411 
2412   // Don't call IsValidView unless there is a scene handler.  This
2413   // avoids WARNING message at end of event and run when the user has
2414   // not instantiated a scene handler, e.g., in batch mode.
2415   G4bool valid = fpSceneHandler && IsValidView();
2416   if (GetConcreteInstance() && valid) {
2417 //    // ???? I can't remember why
2418 //    // if (!fpSceneHandler->GetMarkForClearingTransientStore()) {
2419 //    // is here.  It prevents ShowView at end of run, which seems to be OK
2420 //    // for sequential mode, but MT mode seems to need it (I have not
2421 //    // figured out why). ???? JA ????
2422 //    if (!fpSceneHandler->GetMarkForClearingTransientStore()) {
2423       if (fpScene->GetRefreshAtEndOfRun()) {
2424   fpSceneHandler->DrawEndOfRunModels();
2425         // An extra refresh for auto-refresh viewers.
2426         // ???? I DON'T WHY THIS IS NECESSARY ???? JA ????
2427         if (fpViewer->GetViewParameters().IsAutoRefresh()) {
2428           fpViewer->RefreshView();
2429         }
2430         // ShowView guarantees the view is flushed to the screen.  It also
2431         // triggers other features such picking (if enabled) and allows
2432         // file-writing viewers to close the file.
2433         fpViewer->ShowView();
2434   fpSceneHandler->SetMarkForClearingTransientStore(true);
2435       } else {
2436         if (fpGraphicsSystem->GetFunctionality() ==
2437             G4VGraphicsSystem::fileWriter) {
2438           if (fVerbosity >= warnings) {
2439             G4warn << "\"/vis/viewer/update\" to close file." << G4endl;
2440           }
2441         }
2442       }
2443 //    }
2444   }
2445   fEventRefreshing = false;
2446 }
2447 
2448 void G4VisManager::ClearTransientStoreIfMarked(){
2449   // Assumes valid view.
2450   if (fpSceneHandler->GetMarkForClearingTransientStore()) {
2451     fpSceneHandler->SetMarkForClearingTransientStore(false);
2452     fpSceneHandler->ClearTransientStore();
2453   }
2454   // Record if transients drawn.  These local flags are only set
2455   // *after* ClearTransientStore.  In the code in G4VSceneHandler
2456   // triggered by ClearTransientStore, use these flags so that
2457   // event refreshing is not done too early.
2458   fTransientsDrawnThisEvent = fpSceneHandler->GetTransientsDrawnThisEvent();
2459   fTransientsDrawnThisRun = fpSceneHandler->GetTransientsDrawnThisRun();
2460 }
2461 
2462 void G4VisManager::ResetTransientsDrawnFlags()
2463 {
2464   fTransientsDrawnThisRun = false;
2465   fTransientsDrawnThisEvent = false;
2466   G4SceneHandlerListConstIterator i;
2467   for (i = fAvailableSceneHandlers.begin();
2468        i != fAvailableSceneHandlers.end(); ++i) {
2469     (*i)->SetTransientsDrawnThisEvent(false);
2470     (*i)->SetTransientsDrawnThisRun(false);
2471   }
2472 }
2473 
2474 G4String G4VisManager::ViewerShortName (const G4String& viewerName) const {
2475   G4String viewerShortName = viewerName.substr(0, viewerName.find (' '));
2476   return G4StrUtil::strip_copy(viewerShortName);
2477 }
2478 
2479 G4VViewer* G4VisManager::GetViewer (const G4String& viewerName) const {
2480   G4String viewerShortName = ViewerShortName (viewerName);
2481   std::size_t nHandlers = fAvailableSceneHandlers.size ();
2482   std::size_t iHandler, iViewer;
2483   G4VViewer* viewer = 0;
2484   G4bool found = false;
2485   for (iHandler = 0; iHandler < nHandlers; iHandler++) {
2486     G4VSceneHandler* sceneHandler = fAvailableSceneHandlers [iHandler];
2487     const G4ViewerList& viewerList = sceneHandler -> GetViewerList ();
2488     for (iViewer = 0; iViewer < viewerList.size (); iViewer++) {
2489       viewer = viewerList [iViewer];
2490       if (viewerShortName == viewer -> GetShortName ()) {
2491   found = true;
2492   break;
2493       }
2494     }
2495     if (found) break;
2496   }
2497   if (found) return viewer;
2498   else return 0;
2499 }
2500 
2501 std::vector<G4String> G4VisManager::VerbosityGuidanceStrings;
2502 
2503 G4String G4VisManager::VerbosityString(Verbosity verbosity) {
2504   G4String rs;
2505   switch (verbosity) {
2506   case         quiet: rs = "quiet (0)"; break;
2507   case       startup: rs = "startup (1)"; break;
2508   case        errors: rs = "errors (2)"; break;
2509   case      warnings: rs = "warnings (3)"; break;
2510   case confirmations: rs = "confirmations (4)"; break;
2511   case    parameters: rs = "parameters (5)"; break;
2512   case           all: rs = "all (6)"; break;
2513   }
2514   return rs;
2515 }
2516 
2517 G4VisManager::Verbosity
2518 G4VisManager::GetVerbosityValue(const G4String& verbosityString) {
2519   G4String ss = G4StrUtil::to_lower_copy(verbosityString); 
2520   Verbosity verbosity;
2521   if      (ss[0] == 'q') verbosity = quiet;
2522   else if (ss[0] == 's') verbosity = startup;
2523   else if (ss[0] == 'e') verbosity = errors;
2524   else if (ss[0] == 'w') verbosity = warnings;
2525   else if (ss[0] == 'c') verbosity = confirmations;
2526   else if (ss[0] == 'p') verbosity = parameters;
2527   else if (ss[0] == 'a') verbosity = all;
2528   else {
2529     G4int intVerbosity;
2530     std::istringstream is(ss);
2531     is >> intVerbosity;
2532     if (!is) {
2533       G4warn << "ERROR: G4VisManager::GetVerbosityValue: invalid verbosity \""
2534        << verbosityString << "\"";
2535       for (std::size_t i = 0; i < VerbosityGuidanceStrings.size(); ++i) {
2536   G4warn << '\n' << VerbosityGuidanceStrings[i];
2537       }
2538       verbosity = warnings;
2539       G4warn << "\n  Returning " << VerbosityString(verbosity)
2540        << G4endl;
2541     }
2542     else {
2543       verbosity = GetVerbosityValue(intVerbosity);
2544     }
2545   }
2546   return verbosity;
2547 }
2548 
2549 G4VisManager::Verbosity G4VisManager::GetVerbosityValue(G4int intVerbosity) {
2550   Verbosity verbosity;
2551   if      (intVerbosity < quiet) verbosity = quiet;
2552   else if (intVerbosity > all)   verbosity = all;
2553   else                           verbosity = Verbosity(intVerbosity);
2554   return verbosity;
2555 }
2556 
2557 G4VisManager::Verbosity G4VisManager::GetVerbosity () {
2558   return fVerbosity;
2559 }
2560 
2561 void G4VisManager::SetVerboseLevel (G4int intVerbosity) {
2562   fVerbosity = GetVerbosityValue(intVerbosity);
2563 }
2564 
2565 void G4VisManager::SetVerboseLevel (const G4String& verbosityString) {
2566   fVerbosity = GetVerbosityValue(verbosityString);
2567 }
2568 
2569 G4bool G4VisManager::IsValidView () {
2570 
2571   if (!fInitialised) Initialise ();
2572 
2573   static G4bool noGSPrinting = true;
2574   if (!fpGraphicsSystem) {
2575     // Limit printing - we do not want printing if the user simply does
2576     // not want to use graphics, e.g., in batch mode.
2577     if (noGSPrinting) {
2578       noGSPrinting = false;
2579       if (fVerbosity >= warnings) {
2580   G4warn <<
2581   "WARNING: G4VisManager::IsValidView(): Attempt to draw when no graphics system"
2582   "\n  has been instantiated.  Use \"/vis/open\" or \"/vis/sceneHandler/create\"."
2583   "\n  Alternatively, to avoid this message, suppress instantiation of vis"
2584   "\n  manager (G4VisExecutive) and ensure drawing code is executed only if"
2585   "\n  G4VVisManager::GetConcreteInstance() is non-zero."
2586         << G4endl;
2587       }
2588     }
2589     return false;
2590   }
2591 
2592   if ((!fpScene) || (!fpSceneHandler) || (!fpViewer)) {
2593     if (fVerbosity >= errors) {
2594       G4warn <<
2595   "ERROR: G4VisManager::IsValidView(): Current view is not valid."
2596        << G4endl;
2597       PrintInvalidPointers ();
2598     }
2599     return false;
2600   }
2601 
2602   if (fpScene != fpSceneHandler -> GetScene ()) {
2603     if (fVerbosity >= errors) {
2604       G4warn << "ERROR: G4VisManager::IsValidView ():";
2605       if (fpSceneHandler -> GetScene ()) {
2606   G4warn <<
2607     "\n  The current scene \""
2608          << fpScene -> GetName ()
2609          << "\" is not handled by"
2610     "\n  the current scene handler \""
2611          << fpSceneHandler -> GetName ()
2612          << "\""
2613     "\n  (it currently handles scene \""
2614          << fpSceneHandler -> GetScene () -> GetName ()
2615          << "\")."
2616     "\n  Either:"
2617     "\n  (a) attach it to the scene handler with"
2618     "\n      /vis/sceneHandler/attach "
2619          << fpScene -> GetName ()
2620          << ", or"
2621     "\n  (b) create a new scene handler with "
2622     "\n      /vis/sceneHandler/create <graphics-system>,"
2623     "\n      in which case it should pick up the the new scene."
2624          << G4endl;
2625       }
2626       else {
2627   G4warn << "\n  Scene handler \""
2628          << fpSceneHandler -> GetName ()
2629          << "\" has null scene pointer."
2630     "\n  Attach a scene with /vis/sceneHandler/attach [<scene-name>]"
2631          << G4endl;
2632       }
2633     }
2634     return false;
2635   }
2636 
2637   const G4ViewerList& viewerList = fpSceneHandler -> GetViewerList ();
2638   if (viewerList.size () == 0) {
2639     if (fVerbosity >= errors) {
2640       G4warn <<
2641   "ERROR: G4VisManager::IsValidView (): the current scene handler\n  \""
2642        << fpSceneHandler -> GetName ()
2643        << "\" has no viewers.  Do /vis/viewer/create."
2644        << G4endl;
2645     }
2646     return false;
2647   }
2648 
2649   G4bool isValid = true;
2650   if (fpScene -> IsEmpty ()) {  // Add world by default if possible...
2651     G4bool warn(fVerbosity >= warnings);
2652     G4bool successful = fpScene -> AddWorldIfEmpty (warn);
2653     if (!successful || fpScene -> IsEmpty ()) {        // If still empty...
2654       if (fVerbosity >= errors) {
2655   G4warn << "ERROR: G4VisManager::IsValidView ():";
2656   G4warn <<
2657     "\n  Attempt at some drawing operation when scene is empty."
2658     "\n  Maybe the geometry has not yet been defined."
2659     "  Try /run/initialize."
2660           "\n  Or use \"/vis/scene/add/extent\"."
2661          << G4endl;
2662       }
2663       isValid = false;
2664     }
2665     else {
2666       G4UImanager::GetUIpointer()->ApplyCommand ("/vis/scene/notifyHandlers");
2667       if (fVerbosity >= warnings) {
2668   G4warn <<
2669     "WARNING: G4VisManager: the scene was empty, \"world\" has been"
2670     "\n  added and the scene handlers notified.";
2671   G4warn << G4endl;
2672       }
2673     }
2674   }
2675   return isValid;
2676 }
2677 
2678 void
2679 G4VisManager::RegisterModelFactories() 
2680 {
2681   if (fVerbosity >= warnings) {
2682     G4warn<<"G4VisManager: No model factories registered with G4VisManager."<<G4endl;
2683     G4warn<<"G4VisManager::RegisterModelFactories() should be overridden in derived"<<G4endl;
2684     G4warn<<"class. See G4VisExecutive for an example."<<G4endl;
2685   }
2686 }
2687 
2688 #ifdef G4MULTITHREADED
2689 void G4VisManager::SetUpForAThread()
2690 {
2691   new G4VisStateDependent(this); 
2692 }
2693 #endif
2694 
2695 void G4VisManager::IgnoreStateChanges(G4bool val)
2696 {
2697   fIgnoreStateChanges = val; 
2698 }
2699