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