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