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