Import Geant4 11.3.0.beta source tree
This commit is contained in:
@@ -6,10 +6,141 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 2024-03-18 Gabriele Cosmo (visman-V11-01-33)
|
||||
## 2024-06-04 John Allison (visman-V11-02-12)
|
||||
- G4VisManager:
|
||||
- Implement EventReadyForVis, used by G4SubEvtRunManager.
|
||||
- Restructure EndOfEvent functions to accommodate this, and avoid
|
||||
code duplication. This involved introducing:
|
||||
- Relinquishable, EndOfEventKernel and EndOfEventCleanup.
|
||||
- Correct the use of KeepForPostProcessing/PostProcessingFinished.
|
||||
|
||||
## 2024-05-30 Guy Barrand (visman-V11-02-11)
|
||||
- G4VisExecutive.icc: Qt6: restore vis/OGL as default driver.
|
||||
|
||||
## 2024-03-18 Gabriele Cosmo (visman-V11-02-10)
|
||||
- G4VisExecutive.icc: fixed use of static symbol 'fVerbosity' and replaced
|
||||
with call to dedicated static method, to avoid linkage problems on Windows.
|
||||
|
||||
## 2024-03-04 John Allison (visman-V11-02-09)
|
||||
- G4VViewer.cc: Coverity fix.
|
||||
- Add return statement after G4Exception(...FatalException...) so Coverity
|
||||
does not think a null pointer might be being allowed.
|
||||
- This is a fix to a fix in visman-V11-02-07.
|
||||
|
||||
## 2024-02-05 John Allison (visman-V11-02-08)
|
||||
- G4VisCommandsTouchable.cc:
|
||||
- "/vis/touchable/dump" and "findPath" do not need a scene handler nor a
|
||||
viewer. Move them to the beginning of G4VisCommandsTouchable::SetNewValue,
|
||||
before the check on scene handler and viewer.
|
||||
- This allows the user to "/vis/touchable/dump" even if he/she has
|
||||
not yet opened a viewer.
|
||||
|
||||
## 2024-02-03 John Allison (visman-V11-02-07)
|
||||
- G4VViewer.cc: Coverity fix.
|
||||
- A previous tag changed class G4VViewer::SceneTreeScene to require a
|
||||
G4PhysicalVolumeModel*. Previous to that, it was programmed for a
|
||||
general G4VModel*, which required a check on the type. That check
|
||||
inadvertently remained, even though now not necessary. It seems to
|
||||
confuse Coverity - something to do with the fact that it is called
|
||||
in a virtual function, which has already involved a de-referencing,
|
||||
whereas my checks implied the pointer could be null. It now *must*
|
||||
be valid by construction, so I have removed the checks, and, just
|
||||
to be sure, added a G4Exception on null pointer in the constructor.
|
||||
|
||||
## 2024-02-02 John Allison (visman-V11-02-06)
|
||||
- G4VSceneHandler.cc:
|
||||
- Coverity fix: "const auto&" instead of "auto" to prevent copying.
|
||||
|
||||
## 2024-01-23 John Allison (visman-V11-02-05)
|
||||
- Rationalisation, simplification and much tidying of visman-V11-02-04.
|
||||
- G4VViewer:
|
||||
- Check validity of arguments in SceneTreeScene constructor.
|
||||
- Pre-calculation of quantities in SceneTreeScene constructor.
|
||||
- Avoids repeated calculations in ProcessVolume.
|
||||
- More logical order of some functions.
|
||||
G4VSceneHandler.cc:
|
||||
- Specify the G4PhysicalVolumeModel for construction of scene tree scene.
|
||||
|
||||
## 2024-01-22 John Allison (visman-V11-02-04)
|
||||
- Co-works with modeling-V11-02-01, interfaces-V11-02-01 and greps-V11-02-00.
|
||||
- Limit the number of scene tree items.
|
||||
- For complex geometries, the scene tree can take up a lot of space, and,
|
||||
anyway, not easy to navigate. This tag suppresses the scene tree if the
|
||||
number of touchables exceeds 10,000 (equivalent to about 20 MB).
|
||||
- Better to suppress altogether than create a partial tree?
|
||||
- G4VViewer:
|
||||
- Pre-calculate number of touchables. If >10,000, suppress them in the
|
||||
scene tree and add some information about it to the model item so that
|
||||
it pops up as a tooltip in the GUI.
|
||||
- Some tidying and rationalisation.
|
||||
- G4VSceneHandler:
|
||||
- Simplify loop over models, add some printing (verbosity >= confirmations).
|
||||
- Some tidying and rationalisation.
|
||||
- G4VisCommandsViewer.cc:
|
||||
- Use GetSceneTree (const) rather than AccessSceneTree when not necessary.
|
||||
|
||||
## 2024-01-17 John Allison (visman-V11-02-03)
|
||||
- G4VSceneHandler:
|
||||
- Print number of touchables by depth (if verbosity >= confirmations).
|
||||
- Print problematic volumes (if verbosity >= confirmations).
|
||||
- G4VisCommandsTouchable.cc:
|
||||
- Protect polyhedron pointer in /vis/touchable/dump.
|
||||
|
||||
## 2024-01-16 John Allison (visman-V11-02-02)
|
||||
- Co-works with modeling-V11-02-00 and interfaces-V11-02-00
|
||||
- Improve identification of scene tree models - use full description, including
|
||||
embedded blanks.
|
||||
- G4VisCommandScene.cc:
|
||||
- G4VisCommandSceneActivateModel::SetNewValue:
|
||||
- Need to handle the possibility that the search string
|
||||
contains embedded blanks within quotation marks.
|
||||
(This arises if the search string is automatically generated from the
|
||||
global description, as in G4UIQt, clicking on check box.)
|
||||
- Tidy model searches.
|
||||
- G4VisCommandSceneAdd.cc:
|
||||
- Text and Text2D: Use single quote (') to delineate actual text in description.
|
||||
- This is so that normal quotes can be used in G4VisCommandSceneActivateModel.
|
||||
|
||||
## 2024-01-12 John Allison (visman-V11-02-01)
|
||||
- G4VisExecutive.icc:
|
||||
- Trap use of run-time vis driver choice - not allowed in batch mode.
|
||||
- And (if using run-time choice) insist UI session is instantiated
|
||||
*before* G4VisExecutive.
|
||||
- G4VisManager.cc:
|
||||
- Improve messaging.
|
||||
- G4VSceneHandler.cc:
|
||||
- Minor typo.
|
||||
|
||||
## 2023-12-31 John Allison (visman-V11-02-00)
|
||||
- Delay determination of the run-time-chosen default driver (see visman-V11-01-26).
|
||||
- This run-time-chosen default driver is not actually used until the first
|
||||
use of /vis/open or /vis/sceneHandler/create without driver parameter,
|
||||
so we delay to this point.
|
||||
- This catches the situation when the user instantiates the UI session
|
||||
*after* instantiating the vis manager.
|
||||
- This choice depends on whether or not the user instantiates a
|
||||
UI session, and, indeed, if instantiated, what type, so in this case
|
||||
we *have* to delay.
|
||||
- Note that Geant4 recommends instantiating the UI session as early as
|
||||
possible in order to capture output streams. However, this is not
|
||||
enforceable and even some of our examples do not follow this.
|
||||
- G4VisExecutive:
|
||||
- Keep argc, argv and user-specified system, if specified, for delayed use.
|
||||
- Move informational (G4warn) from G4VisManager.
|
||||
- G4VisManager:
|
||||
- Make GetDefaultGraphicsSystemName() virtual and non const.
|
||||
- It has to be virtual so that the derived class (G4VisExecutive) can
|
||||
override it.
|
||||
- And non-const because on first pass it may/should determine
|
||||
these run-time-chosen defaults.
|
||||
- The code for choosing a default driver *has to be* in user space, i.e.,
|
||||
in G4VisExecutive, so that it has access to use flags. Hence we have to
|
||||
use the virtual function mechanism.
|
||||
- Modify the informational (G4warn) in PrintAvailableGraphicsSystems to give
|
||||
advice and point to further information to be given after /vis/open.
|
||||
- G4VViewer.cc:
|
||||
- Minor, purely cosmetic improvement.
|
||||
|
||||
## 2023-11-12 John Allison (visman-V11-01-32)
|
||||
- G4VisExecutive.icc:
|
||||
- Add single line message "VTK: OpenGL-based drivers suppressed".
|
||||
|
||||
@@ -45,6 +45,8 @@
|
||||
#include "G4THitsMap.hh"
|
||||
#include "G4PseudoScene.hh"
|
||||
|
||||
#include <map>
|
||||
|
||||
class G4Scene;
|
||||
class G4VGraphicsSystem;
|
||||
class G4AttHolder;
|
||||
@@ -451,6 +453,7 @@ protected:
|
||||
G4int fNestingDepth; // For Begin/EndPrimitives.
|
||||
const G4VisAttributes* fpVisAttribs; // Working vis attributes.
|
||||
const G4Transform3D fIdentityTransformation;
|
||||
std::map<G4VPhysicalVolume*,G4String> fProblematicVolumes;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -171,25 +171,25 @@ public: // With description
|
||||
class SceneTreeScene: public G4PseudoScene {
|
||||
// G4PhysicalVolumeModel sends touchables to this scene
|
||||
public:
|
||||
SceneTreeScene() = default;
|
||||
SceneTreeScene(G4VViewer*, G4PhysicalVolumeModel*);
|
||||
~SceneTreeScene() = default;
|
||||
void SetViewer(G4VViewer* pViewer) {fpViewer = pViewer;}
|
||||
void SetModel(G4VModel* pModel); // ...and more (see .cc)
|
||||
private:
|
||||
void ProcessVolume(const G4VSolid& solid) override;
|
||||
std::list<G4SceneTreeItem>::iterator FindOrInsertModel
|
||||
(const G4String& modelType,const G4String& modelID);
|
||||
std::list<G4SceneTreeItem>::iterator FindOrInsertTouchable
|
||||
(const G4String& modelID, G4SceneTreeItem& mother,
|
||||
G4int depth, const G4String& partialPathString, const G4String& fullPathString);
|
||||
G4VViewer* fpViewer = nullptr;
|
||||
G4VModel* fpModel = nullptr;
|
||||
G4int fMaximumExpandedDepth = 0; // To be calculated in SetModel
|
||||
G4PhysicalVolumeModel* fpPVModel = nullptr;
|
||||
std::list<G4SceneTreeItem>::iterator fModelIter; // Points to scene tree item for this model
|
||||
G4int fMaximumExpandedDepth = 0; // To be calculated in constructor
|
||||
const G4int fMaximumExpanded = 30; // So as not to swamp the GUI
|
||||
};
|
||||
SceneTreeScene& AccessSceneTreeScene() {return fSceneTreeScene;}
|
||||
void InsertModelInSceneTree(G4VModel*);
|
||||
const G4SceneTreeItem& GetSceneTree() {return fSceneTree;}
|
||||
G4SceneTreeItem& AccessSceneTree() {return fSceneTree;}
|
||||
void UpdateGUISceneTree(); // A utility
|
||||
const G4int fMaxNTouchables = 10000; // Limits memory to about 50 MB
|
||||
G4bool fCurtailDescent = false; // Flag to curtail descent into PV model for scene tree
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// Access functions.
|
||||
@@ -258,7 +258,6 @@ protected:
|
||||
G4ViewParameters fDefaultVP; // Default view parameters.
|
||||
G4double fKernelVisitElapsedTimeSeconds = 999.; // Default to a large number
|
||||
// Note: fKernelVisitElapsedTimeSeconds is measured in ProcessView().
|
||||
SceneTreeScene fSceneTreeScene; // G4PhysicalVolumeModel sends touchables to this scene
|
||||
G4SceneTreeItem fSceneTree;
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -126,15 +126,19 @@ public: // With description
|
||||
|
||||
private:
|
||||
|
||||
const G4String& GetDefaultGraphicsSystemName() override;
|
||||
void SetDefaultsByArgument(const G4String& system);
|
||||
void SetDefaultsByEnvironment();
|
||||
void SetDefaultsByFile(int argc, char** argv);
|
||||
void SetDefaultsByBatch();
|
||||
void SetDefaultsByBuildFlags();
|
||||
G4bool fSelected;
|
||||
|
||||
void RegisterGraphicsSystems();
|
||||
void RegisterModelFactories();
|
||||
int fUserArgc;
|
||||
char** fUserArgv;
|
||||
G4String fUserSpecifiedSystem;
|
||||
G4bool fSelected;
|
||||
|
||||
void RegisterGraphicsSystems() override;
|
||||
void RegisterModelFactories() override;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -149,6 +149,8 @@
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
|
||||
#define G4warn G4cout
|
||||
|
||||
// The inline keyword prevents the compiler making an external
|
||||
// reference even though they cannot actually be inlined since they
|
||||
// are virtual functions. This prevents a "multiple definition" error
|
||||
@@ -160,31 +162,54 @@
|
||||
|
||||
inline
|
||||
G4VisExecutive::G4VisExecutive(int argc, char** argv, const G4String& system,
|
||||
const G4String& verbosityString):
|
||||
const G4String& verbosityString):
|
||||
G4VisManager(verbosityString),
|
||||
fSelected(false)
|
||||
{
|
||||
if (!fSelected) SetDefaultsByArgument(system);
|
||||
if (!fSelected) SetDefaultsByEnvironment();
|
||||
if (!fSelected) SetDefaultsByFile(argc, argv);
|
||||
if (!fSelected) SetDefaultsByBatch();
|
||||
if (!fSelected) SetDefaultsByBuildFlags();
|
||||
fUserArgc = argc;
|
||||
fUserArgv = argv;
|
||||
fUserSpecifiedSystem = system;
|
||||
}
|
||||
|
||||
inline
|
||||
G4VisExecutive::G4VisExecutive (const G4String& verbosityString):
|
||||
G4VisManager(verbosityString),
|
||||
fSelected(false)
|
||||
G4VisManager(verbosityString)
|
||||
, fUserArgc(0) // >0 if argc is provided by the user...
|
||||
, fUserArgv(nullptr)
|
||||
, fSelected(false)
|
||||
{}
|
||||
|
||||
inline
|
||||
const G4String& G4VisExecutive::GetDefaultGraphicsSystemName ()
|
||||
{
|
||||
if (!fSelected) SetDefaultsByEnvironment();
|
||||
if (!fSelected) SetDefaultsByBatch();
|
||||
if (!fSelected) SetDefaultsByBuildFlags();
|
||||
if (fSelected) return fDefaultGraphicsSystemName;
|
||||
if (fUserArgc > 0) SetDefaultsByArgument(fUserSpecifiedSystem);
|
||||
if (!fSelected) SetDefaultsByEnvironment();
|
||||
if (!fSelected && fUserArgc > 0) SetDefaultsByFile(fUserArgc, fUserArgv);
|
||||
if (!fSelected) { SetDefaultsByBatch();
|
||||
if (fSelected) { // No UI session
|
||||
// Deal with this later - the user may have specified a system
|
||||
// on the command line - see G4VisCommandSceneHandlerCreate.
|
||||
return fDefaultGraphicsSystemName;
|
||||
}
|
||||
}
|
||||
if (!fSelected) SetDefaultsByBuildFlags();
|
||||
if (GetVerbosity() >= warnings) {
|
||||
G4warn << "Default graphics system is: " << fDefaultGraphicsSystemName
|
||||
<< " (based on " << fDefaultGraphicsSystemBasis << ")."
|
||||
<< "\nDefault window size hint is: " << fDefaultXGeometryString
|
||||
<< " (based on " << fDefaultXGeometryStringBasis << ")."
|
||||
<< "\nNote: Parameters specified on the command line will override these defaults."
|
||||
<< "\n Use \"vis/open\" without parameters to get these defaults."
|
||||
<< G4endl;
|
||||
}
|
||||
return fDefaultGraphicsSystemName;
|
||||
}
|
||||
|
||||
inline
|
||||
void G4VisExecutive::SetDefaultsByArgument(const G4String& system)
|
||||
{
|
||||
// 1st priority: selection by G4VisExecuitive argument
|
||||
// 1st priority: selection by G4VisExecutive argument
|
||||
if (!system.empty()) {
|
||||
fDefaultGraphicsSystemName = system;
|
||||
fDefaultGraphicsSystemBasis = "G4VisExecuitive argument";
|
||||
@@ -277,10 +302,10 @@ void G4VisExecutive::SetDefaultsByBatch()
|
||||
G4UIsession* session = G4UImanager::GetUIpointer()->GetBaseSession();
|
||||
if (session == nullptr // Usual case - pure batch
|
||||
|| dynamic_cast<G4UIbatch*>(session)) { // From a macro from batch
|
||||
// Choose an offscreen or file-writing system
|
||||
fDefaultGraphicsSystemName = "TSG_OFFSCREEN";
|
||||
fDefaultGraphicsSystemBasis = "batch session";
|
||||
fSelected = true;
|
||||
// Actually, in this case, we wish to force the user to specify a driver
|
||||
fDefaultGraphicsSystemName = "NO_UI_SESSION";
|
||||
fDefaultGraphicsSystemBasis = "no UI session";
|
||||
fSelected = true; // To prevent any further selection
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,8 +336,8 @@ void G4VisExecutive::SetDefaultsByBuildFlags()
|
||||
fSelected = true;
|
||||
}
|
||||
|
||||
inline void
|
||||
G4VisExecutive::RegisterGraphicsSystems () {
|
||||
inline
|
||||
void G4VisExecutive::RegisterGraphicsSystems () {
|
||||
|
||||
// Graphics Systems not needing external packages or libraries...
|
||||
RegisterGraphicsSystem (new G4ASCIITree);
|
||||
@@ -331,7 +356,6 @@ G4VisExecutive::RegisterGraphicsSystems () {
|
||||
// super-abbreviated names and fallback names where approproiate.
|
||||
|
||||
#ifdef G4VIS_USE_OPENGLQT
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
|
||||
G4VGraphicsSystem* ogliqt = new G4OpenGLImmediateQt;
|
||||
G4VGraphicsSystem* oglsqt = new G4OpenGLStoredQt;
|
||||
RegisterGraphicsSystem(ogliqt);
|
||||
@@ -340,7 +364,6 @@ G4VisExecutive::RegisterGraphicsSystems () {
|
||||
oglsqt->AddNickname("OGL");
|
||||
oglsqt->AddNickname("OGLS");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef G4VIS_USE_OPENGLXM
|
||||
G4VGraphicsSystem* oglixm = new G4OpenGLImmediateXm;
|
||||
@@ -482,12 +505,6 @@ G4VisExecutive::RegisterGraphicsSystems () {
|
||||
|
||||
#ifdef G4VIS_USE_TOOLSSG_QT_GLES
|
||||
tsg_qt_gles->AddNickname("TSG");
|
||||
# if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
if (GetVerbosity() >= startup) {
|
||||
G4cout << " Qt6: Asking ToolsSG to stand in for OpenGL" << G4endl;
|
||||
tsg_qt_gles->AddNickname("OGL");
|
||||
}
|
||||
# endif
|
||||
#elif defined(G4VIS_USE_TOOLSSG_XT_GLES)
|
||||
tsg_xt_gles->AddNickname("TSG");
|
||||
#elif defined(G4VIS_USE_TOOLSSG_X11_GLES)
|
||||
|
||||
@@ -338,6 +338,10 @@ public: // With description
|
||||
virtual void SetUpForAThread();
|
||||
// This method is invoked by G4WorkerRunManager
|
||||
|
||||
virtual void EventReadyForVis(const G4Event*);
|
||||
// This is invoked by G4SubEvtRunManager.
|
||||
// The event is passed to EndOfEventKernel.
|
||||
|
||||
static G4ThreadFunReturnType G4VisSubThread(G4ThreadFunArgType);
|
||||
// Vis sub-thread function.
|
||||
|
||||
@@ -362,6 +366,11 @@ private:
|
||||
// This is called on change of state (G4ApplicationState). It is
|
||||
// used to draw hits, digis and trajectories if included in the
|
||||
// current scene at the end of event, as required.
|
||||
G4bool Relinquishable (G4int eventID, G4int nKeptEvents, G4int nRequests);
|
||||
void EndOfEventKernel (const G4Event* event);
|
||||
void EndOfEventCleanup
|
||||
(const G4Event* currentEvent,
|
||||
G4int eventID); // See EndOfEventKernel: can be == -2?
|
||||
|
||||
void EndOfRun ();
|
||||
|
||||
@@ -402,6 +411,8 @@ public: // With description
|
||||
G4bool GetTransientsDrawnThisEvent () const;
|
||||
G4bool GetDrawEventOnlyIfToBeKept () const;
|
||||
const G4Event* GetRequestedEvent () const;
|
||||
G4int GetNKeepForPostProcessingRequests () const;
|
||||
G4int GetNKeepTheEventRequests () const;
|
||||
G4int GetNKeepRequests () const;
|
||||
G4bool GetReviewingKeptEvents () const;
|
||||
G4bool GetAbortReviewKeptEvents () const;
|
||||
@@ -412,7 +423,10 @@ public: // With description
|
||||
G4int GetMaxEventQueueSize () const;
|
||||
G4bool GetWaitOnEventQueueFull () const;
|
||||
#endif
|
||||
const G4String& GetDefaultGraphicsSystemName() const;
|
||||
virtual const G4String& GetDefaultGraphicsSystemName();
|
||||
// The above has to be virtual so that the derived class, G4VisExecutive,
|
||||
// can override and non-const because on first pass it may/should
|
||||
// determine these defaults.
|
||||
const G4String& GetDefaultXGeometryString () const;
|
||||
const G4String& GetDefaultGraphicsSystemBasis() const;
|
||||
const G4String& GetDefaultXGeometryStringBasis() const;
|
||||
@@ -484,19 +498,18 @@ protected:
|
||||
|
||||
void RegisterMessengers (); // Command messengers.
|
||||
|
||||
const G4int fVerbose;
|
||||
const G4int fVerbose;
|
||||
// No longer used. Use fVerbosity and access functions instead.
|
||||
// fVerbose is kept for backwards compatibility for some user
|
||||
// examples. (It is used in the derived user vis managers to print
|
||||
// available graphics systems.) It is initialised to 1 in the
|
||||
// constructor and cannot be changed.
|
||||
static Verbosity fVerbosity;
|
||||
|
||||
static Verbosity fVerbosity;
|
||||
|
||||
G4String fDefaultGraphicsSystemName;
|
||||
G4String fDefaultXGeometryString;
|
||||
G4String fDefaultGraphicsSystemBasis;
|
||||
G4String fDefaultXGeometryStringBasis;
|
||||
G4String fDefaultGraphicsSystemName;
|
||||
G4String fDefaultXGeometryString;
|
||||
G4String fDefaultGraphicsSystemBasis;
|
||||
G4String fDefaultXGeometryStringBasis;
|
||||
|
||||
private:
|
||||
|
||||
@@ -538,7 +551,8 @@ private:
|
||||
G4bool fTransientsDrawnThisRun;
|
||||
G4bool fTransientsDrawnThisEvent;
|
||||
G4int fNoOfEventsDrawnThisRun;
|
||||
G4int fNKeepRequests;
|
||||
G4int fNKeepForPostProcessingRequests;
|
||||
G4int fNKeepTheEventRequests;
|
||||
G4bool fEventKeepingSuspended;
|
||||
G4bool fDrawEventOnlyIfToBeKept;
|
||||
const G4Event* fpRequestedEvent; // If non-zero, scene handler uses.
|
||||
|
||||
@@ -98,8 +98,12 @@ inline const G4Event* G4VisManager::GetRequestedEvent() const {
|
||||
return fpRequestedEvent;
|
||||
}
|
||||
|
||||
inline G4int G4VisManager::GetNKeepRequests () const {
|
||||
return fNKeepRequests;
|
||||
inline G4int G4VisManager::GetNKeepForPostProcessingRequests () const {
|
||||
return fNKeepForPostProcessingRequests;
|
||||
}
|
||||
|
||||
inline G4int G4VisManager::GetNKeepTheEventRequests () const {
|
||||
return fNKeepTheEventRequests;
|
||||
}
|
||||
|
||||
inline G4bool G4VisManager::GetReviewingKeptEvents() const {
|
||||
@@ -134,7 +138,7 @@ inline G4bool G4VisManager::GetWaitOnEventQueueFull () const {
|
||||
|
||||
#endif
|
||||
|
||||
inline const G4String& G4VisManager::GetDefaultGraphicsSystemName () const {
|
||||
inline const G4String& G4VisManager::GetDefaultGraphicsSystemName () {
|
||||
return fDefaultGraphicsSystemName;
|
||||
}
|
||||
|
||||
|
||||
@@ -94,8 +94,6 @@
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
#include <set>
|
||||
|
||||
#define G4warn G4cout
|
||||
|
||||
G4VSceneHandler::G4VSceneHandler (G4VGraphicsSystem& system, G4int id, const G4String& name):
|
||||
@@ -602,29 +600,30 @@ void G4VSceneHandler::RequestPrimitives (const G4VSolid& solid)
|
||||
break;
|
||||
} else { // Print warnings and drop through to cloud
|
||||
G4VisManager::Verbosity verbosity = G4VisManager::GetVerbosity();
|
||||
static std::set<const G4VSolid*> problematicSolids;
|
||||
if (verbosity >= G4VisManager::errors &&
|
||||
problematicSolids.find(&solid) == problematicSolids.end()) {
|
||||
problematicSolids.insert(&solid);
|
||||
G4warn <<
|
||||
"ERROR: G4VSceneHandler::RequestPrimitives"
|
||||
"\n Polyhedron not available for " << solid.GetName ();
|
||||
G4PhysicalVolumeModel* pPVModel = dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
|
||||
if (pPVModel) {
|
||||
G4warn << "\n Touchable path: " << pPVModel->GetFullPVPath();
|
||||
auto pPVModel = dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
|
||||
if (pPVModel) {
|
||||
auto problematicVolume = pPVModel->GetCurrentPV();
|
||||
if (fProblematicVolumes.find(problematicVolume) == fProblematicVolumes.end()) {
|
||||
fProblematicVolumes[problematicVolume] = "Null polyhedron";
|
||||
if (verbosity >= G4VisManager::errors) {
|
||||
G4warn <<
|
||||
"ERROR: G4VSceneHandler::RequestPrimitives"
|
||||
"\n Polyhedron not available for " << solid.GetName ();
|
||||
G4warn << "\n Touchable path: " << pPVModel->GetFullPVPath();
|
||||
static G4bool explanation = false;
|
||||
if (!explanation) {
|
||||
explanation = true;
|
||||
G4warn <<
|
||||
"\n This means it cannot be visualized in the usual way on most systems."
|
||||
"\n 1) The solid may not have implemented the CreatePolyhedron method."
|
||||
"\n 2) For Boolean solids, the BooleanProcessor, which attempts to create"
|
||||
"\n the resultant polyhedron, may have failed."
|
||||
"\n Try RayTracer. It uses Geant4's tracking algorithms instead.";
|
||||
}
|
||||
}
|
||||
G4warn << "\n Drawing solid with cloud of points.";
|
||||
G4warn << G4endl;
|
||||
}
|
||||
static G4bool explanation = false;
|
||||
if (!explanation) {
|
||||
explanation = true;
|
||||
G4warn <<
|
||||
"\n This means it cannot be visualized in the usual way on most systems."
|
||||
"\n 1) The solid may not have implemented the CreatePolyhedron method."
|
||||
"\n 2) For Boolean solids, the BooleanProcessor, which attempts to create"
|
||||
"\n the resultant polyhedron, may have failed."
|
||||
"\n Try RayTracer. It uses Geant4's tracking algorithms instead.";
|
||||
}
|
||||
G4warn << "\n Drawing solid with cloud of points.";
|
||||
G4warn << G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -708,27 +707,31 @@ void G4VSceneHandler::ProcessScene()
|
||||
const std::vector<G4Scene::Model>& runDurationModelList =
|
||||
fpScene->GetRunDurationModelList();
|
||||
|
||||
if(runDurationModelList.size())
|
||||
{
|
||||
if(verbosity >= G4VisManager::confirmations)
|
||||
{
|
||||
if(runDurationModelList.size()) {
|
||||
if(verbosity >= G4VisManager::confirmations) {
|
||||
G4cout << "Traversing scene data..." << G4endl;
|
||||
static G4int first = true;
|
||||
if (first) {
|
||||
first = false;
|
||||
G4cout <<
|
||||
"(This could happen more than once - in fact, up to three times"
|
||||
"\nper rebuild, for opaque, transparent and non-hidden markers.)"
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Reset visibility of all objects to false - visible objects will then set to true
|
||||
fpViewer->AccessSceneTree().ResetVisibility();
|
||||
|
||||
|
||||
BeginModeling();
|
||||
|
||||
// Create modeling parameters from view parameters...
|
||||
G4ModelingParameters* pMP = CreateModelingParameters();
|
||||
|
||||
for(std::size_t i = 0; i < runDurationModelList.size(); ++i)
|
||||
{
|
||||
if(runDurationModelList[i].fActive)
|
||||
{
|
||||
fpModel = runDurationModelList[i].fpModel;
|
||||
fpModel->SetModelingParameters(pMP);
|
||||
for(std::size_t i = 0; i < runDurationModelList.size(); ++i) {
|
||||
if(runDurationModelList[i].fActive) {
|
||||
fpModel = runDurationModelList[i].fpModel;
|
||||
fpModel->SetModelingParameters(pMP);
|
||||
|
||||
// Describe to the current scene handler
|
||||
fpModel->DescribeYourselfTo(*this);
|
||||
@@ -737,17 +740,44 @@ void G4VSceneHandler::ProcessScene()
|
||||
// uncomment the next line and DrawExtent in namespace above.
|
||||
// DrawExtent(fpModel);
|
||||
|
||||
// Enter models in the scene tree, and for PV models, describe
|
||||
// Enter models in the scene tree. Then for PV models, describe
|
||||
// the model to the scene tree, i.e., enter all the touchables.
|
||||
auto& sceneTreeScene = fpViewer->AccessSceneTreeScene();
|
||||
sceneTreeScene.SetViewer(fpViewer);
|
||||
sceneTreeScene.SetModel(fpModel);
|
||||
if (dynamic_cast<G4PhysicalVolumeModel*>(fpModel)) {
|
||||
fpViewer->InsertModelInSceneTree(fpModel);
|
||||
auto pPVModel = dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
|
||||
if (pPVModel) {
|
||||
G4VViewer::SceneTreeScene sceneTreeScene(fpViewer, pPVModel);
|
||||
fpModel->DescribeYourselfTo(sceneTreeScene);
|
||||
}
|
||||
|
||||
// Reset modeling parameters pointer
|
||||
fpModel->SetModelingParameters(0);
|
||||
fpModel->SetModelingParameters(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Some printing
|
||||
if(verbosity >= G4VisManager::confirmations) {
|
||||
for (const auto& model: runDurationModelList) {
|
||||
if (model.fActive) {
|
||||
auto pvModel = dynamic_cast<G4PhysicalVolumeModel*>(model.fpModel);
|
||||
if (pvModel) {
|
||||
G4int nTouchables = 0;
|
||||
G4cout << "Numbers of touchables by depth in model \""
|
||||
<< pvModel->GetGlobalDescription() << "\":";
|
||||
for (const auto& dn : pvModel->GetNumberOfTouchables()) {
|
||||
G4cout << "\n Depth " << dn.first << ": " << dn.second;
|
||||
nTouchables += dn.second;
|
||||
}
|
||||
G4cout << "\n Total number of touchables: " << nTouchables << G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fProblematicVolumes.size() > 0) {
|
||||
G4cout << "Problematic volumes:";
|
||||
for (const auto& prob: fProblematicVolumes) {
|
||||
G4cout << "\n " << prob.first->GetName() << " (" << prob.second << ')';
|
||||
}
|
||||
G4cout << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -755,7 +785,7 @@ void G4VSceneHandler::ProcessScene()
|
||||
delete pMP;
|
||||
|
||||
EndModeling();
|
||||
}
|
||||
}
|
||||
|
||||
fReadyForTransients = true;
|
||||
|
||||
@@ -854,9 +884,7 @@ void G4VSceneHandler::DrawEvent(const G4Event* event)
|
||||
fpModel -> DescribeYourselfTo (*this);
|
||||
|
||||
// Enter models in the scene tree
|
||||
auto& sceneTreeScene = fpViewer->AccessSceneTreeScene();
|
||||
sceneTreeScene.SetViewer(fpViewer);
|
||||
sceneTreeScene.SetModel(fpModel);
|
||||
fpViewer->InsertModelInSceneTree(fpModel);
|
||||
|
||||
// Reset modeling parameters pointer
|
||||
fpModel -> SetModelingParameters(0);
|
||||
@@ -884,9 +912,7 @@ void G4VSceneHandler::DrawEndOfRunModels()
|
||||
fpModel -> DescribeYourselfTo (*this);
|
||||
|
||||
// Enter models in the scene tree
|
||||
auto& sceneTreeScene = fpViewer->AccessSceneTreeScene();
|
||||
sceneTreeScene.SetViewer(fpViewer);
|
||||
sceneTreeScene.SetModel(fpModel);
|
||||
fpViewer->InsertModelInSceneTree(fpModel);
|
||||
|
||||
// Reset modeling parameters pointer
|
||||
fpModel -> SetModelingParameters(0);
|
||||
@@ -1072,7 +1098,7 @@ G4DisplacedSolid* G4VSceneHandler::CreateCutawaySolid()
|
||||
break;
|
||||
}
|
||||
|
||||
G4Exception("G4VSceneHandler::CreateCutawaySolid", "visman107", JustWarning,
|
||||
G4Exception("G4VSceneHandler::CreateCutawaySolid", "visman0107", JustWarning,
|
||||
"Not programmed for more than 3 cutaway planes");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@ G4VViewer::G4VViewer(G4VSceneHandler& sceneHandler, G4int id, const G4String& na
|
||||
fDefaultVP = fVP;
|
||||
|
||||
fSceneTree.SetType(G4SceneTreeItem::root);
|
||||
fSceneTree.SetDescription(fName);
|
||||
}
|
||||
|
||||
G4VViewer::~G4VViewer()
|
||||
@@ -231,73 +232,129 @@ void G4VViewer::UpdateGUISceneTree()
|
||||
if (uiWindow) uiWindow->UpdateSceneTree(fSceneTree);
|
||||
}
|
||||
|
||||
void G4VViewer::SceneTreeScene::SetModel(G4VModel* pModel)
|
||||
void G4VViewer::InsertModelInSceneTree(G4VModel* model)
|
||||
{
|
||||
fpModel = pModel;
|
||||
auto modelType = model->GetType();
|
||||
auto modelDescription = model->GetGlobalDescription();
|
||||
|
||||
// Insert in tree (if not already inserted)
|
||||
auto& modelType = fpModel->GetType();
|
||||
auto& modelID = fpModel->GetGlobalDescription();
|
||||
FindOrInsertModel(modelType, modelID);
|
||||
auto type = G4SceneTreeItem::model;
|
||||
auto pvModel = dynamic_cast<G4PhysicalVolumeModel*>(model);
|
||||
if (pvModel) type = G4SceneTreeItem::pvmodel;
|
||||
|
||||
auto pvModel = dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
|
||||
fCurtailDescent = false; // This is used later in SceneTreeScene::ProcessVolume
|
||||
G4String furtherInfo;
|
||||
if (pvModel) {
|
||||
// Limit the expanded depth to limit the number expanded so as not to swamp the GUI
|
||||
G4int expanded = 0;
|
||||
for (const auto& dn : pvModel->GetNumberOfTouchables()) {
|
||||
expanded += dn.second;
|
||||
if (fMaximumExpandedDepth < dn.first) fMaximumExpandedDepth = dn.first;
|
||||
if (expanded > fMaximumExpanded) break;
|
||||
struct : public G4PseudoScene {
|
||||
void ProcessVolume(const G4VSolid&) {++fNTotalTouchables;}
|
||||
G4int fNTotalTouchables = 0;
|
||||
} counter;
|
||||
pvModel->DescribeYourselfTo(counter); // Calls ProcessVolume for every touchable
|
||||
if (counter.fNTotalTouchables > fMaxNTouchables) {
|
||||
std::ostringstream oss;
|
||||
oss << counter.fNTotalTouchables << " touchables - too many for scene tree";
|
||||
furtherInfo = oss.str();
|
||||
if (G4VisManager::GetInstance()->GetVerbosity() >= G4VisManager::warnings) {
|
||||
G4ExceptionDescription ed;
|
||||
ed << pvModel->GetGlobalDescription() <<
|
||||
":\n Too many touchables (" << counter.fNTotalTouchables
|
||||
<< ") for scene tree. Scene tree for this model will be empty.";
|
||||
G4Exception("G4VViewer::InsertModelInSceneTree", "visman0404", JustWarning, ed);
|
||||
}
|
||||
fCurtailDescent = true; // This is used later in SceneTreeScene::ProcessVolume
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::list<G4SceneTreeItem>::iterator
|
||||
G4VViewer::SceneTreeScene::FindOrInsertModel(const G4String& modelType, const G4String& modelID)
|
||||
{
|
||||
G4SceneTreeItem::Type type = G4SceneTreeItem::unidentified;
|
||||
if (dynamic_cast<G4PhysicalVolumeModel*>(fpModel)) {
|
||||
type = G4SceneTreeItem::pvmodel;
|
||||
}
|
||||
else {
|
||||
type = G4SceneTreeItem::model;
|
||||
}
|
||||
|
||||
auto& rootItem = fpViewer->fSceneTree;
|
||||
rootItem.SetDescription(fpViewer->GetName());
|
||||
|
||||
// Find appropriate model
|
||||
auto& modelItems = rootItem.AccessChildren();
|
||||
auto& modelItems = fSceneTree.AccessChildren();
|
||||
auto modelIter = modelItems.begin();
|
||||
auto pvModelIter = modelItems.end();
|
||||
for (; modelIter != modelItems.end(); ++modelIter) {
|
||||
if (modelIter->GetType() == G4SceneTreeItem::pvmodel) {
|
||||
pvModelIter = modelIter; // Last PV model
|
||||
pvModelIter = modelIter; // Last pre-existing PV model (if any)
|
||||
}
|
||||
if (modelIter->GetModelDescription() == modelID) break;
|
||||
if (modelIter->GetModelDescription() == modelDescription) break;
|
||||
}
|
||||
|
||||
if (modelIter == modelItems.end()) {
|
||||
// Model not seen before
|
||||
if (modelIter == modelItems.end()) { // Model not seen before
|
||||
G4SceneTreeItem modelItem(type);
|
||||
modelItem.SetDescription("model");
|
||||
modelItem.SetModelType(modelType);
|
||||
modelItem.SetModelDescription(modelID);
|
||||
modelItem.SetModelDescription(modelDescription);
|
||||
modelItem.SetFurtherInfo(furtherInfo);
|
||||
if (pvModelIter != modelItems.end() && // There was pre-existing PV Model...
|
||||
type == G4SceneTreeItem::pvmodel)
|
||||
{ // ...and the new model is also PV...
|
||||
modelIter = rootItem.InsertChild(++pvModelIter, modelItem); // ...insert after, else...
|
||||
type == G4SceneTreeItem::pvmodel) { // ...and the new model is also PV...
|
||||
fSceneTree.InsertChild(++pvModelIter, modelItem); // ...insert after, else...
|
||||
} else {
|
||||
fSceneTree.InsertChild(modelIter, modelItem); // ...insert at end
|
||||
}
|
||||
else {
|
||||
modelIter = rootItem.InsertChild(modelIter, modelItem); // ...insert at end
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Existing model - mark visible == active
|
||||
} else { // Existing model - mark visible == active
|
||||
modelIter->AccessVisAttributes().SetVisibility(true);
|
||||
}
|
||||
}
|
||||
|
||||
return modelIter;
|
||||
G4VViewer::SceneTreeScene::SceneTreeScene(G4VViewer* pViewer, G4PhysicalVolumeModel* pPVModel)
|
||||
: fpViewer (pViewer)
|
||||
, fpPVModel(pPVModel)
|
||||
{
|
||||
if (fpPVModel == nullptr) {
|
||||
G4Exception("G4VViewer::SceneTreeScene::SceneTreeScene", "visman0405", FatalException,
|
||||
"G4PhysicalVolumeModel pointer is null");
|
||||
return; // To keep Coverity happy
|
||||
}
|
||||
|
||||
// Describe the model to an empty scene simply to get the numbers of touchables
|
||||
struct : public G4PseudoScene {
|
||||
void ProcessVolume(const G4VSolid&) {}
|
||||
} counter;
|
||||
fpPVModel->DescribeYourselfTo(counter); // Calls ProcessVolume for every touchable
|
||||
|
||||
// Limit the expanded depth to limit the number expanded so as not to swamp the GUI
|
||||
G4int expanded = 0;
|
||||
for (const auto& dn : fpPVModel->GetNumberOfTouchables()) {
|
||||
expanded += dn.second;
|
||||
if (fMaximumExpandedDepth < dn.first) fMaximumExpandedDepth = dn.first;
|
||||
if (expanded > fMaximumExpanded) break;
|
||||
}
|
||||
|
||||
// Find appropriate model and its iterator
|
||||
const auto& modelID = fpPVModel->GetGlobalDescription();
|
||||
auto& modelItems = fpViewer->fSceneTree.AccessChildren();
|
||||
fModelIter = modelItems.begin();
|
||||
for (; fModelIter != modelItems.end(); ++fModelIter) {
|
||||
if (fModelIter->GetModelDescription() == modelID) break;
|
||||
}
|
||||
if (fModelIter == modelItems.end()) {
|
||||
G4Exception("G4VViewer::SceneTreeScene::SceneTreeScene", "visman0406", JustWarning,
|
||||
"Model not found");
|
||||
}
|
||||
}
|
||||
|
||||
void G4VViewer::SceneTreeScene::ProcessVolume(const G4VSolid&)
|
||||
{
|
||||
if (fpViewer->fCurtailDescent) {
|
||||
fpPVModel->CurtailDescent();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& modelID = fpPVModel->GetGlobalDescription();
|
||||
|
||||
std::ostringstream oss;
|
||||
oss << fpPVModel->GetFullPVPath(); // of this volume
|
||||
G4String fullPathString(oss.str()); // Has a leading space
|
||||
|
||||
// Navigate scene tree and find or insert touchables one by one
|
||||
// Work down the path - "name id", then "name id name id", etc.
|
||||
const auto& nodeIDs = fpPVModel->GetFullPVPath();
|
||||
G4String partialPathString;
|
||||
auto currentIter = fModelIter;
|
||||
G4int depth = 0;
|
||||
for (const auto& nodeID : nodeIDs) {
|
||||
std::ostringstream oss1;
|
||||
oss1 << nodeID;
|
||||
partialPathString += ' ' + oss1.str();
|
||||
currentIter =
|
||||
FindOrInsertTouchable(modelID, *currentIter, ++depth, partialPathString, fullPathString);
|
||||
}
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
@@ -305,12 +362,6 @@ std::list<G4SceneTreeItem>::iterator G4VViewer::SceneTreeScene::FindOrInsertTouc
|
||||
(const G4String& modelID, G4SceneTreeItem& mother,
|
||||
G4int depth, const G4String& partialPathString, const G4String& fullPathString)
|
||||
{
|
||||
auto pPVModel = dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
|
||||
if (pPVModel == nullptr) {
|
||||
G4ExceptionDescription ed;
|
||||
ed << fpModel->GetType() << ": not a Physical VolumeModel";
|
||||
G4Exception("G4VViewer::SceneTreeScene::FindOrInsertTouchable", "visman0404", FatalException, ed);
|
||||
}
|
||||
auto& children = mother.AccessChildren();
|
||||
auto childIter = children.begin();
|
||||
for (; childIter != children.end(); ++childIter) {
|
||||
@@ -328,13 +379,13 @@ std::list<G4SceneTreeItem>::iterator G4VViewer::SceneTreeScene::FindOrInsertTouc
|
||||
// Partial path string refers to the actual volume so it's a touchable
|
||||
childIter->SetType(G4SceneTreeItem::touchable);
|
||||
// Populate with information
|
||||
childIter->SetDescription(fpModel->GetCurrentTag());
|
||||
childIter->SetModelType(fpModel->GetType());
|
||||
childIter->SetDescription(fpPVModel->GetCurrentTag());
|
||||
childIter->SetModelType(fpPVModel->GetType());
|
||||
childIter->SetModelDescription(modelID);
|
||||
childIter->SetPVPath(partialPathString);
|
||||
if (fpVisAttributes) childIter->SetVisAttributes(*fpVisAttributes);
|
||||
if (pPVModel) childIter->SetAttDefs(pPVModel->GetAttDefs());
|
||||
if (pPVModel) childIter->SetAttValues(pPVModel->CreateCurrentAttValues());
|
||||
childIter->SetAttDefs(fpPVModel->GetAttDefs());
|
||||
childIter->SetAttValues(fpPVModel->CreateCurrentAttValues());
|
||||
} // Partial path string refers to an ancester - do nothing
|
||||
|
||||
} else {
|
||||
@@ -359,13 +410,13 @@ std::list<G4SceneTreeItem>::iterator G4VViewer::SceneTreeScene::FindOrInsertTouc
|
||||
// Insert new touchable item
|
||||
G4SceneTreeItem touchable(G4SceneTreeItem::touchable);
|
||||
touchable.SetExpanded(depth > fMaximumExpandedDepth? false: true);
|
||||
touchable.SetDescription(fpModel->GetCurrentTag());
|
||||
touchable.SetModelType(fpModel->GetType());
|
||||
touchable.SetDescription(fpPVModel->GetCurrentTag());
|
||||
touchable.SetModelType(fpPVModel->GetType());
|
||||
touchable.SetModelDescription(modelID);
|
||||
touchable.SetPVPath(partialPathString);
|
||||
if (fpVisAttributes) touchable.SetVisAttributes(*fpVisAttributes);
|
||||
if (pPVModel) touchable.SetAttDefs(pPVModel->GetAttDefs());
|
||||
if (pPVModel) touchable.SetAttValues(pPVModel->CreateCurrentAttValues());
|
||||
touchable.SetAttDefs(fpPVModel->GetAttDefs());
|
||||
touchable.SetAttValues(fpPVModel->CreateCurrentAttValues());
|
||||
childIter = mother.InsertChild(childIter,touchable);
|
||||
|
||||
} else {
|
||||
@@ -380,7 +431,7 @@ std::list<G4SceneTreeItem>::iterator G4VViewer::SceneTreeScene::FindOrInsertTouc
|
||||
std::ostringstream oss;
|
||||
oss << name << ':' << copyNo;
|
||||
ghost.SetDescription(oss.str());
|
||||
ghost.SetModelType(fpModel->GetType());
|
||||
ghost.SetModelType(fpPVModel->GetType());
|
||||
ghost.SetModelDescription(modelID);
|
||||
ghost.SetPVPath(partialPathString);
|
||||
ghost.AccessVisAttributes().SetVisibility(false);
|
||||
@@ -392,39 +443,6 @@ std::list<G4SceneTreeItem>::iterator G4VViewer::SceneTreeScene::FindOrInsertTouc
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
void G4VViewer::SceneTreeScene::ProcessVolume(const G4VSolid&)
|
||||
{
|
||||
auto& modelType = fpModel->GetType();
|
||||
auto& modelID = fpModel->GetGlobalDescription();
|
||||
auto modelIter = FindOrInsertModel(modelType, modelID);
|
||||
|
||||
auto pPVModel = dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
|
||||
if (pPVModel) { // G4PhysicalVolumeModel
|
||||
|
||||
std::ostringstream oss;
|
||||
oss << pPVModel->GetFullPVPath();
|
||||
G4String fullPathString(oss.str()); // Has a leading space - OK
|
||||
|
||||
// Navigate scene tree and find or insert touchables one by one
|
||||
const auto& nodeIDs = pPVModel->GetFullPVPath(); // std::vector<G4PhysicalVolumeNodeID>
|
||||
|
||||
// Work down the path - "name id", then "name id name id", etc.
|
||||
G4String partialPathString;
|
||||
auto currentIter = modelIter;
|
||||
G4int depth = 0;
|
||||
for (const auto& nodeID : nodeIDs) {
|
||||
std::ostringstream oss1;
|
||||
oss1 << nodeID;
|
||||
partialPathString += ' ' + oss1.str(); // Has a leading space - OK
|
||||
currentIter =
|
||||
FindOrInsertTouchable(modelID, *currentIter, ++depth, partialPathString, fullPathString);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Orphan solid - what to do? Push an empty scene tree item????????????????????????
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef G4MULTITHREADED
|
||||
|
||||
void G4VViewer::DoneWithMasterThread()
|
||||
|
||||
@@ -93,7 +93,34 @@ void G4VisCommandSceneActivateModel::SetNewValue (G4UIcommand*,
|
||||
|
||||
G4String searchString, activateString;
|
||||
std::istringstream is (newValue);
|
||||
is >> searchString >> activateString;
|
||||
// Need to handle the possibility that the search string
|
||||
// contains embedded blanks within quotation marks.
|
||||
// (This arises if the search string is automatically generated from the
|
||||
// global description, as in G4UIQt, clicking on check box.)
|
||||
auto lastQuotationMark = newValue.find_last_of('"');
|
||||
if (lastQuotationMark != std::string::npos) { // We have at least one quotation mark
|
||||
auto firstQuotationMark = newValue.find_first_of('"');
|
||||
if (lastQuotationMark != firstQuotationMark) { // We have at least two quotations marks
|
||||
// Note: there must not be more quotation marks - it upsets the command system.
|
||||
searchString = newValue.substr
|
||||
(firstQuotationMark + 1, lastQuotationMark - firstQuotationMark - 1);
|
||||
activateString = newValue.substr(lastQuotationMark + 2);
|
||||
// Perhaps we ought to check number of quotation marks
|
||||
G4int nQuotes = 0;
|
||||
for (auto c : newValue) {
|
||||
if (c == '"') nQuotes++;
|
||||
}
|
||||
if (nQuotes > 2) {
|
||||
G4ExceptionDescription ed;
|
||||
ed << "More than 2 quotation marks in search string: " << searchString;
|
||||
G4Exception("G4VisCommandSceneActivateModel::SetNewValue", "visman0301", JustWarning, ed);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// None or one quotation marks - just input two strings
|
||||
is >> searchString >> activateString;
|
||||
}
|
||||
G4bool activate = G4UIcommand::ConvertToBool(activateString);
|
||||
|
||||
G4Scene* pScene = fpVisManager->GetCurrentScene();
|
||||
@@ -127,10 +154,8 @@ void G4VisCommandSceneActivateModel::SetNewValue (G4UIcommand*,
|
||||
std::vector<G4Scene::Model>& runDurationModelList =
|
||||
pScene->SetRunDurationModelList();
|
||||
for (size_t i = 0; i < runDurationModelList.size(); i++) {
|
||||
const G4String& modelName =
|
||||
runDurationModelList[i].fpModel->GetGlobalDescription();
|
||||
if (searchString == "all" || modelName.find(searchString)
|
||||
!= std::string::npos) {
|
||||
const G4String& modelName = runDurationModelList[i].fpModel->GetGlobalDescription();
|
||||
if (searchString == "all" || modelName.find(searchString) != std::string::npos) {
|
||||
any = true;
|
||||
runDurationModelList[i].fActive = activate;
|
||||
if (verbosity >= G4VisManager::warnings) {
|
||||
@@ -145,10 +170,8 @@ void G4VisCommandSceneActivateModel::SetNewValue (G4UIcommand*,
|
||||
std::vector<G4Scene::Model>& endOfEventModelList =
|
||||
pScene->SetEndOfEventModelList();
|
||||
for (size_t i = 0; i < endOfEventModelList.size(); i++) {
|
||||
const G4String& modelName =
|
||||
endOfEventModelList[i].fpModel->GetGlobalDescription();
|
||||
if (searchString == "all" || modelName.find(searchString)
|
||||
!= std::string::npos) {
|
||||
const G4String& modelName = endOfEventModelList[i].fpModel->GetGlobalDescription();
|
||||
if (searchString == "all" || modelName.find(searchString) != std::string::npos) {
|
||||
any = true;
|
||||
endOfEventModelList[i].fActive = activate;
|
||||
if (verbosity >= G4VisManager::warnings) {
|
||||
@@ -163,10 +186,8 @@ void G4VisCommandSceneActivateModel::SetNewValue (G4UIcommand*,
|
||||
std::vector<G4Scene::Model>& endOfRunModelList =
|
||||
pScene->SetEndOfRunModelList();
|
||||
for (size_t i = 0; i < endOfRunModelList.size(); i++) {
|
||||
const G4String& modelName =
|
||||
endOfRunModelList[i].fpModel->GetGlobalDescription();
|
||||
if (searchString == "all" || modelName.find(searchString)
|
||||
!= std::string::npos) {
|
||||
const G4String& modelName = endOfRunModelList[i].fpModel->GetGlobalDescription();
|
||||
if (searchString == "all" || modelName.find(searchString) != std::string::npos) {
|
||||
any = true;
|
||||
endOfRunModelList[i].fActive = activate;
|
||||
if (verbosity >= G4VisManager::warnings) {
|
||||
|
||||
@@ -2643,8 +2643,8 @@ void G4VisCommandSceneAddText::SetNewValue (G4UIcommand*, G4String newValue) {
|
||||
G4bool successful = pScene -> AddRunDurationModel (model, warn);
|
||||
if (successful) {
|
||||
if (verbosity >= G4VisManager::confirmations) {
|
||||
G4cout << "Text \"" << text
|
||||
<< "\" has been added to scene \"" << currentSceneName << "\"."
|
||||
G4cout << "Text '" << text
|
||||
<< "' has been added to scene \"" << currentSceneName << "\"."
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
@@ -2731,8 +2731,8 @@ void G4VisCommandSceneAddText2D::SetNewValue (G4UIcommand*, G4String newValue) {
|
||||
model->SetType("Text2D");
|
||||
model->SetGlobalTag("Text2D");
|
||||
std::ostringstream oss;
|
||||
oss << "Text2D: \"" << g4text.GetText()
|
||||
<< "\" at " << g4text.GetPosition().x() << ',' << g4text.GetPosition().y()
|
||||
oss << "Text2D: '" << g4text.GetText()
|
||||
<< "' at " << g4text.GetPosition().x() << ',' << g4text.GetPosition().y()
|
||||
<< " with size " << g4text.GetScreenSize()
|
||||
<< " with offsets " << g4text.GetXOffset() << ',' << g4text.GetYOffset();
|
||||
model->SetGlobalDescription(oss.str());
|
||||
@@ -2740,8 +2740,8 @@ void G4VisCommandSceneAddText2D::SetNewValue (G4UIcommand*, G4String newValue) {
|
||||
G4bool successful = pScene -> AddRunDurationModel (model, warn);
|
||||
if (successful) {
|
||||
if (verbosity >= G4VisManager::confirmations) {
|
||||
G4cout << "2D text \"" << text
|
||||
<< "\" has been added to scene \"" << currentSceneName << "\"."
|
||||
G4cout << "2D text '" << text
|
||||
<< "' has been added to scene \"" << currentSceneName << "\"."
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ G4VisCommandSceneHandlerCreate::G4VisCommandSceneHandlerCreate (): fId (0) {
|
||||
parameter -> SetCurrentAsDefault(true);
|
||||
const G4GraphicsSystemList& gslist =
|
||||
fpVisManager -> GetAvailableGraphicsSystems ();
|
||||
G4String candidates;
|
||||
G4String candidates = "NO_UI_SESSION "; // A dummy candidate to catch issue
|
||||
for (const auto gs: gslist) {
|
||||
const G4String& name = gs -> GetName ();
|
||||
candidates += name + ' ';
|
||||
@@ -212,7 +212,7 @@ void G4VisCommandSceneHandlerCreate::SetNewValue (G4UIcommand* command,
|
||||
" no graphics systems available."
|
||||
"\n Did you instantiate any in"
|
||||
" YourVisManager::RegisterGraphicsSystems()?";
|
||||
command->CommandFailed(JustWarning,ed);
|
||||
command->CommandFailed(ed);
|
||||
return;
|
||||
}
|
||||
std::size_t iGS; // Selector index.
|
||||
@@ -237,6 +237,23 @@ void G4VisCommandSceneHandlerCreate::SetNewValue (G4UIcommand* command,
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
if (graphicsSystem == "NO_UI_SESSION") {
|
||||
G4Exception
|
||||
("G4VisCommandSceneHandlerCreate::SetNewValue","visman1001",JustWarning,
|
||||
"This looks like an attempt to use run-time vis driver selection."
|
||||
"\nYou have issued \"/vis/open\" or \"/vis/sceneHandler/create\" without"
|
||||
"\na parameter for the vis driver. This is allowed only if you instantiate"
|
||||
"\na UI session, and only if it is instantiated *before* the first"
|
||||
"\n\"/vis/open\" command. So:"
|
||||
"\na) It is not allowed in batch mode. If you really want to create"
|
||||
"\n some graphics with a file-writing driver in batch mode, you must"
|
||||
"\n request a specific driver on the \"/vis/open\" command line, e.g.,"
|
||||
"\n \"/vis/open TSG_OFFSCREEN\". See, examples/basic/B1/tsg_offscreen.mac."
|
||||
"\nb) If you want to exploit this feature in interactive mode, simply move"
|
||||
"\n the instantiation of the UI session earlier. In any case, this is good"
|
||||
"\n practice in order to capture output in a GUI session.");
|
||||
return;
|
||||
}
|
||||
// Shouldn't happen, since graphicsSystem should be a candidate
|
||||
G4ExceptionDescription ed;
|
||||
ed <<
|
||||
@@ -246,7 +263,7 @@ void G4VisCommandSceneHandlerCreate::SetNewValue (G4UIcommand* command,
|
||||
<< "\" requested."
|
||||
<< "\n Candidates are:";
|
||||
fpVisManager->PrintAvailableGraphicsSystems(verbosity,ed);
|
||||
command->CommandFailed(JustWarning,ed);
|
||||
command->CommandFailed(ed);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -274,9 +291,11 @@ void G4VisCommandSceneHandlerCreate::SetNewValue (G4UIcommand* command,
|
||||
if (iGS >= nSystems || loopCounter >=3) {
|
||||
G4ExceptionDescription ed;
|
||||
ed << "\"" << gsl[iGSBeingTested]->GetNickname()
|
||||
<< "\" is not compatible with your chosen session,"
|
||||
" and no fallback system found.";
|
||||
command->CommandFailed(JustWarning,ed);
|
||||
<< "\" is not compatible with the session,"
|
||||
"\nand no fallback system found. Make sure your session is"
|
||||
"\ninstantiated _before_ you create a graphics system.";
|
||||
G4Exception("G4VisCommandSceneHandlerCreate::SetNewValue",
|
||||
"visman1002", JustWarning, ed);
|
||||
return;
|
||||
}
|
||||
// A fallback system found...but go back and check this too.
|
||||
@@ -312,7 +331,7 @@ void G4VisCommandSceneHandlerCreate::SetNewValue (G4UIcommand* command,
|
||||
ed <<
|
||||
"ERROR: Scene handler \"" << newName
|
||||
<< "\" already exists.";
|
||||
command->CommandFailed(JustWarning,ed);
|
||||
command->CommandFailed(ed);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -349,7 +368,7 @@ void G4VisCommandSceneHandlerCreate::SetNewValue (G4UIcommand* command,
|
||||
<< "\" is not the new name \""
|
||||
<< newName
|
||||
<< "\".\n Please report to vis coordinator.";
|
||||
command->CommandFailed(JustWarning,ed);
|
||||
command->CommandFailed(ed);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -176,6 +176,81 @@ void G4VisCommandsTouchable::SetNewValue
|
||||
return;
|
||||
}
|
||||
|
||||
if (command == fpCommandDump) {
|
||||
|
||||
G4PhysicalVolumeModel::TouchableProperties properties =
|
||||
G4TouchableUtils::FindTouchableProperties(fCurrentTouchableProperties.fTouchablePath);
|
||||
if (properties.fpTouchablePV) {
|
||||
// To handle parameterisations we have to set the copy number
|
||||
properties.fpTouchablePV->SetCopyNo(properties.fCopyNo);
|
||||
G4PhysicalVolumeModel tempPVModel
|
||||
(properties.fpTouchablePV,
|
||||
G4PhysicalVolumeModel::UNLIMITED,
|
||||
properties.fTouchableGlobalTransform,
|
||||
nullptr, // Modelling parameters (not used)
|
||||
true, // use full extent (prevents calculating own extent, which crashes)
|
||||
properties.fTouchableBaseFullPVPath);
|
||||
const std::map<G4String,G4AttDef>* attDefs = tempPVModel.GetAttDefs();
|
||||
std::vector<G4AttValue>* attValues = tempPVModel.CreateCurrentAttValues();
|
||||
G4cout << G4AttCheck(attValues,attDefs);
|
||||
delete attValues;
|
||||
const auto lv = properties.fpTouchablePV->GetLogicalVolume();
|
||||
const auto polyhedron = lv->GetSolid()->GetPolyhedron();
|
||||
if (polyhedron) {
|
||||
polyhedron->SetVisAttributes(lv->GetVisAttributes());
|
||||
G4cout << "\nLocal polyhedron coordinates:\n" << *polyhedron;
|
||||
const G4Transform3D& transform = tempPVModel.GetCurrentTransform();
|
||||
polyhedron->Transform(transform);
|
||||
G4cout << "\nGlobal polyhedron coordinates:\n" << *polyhedron;
|
||||
}
|
||||
} else {
|
||||
G4warn << "Touchable not found." << G4endl;
|
||||
}
|
||||
return;
|
||||
|
||||
} else if (command == fpCommandFindPath) {
|
||||
|
||||
G4String pvName;
|
||||
G4int copyNo;
|
||||
std::istringstream iss(newValue);
|
||||
iss >> pvName >> copyNo;
|
||||
std::vector<G4PhysicalVolumesSearchScene::Findings> findingsVector;
|
||||
std::vector<G4VPhysicalVolume*>::iterator iterWorld =
|
||||
transportationManager->GetWorldsIterator();
|
||||
for (size_t i = 0; i < nWorlds; ++i, ++iterWorld) {
|
||||
G4PhysicalVolumeModel searchModel (*iterWorld); // Unlimited depth.
|
||||
G4ModelingParameters mp; // Default - no culling.
|
||||
searchModel.SetModelingParameters (&mp);
|
||||
// Find all instances at any position in the tree
|
||||
G4PhysicalVolumesSearchScene searchScene (&searchModel, pvName, copyNo);
|
||||
searchModel.DescribeYourselfTo (searchScene); // Initiate search.
|
||||
for (const auto& findings: searchScene.GetFindings()) {
|
||||
findingsVector.push_back(findings);
|
||||
}
|
||||
}
|
||||
for (const auto& findings: findingsVector) {
|
||||
G4cout
|
||||
<< findings.fFoundBasePVPath
|
||||
<< ' ' << findings.fpFoundPV->GetName()
|
||||
<< ' ' << findings.fFoundPVCopyNo
|
||||
<< " (mother logical volume: "
|
||||
<< findings.fpFoundPV->GetMotherLogical()->GetName()
|
||||
<< ')'
|
||||
<< G4endl;
|
||||
}
|
||||
if (findingsVector.size()) {
|
||||
G4cout
|
||||
<< "Use this to set a particular touchable with \"/vis/set/touchable <path>\""
|
||||
<< "\nor to see overlaps: \"/vis/drawLogicalVolume <mother-logical-volume-name>\""
|
||||
<< G4endl;
|
||||
} else {
|
||||
G4warn << pvName;
|
||||
if (copyNo >= 0) G4warn << ':' << copyNo;
|
||||
G4warn << " not found" << G4endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
G4VViewer* currentViewer = fpVisManager -> GetCurrentViewer ();
|
||||
if (!currentViewer) {
|
||||
if (verbosity >= G4VisManager::errors) {
|
||||
@@ -310,36 +385,6 @@ void G4VisCommandsTouchable::SetNewValue
|
||||
}
|
||||
return;
|
||||
|
||||
} else if (command == fpCommandDump) {
|
||||
|
||||
G4PhysicalVolumeModel::TouchableProperties properties =
|
||||
G4TouchableUtils::FindTouchableProperties(fCurrentTouchableProperties.fTouchablePath);
|
||||
if (properties.fpTouchablePV) {
|
||||
// To handle parameterisations we have to set the copy number
|
||||
properties.fpTouchablePV->SetCopyNo(properties.fCopyNo);
|
||||
G4PhysicalVolumeModel tempPVModel
|
||||
(properties.fpTouchablePV,
|
||||
G4PhysicalVolumeModel::UNLIMITED,
|
||||
properties.fTouchableGlobalTransform,
|
||||
nullptr, // Modelling parameters (not used)
|
||||
true, // use full extent (prevents calculating own extent, which crashes)
|
||||
properties.fTouchableBaseFullPVPath);
|
||||
const std::map<G4String,G4AttDef>* attDefs = tempPVModel.GetAttDefs();
|
||||
std::vector<G4AttValue>* attValues = tempPVModel.CreateCurrentAttValues();
|
||||
G4cout << G4AttCheck(attValues,attDefs);
|
||||
delete attValues;
|
||||
const auto lv = properties.fpTouchablePV->GetLogicalVolume();
|
||||
const auto polyhedron = lv->GetSolid()->GetPolyhedron();
|
||||
polyhedron->SetVisAttributes(lv->GetVisAttributes());
|
||||
G4cout << "\nLocal polyhedron coordinates:\n" << *polyhedron;
|
||||
const G4Transform3D& transform = tempPVModel.GetCurrentTransform();
|
||||
polyhedron->Transform(transform);
|
||||
G4cout << "\nGlobal polyhedron coordinates:\n" << *polyhedron;
|
||||
} else {
|
||||
G4warn << "Touchable not found." << G4endl;
|
||||
}
|
||||
return;
|
||||
|
||||
} else if (command == fpCommandExtentForField) {
|
||||
|
||||
G4PhysicalVolumeModel::TouchableProperties properties =
|
||||
@@ -363,48 +408,6 @@ void G4VisCommandsTouchable::SetNewValue
|
||||
}
|
||||
return;
|
||||
|
||||
} else if (command == fpCommandFindPath) {
|
||||
|
||||
G4String pvName;
|
||||
G4int copyNo;
|
||||
std::istringstream iss(newValue);
|
||||
iss >> pvName >> copyNo;
|
||||
std::vector<G4PhysicalVolumesSearchScene::Findings> findingsVector;
|
||||
std::vector<G4VPhysicalVolume*>::iterator iterWorld =
|
||||
transportationManager->GetWorldsIterator();
|
||||
for (size_t i = 0; i < nWorlds; ++i, ++iterWorld) {
|
||||
G4PhysicalVolumeModel searchModel (*iterWorld); // Unlimited depth.
|
||||
G4ModelingParameters mp; // Default - no culling.
|
||||
searchModel.SetModelingParameters (&mp);
|
||||
// Find all instances at any position in the tree
|
||||
G4PhysicalVolumesSearchScene searchScene (&searchModel, pvName, copyNo);
|
||||
searchModel.DescribeYourselfTo (searchScene); // Initiate search.
|
||||
for (const auto& findings: searchScene.GetFindings()) {
|
||||
findingsVector.push_back(findings);
|
||||
}
|
||||
}
|
||||
for (const auto& findings: findingsVector) {
|
||||
G4cout
|
||||
<< findings.fFoundBasePVPath
|
||||
<< ' ' << findings.fpFoundPV->GetName()
|
||||
<< ' ' << findings.fFoundPVCopyNo
|
||||
<< " (mother logical volume: "
|
||||
<< findings.fpFoundPV->GetMotherLogical()->GetName()
|
||||
<< ')'
|
||||
<< G4endl;
|
||||
}
|
||||
if (findingsVector.size()) {
|
||||
G4cout
|
||||
<< "Use this to set a particular touchable with \"/vis/set/touchable <path>\""
|
||||
<< "\nor to see overlaps: \"/vis/drawLogicalVolume <mother-logical-volume-name>\""
|
||||
<< G4endl;
|
||||
} else {
|
||||
G4warn << pvName;
|
||||
if (copyNo >= 0) G4warn << ':' << copyNo;
|
||||
G4warn << " not found" << G4endl;
|
||||
}
|
||||
return;
|
||||
|
||||
} else if (command == fpCommandLocalAxes) {
|
||||
|
||||
G4PhysicalVolumeModel::TouchableProperties properties =
|
||||
|
||||
@@ -1079,7 +1079,7 @@ void G4VisCommandViewerCreate::SetNewValue (G4UIcommand* command, G4String newVa
|
||||
if (existingViewer) {
|
||||
// ...bring view parameters up to date...
|
||||
fExistingVP = existingViewer->GetViewParameters();
|
||||
fExistingSceneTree = existingViewer->AccessSceneTree();
|
||||
fExistingSceneTree = existingViewer->GetSceneTree();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1112,7 +1112,7 @@ void G4VisCommandViewerCreate::SetNewValue (G4UIcommand* command, G4String newVa
|
||||
fThereWasAViewer = true;
|
||||
auto viewer = fpVisManager->GetCurrentViewer();
|
||||
fExistingVP = viewer->GetViewParameters();
|
||||
fExistingSceneTree = viewer->AccessSceneTree();
|
||||
fExistingSceneTree = viewer->GetSceneTree();
|
||||
} else {
|
||||
G4ExceptionDescription ed;
|
||||
if (newViewer) {
|
||||
|
||||
@@ -113,7 +113,8 @@ G4VisManager::G4VisManager (const G4String& verbosityString)
|
||||
, fTransientsDrawnThisRun (false)
|
||||
, fTransientsDrawnThisEvent (false)
|
||||
, fNoOfEventsDrawnThisRun (0)
|
||||
, fNKeepRequests (0)
|
||||
, fNKeepForPostProcessingRequests (0)
|
||||
, fNKeepTheEventRequests (0)
|
||||
, fEventKeepingSuspended (false)
|
||||
, fDrawEventOnlyIfToBeKept (false)
|
||||
, fpRequestedEvent (0)
|
||||
@@ -1735,7 +1736,7 @@ void G4VisManager::PrintAvailableGraphicsSystems
|
||||
for (const auto& gs: fAvailableGraphicsSystems) {
|
||||
const G4String& name = gs->GetName();
|
||||
const std::vector<G4String>& nicknames = gs->GetNicknames();
|
||||
if (verbosity <= warnings) {
|
||||
if (verbosity >= warnings) {
|
||||
// Brief output
|
||||
out << " " << name << " (";
|
||||
for (std::size_t i = 0; i < nicknames.size(); ++i) {
|
||||
@@ -1751,15 +1752,20 @@ void G4VisManager::PrintAvailableGraphicsSystems
|
||||
}
|
||||
out << std::endl;
|
||||
}
|
||||
out << "Default graphics system is: " << fDefaultGraphicsSystemName
|
||||
<< " (based on " << fDefaultGraphicsSystemBasis << ")."
|
||||
<< "\nDefault window size hint is: " << fDefaultXGeometryString
|
||||
<< " (based on " << fDefaultXGeometryStringBasis << ")."
|
||||
<< "\nNote: Parameters specified on the command line will override these defaults."
|
||||
<< "\n Use \"vis/open\" without parameters to get these defaults."
|
||||
out <<
|
||||
"You may choose a graphics system (driver) with a parameter of"
|
||||
"\nthe command \"/vis/open\" or \"/vis/sceneHandler/create\","
|
||||
"\nor you may omit the driver parameter and choose at run time:"
|
||||
"\n- by argument in the construction of G4VisExecutive;"
|
||||
"\n- by environment variable \"G4VIS_DEFAULT_DRIVER\";"
|
||||
"\n- by entry in \"~/.g4session\";"
|
||||
"\n- by build flags."
|
||||
"\n- Note: This feature is not allowed in batch mode."
|
||||
"\nFor further information see \"examples/basic/B1/exampleB1.cc\""
|
||||
"\nand \"vis.mac\"."
|
||||
<< std::endl;
|
||||
} else {
|
||||
out << " NONE!!! None registered - yet! Mmmmm!" << G4endl;
|
||||
out << " NONE!!! None registered - yet! Mmmmm!" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1983,14 +1989,14 @@ G4ThreadFunReturnType G4VisManager::G4VisSubThread(G4ThreadFunArgType p)
|
||||
// Then pop and release event
|
||||
G4MUTEXLOCK(&mtVisSubThreadMutex);
|
||||
mtVisEventQueue.pop_front();
|
||||
event->PostProcessingFinished();
|
||||
pVisManager->EndOfEventCleanup(event, event->GetEventID());
|
||||
eventQueueSize = mtVisEventQueue.size();
|
||||
G4MUTEXUNLOCK(&mtVisSubThreadMutex);
|
||||
// G4cout << "Event queue size (B): " << eventQueueSize << G4endl;
|
||||
}
|
||||
|
||||
G4MUTEXLOCK(&mtVisSubThreadMutex);
|
||||
G4int runInProgress = mtRunInProgress;
|
||||
G4bool runInProgress = mtRunInProgress;
|
||||
G4MUTEXUNLOCK(&mtVisSubThreadMutex);
|
||||
if (!runInProgress) {
|
||||
// EndOfRun on master thread has signalled end of run. There is
|
||||
@@ -2018,6 +2024,10 @@ namespace {
|
||||
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
G4bool isSubEventRunManagerType = false;
|
||||
}
|
||||
|
||||
void G4VisManager::BeginOfRun ()
|
||||
{
|
||||
if (fIgnoreStateChanges) return;
|
||||
@@ -2029,12 +2039,20 @@ void G4VisManager::BeginOfRun ()
|
||||
// << G4Threading::G4GetThreadId() << G4endl;
|
||||
|
||||
G4RunManager* runManager = G4RunManagerFactory::GetMasterRunManager();
|
||||
G4RunManager::RMType rmType = runManager->GetRunManagerType();
|
||||
isSubEventRunManagerType =
|
||||
(rmType == G4RunManager::subEventMasterRM) ||
|
||||
(rmType == G4RunManager::subEventWorkerRM);
|
||||
|
||||
// If sub-event active, ignore if invoked from worker thread
|
||||
if(isSubEventRunManagerType && G4Threading::IsWorkerThread()) return;
|
||||
|
||||
// For a fake run...
|
||||
G4int nEventsToBeProcessed = runManager->GetNumberOfEventsToBeProcessed();
|
||||
if (nEventsToBeProcessed == 0) return;
|
||||
|
||||
fNKeepRequests = 0;
|
||||
fNKeepForPostProcessingRequests = 0;
|
||||
fNKeepTheEventRequests = 0;
|
||||
fEventKeepingSuspended = false;
|
||||
fTransientsDrawnThisRun = false;
|
||||
if (fpSceneHandler) fpSceneHandler->SetTransientsDrawnThisRun(false);
|
||||
@@ -2082,6 +2100,8 @@ void G4VisManager::BeginOfEvent ()
|
||||
|
||||
if (!GetConcreteInstance()) return;
|
||||
|
||||
if (isSubEventRunManagerType) return;
|
||||
|
||||
// G4cout << "G4VisManager::BeginOfEvent: thread: "
|
||||
// << G4Threading::G4GetThreadId() << G4endl;
|
||||
|
||||
@@ -2093,19 +2113,38 @@ void G4VisManager::BeginOfEvent ()
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef G4MULTITHREADED
|
||||
void G4VisManager::EventReadyForVis(const G4Event* event)
|
||||
// This is invoked by G4SubEvtRunManager.
|
||||
// The event is passed to EndOfEventKernel.
|
||||
{
|
||||
if (fIgnoreStateChanges) return;
|
||||
|
||||
if (!GetConcreteInstance()) return;
|
||||
|
||||
G4bool valid = fpSceneHandler && IsValidView();
|
||||
if (!valid) return;
|
||||
|
||||
G4AutoLock al(&visEndOfEventMutex);
|
||||
EndOfEventKernel(event);
|
||||
}
|
||||
#endif
|
||||
|
||||
void G4VisManager::EndOfEvent ()
|
||||
{
|
||||
if (fIgnoreStateChanges) return;
|
||||
|
||||
if (!GetConcreteInstance()) return;
|
||||
|
||||
// G4cout << "G4VisManager::EndOfEvent: thread: "
|
||||
// << G4Threading::G4GetThreadId() << G4endl;
|
||||
if (isSubEventRunManagerType) return;
|
||||
|
||||
// G4cout << "G4VisManager::EndOfEvent: thread: "
|
||||
// << G4Threading::G4GetThreadId() << G4endl;
|
||||
|
||||
#ifdef G4MULTITHREADED
|
||||
G4AutoLock al(&visEndOfEventMutex);
|
||||
// Testing.
|
||||
// std::this_thread::sleep_for(std::chrono::seconds(5));
|
||||
// std::this_thread::sleep_for(std::chrono::seconds(5));
|
||||
#endif
|
||||
|
||||
// Don't call IsValidView unless there is a scene handler. This
|
||||
@@ -2124,10 +2163,81 @@ void G4VisManager::EndOfEvent ()
|
||||
const G4Event* currentEvent = eventManager->GetConstCurrentEvent();
|
||||
if (!currentEvent) return;
|
||||
|
||||
// Call kernel
|
||||
EndOfEventKernel(currentEvent);
|
||||
}
|
||||
|
||||
G4bool G4VisManager::Relinquishable (G4int eventID, G4int nKeptEvents, G4int nRequests)
|
||||
// Figures out if event is relinquishable, i.e., the run manager(s) may delete.
|
||||
// If _not_ relinquishable, KeepCurrentEvent is called as soon as event is recieved.
|
||||
// If relinquishable, PostProcesssingFinshed is called when drawing finished.
|
||||
// nKeptEvents is number of events currently kept by the run manager.
|
||||
// nRequests is the number of requests for keeping made by the vis maanager.
|
||||
{
|
||||
G4bool relinquishable = false;
|
||||
|
||||
G4RunManager* runManager = G4RunManagerFactory::GetMasterRunManager();
|
||||
G4int nEventsToBeProcessed = runManager->GetNumberOfEventsToBeProcessed();
|
||||
|
||||
if (fpScene->GetRefreshAtEndOfEvent()) {
|
||||
|
||||
// Unless last event (in which case wait end of run)...
|
||||
if (eventID < nEventsToBeProcessed - 1) {
|
||||
relinquishable = true;
|
||||
} else { // Last event - relinquish too if user has kept some
|
||||
if (nKeptEvents > 0) {
|
||||
relinquishable = true;
|
||||
}
|
||||
}
|
||||
fpSceneHandler->SetMarkForClearingTransientStore(true);
|
||||
|
||||
} else { // Accumulating events...
|
||||
|
||||
G4int maxNumberOfKeptEvents = fpScene->GetMaxNumberOfKeptEvents();
|
||||
|
||||
if (maxNumberOfKeptEvents >= 0 &&
|
||||
nRequests >= maxNumberOfKeptEvents) {
|
||||
|
||||
fEventKeepingSuspended = true;
|
||||
static G4bool warned = false;
|
||||
if (!warned) {
|
||||
if (fVerbosity >= warnings) {
|
||||
G4warn <<
|
||||
"WARNING: G4VisManager::EndOfEvent: Automatic event keeping suspended."
|
||||
<< G4endl;
|
||||
if (maxNumberOfKeptEvents > 0) {
|
||||
G4warn <<
|
||||
"\n The number of events exceeds the maximum, "
|
||||
<< maxNumberOfKeptEvents <<
|
||||
", that may be kept by\n the vis manager."
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
warned = true;
|
||||
}
|
||||
relinquishable = true;
|
||||
|
||||
} else if (maxNumberOfKeptEvents != 0) { // i.e., indefinite keeping
|
||||
|
||||
// Relinquish anyway if disabled or suspended
|
||||
if (!GetConcreteInstance() || fEventKeepingSuspended) {
|
||||
relinquishable = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return relinquishable;
|
||||
}
|
||||
|
||||
void G4VisManager::EndOfEventKernel (const G4Event* currentEvent)
|
||||
{
|
||||
G4RunManager* runManager = G4RunManagerFactory::GetMasterRunManager();
|
||||
const G4Run* currentRun = runManager->GetCurrentRun();
|
||||
G4EventManager* eventManager = G4EventManager::GetEventManager();
|
||||
|
||||
// Discard event if fDrawEventOnlyIfToBeKept flag is set unless the
|
||||
// user has requested the event to be kept.
|
||||
if (fDrawEventOnlyIfToBeKept) {
|
||||
if (!currentEvent->ToBeKept()) return;
|
||||
if (!currentEvent->KeepTheEventFlag()) return;
|
||||
}
|
||||
|
||||
if (G4Threading::IsMultithreadedApplication()) {
|
||||
@@ -2138,12 +2248,12 @@ void G4VisManager::EndOfEvent ()
|
||||
G4MUTEXLOCK(&mtVisSubThreadMutex);
|
||||
std::size_t eventQueueSize = mtVisEventQueue.size();
|
||||
G4MUTEXUNLOCK(&mtVisSubThreadMutex);
|
||||
// G4cout << "Event queue size (1): " << eventQueueSize << G4endl;
|
||||
// G4cout << "Event queue size (1): " << eventQueueSize << G4endl;
|
||||
|
||||
G4bool eventQueueFull = false;
|
||||
while (fMaxEventQueueSize > 0 && (G4int)eventQueueSize >= fMaxEventQueueSize) {
|
||||
|
||||
// G4cout << "Event queue size (2): " << eventQueueSize << G4endl;
|
||||
// G4cout << "Event queue size (2): " << eventQueueSize << G4endl;
|
||||
if (fWaitOnEventQueueFull) {
|
||||
static G4bool warned = false;
|
||||
if (!warned) {
|
||||
@@ -2192,24 +2302,25 @@ void G4VisManager::EndOfEvent ()
|
||||
}
|
||||
|
||||
if (!eventQueueFull) {
|
||||
G4MUTEXLOCK(&mtVisSubThreadMutex);
|
||||
// Keep event for processing and put event on vis event queue
|
||||
// Make sure the event is not deleted by the run manager while in the vis queue
|
||||
currentEvent->KeepForPostProcessing();
|
||||
if (fpScene->GetRefreshAtEndOfEvent()) {
|
||||
// Keep one event (cannot know which is last so any will do)
|
||||
if (fNKeepRequests == 0) {
|
||||
eventManager->KeepTheCurrentEvent();
|
||||
fNKeepRequests++;
|
||||
}
|
||||
fNKeepForPostProcessingRequests++;
|
||||
if (!Relinquishable(currentEvent->GetEventID(),
|
||||
(G4int)currentRun->GetEventVector()->size(),
|
||||
fNKeepTheEventRequests)) {
|
||||
eventManager->KeepTheCurrentEvent();
|
||||
fNKeepTheEventRequests++; // Counts number of calls to KeepTheCurrentEvent
|
||||
}
|
||||
G4MUTEXLOCK(&mtVisSubThreadMutex);
|
||||
// Put event on vis queue
|
||||
mtVisEventQueue.push_back(currentEvent);
|
||||
G4MUTEXUNLOCK(&mtVisSubThreadMutex);
|
||||
}
|
||||
|
||||
// G4MUTEXLOCK(&mtVisSubThreadMutex);
|
||||
// G4int eQS = mtVisEventQueue.size();
|
||||
// G4MUTEXUNLOCK(&mtVisSubThreadMutex);
|
||||
// G4cout << "Event queue size (5): " << eQS << G4endl;
|
||||
// G4MUTEXLOCK(&mtVisSubThreadMutex);
|
||||
// G4int eQS = mtVisEventQueue.size();
|
||||
// G4MUTEXUNLOCK(&mtVisSubThreadMutex);
|
||||
// G4cout << "Event queue size (5): " << eQS << G4endl;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2217,14 +2328,9 @@ void G4VisManager::EndOfEvent ()
|
||||
|
||||
// Sequential mode
|
||||
|
||||
G4int nEventsToBeProcessed = 0;
|
||||
G4int nKeptEvents = 0;
|
||||
G4int eventID = -2; // (If no run manager, triggers ShowView as normal.)
|
||||
if (currentRun) {
|
||||
nEventsToBeProcessed = runManager->GetNumberOfEventsToBeProcessed();
|
||||
eventID = currentEvent->GetEventID();
|
||||
const std::vector<const G4Event*>* events = currentRun->GetEventVector();
|
||||
if (events) nKeptEvents = (G4int)events->size();
|
||||
}
|
||||
|
||||
// We are about to draw the event (trajectories, etc.), but first we
|
||||
@@ -2237,69 +2343,45 @@ void G4VisManager::EndOfEvent ()
|
||||
// See, for example, G4HepRepFileSceneHandler::ClearTransientStore.
|
||||
ClearTransientStoreIfMarked();
|
||||
|
||||
// Keep - but relinquish (PostProcessingFinished) later if not needed
|
||||
currentEvent->KeepForPostProcessing();
|
||||
if (!Relinquishable(currentEvent->GetEventID(),
|
||||
(G4int)currentRun->GetEventVector()->size(),
|
||||
fNKeepTheEventRequests)) {
|
||||
eventManager->KeepTheCurrentEvent();
|
||||
fNKeepTheEventRequests++; // Counts number of calls to KeepTheCurrentEvent
|
||||
}
|
||||
|
||||
// Now draw the event...
|
||||
fpSceneHandler->DrawEvent(currentEvent);
|
||||
++fNoOfEventsDrawnThisRun;
|
||||
|
||||
if (fpScene->GetRefreshAtEndOfEvent()) {
|
||||
EndOfEventCleanup(currentEvent,eventID);
|
||||
}
|
||||
}
|
||||
|
||||
// Unless last event (in which case wait end of run)...
|
||||
if (eventID < nEventsToBeProcessed - 1) {
|
||||
// ShowView guarantees the view is flushed to the screen. It also
|
||||
// triggers other features such picking (if enabled) and allows
|
||||
// file-writing viewers to close the file.
|
||||
fpViewer->ShowView();
|
||||
} else { // Last event...
|
||||
// Keep, but only if user has not kept any...
|
||||
if (nKeptEvents == 0) {
|
||||
eventManager->KeepTheCurrentEvent();
|
||||
fNKeepRequests++;
|
||||
}
|
||||
}
|
||||
fpSceneHandler->SetMarkForClearingTransientStore(true);
|
||||
|
||||
}
|
||||
void G4VisManager::EndOfEventCleanup
|
||||
(const G4Event* currentEvent,
|
||||
G4int eventID) // See EndOfEventKernel: can be == -2?
|
||||
{
|
||||
G4RunManager* runManager = G4RunManagerFactory::GetMasterRunManager();
|
||||
G4int nKeptEvents = 0;
|
||||
const G4Run* currentRun = runManager->GetCurrentRun();
|
||||
if (currentRun) {
|
||||
const std::vector<const G4Event*>* events = currentRun->GetEventVector();
|
||||
if (events) nKeptEvents = (G4int)events->size();
|
||||
}
|
||||
|
||||
// Both modes - sequential and MT
|
||||
|
||||
if (!(fpScene->GetRefreshAtEndOfEvent())) {
|
||||
|
||||
// Accumulating events...
|
||||
|
||||
G4int maxNumberOfKeptEvents = fpScene->GetMaxNumberOfKeptEvents();
|
||||
|
||||
if (maxNumberOfKeptEvents >= 0 &&
|
||||
fNKeepRequests >= maxNumberOfKeptEvents) {
|
||||
|
||||
fEventKeepingSuspended = true;
|
||||
static G4bool warned = false;
|
||||
if (!warned) {
|
||||
if (fVerbosity >= warnings) {
|
||||
G4warn <<
|
||||
"WARNING: G4VisManager::EndOfEvent: Automatic event keeping suspended."
|
||||
<< G4endl;
|
||||
if (maxNumberOfKeptEvents > 0) {
|
||||
G4warn <<
|
||||
"\n The number of events exceeds the maximum, "
|
||||
<< maxNumberOfKeptEvents <<
|
||||
", that may be kept by\n the vis manager."
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
warned = true;
|
||||
}
|
||||
|
||||
} else if (maxNumberOfKeptEvents != 0) {
|
||||
|
||||
// If not disabled nor suspended.
|
||||
if (GetConcreteInstance() && !fEventKeepingSuspended) {
|
||||
// G4cout <<
|
||||
// "Requesting keeping event " << currentEvent->GetEventID()
|
||||
// << G4endl;
|
||||
eventManager->KeepTheCurrentEvent();
|
||||
fNKeepRequests++;
|
||||
}
|
||||
// Seems to relinquish every event - probably becuase it doesn't get here soon enough.
|
||||
// In fact, it makes sense to do this - immediate post processing is finished,
|
||||
// and a user-requested number of events have been kept. So great!
|
||||
if (Relinquishable(eventID, nKeptEvents, fNKeepForPostProcessingRequests)) {
|
||||
currentEvent->PostProcessingFinished();
|
||||
if (fpScene->GetRefreshAtEndOfEvent()) { // && eventID == -2?
|
||||
// ShowView guarantees the view is flushed to the screen. It also
|
||||
// triggers other features such picking (if enabled) and allows
|
||||
// file-writing viewers to close the file.
|
||||
fpViewer->ShowView();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2366,17 +2448,17 @@ void G4VisManager::EndOfRun ()
|
||||
if (nKeptEvents == 1) G4warn << " event has";
|
||||
else G4warn << " events have";
|
||||
G4warn << " been kept for refreshing and/or reviewing." << G4endl;
|
||||
if (nKeptEvents != fNKeepRequests) {
|
||||
if (nKeptEvents != fNKeepTheEventRequests) {
|
||||
G4warn << " (Note: ";
|
||||
if (fNKeepRequests == 0) {
|
||||
if (fNKeepTheEventRequests == 0) {
|
||||
G4warn << "No keep requests were";
|
||||
} else if (fNKeepRequests == 1) {
|
||||
} else if (fNKeepTheEventRequests == 1) {
|
||||
G4warn << "1 keep request was";
|
||||
} else {
|
||||
G4warn << fNKeepRequests << " keep requests were";
|
||||
G4warn << fNKeepTheEventRequests << " keep requests were";
|
||||
}
|
||||
G4warn << " made by the vis manager.";
|
||||
if (fNKeepRequests == 0) {
|
||||
if (fNKeepTheEventRequests == 0) {
|
||||
G4warn <<
|
||||
"\n The kept events are those you have asked to be kept in your user action(s).)";
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user