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