Geant4  10.03
G4VisManager.cc
Go to the documentation of this file.
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 // $Id: G4VisManager.cc 101792 2016-11-28 16:47:50Z gcosmo $
27 //
28 //
29 // GEANT4 Visualization Manager - John Allison 02/Jan/1996.
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"
86 #include "G4SolidsWorkspacePool.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  fpRequestedEvent (0),
115  fAbortReviewKeptEvents (false),
116  fIsDrawGroup (false),
117  fDrawGroupNestingDepth (0),
118  fIgnoreStateChanges (false)
119 #ifdef G4MULTITHREADED
120 , fMaxEventQueueSize (100)
121 , fWaitOnEventQueueFull (true)
122 #endif
123  // All other objects use default constructors.
124 {
125  fpTrajDrawModelMgr = new G4VisModelManager<G4VTrajectoryModel>("/vis/modeling/trajectories");
126  fpTrajFilterMgr = new G4VisFilterManager<G4VTrajectory>("/vis/filtering/trajectories");
127  fpHitFilterMgr = new G4VisFilterManager<G4VHit>("/vis/filtering/hits");
128  fpDigiFilterMgr = new G4VisFilterManager<G4VDigi>("/vis/filtering/digi");
129 
130  VerbosityGuidanceStrings.push_back
131  ("Simple graded message scheme - digit or string (1st character defines):");
132  VerbosityGuidanceStrings.push_back
133  (" 0) quiet, // Nothing is printed.");
134  VerbosityGuidanceStrings.push_back
135  (" 1) startup, // Startup and endup messages are printed...");
136  VerbosityGuidanceStrings.push_back
137  (" 2) errors, // ...and errors...");
138  VerbosityGuidanceStrings.push_back
139  (" 3) warnings, // ...and warnings...");
140  VerbosityGuidanceStrings.push_back
141  (" 4) confirmations, // ...and confirming messages...");
142  VerbosityGuidanceStrings.push_back
143  (" 5) parameters, // ...and parameters of scenes and views...");
144  VerbosityGuidanceStrings.push_back
145  (" 6) all // ...and everything available.");
146 
147  if (fpInstance) {
149  ("G4VisManager::G4VisManager",
150  "visman0001", FatalException,
151  "Attempt to Construct more than one VisManager");
152  }
153 
154  fpInstance = this;
155  SetConcreteInstance(this);
156 
158  // No need to delete this; G4StateManager does this.
159 
160  fVerbosity = GetVerbosityValue(verbosityString);
161  if (fVerbosity >= startup) {
162  G4cout
163  << "Visualization Manager instantiating with verbosity \""
165  << "\"..." << G4endl;
166  }
167 
168  // Note: The specific graphics systems must be instantiated in a
169  // higher level library to avoid circular dependencies. Also,
170  // some specifically need additional external libararies that the
171  // user must supply. Therefore we ask the user to implement
172  // RegisterGraphicsSystems() and RegisterModelFactories()
173  // in a subclass. We have to wait for the subclass to instantiate
174  // so RegisterGraphicsSystems() cannot be called from this
175  // constructor; it is called from Initialise(). So we ask the
176  // user:
177  // (a) to write a subclass and implement RegisterGraphicsSystems()
178  // and RegisterModelFactories(). See
179  // visualization/include/G4VisExecutive.hh/icc as an example.
180  // (b) instantiate the subclass.
181  // (c) invoke the Initialise() method of the subclass.
182  // For example:
183  // ...
184  // #ifdef G4VIS_USE
185  // // Instantiate and initialise Visualization Manager.
186  // G4VisManager* visManager = new G4VisExecutive;
187  // visManager -> SetVerboseLevel (Verbose);
188  // visManager -> Initialise ();
189  // #endif
190  // // (Don't forget to delete visManager;)
191  // ...
192 
193  // Make top level command directory...
194  // Vis commands should *not* be broadcast to threads (2nd argument).
195  G4UIcommand* directory = new G4UIdirectory ("/vis/",false);
196  directory -> SetGuidance ("Visualization commands.");
197  fDirectoryList.push_back (directory);
198 
199  // Instantiate *basic* top level commands so that they can be used
200  // immediately after instantiation of the vis manager. Other top
201  // level and lower level commands are instantiated later in
202  // RegisterMessengers.
203  G4VVisCommand::SetVisManager (this); // Sets shared pointer
206 }
207 
209  fpInstance = 0;
210  size_t i;
211  for (i = 0; i < fSceneList.size (); ++i) {
212  delete fSceneList[i];
213  }
214  for (i = 0; i < fAvailableSceneHandlers.size (); ++i) {
215  if (fAvailableSceneHandlers[i] != NULL) {
216  delete fAvailableSceneHandlers[i];
217  }
218  }
219  for (i = 0; i < fAvailableGraphicsSystems.size (); ++i) {
220  if (fAvailableGraphicsSystems[i]) {
221  delete fAvailableGraphicsSystems[i];
222  }
223  }
224  if (fVerbosity >= startup) {
225  G4cout << "Graphics systems deleted." << G4endl;
226  G4cout << "Visualization Manager deleting..." << G4endl;
227  }
228  for (i = 0; i < fMessengerList.size (); ++i) {
229  delete fMessengerList[i];
230  }
231  for (i = 0; i < fDirectoryList.size (); ++i) {
232  delete fDirectoryList[i];
233  }
234 
235  delete fpDigiFilterMgr;
236  delete fpHitFilterMgr;
237  delete fpTrajFilterMgr;
238  delete fpTrajDrawModelMgr;
239 }
240 
242  if (!fpInstance) {
244  ("G4VisManager::GetInstance",
245  "visman0002", FatalException, "VisManager not yet instantiated");
246  }
247  return fpInstance;
248 }
249 
251 
252  if (fInitialised && fVerbosity >= warnings) {
253  G4cout << "WARNING: G4VisManager::Initialise: already initialised."
254  << G4endl;
255  return;
256  }
257 
258  if (fVerbosity >= startup) {
259  G4cout << "Visualization Manager initialising..." << G4endl;
260  }
261 
262  if (fVerbosity >= parameters) {
263  G4cout <<
264  "\nYou have instantiated your own Visualization Manager, inheriting"
265  "\n G4VisManager and implementing RegisterGraphicsSystems(), in which"
266  "\n you should, normally, instantiate drivers which do not need"
267  "\n external packages or libraries, and, optionally, drivers under"
268  "\n control of environment variables."
269  "\n Also you should implement RegisterModelFactories()."
270  "\n See visualization/management/include/G4VisExecutive.hh/icc, for example."
271  "\n In your main() you will have something like:"
272  "\n #ifdef G4VIS_USE"
273  "\n G4VisManager* visManager = new G4VisExecutive;"
274  "\n visManager -> SetVerboseLevel (Verbose);"
275  "\n visManager -> Initialize ();"
276  "\n #endif"
277  "\n (Don't forget to delete visManager;)"
278  "\n"
279  << G4endl;
280  }
281 
282  if (fVerbosity >= startup) {
283  G4cout << "Registering graphics systems..." << G4endl;
284  }
285 
287 
288  if (fVerbosity >= startup) {
289  G4cout <<
290  "\nYou have successfully registered the following graphics systems."
291  << G4endl;
293  G4cout << G4endl;
294  }
295 
296  // Make command directories for commands instantiated in the
297  // modeling subcategory...
298  G4UIcommand* directory;
299  directory = new G4UIdirectory ("/vis/modeling/");
300  directory -> SetGuidance ("Modeling commands.");
301  fDirectoryList.push_back (directory);
302  directory = new G4UIdirectory ("/vis/modeling/trajectories/");
303  directory -> SetGuidance ("Trajectory model commands.");
304  fDirectoryList.push_back (directory);
305  directory = new G4UIdirectory ("/vis/modeling/trajectories/create/");
306  directory -> SetGuidance ("Create trajectory models and messengers.");
307  fDirectoryList.push_back (directory);
308 
309  // Filtering command directory
310  directory = new G4UIdirectory ("/vis/filtering/");
311  directory -> SetGuidance ("Filtering commands.");
312  fDirectoryList.push_back (directory);
313  directory = new G4UIdirectory ("/vis/filtering/trajectories/");
314  directory -> SetGuidance ("Trajectory filtering commands.");
315  fDirectoryList.push_back (directory);
316  directory = new G4UIdirectory ("/vis/filtering/trajectories/create/");
317  directory -> SetGuidance ("Create trajectory filters and messengers.");
318  fDirectoryList.push_back (directory);
319  directory = new G4UIdirectory ("/vis/filtering/hits/");
320  directory -> SetGuidance ("Hit filtering commands.");
321  fDirectoryList.push_back (directory);
322  directory = new G4UIdirectory ("/vis/filtering/hits/create/");
323  directory -> SetGuidance ("Create hit filters and messengers.");
324  fDirectoryList.push_back (directory);
325  directory = new G4UIdirectory ("/vis/filtering/digi/");
326  directory -> SetGuidance ("Digi filtering commands.");
327  fDirectoryList.push_back (directory);
328  directory = new G4UIdirectory ("/vis/filtering/digi/create/");
329  directory -> SetGuidance ("Create digi filters and messengers.");
330  fDirectoryList.push_back (directory);
331 
333 
334  if (fVerbosity >= startup) {
335  G4cout << "Registering model factories..." << G4endl;
336  }
337 
339 
340  if (fVerbosity >= startup) {
341  G4cout <<
342  "\nYou have successfully registered the following model factories."
343  << G4endl;
345  G4cout << G4endl;
346  }
347 
348  if (fVerbosity >= startup) {
350  G4cout << G4endl;
351  }
352 
353  if (fVerbosity >= startup) {
355  G4cout << G4endl;
356  }
357 
358  fInitialised = true;
359 }
360 
362 
363  // Instantiate individual messengers/commands (often - but not
364  // always - one command per messenger).
365 
366  G4UIcommand* directory;
367 
368  // *Basic* top level commands were instantiated in the constructor
369  // so that they can be used immediately after instantiation of the
370  // vis manager. Other top level and lower level commands are
371  // instantiated here.
372 
373  // Other top level commands...
378 
379  // Compound commands...
385 
386  directory = new G4UIdirectory ("/vis/geometry/");
387  directory -> SetGuidance("Operations on vis attributes of Geant4 geometry.");
388  fDirectoryList.push_back (directory);
391 
392  directory = new G4UIdirectory ("/vis/geometry/set/");
393  directory -> SetGuidance("Set vis attributes of Geant4 geometry.");
394  fDirectoryList.push_back (directory);
404 
405 #ifdef G4MULTITHREADED
406  directory = new G4UIdirectory ("/vis/multithreading/");
407  directory -> SetGuidance("Commands unique to multithreading mode.");
408  fDirectoryList.push_back (directory);
409  RegisterMessenger(new G4VisCommandMultithreadingActionOnEventQueueFull);
410  RegisterMessenger(new G4VisCommandMultithreadingMaxEventQueueSize);
411 #endif
412 
413  directory = new G4UIdirectory ("/vis/set/");
414  directory -> SetGuidance
415  ("Set quantities for use in future commands where appropriate.");
416  fDirectoryList.push_back (directory);
423 
424  directory = new G4UIdirectory ("/vis/scene/");
425  directory -> SetGuidance ("Operations on Geant4 scenes.");
426  fDirectoryList.push_back (directory);
434 
435  directory = new G4UIdirectory ("/vis/scene/add/");
436  directory -> SetGuidance ("Add model to current scene.");
437  fDirectoryList.push_back (directory);
460 
461  directory = new G4UIdirectory ("/vis/sceneHandler/");
462  directory -> SetGuidance ("Operations on Geant4 scene handlers.");
463  fDirectoryList.push_back (directory);
468 
469  directory = new G4UIdirectory ("/vis/touchable/");
470  directory -> SetGuidance ("Operations on touchables.");
471  fDirectoryList.push_back (directory);
473 
474  directory = new G4UIdirectory ("/vis/touchable/set/");
475  directory -> SetGuidance ("Set vis attributes of current touchable.");
476  fDirectoryList.push_back (directory);
478 
479  directory = new G4UIdirectory ("/vis/viewer/");
480  directory -> SetGuidance ("Operations on Geant4 viewers.");
481  fDirectoryList.push_back (directory);
493 #ifndef WIN32
495 #endif
506 
507  directory = new G4UIdirectory ("/vis/viewer/default/");
508  directory -> SetGuidance("Set default values for future viewers.");
509  fDirectoryList.push_back (directory);
512 
513  directory = new G4UIdirectory ("/vis/viewer/set/");
514  directory -> SetGuidance ("Set view parameters of current viewer.");
515  fDirectoryList.push_back (directory);
517 
518  // List manager commands
523 
524  // Trajectory filter manager commands
529 
530  // Hit filter manager commands
535 
536  // Digi filter manager commands
541 }
542 
544  if (IsValidView ()) {
545  SetConcreteInstance(this);
546  if (fVerbosity >= confirmations) {
547  G4cout << "G4VisManager::Enable: visualization enabled." << G4endl;
548  }
549  if (fVerbosity >= warnings) {
550  auto nKeptEvents =
552  G4cout <<
553  "There are " << nKeptEvents << " kept events."
554  "\n \"/vis/reviewKeptEvents\" to review them one by one."
555  "\n \"/vis/viewer/flush\" or \"/vis/viewer/rebuild\" to see them accumulated."
556  << G4endl;
557  }
558  }
559  else {
560  if (fVerbosity >= warnings) {
561  G4cout <<
562  "G4VisManager::Enable: WARNING: visualization remains disabled for"
563  "\n above reasons. Rectifying with valid vis commands will"
564  "\n automatically enable."
565  << G4endl;
566  }
567  }
568 }
569 
572  if (fVerbosity >= confirmations) {
573  G4cout <<
574  "G4VisManager::Disable: visualization disabled."
575  "\n The pointer returned by GetConcreteInstance will be zero."
576  "\n Note that it will become enabled after some valid vis commands."
577  << G4endl;
578  }
579  if (fVerbosity >= warnings) {
580  G4int currentTrajectoryType =
582  if (currentTrajectoryType > 0) {
583  G4cout <<
584  "You may wish to disable trajectory production too:"
585  "\n \"/tracking/storeTrajectory 0\""
586  "\nbut don't forget to re-enable with"
587  "\n \"/vis/enable\""
588  "\n \"/tracking/storeTrajectory " << currentTrajectoryType << "\" (for your case)."
589  << G4endl;
590  }
591  }
592 }
593 
595  G4int nSystems = fAvailableGraphicsSystems.size ();
596  if (nSystems == 0) {
597  if (fVerbosity >= warnings) {
598  G4cout << "G4VisManager::GetAvailableGraphicsSystems: WARNING: no"
599  "\n graphics system available!"
600  "\n 1) Did you have environment variables G4VIS_BUILD_xxxx_DRIVER set"
601  "\n when you compiled/built the visualization code?"
602  "\n 2) Did you instantiate your own Visualization Manager and forget"
603  "\n to implement RegisterGraphicsSystems correctly?"
604  "\n 3) You can register your own graphics system, e.g.,"
605  "\n visManager->RegisterGraphicsSystem(new MyGraphicsSystem);)"
606  "\n after instantiating your vis manager and before"
607  "\n visManager->Initialize()."
608  << G4endl;
609  }
610  }
612 }
613 
615  G4bool happy = true;
616  if (pSystem) {
617  fAvailableGraphicsSystems.push_back (pSystem);
618  if (fVerbosity >= confirmations) {
619  G4cout << "G4VisManager::RegisterGraphicsSystem: "
620  << pSystem -> GetName ();
621  if (pSystem -> GetNickname () != "") {
622  G4cout << " (" << pSystem -> GetNickname () << ")";
623  }
624  G4cout << " registered." << G4endl;
625  }
626  }
627  else {
628  if (fVerbosity >= errors) {
629  G4cout << "G4VisManager::RegisterGraphicsSystem: null pointer!"
630  << G4endl;
631  }
632  happy=false;
633  }
634  return happy;
635 }
636 
637 const G4VTrajectoryModel*
639 {
640  assert (0 != fpTrajDrawModelMgr);
641 
643 
644  if (0 == model) {
645  // No model was registered with the trajectory model manager.
646  // Use G4TrajectoryDrawByCharge as a fallback.
648  if (fVerbosity >= warnings) {
649  G4cout<<"G4VisManager: Using G4TrajectoryDrawByCharge as fallback trajectory model."<<G4endl;
650  G4cout<<"See commands in /vis/modeling/trajectories/ for other options."<<G4endl;
651  }
652  }
653 
654  model = fpTrajDrawModelMgr->Current();
655  assert (0 != model); // Should definitely exist now
656 
657  return model;
658 }
659 
661 {
663 }
664 
665 void
667 {
668  fpTrajDrawModelMgr->Register(factory);
669 }
670 
672 {
673  fpTrajFilterMgr->Register(model);
674 }
675 
676 void
678 {
679  fpTrajFilterMgr->Register(factory);
680 }
681 
683 {
684  fpHitFilterMgr->Register(model);
685 }
686 
687 void
689 {
690  fpHitFilterMgr->Register(factory);
691 }
692 
694 {
695  fpDigiFilterMgr->Register(model);
696 }
697 
698 void
700 {
701  fpDigiFilterMgr->Register(factory);
702 }
703 
705 {
707 }
708 
709 void G4VisManager::BeginDraw (const G4Transform3D& objectTransform)
710 {
711 #ifdef G4MULTITHREADED
712  if (G4Threading::IsWorkerThread()) return;
713 #endif
715  if (fDrawGroupNestingDepth > 1) {
717  ("G4VisManager::BeginDraw",
718  "visman0008", JustWarning,
719  "Nesting detected. It is illegal to nest Begin/EndDraw."
720  "\n Ignored");
721  return;
722  }
723  if (IsValidView ()) {
725  fpSceneHandler -> BeginPrimitives (objectTransform);
726  fIsDrawGroup = true;
727  }
728 }
729 
731 {
732 #ifdef G4MULTITHREADED
733  if (G4Threading::IsWorkerThread()) return;
734 #endif
736  if (fDrawGroupNestingDepth != 0) {
738  return;
739  }
740  if (IsValidView ()) {
741  fpSceneHandler -> EndPrimitives ();
742  }
743  fIsDrawGroup = false;
744 }
745 
746 void G4VisManager::BeginDraw2D (const G4Transform3D& objectTransform)
747 {
748 #ifdef G4MULTITHREADED
749  if (G4Threading::IsWorkerThread()) return;
750 #endif
752  if (fDrawGroupNestingDepth > 1) {
754  ("G4VisManager::BeginDraw2D",
755  "visman0009", JustWarning,
756  "Nesting detected. It is illegal to nest Begin/EndDraw2D."
757  "\n Ignored");
758  return;
759  }
760  if (IsValidView ()) {
762  fpSceneHandler -> BeginPrimitives2D (objectTransform);
763  fIsDrawGroup = true;
764  }
765 }
766 
768 {
769 #ifdef G4MULTITHREADED
770  if (G4Threading::IsWorkerThread()) return;
771 #endif
773  if (fDrawGroupNestingDepth != 0) {
775  return;
776  }
777  if (IsValidView ()) {
778  fpSceneHandler -> EndPrimitives2D ();
779  }
780  fIsDrawGroup = false;
781 }
782 
783 template <class T> void G4VisManager::DrawT
784 (const T& graphics_primitive, const G4Transform3D& objectTransform) {
785 #ifdef G4MULTITHREADED
786  if (G4Threading::IsWorkerThread()) return;
787 #endif
788  if (fIsDrawGroup) {
789  if (objectTransform != fpSceneHandler->GetObjectTransformation()) {
791  ("G4VSceneHandler::DrawT",
792  "visman0010", FatalException,
793  "Different transform detected in Begin/EndDraw group.");
794  }
795  fpSceneHandler -> AddPrimitive (graphics_primitive);
796  } else {
797  if (IsValidView ()) {
798  ClearTransientStoreIfMarked();
799  fpSceneHandler -> BeginPrimitives (objectTransform);
800  fpSceneHandler -> AddPrimitive (graphics_primitive);
801  fpSceneHandler -> EndPrimitives ();
802  }
803  }
804 }
805 
806 template <class T> void G4VisManager::DrawT2D
807 (const T& graphics_primitive, const G4Transform3D& objectTransform) {
808 #ifdef G4MULTITHREADED
809  if (G4Threading::IsWorkerThread()) return;
810 #endif
811  if (fIsDrawGroup) {
812  if (objectTransform != fpSceneHandler->GetObjectTransformation()) {
814  ("G4VSceneHandler::DrawT",
815  "visman0011", FatalException,
816  "Different transform detected in Begin/EndDraw2D group.");
817  }
818  fpSceneHandler -> AddPrimitive (graphics_primitive);
819  } else {
820  if (IsValidView ()) {
821  ClearTransientStoreIfMarked();
822  fpSceneHandler -> BeginPrimitives2D (objectTransform);
823  fpSceneHandler -> AddPrimitive (graphics_primitive);
824  fpSceneHandler -> EndPrimitives2D ();
825  }
826  }
827 }
828 
829 void G4VisManager::Draw (const G4Circle& circle,
830  const G4Transform3D& objectTransform)
831 {
832  DrawT (circle, objectTransform);
833 }
834 
835 void G4VisManager::Draw (const G4Polyhedron& polyhedron,
836  const G4Transform3D& objectTransform)
837 {
838  DrawT (polyhedron, objectTransform);
839 }
840 
841 void G4VisManager::Draw (const G4Polyline& line,
842  const G4Transform3D& objectTransform)
843 {
844  DrawT (line, objectTransform);
845 }
846 
847 void G4VisManager::Draw (const G4Polymarker& polymarker,
848  const G4Transform3D& objectTransform)
849 {
850  DrawT (polymarker, objectTransform);
851 }
852 
853 void G4VisManager::Draw (const G4Scale& scale,
854  const G4Transform3D& objectTransform)
855 {
856  DrawT (scale, objectTransform);
857 }
858 
859 void G4VisManager::Draw (const G4Square& square,
860  const G4Transform3D& objectTransform)
861 {
862  DrawT (square, objectTransform);
863 }
864 
865 void G4VisManager::Draw (const G4Text& text,
866  const G4Transform3D& objectTransform)
867 {
868  DrawT (text, objectTransform);
869 }
870 
871 void G4VisManager::Draw2D (const G4Circle& circle,
872  const G4Transform3D& objectTransform)
873 {
874  DrawT2D (circle, objectTransform);
875 }
876 
877 void G4VisManager::Draw2D (const G4Polyhedron& polyhedron,
878  const G4Transform3D& objectTransform)
879 {
880  DrawT2D (polyhedron, objectTransform);
881 }
882 
884  const G4Transform3D& objectTransform)
885 {
886  DrawT2D (line, objectTransform);
887 }
888 
889 void G4VisManager::Draw2D (const G4Polymarker& polymarker,
890  const G4Transform3D& objectTransform)
891 {
892  DrawT2D (polymarker, objectTransform);
893 }
894 
895 void G4VisManager::Draw2D (const G4Square& square,
896  const G4Transform3D& objectTransform)
897 {
898  DrawT2D (square, objectTransform);
899 }
900 
901 void G4VisManager::Draw2D (const G4Text& text,
902  const G4Transform3D& objectTransform)
903 {
904  DrawT2D (text, objectTransform);
905 }
906 
907 void G4VisManager::Draw (const G4VHit& hit) {
908 #ifdef G4MULTITHREADED
909  if (G4Threading::IsWorkerThread()) return;
910 #endif
911  if (fIsDrawGroup) {
912  fpSceneHandler -> AddCompound (hit);
913  } else {
914  if (IsValidView ()) {
916  fpSceneHandler -> AddCompound (hit);
917  }
918  }
919 }
920 
921 void G4VisManager::Draw (const G4VDigi& digi) {
922 #ifdef G4MULTITHREADED
923  if (G4Threading::IsWorkerThread()) return;
924 #endif
925  if (fIsDrawGroup) {
926  fpSceneHandler -> AddCompound (digi);
927  } else {
928  if (IsValidView ()) {
930  fpSceneHandler -> AddCompound (digi);
931  }
932  }
933 }
934 
935 void G4VisManager::Draw (const G4VTrajectory& traj) {
936 #ifdef G4MULTITHREADED
937  if (G4Threading::IsWorkerThread()) return;
938 #endif
939  // A trajectory needs a trajectories model to provide G4Atts, etc.
940  static G4TrajectoriesModel trajectoriesModel;
941  trajectoriesModel.SetCurrentTrajectory(&traj);
943 #ifdef G4MULTITHREADED
946  }
947 #endif
948  const G4Run* currentRun = runManager->GetCurrentRun();
949  if (currentRun) {
950  trajectoriesModel.SetRunID(currentRun->GetRunID());
951  }
952  const G4Event* currentEvent =
954  if (currentEvent) {
955  trajectoriesModel.SetEventID(currentEvent->GetEventID());
956  }
957  if (fIsDrawGroup) {
958  fpSceneHandler -> SetModel (&trajectoriesModel);
959  fpSceneHandler -> AddCompound (traj);
960  fpSceneHandler -> SetModel (0);
961  } else {
962  if (IsValidView ()) {
964  fpSceneHandler -> SetModel (&trajectoriesModel);
965  fpSceneHandler -> AddCompound (traj);
966  fpSceneHandler -> SetModel (0);
967  }
968  }
969 }
970 
971 void G4VisManager::Draw (const G4LogicalVolume& logicalVol,
972  const G4VisAttributes& attribs,
973  const G4Transform3D& objectTransform) {
974 #ifdef G4MULTITHREADED
975  if (G4Threading::IsWorkerThread()) return;
976 #endif
977  // Find corresponding solid.
978  G4VSolid* pSol = logicalVol.GetSolid ();
979  Draw (*pSol, attribs, objectTransform);
980 }
981 
982 void G4VisManager::Draw (const G4VSolid& solid,
983  const G4VisAttributes& attribs,
984  const G4Transform3D& objectTransform) {
985 #ifdef G4MULTITHREADED
986  if (G4Threading::IsWorkerThread()) return;
987 #endif
988  if (fIsDrawGroup) {
989  fpSceneHandler -> PreAddSolid (objectTransform, attribs);
991  fpSceneHandler -> PostAddSolid ();
992  } else {
993  if (IsValidView ()) {
995  fpSceneHandler -> PreAddSolid (objectTransform, attribs);
997  fpSceneHandler -> PostAddSolid ();
998  }
999  }
1000 }
1001 
1002 void G4VisManager::Draw (const G4VPhysicalVolume& physicalVol,
1003  const G4VisAttributes& attribs,
1004  const G4Transform3D& objectTransform) {
1005 #ifdef G4MULTITHREADED
1006  if (G4Threading::IsWorkerThread()) return;
1007 #endif
1008  // Note: It is tempting to use a temporary model here, as for
1009  // trajectories, in order to get at the G4Atts of the physical
1010  // volume. I tried it (JA). But it's not easy to pass the
1011  // vis attributes. Also other aspects of the model seem not to
1012  // be properly set up. So, the idea has been abandoned for the time
1013  // being. The model pointer will be null. So when picking there
1014  // will be no G4Atts from this physical volume.
1015  //
1016  // If this is called from DrawHit, for example, the user may G4Atts to the
1017  // hit and these will be available with "/vis/scene/add/hits".
1018  //
1019  // Find corresponding logical volume and solid.
1020  G4LogicalVolume* pLV = physicalVol.GetLogicalVolume ();
1021  G4VSolid* pSol = pLV -> GetSolid ();
1022  Draw (*pSol, attribs, objectTransform);
1023 }
1024 
1026  if (!fInitialised) Initialise ();
1027  if (fpGraphicsSystem) {
1028  G4VSceneHandler* pSceneHandler =
1030  if (pSceneHandler) {
1031  fAvailableSceneHandlers.push_back (pSceneHandler);
1032  fpSceneHandler = pSceneHandler; // Make current.
1033  }
1034  else {
1035  if (fVerbosity >= errors) {
1036  G4cout << "ERROR in G4VisManager::CreateSceneHandler during "
1037  << fpGraphicsSystem -> GetName ()
1038  << " scene handler creation.\n No action taken."
1039  << G4endl;
1040  }
1041  }
1042  }
1043  else PrintInvalidPointers ();
1044 }
1045 
1047 (const G4String& name, const G4String& XGeometry)
1048 {
1049 
1050  if (!fInitialised) Initialise ();
1051 
1052  if (!fpSceneHandler) {
1053  PrintInvalidPointers ();
1054  return;
1055  }
1056 
1057  G4VViewer* p = fpGraphicsSystem -> CreateViewer (*fpSceneHandler, name);
1058 
1059  if (!p) {
1060  if (fVerbosity >= errors) {
1061  G4cerr << "ERROR in G4VisManager::CreateViewer during "
1062  << fpGraphicsSystem -> GetName ()
1063  << " viewer creation.\n No action taken."
1064  << G4endl;
1065  }
1066  return;
1067  }
1068 
1069  if (p -> GetViewId() < 0) {
1070  if (fVerbosity >= errors) {
1071  G4cerr << "ERROR in G4VisManager::CreateViewer during "
1072  << fpGraphicsSystem -> GetName ()
1073  << " viewer initialisation.\n No action taken."
1074  << G4endl;
1075  }
1076  return;
1077  }
1078 
1079  // Viewer is created, now we can set geometry parameters
1080  // Before 12/2008, it was done in G4VViewer.cc but it did not have to be there!
1081 
1082  G4ViewParameters initialvp = p -> GetViewParameters();
1083  initialvp.SetXGeometryString(XGeometry); //parse string and store parameters
1084  p -> SetViewParameters(initialvp);
1085  p -> Initialise (); // (Viewer itself may change view parameters further.)
1086 
1087  fpViewer = p; // Make current.
1088  fpSceneHandler -> AddViewerToList (fpViewer);
1089  fpSceneHandler -> SetCurrentViewer (fpViewer);
1090  if (fVerbosity >= confirmations) {
1091  G4cout << "G4VisManager::CreateViewer: new viewer created."
1092  << G4endl;
1093  }
1094 
1095  const G4ViewParameters& vp = fpViewer->GetViewParameters();
1096  if (fVerbosity >= parameters) {
1097  G4cout << " view parameters are:\n " << vp << G4endl;
1098  }
1099 
1100  if (vp.IsCulling () && vp.IsCullingInvisible ()) {
1101  static G4bool warned = false;
1102  if (fVerbosity >= confirmations) {
1103  if (!warned) {
1104  G4cout <<
1105  "NOTE: objects with visibility flag set to \"false\""
1106  " will not be drawn!"
1107  "\n \"/vis/viewer/set/culling global false\" to Draw such objects."
1108  "\n Also see other \"/vis/viewer/set\" commands."
1109  << G4endl;
1110  warned = true;
1111  }
1112  }
1113  }
1114  if (vp.IsCullingCovered ()) {
1115  static G4bool warned = false;
1116  if (fVerbosity >= warnings) {
1117  if (!warned) {
1118  G4cout <<
1119  "WARNING: covered objects in solid mode will not be rendered!"
1120  "\n \"/vis/viewer/set/culling coveredDaughters false\" to reverse this."
1121  "\n Also see other \"/vis/viewer/set\" commands."
1122  << G4endl;
1123  warned = true;
1124  }
1125  }
1126  }
1127 }
1128 
1130  if (fVerbosity >= confirmations) {
1131  G4cout << "G4VisManager::GeometryHasChanged() called." << G4endl;
1132  }
1133 
1134  // Change the world...
1135  G4VPhysicalVolume* pWorld =
1137  -> GetNavigatorForTracking () -> GetWorldVolume ();
1138  if (!pWorld) {
1139  if (fVerbosity >= warnings) {
1140  G4cout << "WARNING: There is no world volume!" << G4endl;
1141  }
1142  }
1143 
1144  // Check scenes.
1145  G4SceneList& sceneList = fSceneList;
1146  G4int iScene, nScenes = sceneList.size ();
1147  for (iScene = 0; iScene < nScenes; iScene++) {
1148  G4Scene* pScene = sceneList [iScene];
1149  std::vector<G4Scene::Model>& modelList = pScene -> SetRunDurationModelList ();
1150  if (modelList.size ()) {
1151  G4bool modelInvalid;
1152  do { // Remove, if required, one at a time.
1153  modelInvalid = false;
1154  std::vector<G4Scene::Model>::iterator iterModel;
1155  for (iterModel = modelList.begin();
1156  iterModel != modelList.end();
1157  ++iterModel) {
1158  modelInvalid = !(iterModel->fpModel->Validate(fVerbosity>=warnings));
1159  if (modelInvalid) {
1160  // Model invalid - remove and break.
1161  if (fVerbosity >= warnings) {
1162  G4cout << "WARNING: Model \""
1163  << iterModel->fpModel->GetGlobalDescription ()
1164  <<
1165  "\" is no longer valid - being removed\n from scene \""
1166  << pScene -> GetName () << "\""
1167  << G4endl;
1168  }
1169  modelList.erase (iterModel);
1170  break;
1171  }
1172  }
1173  } while (modelInvalid);
1174 
1175  if (modelList.size () == 0) {
1176  if (fVerbosity >= warnings) {
1177  G4cout << "WARNING: No models left in this scene \""
1178  << pScene -> GetName ()
1179  << "\"."
1180  << G4endl;
1181  }
1182  }
1183  else {
1184  pScene->CalculateExtent();
1186  ApplyCommand (G4String("/vis/scene/notifyHandlers " + pScene->GetName()));
1187  }
1188  }
1189  }
1190 
1191  // Check the manager's current scene...
1192  if (fpScene && fpScene -> GetRunDurationModelList ().size () == 0) {
1193  if (fVerbosity >= warnings) {
1194  G4cout << "WARNING: The current scene \""
1195  << fpScene -> GetName ()
1196  << "\" has no models."
1197  << G4endl;
1198  }
1199  }
1200 }
1201 
1203 
1204  if (fVerbosity >= confirmations) {
1205  G4cout << "G4VisManager::NotifyHandler() called." << G4endl;
1206  }
1207 
1208  // Check scenes.
1209  G4SceneList& sceneList = fSceneList;
1210  G4int iScene, nScenes = sceneList.size ();
1211  for (iScene = 0; iScene < nScenes; iScene++) {
1212  G4Scene* pScene = sceneList [iScene];
1213  std::vector<G4Scene::Model>& modelList = pScene -> SetRunDurationModelList ();
1214 
1215  if (modelList.size ()) {
1216  pScene->CalculateExtent();
1218  ApplyCommand (G4String("/vis/scene/notifyHandlers " + pScene->GetName()));
1219  }
1220  }
1221 
1222  // Check the manager's current scene...
1223  if (fpScene && fpScene -> GetRunDurationModelList ().size () == 0) {
1224  if (fVerbosity >= warnings) {
1225  G4cout << "WARNING: The current scene \""
1226  << fpScene -> GetName ()
1227  << "\" has no models."
1228  << G4endl;
1229  }
1230  }
1231 }
1232 
1234 {
1235  return fpTrajFilterMgr->Accept(trajectory);
1236 }
1237 
1239 {
1240  return fpHitFilterMgr->Accept(hit);
1241 }
1242 
1244 {
1245  return fpDigiFilterMgr->Accept(digi);
1246 }
1247 
1249 {
1250  G4bool visible(true);
1251 
1252  // See if trajectory passes filter
1253  G4bool passed = FilterTrajectory(trajectory);
1254 
1255  if (!passed) {
1256  // Draw invisible trajectory if trajectory failed filter and
1257  // are filtering in soft mode
1258  if (fpTrajFilterMgr->GetMode() == FilterMode::Soft) visible = false;
1259  else {return;}
1260  }
1261 
1262  // Go on to draw trajectory
1263  assert (0 != fpTrajDrawModelMgr);
1264 
1265  const G4VTrajectoryModel* trajectoryModel = CurrentTrajDrawModel();
1266 
1267  assert (0 != trajectoryModel); // Should exist
1268 
1269  if (IsValidView()) {
1270  trajectoryModel->Draw(trajectory, visible);
1271  }
1272 }
1273 
1275 (const G4String& name,
1276  G4VUserVisAction* pVisAction,
1277  const G4VisExtent& extent) {
1278  fRunDurationUserVisActions.push_back(UserVisAction(name,pVisAction));
1279  if (extent.GetExtentRadius() > 0.) {
1280  fUserVisActionExtents[pVisAction] = extent;
1281  } else {
1282  if (fVerbosity >= warnings) {
1283  G4cout <<
1284  "WARNING: No extent set for user vis action \"" << name << "\"."
1285  << G4endl;
1286  }
1287  }
1288 }
1289 
1291 (const G4String& name,
1292  G4VUserVisAction* pVisAction,
1293  const G4VisExtent& extent) {
1294  fEndOfEventUserVisActions.push_back(UserVisAction(name,pVisAction));
1295  if (extent.GetExtentRadius() > 0.) {
1296  fUserVisActionExtents[pVisAction] = extent;
1297  } else {
1298  if (fVerbosity >= warnings) {
1299  G4cout <<
1300  "WARNING: No extent set for user vis action \"" << name << "\"."
1301  << G4endl;
1302  }
1303  }
1304 }
1305 
1307 (const G4String& name,
1308  G4VUserVisAction* pVisAction,
1309  const G4VisExtent& extent) {
1310  fEndOfRunUserVisActions.push_back(UserVisAction(name,pVisAction));
1311  if (extent.GetExtentRadius() > 0.) {
1312  fUserVisActionExtents[pVisAction] = extent;
1313  } else {
1314  if (fVerbosity >= warnings) {
1315  G4cout <<
1316  "WARNING: No extent set for user vis action \"" << name << "\"."
1317  << G4endl;
1318  }
1319  }
1320 }
1321 
1323  if (pScene != fpScene) {
1324  // A change of scene. Therefore reset transients drawn flags. All
1325  // memory of previous transient proceessing thereby erased...
1327  }
1328  fpScene = pScene;
1329 }
1330 
1332  fpGraphicsSystem = pSystem;
1333  if (fVerbosity >= confirmations) {
1334  G4cout << "G4VisManager::SetCurrentGraphicsSystem: system now "
1335  << pSystem -> GetName () << G4endl;
1336  }
1337  // If current scene handler is of same graphics system, leave unchanged.
1338  // Else find the most recent scene handler of same graphics system.
1339  // Or clear pointers.
1340  if (!(fpSceneHandler && fpSceneHandler -> GetGraphicsSystem () == pSystem)) {
1341  const G4SceneHandlerList& sceneHandlerList = fAvailableSceneHandlers;
1342  G4int nSH = sceneHandlerList.size (); // No. of scene handlers.
1343  G4int iSH;
1344  for (iSH = nSH - 1; iSH >= 0; iSH--) {
1345  if (sceneHandlerList [iSH] -> GetGraphicsSystem () == pSystem) break;
1346  }
1347  if (iSH >= 0) {
1348  fpSceneHandler = sceneHandlerList [iSH];
1349  if (fVerbosity >= confirmations) {
1350  G4cout << " Scene Handler now "
1351  << fpSceneHandler -> GetName () << G4endl;
1352  }
1353  if (fpScene != fpSceneHandler -> GetScene ()) {
1354  fpScene = fpSceneHandler -> GetScene ();
1355  if (fVerbosity >= confirmations) {
1356  G4cout << " Scene now \""
1357  << fpScene -> GetName () << "\"" << G4endl;
1358  }
1359  }
1360  const G4ViewerList& viewerList = fpSceneHandler -> GetViewerList ();
1361  if (viewerList.size ()) {
1362  fpViewer = viewerList [0];
1363  if (fVerbosity >= confirmations) {
1364  G4cout << " Viewer now " << fpViewer -> GetName () << G4endl;
1365  }
1366  }
1367  else {
1368  fpViewer = 0;
1369  }
1370  }
1371  else {
1372  fpSceneHandler = 0;
1373  fpViewer = 0;
1374  }
1375  }
1376 }
1377 
1379  fpSceneHandler = pSceneHandler;
1380  if (fVerbosity >= confirmations) {
1381  G4cout << "G4VisManager::SetCurrentSceneHandler: scene handler now \""
1382  << pSceneHandler -> GetName () << "\"" << G4endl;
1383  }
1384  if (fpScene != fpSceneHandler -> GetScene ()) {
1385  fpScene = fpSceneHandler -> GetScene ();
1386  if (fVerbosity >= confirmations) {
1387  G4cout << " Scene now \""
1388  << fpScene -> GetName () << "\"" << G4endl;
1389  }
1390  }
1391  if (fpGraphicsSystem != pSceneHandler -> GetGraphicsSystem ()) {
1392  fpGraphicsSystem = pSceneHandler -> GetGraphicsSystem ();
1393  if (fVerbosity >= confirmations) {
1394  G4cout << " Graphics system now \""
1395  << fpGraphicsSystem -> GetName () << "\"" << G4endl;
1396  }
1397  }
1398  const G4ViewerList& viewerList = fpSceneHandler -> GetViewerList ();
1399  G4int nViewers = viewerList.size ();
1400  if (nViewers) {
1401  G4int iViewer;
1402  for (iViewer = 0; iViewer < nViewers; iViewer++) {
1403  if (fpViewer == viewerList [iViewer]) break;
1404  }
1405  if (iViewer >= nViewers) {
1406  fpViewer = viewerList [0];
1407  if (fVerbosity >= confirmations) {
1408  G4cout << " Viewer now \"" << fpViewer -> GetName () << "\""
1409  << G4endl;
1410  }
1411  }
1412  if (!IsValidView ()) {
1413  if (fVerbosity >= warnings) {
1414  G4cout <<
1415  "WARNING: Problem setting scene handler - please report circumstances."
1416  << G4endl;
1417  }
1418  }
1419  }
1420  else {
1421  fpViewer = 0;
1422  if (fVerbosity >= warnings) {
1423  G4cout <<
1424  "WARNING: No viewers for this scene handler - please create one."
1425  << G4endl;
1426  }
1427  }
1428 }
1429 
1431  fpViewer = pViewer;
1432  if (fVerbosity >= confirmations) {
1433  G4cout << "G4VisManager::SetCurrentViewer: viewer now "
1434  << pViewer -> GetName ()
1435  << G4endl;
1436  }
1437  fpSceneHandler = fpViewer -> GetSceneHandler ();
1438  if (!fpSceneHandler) {
1439  if (fVerbosity >= warnings) {
1440  G4cout <<
1441  "WARNING: No scene handler for this viewer - please create one."
1442  << G4endl;
1443  }
1444  return;
1445  }
1446  fpViewer->SetView();
1447  fpSceneHandler -> SetCurrentViewer (pViewer);
1448  fpScene = fpSceneHandler -> GetScene ();
1449  fpGraphicsSystem = fpSceneHandler -> GetGraphicsSystem ();
1450  if (!IsValidView ()) {
1451  if (fVerbosity >= warnings) {
1452  G4cout <<
1453  "WARNING: Problem setting viewer - please report circumstances."
1454  << G4endl;
1455  }
1456  }
1457 }
1458 
1460 {
1461  G4cout << "Current available graphics systems are:\n";
1462  if (fAvailableGraphicsSystems.size ()) {
1463  for (const auto& gs: fAvailableGraphicsSystems) {
1464  const G4String& name = gs->GetName();
1465  const std::vector<G4String>& nicknames = gs->GetNicknames();
1466  if (verbosity <= warnings) {
1467  // Brief output
1468  G4cout << name << " (";
1469  for (size_t i = 0; i < nicknames.size(); ++i) {
1470  if (i != 0) {
1471  G4cout << ", ";
1472  }
1473  G4cout << nicknames[i];
1474  }
1475  G4cout << ')';
1476  } else {
1477  // Full output
1478  G4cout << *gs;
1479  }
1480  G4cout << G4endl;
1481  }
1482  } else {
1483  G4cout << "\n NONE!!! None registered - yet! Mmmmm!" << G4endl;
1484  }
1485 }
1486 
1488 {
1489  {
1490  //fpTrajDrawModelMgr->Print(G4cout);
1491  G4cout << "Registered model factories:" << G4endl;
1492  const std::vector<G4VModelFactory<G4VTrajectoryModel>*>& factoryList =
1494  if (factoryList.empty()) G4cout << " None" << G4endl;
1495  else {
1496  std::vector<G4VModelFactory<G4VTrajectoryModel>*>::const_iterator i;
1497  for (i = factoryList.begin(); i != factoryList.end(); ++i)
1498  (*i)->Print(G4cout);
1499  }
1500  const G4VisListManager<G4VTrajectoryModel>* listManager =
1502  const std::map<G4String, G4VTrajectoryModel*>& modelMap =
1503  listManager->Map();
1504  if (!modelMap.empty()) {
1505  G4cout << "\nRegistered models:" << G4endl;
1506  std::map<G4String, G4VTrajectoryModel*>::const_iterator i;
1507  for (i = modelMap.begin(); i != modelMap.end(); ++i) {
1508  G4cout << " " << i->second->Name();
1509  if (i->second == listManager->Current()) G4cout << " (Current)";
1510  G4cout << G4endl;
1511  if (verbosity >= parameters) i->second->Print(G4cout);
1512  }
1513  }
1514  }
1515 
1516  G4cout << G4endl;
1517 
1518  {
1519  //fpTrajFilterMgr->Print(G4cout);
1520  G4cout << "Registered filter factories:" << G4endl;
1521  const std::vector<G4VModelFactory<G4VFilter<G4VTrajectory> >*>&
1522  factoryList = fpTrajFilterMgr->FactoryList();
1523  if (factoryList.empty()) G4cout << " None" << G4endl;
1524  else {
1525  std::vector<G4VModelFactory<G4VFilter<G4VTrajectory> >*>::const_iterator i;
1526  for (i = factoryList.begin(); i != factoryList.end(); ++i)
1527  (*i)->Print(G4cout);
1528  }
1529  const std::vector<G4VFilter<G4VTrajectory>*>&
1530  filterList = fpTrajFilterMgr->FilterList();
1531  if (!filterList.empty()) {
1532  G4cout << "\nRegistered filters:" << G4endl;
1533  std::vector<G4VFilter<G4VTrajectory>*>::const_iterator i;
1534  for (i = filterList.begin(); i != filterList.end(); ++i) {
1535  G4cout << " " << (*i)->GetName() << G4endl;
1536  if (verbosity >= parameters) (*i)->PrintAll(G4cout);
1537  }
1538  }
1539  }
1540 }
1541 
1543 {
1544  G4cout <<
1545  "You have successfully registered the following user vis actions."
1546  << G4endl;
1547  G4cout << "Run Duration User Vis Actions:";
1548  if (fRunDurationUserVisActions.empty()) G4cout << " none" << G4endl;
1549  else {
1550  G4cout << G4endl;
1551  for (size_t i = 0; i < fRunDurationUserVisActions.size(); i++) {
1552  const G4String& name = fRunDurationUserVisActions[i].fName;
1553  G4cout << " " << name << G4endl;
1554  }
1555  }
1556 
1557  G4cout << "End of Event User Vis Actions:";
1558  if (fEndOfEventUserVisActions.empty()) G4cout << " none" << G4endl;
1559  else {
1560  G4cout << G4endl;
1561  for (size_t i = 0; i < fEndOfEventUserVisActions.size(); i++) {
1562  const G4String& name = fEndOfEventUserVisActions[i].fName;
1563  G4cout << " " << name << G4endl;
1564  }
1565  }
1566 
1567  G4cout << "End of Run User Vis Actions:";
1568  if (fEndOfRunUserVisActions.empty()) G4cout << " none" << G4endl;
1569  else {
1570  G4cout << G4endl;
1571  for (size_t i = 0; i < fEndOfRunUserVisActions.size(); i++) {
1572  const G4String& name = fEndOfRunUserVisActions[i].fName;
1573  G4cout << " " << name << G4endl;
1574  }
1575  }
1576 }
1577 
1579  G4cout <<
1580  "Some /vis commands (optionally) take a string to specify colour."
1581  "\nAvailable colours:\n ";
1582  const std::map<G4String, G4Colour>& map = G4Colour::GetMap();
1583  for (std::map<G4String, G4Colour>::const_iterator i = map.begin();
1584  i != map.end();) {
1585  G4cout << i->first;
1586  if (++i != map.end()) G4cout << ", ";
1587  }
1588  G4cout << G4endl;
1589 }
1590 
1592  if (fVerbosity >= errors) {
1593  G4cerr << "ERROR: G4VisManager::PrintInvalidPointers:";
1594  if (!fpGraphicsSystem) {
1595  G4cerr << "\n null graphics system pointer.";
1596  }
1597  else {
1598  G4cerr << "\n Graphics system is " << fpGraphicsSystem -> GetName ()
1599  << " but:";
1600  if (!fpScene)
1601  G4cerr <<
1602  "\n Null scene pointer. Use \"/vis/drawVolume\" or"
1603  " \"/vis/scene/create\".";
1604  if (!fpSceneHandler)
1605  G4cerr <<
1606  "\n Null scene handler pointer. Use \"/vis/open\" or"
1607  " \"/vis/sceneHandler/create\".";
1608  if (!fpViewer )
1609  G4cerr <<
1610  "\n Null viewer pointer. Use \"/vis/viewer/create\".";
1611  }
1612  G4cerr << G4endl;
1613  }
1614 }
1615 
1616 #ifdef G4MULTITHREADED
1617 
1618 namespace {
1619  G4bool mtRunInProgress = false;
1620  std::deque<const G4Event*> mtVisEventQueue;
1621  G4Thread* mtVisSubThread = 0;
1622  G4Mutex mtVisSubThreadMutex = G4MUTEX_INITIALIZER;
1623 }
1624 
1625 G4ThreadFunReturnType G4VisManager::G4VisSubThread(G4ThreadFunArgType p)
1626 {
1627  G4VisManager* pVisManager = (G4VisManager*)p;
1628  G4VSceneHandler* pSceneHandler = pVisManager->GetCurrentSceneHandler();
1629  if (!pSceneHandler) return 0;
1630  G4Scene* pScene = pSceneHandler->GetScene();
1631  if (!pScene) return 0;
1632  G4VViewer* pViewer = pVisManager->GetCurrentViewer();
1633  if (!pViewer) return 0;
1634 
1636 
1637 // G4cout << "G4VisManager::G4VisSubThread: thread: "
1638 // << G4Threading::G4GetThreadId() << std::endl;
1639 
1640  // Set up geometry and navigation for a thread
1643  G4Navigator* navigator =
1645  navigator->SetWorldVolume
1646  (G4MTRunManager::GetMasterRunManagerKernel()->GetCurrentWorld());
1647 
1648  pViewer->SwitchToVisSubThread();
1649 
1650  while (true) {
1651 
1652  G4MUTEXLOCK(&mtVisSubThreadMutex);
1653  G4int eventQueueSize = mtVisEventQueue.size();
1654  G4MUTEXUNLOCK(&mtVisSubThreadMutex);
1655 // G4cout << "Event queue size (A): " << eventQueueSize << G4endl;
1656 
1657  while (eventQueueSize) {
1658 
1659  G4MUTEXLOCK(&mtVisSubThreadMutex);
1660  const G4Event* event = mtVisEventQueue.front();
1661  G4MUTEXUNLOCK(&mtVisSubThreadMutex);
1662 // G4int eventID = event->GetEventID();
1663 // G4cout <<
1664 // "G4VisManager::G4VisSubThread: Vis sub-thread: Dealing with event: "
1665 // << eventID << G4endl;
1666 
1667  // Here comes the event drawing
1668  pVisManager->SetTransientsDrawnThisEvent(false);
1669  pSceneHandler->SetTransientsDrawnThisEvent(false);
1670 
1671  // We are about to draw the event (trajectories, etc.), but first we
1672  // have to clear the previous event(s) if necessary. If this event
1673  // needs to be drawn afresh, e.g., the first event or any event when
1674  // "accumulate" is not requested, the old event has to be cleared.
1675  // We have postponed this so that, for normal viewers like OGL, the
1676  // previous event(s) stay on screen until this new event comes
1677  // along. For a file-writing viewer the geometry has to be drawn.
1678  // See, for example, G4HepRepFileSceneHandler::ClearTransientStore.
1679  pVisManager->ClearTransientStoreIfMarked();
1680 
1681  // Now draw the event...
1682  pSceneHandler->DrawEvent(event);
1683  ++pVisManager->fNoOfEventsDrawnThisRun;
1684 
1685  if (pScene->GetRefreshAtEndOfEvent()) {
1686 
1687  // ShowView guarantees the view is flushed to the screen. It also
1688  // triggers other features such picking (if enabled) and allows
1689  // file-writing viewers to close the file.
1690  pViewer->ShowView();
1691  pSceneHandler->SetMarkForClearingTransientStore(true);
1692 
1693  }
1694 
1695  // Testing.
1696 // std::this_thread::sleep_for(std::chrono::seconds(5));
1697 
1698  // Then pop and release event
1699  G4MUTEXLOCK(&mtVisSubThreadMutex);
1700  mtVisEventQueue.pop_front();
1701  event->PostProcessingFinished();
1702  eventQueueSize = mtVisEventQueue.size();
1703  G4MUTEXUNLOCK(&mtVisSubThreadMutex);
1704 // G4cout << "Event queue size (B): " << eventQueueSize << G4endl;
1705  }
1706 
1707  G4MUTEXLOCK(&mtVisSubThreadMutex);
1708  G4int runInProgress = mtRunInProgress;
1709  G4MUTEXUNLOCK(&mtVisSubThreadMutex);
1710  if (!runInProgress) {
1711  // EndOfRun on master thread has signalled end of run. There is
1712  // nothing to draw so...
1713  break;
1714  }
1715 
1716  // Run still in progress but nothing to draw, so wait a while.
1717 #ifdef G4VIS_USE_STD11
1718  std::this_thread::sleep_for(std::chrono::milliseconds(100));
1719 #else
1720  G4THREADSLEEP(1);
1721 #endif
1722  }
1723 
1724  // Inform viewer that we have finished all sub-thread drawing
1725  pViewer->DoneWithVisSubThread();
1726  pViewer->MovingToMasterThread();
1727 // G4cout << "G4VisManager::G4VisSubThread: Vis sub-thread: ending" << G4endl;
1728  return /*(G4ThreadFunReturnType)*/0;
1729 }
1730 
1731 namespace {
1732  // G4Mutex visBeginOfRunMutex = G4MUTEX_INITIALIZER;
1733  // G4Mutex visBeginOfEventMutex = G4MUTEX_INITIALIZER;
1734  G4Mutex visEndOfEventMutex = G4MUTEX_INITIALIZER;
1735  // G4Mutex visEndOfRunMutex = G4MUTEX_INITIALIZER;
1736 }
1737 
1738 #endif
1739 
1741 {
1742  if (fIgnoreStateChanges) return;
1743 
1744  if (!GetConcreteInstance()) return;
1745 
1746 #ifdef G4MULTITHREADED
1747  if (G4Threading::IsWorkerThread()) return;
1748 #endif
1749 // G4cout << "G4VisManager::BeginOfRun: thread: "
1750 // << G4Threading::G4GetThreadId() << G4endl;
1751 
1752  G4RunManager* runManager = G4RunManager::GetRunManager();
1753 #ifdef G4MULTITHREADED
1755  runManager = G4MTRunManager::GetMasterRunManager();
1756  }
1757 #endif
1758 
1759  // For a fake run...
1760  G4int nEventsToBeProcessed = runManager->GetNumberOfEventsToBeProcessed();
1761  if (nEventsToBeProcessed == 0) return;
1762 
1763  fNKeepRequests = 0;
1764  fKeptLastEvent = false;
1765  fEventKeepingSuspended = false;
1766  fTransientsDrawnThisRun = false;
1769 
1770 #ifdef G4MULTITHREADED
1771 // There is a static method G4Threading::IsMultithreadedApplication()
1772 // that returns true only if G4MTRunManager is instantiated with MT
1773 // installation. Thus method returns false if G4RunManager base class is
1774 // instantiated even with the MT installation, or of course with sequential
1775 // installation.
1777 
1778  // Inform viewer that we have finished all master thread drawing for now...
1779  if (fpViewer) fpViewer->DoneWithMasterThread();
1780 
1781  // Start vis sub-thread
1782 // G4cout << "G4VisManager::BeginOfRun: Starting vis sub-thread" << G4endl;
1783  G4MUTEXLOCK(&mtVisSubThreadMutex);
1784  mtRunInProgress = true;
1785  G4MUTEXUNLOCK(&mtVisSubThreadMutex);
1786  mtVisSubThread = new G4Thread;
1787  // Launch vis thread
1788  G4THREADCREATE(mtVisSubThread,G4VisSubThread,this);
1789 
1790  // Tricky things for some viewers (e.g., Qt):
1791  // - Launch the vis thread
1792  // - Wait for the vis thread to set its QThread
1793  // - Then move current QOpenGL context (if Qt) to this Qthread
1794  // - Go ahead
1795  if (fpViewer) fpViewer->MovingToVisSubThread();
1796  }
1797 #endif
1798 }
1799 
1801 {
1802  if (fIgnoreStateChanges) return;
1803 
1804  if (!GetConcreteInstance()) return;
1805 
1806 // G4cout << "G4VisManager::BeginOfEvent: thread: "
1807 // << G4Threading::G4GetThreadId() << G4endl;
1808 
1809  // Some instructions that should NOT be in multithreaded version.
1810 #ifndef G4MULTITHREADED
1811  // These instructions are in G4VisSubThread for multithreading.
1812  fTransientsDrawnThisEvent = false;
1814 #endif
1815 }
1816 
1818 {
1819  if (fIgnoreStateChanges) return;
1820 
1821  if (!GetConcreteInstance()) return;
1822 
1823  // Don't call IsValidView unless there is a scene handler. This
1824  // avoids WARNING message at end of event and run when the user has
1825  // not instantiated a scene handler, e.g., in batch mode.
1826  G4bool valid = fpSceneHandler && IsValidView();
1827  if (!valid) return;
1828 
1829 // G4cout << "G4VisManager::EndOfEvent: thread: "
1830 // << G4Threading::G4GetThreadId() << G4endl;
1831 
1832 #ifdef G4MULTITHREADED
1833  G4AutoLock al(&visEndOfEventMutex);
1834  // Testing.
1835 // std::this_thread::sleep_for(std::chrono::seconds(5));
1836 #endif
1837 
1838  G4RunManager* runManager = G4RunManager::GetRunManager();
1839 #ifdef G4MULTITHREADED
1841  runManager = G4MTRunManager::GetMasterRunManager();
1842  }
1843 #endif
1844 
1845  const G4Run* currentRun = runManager->GetCurrentRun();
1846  if (!currentRun) return;
1847 
1848  // This gets the thread-local event manager
1850  const G4Event* currentEvent = eventManager->GetConstCurrentEvent();
1851  if (!currentEvent) return;
1852 
1854 
1855 #ifdef G4MULTITHREADED
1856 
1857  // Wait if too many events in the queue.
1858  G4MUTEXLOCK(&mtVisSubThreadMutex);
1859  G4int eventQueueSize = mtVisEventQueue.size();
1860  G4MUTEXUNLOCK(&mtVisSubThreadMutex);
1861 // G4cout << "Event queue size (1): " << eventQueueSize << G4endl;
1862 
1863  G4bool eventQueueFull = false;
1864  while (fMaxEventQueueSize > 0 && eventQueueSize >= fMaxEventQueueSize) {
1865 
1866 // G4cout << "Event queue size (2): " << eventQueueSize << G4endl;
1867  if (fWaitOnEventQueueFull) {
1868  static G4bool warned = false;
1869  if (!warned) {
1870  G4cout <<
1871  "WARNING: The number of events in the visualisation queue has exceeded"
1872  "\n the maximum, "
1873  << fMaxEventQueueSize <<
1874  ".\n If, during a multithreaded run, the simulation gets ahead of the"
1875  "\n visualisation by more than this maximum, the simulation is delayed"
1876  "\n until the vis sub-thread has drawn a few more events and removed them"
1877  "\n from the queue. You may change this maximum number of events with"
1878  "\n \"/vis/multithreading/maxEventQueueSize <N>\", where N is the maximum"
1879  "\n number you wish to allow. N <= 0 means \"unlimited\"."
1880  "\n Alternatively you may choose to discard events for drawing by setting"
1881  "\n \"/vis/multithreading/actionOnEventQueueFull discard\"."
1882  "\n To avoid visualisation altogether: \"/vis/disable\"."
1883  "\n And maybe \"/tracking/storeTrajectories 0\"."
1884  << G4endl;
1885  warned = true;
1886  }
1887  // G4cout << "Event queue size (3): " << eventQueueSize << G4endl;
1888  // Wait a while to give event drawing time to reduce the queue...
1889 #ifdef G4VIS_USE_STD11
1890  std::this_thread::sleep_for(std::chrono::milliseconds(100));
1891 #else
1892  G4THREADSLEEP(1);
1893 #endif
1894  // G4cout << "Event queue size (4): " << eventQueueSize << G4endl;
1895  } else {
1896  static G4bool warned = false;
1897  if (!warned) {
1898  G4cout <<
1899  "WARNING: The number of events in the visualisation queue has exceeded"
1900  "\n the maximum, "
1901  << fMaxEventQueueSize <<
1902  ".\n Some events have been discarded for drawing. You may change this"
1903  "\n behaviour with \"/vis/multithreading/actionOnEventQueueFull wait\"."
1904  "\n To avoid visualisation altogether: \"/vis/disable\"."
1905  "\n And maybe \"/tracking/storeTrajectories 0\"."
1906  << G4endl;
1907  warned = true;
1908  }
1909  eventQueueFull = true; // Causes event to be discarded for drawing.
1910  break;
1911  }
1912 
1913  G4MUTEXLOCK(&mtVisSubThreadMutex);
1914  eventQueueSize = mtVisEventQueue.size();
1915  G4MUTEXUNLOCK(&mtVisSubThreadMutex);
1916  }
1917 
1918  if (!eventQueueFull) {
1919  G4MUTEXLOCK(&mtVisSubThreadMutex);
1920  // Keep event for processing and put event on vis event queue
1921  currentEvent->KeepForPostProcessing();
1922  mtVisEventQueue.push_back(currentEvent);
1923  G4MUTEXUNLOCK(&mtVisSubThreadMutex);
1924  }
1925 
1926 // G4MUTEXLOCK(&mtVisSubThreadMutex);
1927 // G4int eQS = mtVisEventQueue.size();
1928 // G4MUTEXUNLOCK(&mtVisSubThreadMutex);
1929 // G4cout << "Event queue size (5): " << eQS << G4endl;
1930 
1931 #endif
1932 
1933  } else {
1934 
1935  // Sequential mode
1936 
1937  G4int nEventsToBeProcessed = 0;
1938  G4int nKeptEvents = 0;
1939  G4int eventID = -2; // (If no run manager, triggers ShowView as normal.)
1940  if (currentRun) {
1941  nEventsToBeProcessed = runManager->GetNumberOfEventsToBeProcessed();
1942  eventID = currentEvent->GetEventID();
1943  const std::vector<const G4Event*>* events = currentRun->GetEventVector();
1944  if (events) nKeptEvents = events->size();
1945  }
1946 
1947  // We are about to draw the event (trajectories, etc.), but first we
1948  // have to clear the previous event(s) if necessary. If this event
1949  // needs to be drawn afresh, e.g., the first event or any event when
1950  // "accumulate" is not requested, the old event has to be cleared.
1951  // We have postponed this so that, for normal viewers like OGL, the
1952  // previous event(s) stay on screen until this new event comes
1953  // along. For a file-writing viewer the geometry has to be drawn.
1954  // See, for example, G4HepRepFileSceneHandler::ClearTransientStore.
1956 
1957  // Now draw the event...
1958  fpSceneHandler->DrawEvent(currentEvent);
1960 
1962 
1963  // Unless last event (in which case wait end of run)...
1964  if (eventID < nEventsToBeProcessed - 1) {
1965  // ShowView guarantees the view is flushed to the screen. It also
1966  // triggers other features such picking (if enabled) and allows
1967  // file-writing viewers to close the file.
1968  fpViewer->ShowView();
1969  } else { // Last event...
1970  // Keep, but only if user has not kept any...
1971  if (nKeptEvents == 0) {
1972  eventManager->KeepTheCurrentEvent();
1973  fNKeepRequests++;
1974  fKeptLastEvent = true;
1975  }
1976  }
1978 
1979  }
1980  }
1981 
1982  // Both modes - sequential and MT
1983 
1984  if (!(fpScene->GetRefreshAtEndOfEvent())) {
1985 
1986  // Accumulating events...
1987 
1988  G4int maxNumberOfKeptEvents = fpScene->GetMaxNumberOfKeptEvents();
1989 
1990  if (maxNumberOfKeptEvents > 0 &&
1991  fNKeepRequests >= maxNumberOfKeptEvents) {
1992 
1993  fEventKeepingSuspended = true;
1994  static G4bool warned = false;
1995  if (!warned) {
1996  if (fVerbosity >= warnings) {
1997  G4cout <<
1998  "WARNING: G4VisManager::EndOfEvent: Automatic event keeping suspended."
1999  "\n The number of events exceeds the maximum, "
2000  << maxNumberOfKeptEvents <<
2001  ", that may be kept by\n the vis manager."
2002  << G4endl;
2003  }
2004  warned = true;
2005  }
2006 
2007  } else if (maxNumberOfKeptEvents != 0) {
2008 
2009  // If not disabled nor suspended.
2011 // G4cout <<
2012 // "Requesting keeping event " << currentEvent->GetEventID()
2013 // << G4endl;
2014  eventManager->KeepTheCurrentEvent();
2015  fNKeepRequests++;
2016  }
2017 
2018  }
2019  }
2020 }
2021 
2023 {
2024  if (fIgnoreStateChanges) return;
2025 
2026  if (!GetConcreteInstance()) return;
2027 
2028 #ifdef G4MULTITHREADED
2029  if (G4Threading::IsWorkerThread()) return;
2030 #endif
2031 
2032 // G4cout << "G4VisManager::EndOfRun: thread: "
2033 // << G4Threading::G4GetThreadId() << G4endl;
2034 
2035  G4RunManager* runManager = G4RunManager::GetRunManager();
2036 #ifdef G4MULTITHREADED
2038  runManager = G4MTRunManager::GetMasterRunManager();
2039  }
2040 #endif
2041 
2042  // For a fake run...
2043  G4int nEventsToBeProcessed = runManager->GetNumberOfEventsToBeProcessed();
2044  if (nEventsToBeProcessed == 0) return;
2045 
2046  const G4Run* currentRun = runManager->GetCurrentRun();
2047  if (!currentRun) return;
2048 
2049 #ifdef G4MULTITHREADED
2050  // G4AutoLock al(&visEndOfRunMutex); ???
2052  // Reset flag so that sub-thread exits when it has finished processing.
2053  G4MUTEXLOCK(&mtVisSubThreadMutex);
2054  mtRunInProgress = false;
2055  G4MUTEXUNLOCK(&mtVisSubThreadMutex);
2056  // Wait for sub-thread to finish.
2057  G4THREADJOIN(*mtVisSubThread);
2058  delete mtVisSubThread;
2059  if (fpViewer) fpViewer->SwitchToMasterThread();
2060  }
2061 #endif
2062 
2063 #ifdef G4MULTITHREADED
2064  // Print warning about discarded events, if any.
2065  // Don't call IsValidView unless there is a scene handler. This
2066  // avoids WARNING message from IsValidView() when the user has
2067  // not instantiated a scene handler, e.g., in batch mode.
2068  if (fpSceneHandler && IsValidView()) { // Events should have been drawn
2069  G4int noOfEventsRequested = runManager->GetNumberOfEventsToBeProcessed();
2070  if (fNoOfEventsDrawnThisRun != noOfEventsRequested) {
2071  if (!fWaitOnEventQueueFull && fVerbosity >= warnings) {
2072  G4cout
2073  << "WARNING: Number of events drawn this run, "
2074  << fNoOfEventsDrawnThisRun << ", is different to number requested, "
2075  << noOfEventsRequested <<
2076  ".\n (This is because you requested \"/vis/multithreading/actionOnEventQueueFull discard\".)"
2077  << G4endl;
2078  }
2079  }
2080  }
2081 #endif
2082 
2083  G4int nKeptEvents = 0;
2084  const std::vector<const G4Event*>* events = currentRun->GetEventVector();
2085  if (events) nKeptEvents = events->size();
2086  if (nKeptEvents && !fKeptLastEvent) {
2087  if (fVerbosity >= warnings) {
2088  G4cout << "WARNING: " << nKeptEvents;
2089  if (nKeptEvents == 1) G4cout << " event has";
2090  else G4cout << " events have";
2091  G4cout << " been kept for refreshing and/or reviewing." << G4endl;
2092  if (nKeptEvents != fNKeepRequests) {
2093  G4cout << " (Note: ";
2094  if (fNKeepRequests == 0) {
2095  G4cout << "No keep requests were";
2096  } else if (fNKeepRequests == 1) {
2097  G4cout << "Only 1 keep request was";
2098  } else {
2099  G4cout << "Only " << fNKeepRequests << " keep requests were";
2100  }
2101  G4cout << " made by the vis manager.)" << G4endl;
2102  }
2103  G4cout <<
2104  "\n \"/vis/reviewKeptEvents\" to review them one by one."
2105  "\n \"/vis/viewer/flush\" or \"/vis/viewer/rebuild\" to see them accumulated."
2106  << G4endl;
2107  }
2108  // static G4bool warned = false;
2109  // if (!valid && fVerbosity >= warnings && !warned) {
2110  // G4cout <<
2111  // " Only useful if before starting the run:"
2112  // "\n a) trajectories are stored (\"/vis/scene/add/trajectories [smooth|rich]\"), or"
2113  // "\n b) the Draw method of any hits or digis is implemented."
2114  // "\n To view trajectories, hits or digis:"
2115  // "\n open a viewer, draw a volume, \"/vis/scene/add/trajectories\""
2116  // "\n \"/vis/scene/add/hits\" or \"/vis/scene/add/digitisations\""
2117  // "\n and, possibly, \"/vis/viewer/flush\"."
2118  // "\n To see all events: \"/vis/scene/endOfEventAction accumulate\"."
2119  // "\n (You may need \"/vis/viewer/flush\" or even \"/vis/viewer/rebuild\".)"
2120  // "\n To see events individually: \"/vis/reviewKeptEvents\"."
2121  // << G4endl;
2122  // warned = true;
2123  // }
2124  }
2125 
2127  G4cout <<
2128  "WARNING: G4VisManager::EndOfRun: Automatic event keeping was suspended."
2129  "\n The number of events in the run exceeded the maximum, "
2131  ", that may be\n kept by the vis manager." <<
2132  "\n The number of events kept by the vis manager can be changed with"
2133  "\n \"/vis/scene/endOfEventAction accumulate <N>\", where N is the"
2134  "\n maximum number you wish to allow. N < 0 means \"unlimited\"."
2135  << G4endl;
2136  }
2137 
2138  // Don't call IsValidView unless there is a scene handler. This
2139  // avoids WARNING message at end of event and run when the user has
2140  // not instantiated a scene handler, e.g., in batch mode.
2141  G4bool valid = fpSceneHandler && IsValidView();
2142  if (GetConcreteInstance() && valid) {
2143 // // ???? I can't remember why
2144 // // if (!fpSceneHandler->GetMarkForClearingTransientStore()) {
2145 // // is here. It prevents ShowView at end of run, which seems to be OK
2146 // // for sequential mode, but MT mode seems to need it (I have not
2147 // // figured out why). ???? JA ????
2148 // if (!fpSceneHandler->GetMarkForClearingTransientStore()) {
2149  if (fpScene->GetRefreshAtEndOfRun()) {
2151  // An extra refresh for auto-refresh viewers.
2152  // ???? I DON'T WHY THIS IS NECESSARY ???? JA ????
2154  fpViewer->RefreshView();
2155  }
2156  // ShowView guarantees the view is flushed to the screen. It also
2157  // triggers other features such picking (if enabled) and allows
2158  // file-writing viewers to close the file.
2159  fpViewer->ShowView();
2161  } else {
2164  if (fVerbosity >= warnings) {
2165  G4cout << "\"/vis/viewer/update\" to close file." << G4endl;
2166  }
2167  }
2168  }
2169 // }
2170  }
2171  fEventRefreshing = false;
2172 }
2173 
2175  // Assumes valid view.
2179  }
2180  // Record if transients drawn. These local flags are only set
2181  // *after* ClearTransientStore. In the code in G4VSceneHandler
2182  // triggered by ClearTransientStore, use these flags so that
2183  // event refreshing is not done too early.
2186 }
2187 
2189 {
2190  fTransientsDrawnThisRun = false;
2191  fTransientsDrawnThisEvent = false;
2193  for (i = fAvailableSceneHandlers.begin();
2194  i != fAvailableSceneHandlers.end(); ++i) {
2195  (*i)->SetTransientsDrawnThisEvent(false);
2196  (*i)->SetTransientsDrawnThisRun(false);
2197  }
2198 }
2199 
2201  G4String viewerShortName (viewerName);
2202  viewerShortName = viewerShortName (0, viewerShortName.find (' '));
2203  return viewerShortName.strip ();
2204 }
2205 
2206 G4VViewer* G4VisManager::GetViewer (const G4String& viewerName) const {
2207  G4String viewerShortName = ViewerShortName (viewerName);
2208  size_t nHandlers = fAvailableSceneHandlers.size ();
2209  size_t iHandler, iViewer;
2210  G4VViewer* viewer = 0;
2211  G4bool found = false;
2212  for (iHandler = 0; iHandler < nHandlers; iHandler++) {
2213  G4VSceneHandler* sceneHandler = fAvailableSceneHandlers [iHandler];
2214  const G4ViewerList& viewerList = sceneHandler -> GetViewerList ();
2215  for (iViewer = 0; iViewer < viewerList.size (); iViewer++) {
2216  viewer = viewerList [iViewer];
2217  if (viewerShortName == viewer -> GetShortName ()) {
2218  found = true;
2219  break;
2220  }
2221  }
2222  if (found) break;
2223  }
2224  if (found) return viewer;
2225  else return 0;
2226 }
2227 
2228 std::vector<G4String> G4VisManager::VerbosityGuidanceStrings;
2229 
2231  G4String rs;
2232  switch (verbosity) {
2233  case quiet: rs = "quiet (0)"; break;
2234  case startup: rs = "startup (1)"; break;
2235  case errors: rs = "errors (2)"; break;
2236  case warnings: rs = "warnings (3)"; break;
2237  case confirmations: rs = "confirmations (4)"; break;
2238  case parameters: rs = "parameters (5)"; break;
2239  case all: rs = "all (6)"; break;
2240  }
2241  return rs;
2242 }
2243 
2246  G4String ss(verbosityString); ss.toLower();
2247  Verbosity verbosity;
2248  if (ss(0) == 'q') verbosity = quiet;
2249  else if (ss(0) == 's') verbosity = startup;
2250  else if (ss(0) == 'e') verbosity = errors;
2251  else if (ss(0) == 'w') verbosity = warnings;
2252  else if (ss(0) == 'c') verbosity = confirmations;
2253  else if (ss(0) == 'p') verbosity = parameters;
2254  else if (ss(0) == 'a') verbosity = all;
2255  else {
2256  G4int intVerbosity;
2257  std::istringstream is(ss);
2258  is >> intVerbosity;
2259  if (!is) {
2260  G4cerr << "ERROR: G4VisManager::GetVerbosityValue: invalid verbosity \""
2261  << verbosityString << "\"";
2262  for (size_t i = 0; i < VerbosityGuidanceStrings.size(); ++i) {
2263  G4cerr << '\n' << VerbosityGuidanceStrings[i];
2264  }
2265  verbosity = warnings;
2266  G4cerr << "\n Returning " << VerbosityString(verbosity)
2267  << G4endl;
2268  }
2269  else {
2270  verbosity = GetVerbosityValue(intVerbosity);
2271  }
2272  }
2273  return verbosity;
2274 }
2275 
2277  Verbosity verbosity;
2278  if (intVerbosity < quiet) verbosity = quiet;
2279  else if (intVerbosity > all) verbosity = all;
2280  else verbosity = Verbosity(intVerbosity);
2281  return verbosity;
2282 }
2283 
2285  return fVerbosity;
2286 }
2287 
2289  fVerbosity = GetVerbosityValue(intVerbosity);
2290 }
2291 
2292 void G4VisManager::SetVerboseLevel (const G4String& verbosityString) {
2293  fVerbosity = GetVerbosityValue(verbosityString);
2294 }
2295 
2297 
2298  if (!fInitialised) Initialise ();
2299 
2300  static G4bool noGSPrinting = true;
2301  if (!fpGraphicsSystem) {
2302  // Limit printing - we do not want printing if the user simply does
2303  // not want to use graphics, e.g., in batch mode.
2304  if (noGSPrinting) {
2305  noGSPrinting = false;
2306  if (fVerbosity >= warnings) {
2307  G4cout <<
2308  "WARNING: G4VisManager::IsValidView(): Attempt to draw when no graphics system"
2309  "\n has been instantiated. Use \"/vis/open\" or \"/vis/sceneHandler/create\"."
2310  "\n Alternatively, to avoid this message, suppress instantiation of vis"
2311  "\n manager (G4VisExecutive), possibly by setting G4VIS_NONE, and ensure"
2312  "\n drawing code is executed only if G4VVisManager::GetConcreteInstance()"
2313  "\n is non-zero."
2314  << G4endl;
2315  }
2316  }
2317  return false;
2318  }
2319 
2320  if ((!fpScene) || (!fpSceneHandler) || (!fpViewer)) {
2321  if (fVerbosity >= errors) {
2322  G4cerr <<
2323  "ERROR: G4VisManager::IsValidView(): Current view is not valid."
2324  << G4endl;
2326  }
2327  return false;
2328  }
2329 
2330  if (fpScene != fpSceneHandler -> GetScene ()) {
2331  if (fVerbosity >= errors) {
2332  G4cerr << "ERROR: G4VisManager::IsValidView ():";
2333  if (fpSceneHandler -> GetScene ()) {
2334  G4cout <<
2335  "\n The current scene \""
2336  << fpScene -> GetName ()
2337  << "\" is not handled by"
2338  "\n the current scene handler \""
2339  << fpSceneHandler -> GetName ()
2340  << "\""
2341  "\n (it currently handles scene \""
2342  << fpSceneHandler -> GetScene () -> GetName ()
2343  << "\")."
2344  "\n Either:"
2345  "\n (a) attach it to the scene handler with"
2346  "\n /vis/sceneHandler/attach "
2347  << fpScene -> GetName ()
2348  << ", or"
2349  "\n (b) create a new scene handler with "
2350  "\n /vis/sceneHandler/create <graphics-system>,"
2351  "\n in which case it should pick up the the new scene."
2352  << G4endl;
2353  }
2354  else {
2355  G4cout << "\n Scene handler \""
2356  << fpSceneHandler -> GetName ()
2357  << "\" has null scene pointer."
2358  "\n Attach a scene with /vis/sceneHandler/attach [<scene-name>]"
2359  << G4endl;
2360  }
2361  }
2362  return false;
2363  }
2364 
2365  const G4ViewerList& viewerList = fpSceneHandler -> GetViewerList ();
2366  if (viewerList.size () == 0) {
2367  if (fVerbosity >= errors) {
2368  G4cerr <<
2369  "ERROR: G4VisManager::IsValidView (): the current scene handler\n \""
2370  << fpSceneHandler -> GetName ()
2371  << "\" has no viewers. Do /vis/viewer/create."
2372  << G4endl;
2373  }
2374  return false;
2375  }
2376 
2377  G4bool isValid = true;
2378  if (fpScene -> IsEmpty ()) { // Add world by default if possible...
2379  G4bool warn(fVerbosity >= warnings);
2380  G4bool successful = fpScene -> AddWorldIfEmpty (warn);
2381  if (!successful || fpScene -> IsEmpty ()) { // If still empty...
2382  if (fVerbosity >= errors) {
2383  G4cerr << "ERROR: G4VisManager::IsValidView ():";
2384  G4cerr <<
2385  "\n Attempt at some drawing operation when scene is empty."
2386  "\n Maybe the geometry has not yet been defined."
2387  " Try /run/initialize."
2388  "\n Or use \"/vis/scene/add/extent\"."
2389  << G4endl;
2390  }
2391  isValid = false;
2392  }
2393  else {
2394  G4UImanager::GetUIpointer()->ApplyCommand ("/vis/scene/notifyHandlers");
2395  if (fVerbosity >= warnings) {
2396  G4cout <<
2397  "WARNING: G4VisManager: the scene was empty, \"world\" has been"
2398  "\n added and the scene handlers notified.";
2399  G4cout << G4endl;
2400  }
2401  }
2402  }
2403  return isValid;
2404 }
2405 
2406 void
2408 {
2409  if (fVerbosity >= warnings) {
2410  G4cout<<"G4VisManager: No model factories registered with G4VisManager."<<G4endl;
2411  G4cout<<"G4VisManager::RegisterModelFactories() should be overridden in derived"<<G4endl;
2412  G4cout<<"class. See G4VisExecutive for an example."<<G4endl;
2413  }
2414 }
2415 
2416 #ifdef G4MULTITHREADED
2417 void G4VisManager::SetUpForAThread()
2418 {
2419  new G4VisStateDependent(this);
2420 }
2421 #endif
2422 
2424 {
2425  fIgnoreStateChanges = val;
2426 }
#define G4MUTEXUNLOCK
Definition: G4Threading.hh:180
G4bool FilterDigi(const G4VDigi &)
#define G4THREADJOIN(worker)
Definition: G4Threading.hh:182
void Initialise()
void RegisterEndOfEventUserVisAction(const G4String &name, G4VUserVisAction *, const G4VisExtent &=G4VisExtent::NullExtent)
void RegisterModelFactory(G4TrajDrawModelFactory *factory)
G4VisFilterManager< G4VTrajectory > * fpTrajFilterMgr
Definition: G4Text.hh:73
static Verbosity fVerbosity
const std::vector< Factory * > & FactoryList() const
virtual void SetView()=0
void PrintAvailableColours(Verbosity) const
G4VisFilterManager< G4VHit > * fpHitFilterMgr
void PrintAvailableUserVisActions(Verbosity) const
virtual void RegisterModelFactories()
void PrintAvailableModels(Verbosity) const
void SetCurrentSceneHandler(G4VSceneHandler *)
static G4VVisManager * GetConcreteInstance()
void PrintAvailableGraphicsSystems(Verbosity) const
void SetEventID(G4int eventID)
G4String strip(G4int strip_Type=trailing, char c=' ')
G4bool IsCullingInvisible() const
virtual void ShowView()
Definition: G4VViewer.cc:103
void RegisterEndOfRunUserVisAction(const G4String &name, G4VUserVisAction *, const G4VisExtent &=G4VisExtent::NullExtent)
G4VisStateDependent * fpStateDependent
void PrintInvalidPointers() const
void SetVerboseLevel(G4int)
G4TrackingManager * GetTrackingManager() const
void SetRunID(G4int runID)
static G4SolidsWorkspacePool * GetInstance()
const G4ViewParameters & GetViewParameters() const
G4int fNKeepRequests
G4Navigator * GetNavigatorForTracking() const
G4VSolid * GetSolid() const
void GeometryHasChanged()
const std::vector< const G4Event * > * GetEventVector() const
Definition: G4Run.hh:115
const Model * Current() const
Definition: G4VHit.hh:48
void SetCurrentScene(G4Scene *)
const char * name(G4int ptype)
G4bool GetMarkForClearingTransientStore() const
G4bool GetRefreshAtEndOfEvent() const
static std::vector< G4String > VerbosityGuidanceStrings
const G4String & GetName() const
int G4int
Definition: G4Types.hh:78
static Verbosity GetVerbosityValue(const G4String &)
static G4RunManagerKernel * GetRunManagerKernel()
const G4Run * GetCurrentRun() const
#define G4MUTEX_INITIALIZER
Definition: G4Threading.hh:175
void EndDraw2D()
G4int G4Thread
Definition: G4Threading.hh:174
void BeginDraw(const G4Transform3D &objectTransformation=G4Transform3D())
const G4VTrajectoryModel * CurrentTrajDrawModel() const
G4bool fTransientsDrawnThisEvent
const std::vector< Filter * > & FilterList() const
std::vector< G4UIcommand * > fDirectoryList
G4bool IsValidView()
std::vector< G4UImessenger * > fMessengerList
static G4UImanager * GetUIpointer()
Definition: G4UImanager.cc:58
void RegisterMessengers()
G4int GetEventID() const
Definition: G4Event.hh:151
std::vector< G4VSceneHandler * >::const_iterator G4SceneHandlerListConstIterator
static G4VisManager * fpInstance
G4String Placement() const
void RegisterMessenger(G4UImessenger *messenger)
void SelectTrajectoryModel(const G4String &model)
void SetCurrentTrajectory(const G4VTrajectory *pTraj)
G4VSceneHandler * fpSceneHandler
void SetTransientsDrawnThisEvent(G4bool)
std::vector< UserVisAction > fEndOfRunUserVisActions
#define G4THREADCREATE(worker, func, arg)
Definition: G4Threading.hh:181
static G4RunManagerKernel * GetMasterRunManagerKernel()
G4double GetExtentRadius() const
Definition: G4VisExtent.cc:73
G4int fDrawGroupNestingDepth
void IgnoreStateChanges(G4bool)
G4bool fEventKeepingSuspended
G4String ViewerShortName(const G4String &viewerName) const
friend class G4VisStateDependent
G4GLOB_DLL std::ostream G4cout
std::vector< UserVisAction > fRunDurationUserVisActions
bool Accept(const T &)
G4VisModelManager< G4VTrajectoryModel > * fpTrajDrawModelMgr
void Register(Model *)
G4SceneHandlerList fAvailableSceneHandlers
const std::map< G4String, T * > & Map() const
bool G4bool
Definition: G4Types.hh:79
G4bool FilterTrajectory(const G4VTrajectory &)
virtual void Draw(const G4VTrajectory &trajectory, const G4bool &visible=true) const =0
static G4MTRunManager * GetMasterRunManager()
G4bool GetRefreshAtEndOfRun() const
void ResetTransientsDrawnFlags()
G4int GetRunID() const
Definition: G4Run.hh:76
G4bool GetTransientsDrawnThisRun() const
static G4VisManager * GetInstance()
Definition: G4Run.hh:46
G4int fNoOfEventsDrawnThisRun
void KeepForPostProcessing() const
Definition: G4Event.hh:139
void SetCurrentGraphicsSystem(G4VGraphicsSystem *)
void SetXGeometryString(const G4String &)
G4int GetNumberOfEventsToBeProcessed() const
const T * Current() const
HepGeom::Transform3D G4Transform3D
G4bool GetTransientsDrawnThisEvent() const
G4Scene * fpScene
G4bool IsCullingCovered() const
#define G4MUTEXLOCK
Definition: G4Threading.hh:179
virtual ~G4VisManager()
void CalculateExtent()
Definition: G4Scene.cc:72
G4VisFilterManager< G4VDigi > * fpDigiFilterMgr
G4bool IsMultithreadedApplication()
Definition: G4Threading.cc:152
void toLower()
G4String Placement() const
G4bool fEventRefreshing
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
G4bool IsWorkerThread()
Definition: G4Threading.cc:145
static G4TransportationManager * GetTransportationManager()
void RegisterRunDurationUserVisAction(const G4String &name, G4VUserVisAction *, const G4VisExtent &=G4VisExtent::NullExtent)
void SetCurrentViewer(G4VViewer *)
virtual void DescribeYourselfTo(G4VGraphicsScene &scene) const =0
static G4RunManager * GetRunManager()
Definition: G4RunManager.cc:79
G4int G4Mutex
Definition: G4Threading.hh:173
G4Scene * GetScene() const
void SetTransientsDrawnThisEvent(G4bool)
void SetCurrent(const G4String &)
G4GraphicsSystemList fAvailableGraphicsSystems
G4VisManager(const G4String &verbosityString="warnings")
Definition: G4VisManager.cc:99
G4bool FilterHit(const G4VHit &)
#define G4THREADSLEEP(tick)
Definition: G4Threading.hh:49
G4LogicalVolume * GetLogicalVolume() const
G4bool fInitialised
void DrawEvent(const G4Event *)
G4VViewer * GetViewer(const G4String &viewerName) const
void DrawT(const T &graphics_primitive, const G4Transform3D &objectTransform)
std::vector< UserVisAction > fEndOfEventUserVisActions
void BeginDraw2D(const G4Transform3D &objectTransformation=G4Transform3D())
static G4String VerbosityString(Verbosity)
G4VSceneHandler * GetCurrentSceneHandler() const
void SetWorldVolume(G4VPhysicalVolume *pWorld)
static G4EventManager * GetEventManager()
const List * ListManager() const
G4int GetStoreTrajectory() const
FilterMode::Mode GetMode() const
static Verbosity GetVerbosity()
G4bool fIgnoreStateChanges
void RefreshView()
G4VViewer * fpViewer
void Draw(const G4Circle &, const G4Transform3D &objectTransformation=G4Transform3D())
static void SetVisManager(G4VisManager *)
virtual void RegisterGraphicsSystems()=0
static G4GeometryWorkspacePool * GetInstance()
#define G4endl
Definition: G4ios.hh:61
void RegisterModel(G4VTrajectoryModel *model)
const std::vector< Factory * > & FactoryList() const
G4bool RegisterGraphicsSystem(G4VGraphicsSystem *)
G4VViewer * GetCurrentViewer() const
void BeginOfEvent()
void DispatchToModel(const G4VTrajectory &)
static const std::map< G4String, G4Colour > & GetMap()
Definition: G4Colour.cc:147
void CreateViewer(const G4String &name="", const G4String &XGeometry="")
virtual void ClearTransientStore()
void SetTransientsDrawnThisRun(G4bool)
void SetUpForSpecialThread(G4String aPrefix)
Definition: G4UImanager.cc:735
const G4Event * GetConstCurrentEvent()
void CreateSceneHandler(const G4String &name="")
G4VGraphicsSystem * fpGraphicsSystem
Functionality GetFunctionality() const
void DrawT2D(const T &graphics_primitive, const G4Transform3D &objectTransform)
const G4GraphicsSystemList & GetAvailableGraphicsSystems()
G4bool IsCulling() const
void NotifyHandlers()
G4int GetMaxNumberOfKeptEvents() const
static void SetConcreteInstance(G4VVisManager *)
void Draw2D(const G4Circle &, const G4Transform3D &objectTransformation=G4Transform3D())
void ClearTransientStoreIfMarked()
void * G4ThreadFunArgType
Definition: G4Threading.hh:185
G4bool fIsDrawGroup
void SetMarkForClearingTransientStore(G4bool)
void KeepTheCurrentEvent()
G4bool IsAutoRefresh() const
G4bool fKeptLastEvent
G4int ApplyCommand(const char *aCommand)
Definition: G4UImanager.cc:446
G4GLOB_DLL std::ostream G4cerr
void * G4ThreadFunReturnType
Definition: G4Threading.hh:184
G4bool fTransientsDrawnThisRun
G4SceneList fSceneList