Import Geant4 11.0.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2021-06-25 16:12:29 +02:00
parent c968e26a39
commit 6399a014b6
4200 changed files with 207479 additions and 237366 deletions
@@ -1,6 +1,3 @@
#------------------------------------------------------------------------------
# Module : G4vis_management
# Package: Geant4.src.G4visualization.G4vis_management
#------------------------------------------------------------------------------
# - G4vis_management category build
geant4_global_library_target(COMPONENTS sources.cmake)
+94
View File
@@ -25,6 +25,100 @@ committal in the CVS repository !
History file for visualization management sub-category
------------------------------------------------------
07 June 2021 John Allison (visman-V10-07-10)
- G4VSceneHandler:
o Implement a default AddCompound (const G4Mesh&).
. Just draws the "container" volume and prints a G4Exception
with guidance.
- G4ViewParameters:
o Add new data members and accessors and operator<< and operator!=
G4bool fSpecialMeshRendering; // Request special rendering
std::vector<G4ModelingParameters::PVNameCopyNo> fSpecialMeshVolumes;
- G4VisCommandsViewerSet:
o Implement new commands:
/vis/viewer/set/specialMeshRendering
/vis/viewer/set/specialMeshVolumes
- G4VisCommandsSet: Minor improvement to guidance.
28 May 2021 Ben Morgan (visman-V10-07-09)
- Migrate to modular CMake build
22 May 2021 John Allison (visman-V10-07-08)
- Exploit C++17 to parse saved files in /vis/viewer/interpolate.
o Unifies Unix and Windows code.
o Avoids the use of Unix-specific system call to popen.
o Uses <filesystem>.
11 May 2021 John Allison (visman-V10-07-07)
- Introduce /vis/scene/add/localAxes and /vis/touchable/localAxes.
05 May 2021 Guy Barrand (visman-V10-07-06)
- G4VisExecutive.icc
o Four new (mutually exclusive) vis drivers (in vis_toolsg-V10-07-00):
. TOOLSSG_X11_GLES
. TOOLSSG_WINDOWS_GLES
. TOOLSSG_XT_GLES
. TOOLSSG_QT_GLE
31 March 2021 Gabriele Cosmo (visman-V10-07-05)
- Use existing facility to find logical volume in store, rather than looping
through in G4VisCommandSceneAddLogicalVolume::SetNewValue().
28 March 2021 John Allison (visman-V10-07-04)
- G4VisCommandsSceneAdd.cc:
o /vis/scene/add/volume (and /vis/drawVolume, which calls it):
. Exploit G4PhysicalVolumesSearchScene to streamline geometry tree searches.
. Avoid calculating extent of a temporary physical volume when not
necessary.
- G4VisCommandsSet.cc, G4VisCommandsTouchable.cc and G4VisCommandsViewer.cc:
o Add comment of explanation where using G4PhysicalVolumesSearchScene.
- The above does introduce a change of behaviour for the case that a user
names the volume(s) requested, e.g., "/vis/drawVolume Shape1". The user will
not normally see any difference - but it does avoid extravagant computation
in some circumstances. The issue is this (I copy and paste a snippet from the
code for /vis/scene/add/volume):
// When it comes to determining the extent of a physical volume we normally
// assume the user wishes to ignore "invisible" volumes. For example, most
// users make the world volume invisible. So we ask the physical volume
// model to traverse the geometry hierarchy, starting at the named physical
// volume, until it finds non-invisible ones, whose extents are accumulated
// to determine the overall extent. (Once a non-invisible volume is found,
// the search is curtailed - daughters are always contained within the mother
// so they have no subsequent influence on the extent of the mother - but the
// search continues at the same level until all highest level non-invisible
// volumes are found an their extents accumulated.) So the default is
G4bool useFullExtent = false;
// However, the above procedure can be time consuming in some situations, such
// as a nested parameterisation whose ultimate volumes are the first non-
// visible ones, which are typical of a medical "phantom". So we assume here
// below that if a user specifies a name other than "world" or "worlds" he/she
// wished the extent to be determined by the volume, whether it is visible
// or not. So we set useFullExtent true at that point below.
09 March 2021 John Allison (visman-V10-07-03)
- G4VisExecutive.icc: Remove Wt.
02 February 2021 John Allison (visman-V10-07-02)
- Interrupt macro (vis.mac) if graphics system invalid/unavailable.
o Issues "Batch is interrupted" and avoids long litany of further errors.
30 December 2020 John Allison (visman-V10-07-01)
- Remove deprecated G4VisManager::SetUserAction.
o Use RegisterRunDurationUserVisAction or similar instead. These functions
represent quite an advanced use of G4 visualisation and are rarely used.
They have been deprecated and a warning printed since 2016.
examples/extended/visualization were updated long ago.
29 December 2020 John Allison (visman-V10-07-00)
- G4VisCommandsSet.cc: /vis/set/extentForField:
o Parameters are no longer omitable.
- G4VisCommandsSceneAdd.cc: /vis/scene/add/electricField and magneticField:
o Improve guidance to take note of change to G4VFieldModel - see
modeling-V10-07-00 - namely that the number of data points is now
calculated on the basis of the extent, which can be set as above.
(If not set, the extent is null, and in G4VFieldModel, is taken to be
the extent of the current scene.)
16 November 2020 Gabriele Cosmo (visman-V10-06-12)
- Fixed typos in printed-out text. Addressing problem report #2285.
@@ -139,6 +139,7 @@ public: // With description
virtual void AddCompound (const G4VDigi&);
virtual void AddCompound (const G4THitsMap<G4double>&);
virtual void AddCompound (const G4THitsMap<G4StatDouble>&);
virtual void AddCompound (const G4Mesh&);
//////////////////////////////////////////////////////////////
// Functions for adding primitives.
@@ -201,6 +201,8 @@ public: // With description
G4double GetDisplayLightFrontRed () const;
G4double GetDisplayLightFrontGreen () const;
G4double GetDisplayLightFrontBlue () const;
G4bool IsSpecialMeshRendering () const;
const std::vector<G4ModelingParameters::PVNameCopyNo>& GetSpecialMeshVolumes() const;
// Here Follow functions to evaluate useful quantities as a
// function of the radius of the Bounding Extent of the object being
@@ -293,6 +295,8 @@ public: // With description
void SetDisplayLightFrontRed (G4double);
void SetDisplayLightFrontGreen (G4double);
void SetDisplayLightFrontBlue (G4double);
void SetSpecialMeshRendering (G4bool);
void SetSpecialMeshVolumes (const std::vector<G4ModelingParameters::PVNameCopyNo>&);
// Command dumping functions.
// For camera commands we need to provide the standard target point from
@@ -387,6 +391,8 @@ private:
G4double fDisplayLightFrontX, fDisplayLightFrontY, fDisplayLightFrontZ,
fDisplayLightFrontT;
G4double fDisplayLightFrontRed, fDisplayLightFrontGreen, fDisplayLightFrontBlue;
G4bool fSpecialMeshRendering; // Request special rendering of parameterised volumes
std::vector<G4ModelingParameters::PVNameCopyNo> fSpecialMeshVolumes; // If empty, all meshes.
enum { // Constants for geometry mask in ParseGeometry and related functions.
fNoValue = 0,
@@ -295,6 +295,13 @@ inline G4int G4ViewParameters::GetNumberOfCloudPoints () const {
return fNumberOfCloudPoints;
}
inline G4bool G4ViewParameters::IsSpecialMeshRendering () const
{return fSpecialMeshRendering;}
inline const std::vector<G4ModelingParameters::PVNameCopyNo>&
G4ViewParameters::GetSpecialMeshVolumes() const
{return fSpecialMeshVolumes;}
inline void
G4ViewParameters::SetDrawingStyle (G4ViewParameters::DrawingStyle style) {
fDrawingStyle = style;
@@ -553,3 +560,10 @@ inline void G4ViewParameters::SetDisplayLightFrontGreen (G4double displayLightFr
inline void G4ViewParameters::SetDisplayLightFrontBlue (G4double displayLightFrontBlue) {
fDisplayLightFrontBlue = displayLightFrontBlue;
}
inline void G4ViewParameters::SetSpecialMeshRendering (G4bool smr)
{fSpecialMeshRendering = smr;}
inline void G4ViewParameters::SetSpecialMeshVolumes
(const std::vector<G4ModelingParameters::PVNameCopyNo>& smvs)
{fSpecialMeshVolumes = smvs;}
@@ -283,6 +283,18 @@ private:
G4UIcommand* fpCommand;
};
class G4VisCommandSceneAddLocalAxes: public G4VVisCommandScene {
public:
G4VisCommandSceneAddLocalAxes ();
virtual ~G4VisCommandSceneAddLocalAxes ();
G4String GetCurrentValue (G4UIcommand* command);
void SetNewValue (G4UIcommand* command, G4String newValue);
private:
G4VisCommandSceneAddLocalAxes (const G4VisCommandSceneAddLocalAxes&);
G4VisCommandSceneAddLocalAxes& operator = (const G4VisCommandSceneAddLocalAxes&);
G4UIcommand* fpCommand;
};
class G4VisCommandSceneAddLogicalVolume: public G4VVisCommandScene {
public:
G4VisCommandSceneAddLogicalVolume ();
@@ -51,6 +51,7 @@ private:
G4UIcmdWithoutParameter* fpCommandDump;
G4UIcmdWithABool* fpCommandExtentForField;
G4UIcommand* fpCommandFindPath;
G4UIcmdWithoutParameter* fpCommandLocalAxes;
G4UIcmdWithABool* fpCommandShowExtent;
G4UIcmdWithABool* fpCommandVolumeForField;
};
@@ -75,6 +75,8 @@ private:
G4UIcommand* fpCommandProjection;
G4UIcmdWithAString* fpCommandRotationStyle;
G4UIcommand* fpCommandSectionPlane;
G4UIcmdWithABool* fpCommandSpecialMeshRendering;
G4UIcommand* fpCommandSpecialMeshVolumes;
G4UIcmdWithAString* fpCommandStyle;
G4UIcmdWith3VectorAndUnit* fpCommandTargetPoint;
G4UIcommand* fpCommandUpThetaPhi;
@@ -47,12 +47,6 @@
#include "G4VRML2File.hh"
#include "G4GMocrenFile.hh"
// FIXME : avoid mix with QT/WT driver (should be done by cmake??)
#if defined(G4VIS_USE_OPENGLWT)
// do not want GL2P2 in WT case
#undef G4VIS_BUILD_OPENGL_GL2PS
#endif
// Needing external packages or libraries...
#ifdef G4VIS_USE_DAWN
@@ -79,10 +73,6 @@
#include "G4OpenGLStoredQt.hh"
#endif
#ifdef G4VIS_USE_OPENGLWT
#include "G4OpenGLImmediateWt.hh"
#endif
#ifdef G4VIS_USE_OIX
#include "G4OpenInventorX.hh"
#include "G4OpenInventorXtExtended.hh"
@@ -109,6 +99,22 @@
#include "G4Qt3D.hh"
#endif
#ifdef G4VIS_USE_TOOLSSG_X11_GLES
#include "G4ToolsSGX11GLES.hh"
#endif
#ifdef G4VIS_USE_TOOLSSG_WINDOWS_GLES
#include "G4ToolsSGWindowsGLES.hh"
#endif
#ifdef G4VIS_USE_TOOLSSG_XT_GLES
#include "G4ToolsSGXtGLES.hh"
#endif
#ifdef G4VIS_USE_TOOLSSG_QT_GLES
#include "G4ToolsSGQtGLES.hh"
#endif
// 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
@@ -211,10 +217,6 @@ G4VisExecutive::RegisterGraphicsSystems () {
#endif
#endif
#ifdef G4VIS_USE_OPENGLWT
RegisterGraphicsSystem (new G4OpenGLImmediateWt);
#endif
// Register OI graphics system with super-abbreviated nickname
#ifdef G4VIS_USE_OI
G4VGraphicsSystem* oi = 0;
@@ -243,6 +245,23 @@ G4VisExecutive::RegisterGraphicsSystems () {
#ifdef G4VIS_USE_QT3D
RegisterGraphicsSystem (new G4Qt3D);
#endif
#ifdef G4VIS_USE_TOOLSSG_X11_GLES
RegisterGraphicsSystem (new G4ToolsSGX11GLES);
#endif
#ifdef G4VIS_USE_TOOLSSG_WINDOWS_GLES
RegisterGraphicsSystem (new G4ToolsSGWindowsGLES);
#endif
#ifdef G4VIS_USE_TOOLSSG_XT_GLES
RegisterGraphicsSystem (new G4ToolsSGXtGLES);
#endif
#ifdef G4VIS_USE_TOOLSSG_QT_GLES
RegisterGraphicsSystem (new G4ToolsSGQtGLES);
#endif
}
// See comments about inlining above.
@@ -186,12 +186,6 @@ public: // With description
void RegisterEndOfRunUserVisAction
(const G4String& name, G4VUserVisAction*,
const G4VisExtent& = G4VisExtent());
void SetUserAction
(G4VUserVisAction* pVisAction,
const G4VisExtent& = G4VisExtent());
// SetUserAction is deprecated. Use RegisterRunDurationUserVisAction
// or other of the above.
void SetUserActionExtent (const G4VisExtent&); //Legacy: deprecated.
G4bool RegisterGraphicsSystem (G4VGraphicsSystem*);
// Register an individual graphics system. Normally this is done in
+20 -44
View File
@@ -1,13 +1,8 @@
#------------------------------------------------------------------------------
# Module : G4vis_management
# Package: Geant4.src.G4visualization.G4vis_management
#------------------------------------------------------------------------------
# - G4vis_management module build definition
#
# Define the Geant4 Module.
#
geant4_define_module(NAME G4vis_management
HEADERS
geant4_add_module(G4vis_management
PUBLIC_HEADERS
G4GraphicsSystemList.hh
G4Scene.hh
G4Scene.icc
@@ -73,47 +68,28 @@ geant4_define_module(NAME G4vis_management
G4VisCommandsViewerDefault.cc
G4VisCommandsViewerSet.cc
G4VisManager.cc
G4VisStateDependent.cc
GRANULAR_DEPENDENCIES
G4VisStateDependent.cc)
geant4_module_link_libraries(G4vis_management
PUBLIC
G4modeling
G4hepgeometry
G4graphics_reps
G4globman
G4intercoms
G4hits
PRIVATE
G4csg
G4detutils
G4digits
G4event
G4geomBoolean
G4geometrymng
G4globman
G4graphics_reps
G4hepnumerics
G4hits
G4intercoms
G4magneticfield
G4materials
G4modeling
G4navigation
G4partman
G4procman
G4run
G4specsolids
G4tasking
G4track
G4tracking
G4vis_management
G4volumes
GLOBAL_DEPENDENCIES
G4digits_hits
G4event
G4geometry
G4global
G4graphics_reps
G4intercoms
G4geometrymng
G4materials
G4modeling
G4particles
G4processes
G4partman
G4tracking
G4run
G4tasking
G4track
G4tracking
)
# List any source specific properties here
G4navigation
G4digits
G4heprandom)
@@ -76,6 +76,7 @@
#include "G4VDigi.hh"
#include "G4ScoringManager.hh"
#include "G4VScoringMesh.hh"
#include "G4Mesh.hh"
#include "G4DefaultLinearColorMap.hh"
#include "Randomize.hh"
#include "G4StateManager.hh"
@@ -423,6 +424,34 @@ void G4VSceneHandler::AddCompound (const G4THitsMap<G4StatDouble>& hits) {
}
}
void G4VSceneHandler::AddCompound(const G4Mesh& mesh)
{
G4ExceptionDescription ed;
ed << "There has been an attempt to draw a mesh (a nested parameterisation),"
"\nbut it is not implemented by the current graphics driver. Here we simply"
"\ndraw the container, \"" << mesh.GetContainerVolume()->GetName() << "\".";
G4Exception("G4VSceneHandler::AddCompound(const G4Mesh&)",
"visman0107", JustWarning, ed);
const auto& pv = mesh.GetContainerVolume();
const auto& lv = pv->GetLogicalVolume();
const auto& solid = lv->GetSolid();
const auto& transform = mesh.GetTransform();
// Make sure container is visible
const auto& saveVisAtts = lv->GetVisAttributes();
auto tmpVisAtts = *saveVisAtts;
tmpVisAtts.SetVisibility(true);
auto colour = saveVisAtts->GetColour();
colour.SetAlpha(1.);
tmpVisAtts.SetColour(colour);
// Draw container
PreAddSolid(transform,tmpVisAtts);
solid->DescribeYourselfTo(*this);
PostAddSolid();
// Restore vis attributes
lv->SetVisAttributes(saveVisAtts);
}
void G4VSceneHandler::AddViewerToList (G4VViewer* pViewer) {
fViewerList.push_back (pViewer);
}
@@ -632,7 +661,7 @@ void G4VSceneHandler::RequestPrimitives (const G4VSolid& solid)
case G4ViewParameters::cloud:
{
// Form solid out of cloud of dots
// Form solid out of cloud of dots on surface of solid
G4Polymarker dots;
// Note: OpenGL has a fast implementation of polymarker so it's better
// to build a polymarker rather than add a succession of circles.
@@ -644,14 +673,14 @@ void G4VSceneHandler::RequestPrimitives (const G4VSolid& solid)
G4int numberOfCloudPoints = GetNumberOfCloudPoints(fpVisAttribs);
if (numberOfCloudPoints <= 0) numberOfCloudPoints = vp.GetNumberOfCloudPoints();
for (G4int i = 0; i < numberOfCloudPoints; ++i) {
G4ThreeVector p = solid.GetPointOnSurface();
dots.push_back(p);
G4ThreeVector p = solid.GetPointOnSurface();
dots.push_back(p);
}
BeginPrimitives (fObjectTransformation);
AddPrimitive(dots);
EndPrimitives ();
}
break;
}
}
}
@@ -705,14 +734,21 @@ void G4VSceneHandler::ProcessScene()
{
if(runDurationModelList[i].fActive)
{
fpModel = runDurationModelList[i].fpModel;
// Note: this is not the place to take action on
// pModel->GetTransformation(). The model must take care of
// this in pModel->DescribeYourselfTo(*this). See, for example,
// G4PhysicalVolumeModel and /vis/scene/add/logo.
fpModel->SetModelingParameters(pMP);
fpModel->DescribeYourselfTo(*this);
fpModel->SetModelingParameters(0);
fpModel = runDurationModelList[i].fpModel;
// Note: this is not the place to apply the transformation
// pModel->GetTransformation(). The model must take care of
// the required transformation itself - thus the models components
// have already been transformed. The model could receive the
// transformation in its constructor, e.g., G4PhysicalVolumeModel, or
// handle it in the model's SetTransformation, e.g., in G4AxesModel
// (relatively simple) or in G4ArrowModel (quite complicated) - see
// G4VModel.hh. This avoids having to transform the components perhaps
// multiple times. The reasons for this are mainly to do with how we
// implement G4PhysicalVolumeModel.
// See also /vis/scene/add/logo.
fpModel->SetModelingParameters(pMP);
fpModel->DescribeYourselfTo(*this);
fpModel->SetModelingParameters(0);
}
}
@@ -905,6 +941,9 @@ G4ModelingParameters* G4VSceneHandler::CreateModelingParameters ()
pModelingParams->SetVisAttributesModifiers(vp.GetVisAttributesModifiers());
pModelingParams->SetSpecialMeshRendering(vp.IsSpecialMeshRendering());
pModelingParams->SetSpecialMeshVolumes(vp.GetSpecialMeshVolumes());
return pModelingParams;
}
@@ -1050,6 +1050,19 @@ std::ostream& operator << (std::ostream& os, const G4ViewParameters& v) {
<< ' ' << v.fDisplayLightFrontGreen << ' ' << v.fDisplayLightFrontBlue;
}
os << "\n Special Mesh Rendering: ";
if (v.fSpecialMeshRendering) {
os << "on: ";
if (v.fSpecialMeshVolumes.empty()) {
os << "all meshes";
} else {
os << "selected meshes";
for (const auto& vol: v.fSpecialMeshVolumes) {
os << "\n " << vol.GetName() << ':' << vol.GetCopyNo();
}
}
} else os << "off";
return os;
}
@@ -1094,7 +1107,8 @@ G4bool G4ViewParameters::operator != (const G4ViewParameters& v) const {
(fAutoRefresh != v.fAutoRefresh) ||
(fBackgroundColour != v.fBackgroundColour) ||
(fPicking != v.fPicking) ||
(fRotationStyle != v.fRotationStyle)
(fRotationStyle != v.fRotationStyle) ||
(fSpecialMeshRendering != v.fSpecialMeshRendering)
)
return true;
@@ -1154,6 +1168,11 @@ G4bool G4ViewParameters::operator != (const G4ViewParameters& v) const {
}
}
if (fSpecialMeshRendering) {
if (fSpecialMeshVolumes != v.fSpecialMeshVolumes)
return true;;
}
return false;
}
@@ -372,28 +372,20 @@ void G4VisCommandOpen::SetNewValue (G4UIcommand* command, G4String newValue) {
newVerbose = 2;
UImanager->SetVerboseLevel(newVerbose);
auto errorCode = UImanager->ApplyCommand(G4String("/vis/sceneHandler/create " + systemName));
if (errorCode == 0) {
UImanager->ApplyCommand(G4String("/vis/viewer/create ! ! " + windowSizeHint));
} else {
// Use set to get alphabetical order
std::set<G4String> candidates;
for (const auto gs: fpVisManager -> GetAvailableGraphicsSystems()) {
// Just list nicknames, but exclude FALLBACK nicknames
for (const auto& nickname: gs->GetNicknames()) {
if (!nickname.contains("FALLBACK")) {
candidates.insert(nickname);
}
}
}
std::ostringstream oss;
oss << "Candidates are:";
for (const auto& candidate: candidates) {
oss << ' ' << candidate;
};
G4cerr << oss.str() << G4endl;
command->CommandFailed(oss);
if (errorCode != 0) {
G4ExceptionDescription ed;
ed << "sub-command \"/vis/sceneHandler/create\" failed.";
command->CommandFailed(errorCode,ed);
goto restore;
}
UImanager->SetVerboseLevel(keepVerbose);
errorCode = UImanager->ApplyCommand(G4String("/vis/viewer/create ! ! " + windowSizeHint));
if (errorCode != 0) {
G4ExceptionDescription ed;
ed << "sub-command \"/vis/viewer/create\" failed.";
command->CommandFailed(errorCode,ed);
goto restore;
}
restore: UImanager->SetVerboseLevel(keepVerbose);
}
////////////// /vis/specify ///////////////////////////////////////
@@ -573,11 +573,11 @@ void G4VisCommandSceneList::SetNewValue (G4UIcommand*, G4String newValue) {
G4cout << G4endl;
}
if (!found) {
G4cout << "No scenes found";
G4cerr << "No scenes found";
if (name != "all") {
G4cout << " of name \"" << name << "\"";
G4cerr << " of name \"" << name << "\"";
}
G4cout << "." << G4endl;
G4cerr << "." << G4endl;
}
}
@@ -533,19 +533,19 @@ G4VisCommandSceneAddElectricField::G4VisCommandSceneAddElectricField () {
fpCommand -> SetGuidance
("Adds electric field representation to current scene.");
fpCommand -> SetGuidance
("The first parameter is no. of data points per half scene. So, possibly, at"
("The first parameter is no. of data points per half extent. So, possibly, at"
"\nmaximum, the number of data points sampled is (2*n+1)^3, which can grow"
"\nlarge--be warned!"
"\nThe default value is 10, i.e., a 21x21x21 array, i.e., 9,261 sampling points."
"\nThat may swamp you scene, but usually, a field is limited to a small part of"
"\nthe scene, so it's not a problem. But if it is, here are some of the things"
"\nThat may swamp your view, but usually, a field is limited to a small part of"
"\nthe extent, so it's not a problem. But if it is, here are some of the things"
"\nyou can do:"
"\n- reduce the number of data points per half scene (first parameter);"
"\n- reduce the number of data points per half extent (first parameter);"
"\n- specify \"lightArrow\" (second parameter);"
"\n- restrict the region sampled with \"/vis/set/extentForField\";"
"\n- restrict the drawing to a specific volume with"
"\n \"/vis/set/volumeForField\" or \"/vis/touchable/volumeForField\"."
"\nNote: you may have to deactivate existing field models with"
"\nNote: you might have to deactivate existing field models with"
"\n \"/vis/scene/activateModel Field false\" and re-issue"
"\n \"/vis/scene/add/...Field\" command again.");
fpCommand -> SetGuidance
@@ -553,7 +553,7 @@ G4VisCommandSceneAddElectricField::G4VisCommandSceneAddElectricField () {
"\nto the magnitude of the field and the colour is mapped onto the range"
"\nas a fraction of the maximum magnitude: 0->0.5->1 is red->green->blue.");
G4UIparameter* parameter;
parameter = new G4UIparameter ("nDataPointsPerHalfScene", 'i', omitable = true);
parameter = new G4UIparameter ("nDataPointsPerHalfExtent", 'i', omitable = true);
parameter -> SetDefaultValue (10);
fpCommand -> SetParameter (parameter);
parameter = new G4UIparameter ("representation", 's', omitable = true);
@@ -584,10 +584,10 @@ void G4VisCommandSceneAddElectricField::SetNewValue
return;
}
G4int nDataPointsPerHalfScene;
G4int nDataPointsPerHalfExtent;
G4String representation;
std::istringstream iss(newValue);
iss >> nDataPointsPerHalfScene >> representation;
iss >> nDataPointsPerHalfExtent >> representation;
G4ElectricFieldModel::Representation
modelRepresentation = G4ElectricFieldModel::fullArrow;
if (representation == "lightArrow") {
@@ -595,7 +595,7 @@ void G4VisCommandSceneAddElectricField::SetNewValue
}
G4VModel* model;
model = new G4ElectricFieldModel
(nDataPointsPerHalfScene,modelRepresentation,
(nDataPointsPerHalfExtent,modelRepresentation,
fCurrentArrow3DLineSegmentsPerCircle,
fCurrentExtentForField,
fCurrrentPVFindingsForField);
@@ -607,8 +607,8 @@ void G4VisCommandSceneAddElectricField::SetNewValue
<< "Electric field, if any, will be drawn in scene \""
<< currentSceneName
<< "\"\n with "
<< nDataPointsPerHalfScene
<< " data points per half scene and with representation \""
<< nDataPointsPerHalfExtent
<< " data points per half extent and with representation \""
<< representation
<< '\"'
<< G4endl;
@@ -1240,6 +1240,132 @@ void G4VisCommandSceneAddLine2D::Line2D::operator()
sceneHandler.EndPrimitives2D();
}
////////////// /vis/scene/add/localAxes ///////////////////////////////////////
G4VisCommandSceneAddLocalAxes::G4VisCommandSceneAddLocalAxes () {
G4bool omitable;
fpCommand = new G4UIcommand ("/vis/scene/add/localAxes", this);
fpCommand -> SetGuidance
("Adds local axes to physical volume(s).");
G4UIparameter* parameter;
parameter = new G4UIparameter ("physical-volume-name", 's', omitable = false);
fpCommand -> SetParameter (parameter);
parameter = new G4UIparameter ("copy-no", 'i', omitable = true);
parameter -> SetGuidance ("If negative, matches any copy no.");
parameter -> SetDefaultValue (-1);
fpCommand -> SetParameter (parameter);
}
G4VisCommandSceneAddLocalAxes::~G4VisCommandSceneAddLocalAxes () {
delete fpCommand;
}
G4String G4VisCommandSceneAddLocalAxes::GetCurrentValue (G4UIcommand*) {
return "world 0 -1";
}
void G4VisCommandSceneAddLocalAxes::SetNewValue (G4UIcommand*,
G4String newValue) {
G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
G4bool warn = verbosity >= G4VisManager::warnings;
G4Scene* pScene = fpVisManager->GetCurrentScene();
if (!pScene) {
if (verbosity >= G4VisManager::errors) {
G4cerr << "ERROR: No current scene. Please create one." << G4endl;
}
return;
}
G4String name;
G4int copyNo;
std::istringstream is (newValue);
is >> name >> copyNo;
std::vector<G4PhysicalVolumesSearchScene::Findings> findingsVector;
// Search all worlds...
G4TransportationManager* transportationManager =
G4TransportationManager::GetTransportationManager ();
std::vector<G4VPhysicalVolume*>::iterator iterWorld =
transportationManager->GetWorldsIterator();
size_t nWorlds = transportationManager->GetNoWorlds();
for (size_t i = 0; i < nWorlds; ++i, ++iterWorld) {
G4ModelingParameters mp; // Default - no culling.
G4PhysicalVolumeModel searchModel
(*iterWorld,
G4PhysicalVolumeModel::UNLIMITED,
G4Transform3D(),
&mp,
true); // Use full extent (avoids initial descent of geometry tree)
G4PhysicalVolumesSearchScene searchScene
(&searchModel, name, copyNo);
searchModel.DescribeYourselfTo (searchScene); // Initiate search.
for (const auto& findings: searchScene.GetFindings()) {
findingsVector.push_back(findings);
}
}
G4int id = 0; // To distinguish axes models by their global description
for (const auto& findings: findingsVector) {
// Create axes model based on size and transformation of found volume(s).
const auto& extent = findings.fpFoundPV->GetLogicalVolume()->GetSolid()->GetExtent();
const auto& transform = findings.fFoundObjectTransformation;
const G4double lengthMax = extent.GetExtentRadius()/2.;
const G4double intLog10LengthMax = std::floor(std::log10(lengthMax));
G4double length = std::pow(10,intLog10LengthMax);
if (5.*length < lengthMax) length *= 5.;
else if (2.*length < lengthMax) length *= 2.;
const auto& axesModel = new G4AxesModel(0.,0.,0.,length);
axesModel->SetTransformation(transform);
axesModel->SetGlobalTag("LocalAxesModel");
std::ostringstream oss; oss
<< "Local Axes for " << findings.fpFoundPV->GetName()
<< ':' << findings.fFoundPVCopyNo << ':' << id++;
axesModel->SetGlobalDescription(oss.str());
// ...so add it to the scene.
G4bool successful = pScene->AddRunDurationModel(axesModel,warn);
if (successful) {
if (verbosity >= G4VisManager::confirmations) {
G4cout << "\"" << findings.fpFoundPV->GetName()
<< "\", copy no. " << findings.fFoundPVCopyNo
<< ",\n found in searched volume \""
<< findings.fpSearchPV->GetName()
<< "\" at depth " << findings.fFoundDepth
<< ",\n base path: \"" << findings.fFoundBasePVPath
<< "\".\n Local axes have been added to scene \""
<< pScene->GetName() << "\".";
if (verbosity >= G4VisManager::parameters) {
G4cout << " With extent " << extent
<< "\n at " << transform.getRotation()
<< " " << transform.getTranslation();
}
G4cout << G4endl;
}
} else {
G4VisCommandsSceneAddUnsuccessful(verbosity);
}
}
if (findingsVector.empty()) {
if (verbosity >= G4VisManager::errors) {
G4cerr << "ERROR: Volume \"" << name << "\"";
if (copyNo >= 0) {
G4cerr << ", copy no. " << copyNo << ",";
}
G4cerr << " not found." << G4endl;
}
G4VisCommandsSceneAddUnsuccessful(verbosity);
return;
}
CheckSceneAndNotifyHandlers(pScene);
}
////////////// /vis/scene/add/logicalVolume //////////////////////////////////
G4VisCommandSceneAddLogicalVolume::G4VisCommandSceneAddLogicalVolume () {
@@ -1315,20 +1441,9 @@ void G4VisCommandSceneAddLogicalVolume::SetNewValue (G4UIcommand*,
G4bool checkOverlaps = G4UIcommand::ConvertToBool(overlapString);
G4LogicalVolumeStore *pLVStore = G4LogicalVolumeStore::GetInstance();
int nLV = pLVStore -> size ();
int iLV;
G4LogicalVolume* pLV = 0;
for (iLV = 0; iLV < nLV; iLV++ ) {
pLV = (*pLVStore) [iLV];
if (pLV -> GetName () == name) break;
}
if (iLV == nLV) {
if (verbosity >= G4VisManager::errors) {
G4cerr << "ERROR: Logical volume " << name
<< " not found in logical volume store." << G4endl;
}
return;
}
G4LogicalVolume* pLV = nullptr;
pLV = pLVStore->GetVolume(name);
if (pLV == nullptr) return; // Volume not found; warning message thrown
const std::vector<G4Scene::Model>& rdModelList =
pScene -> GetRunDurationModelList();
@@ -1712,7 +1827,7 @@ void G4VisCommandSceneAddLogo::SetNewValue (G4UIcommand*, G4String newValue) {
if (verbosity >= G4VisManager::parameters) {
G4cout << "\n with extent " << extent
<< "\n at " << transform.getRotation()
<< transform.getTranslation();
<< " " << transform.getTranslation();
}
G4cout << G4endl;
}
@@ -2398,7 +2513,7 @@ void G4VisCommandSceneAddScale::SetNewValue (G4UIcommand*, G4String newValue) {
if (verbosity >= G4VisManager::parameters) {
G4cout << "\n with extent " << scaleExtent
<< "\n at " << transform.getRotation()
<< transform.getTranslation();
<< " " << transform.getTranslation();
}
G4cout << G4endl;
}
@@ -3058,6 +3173,24 @@ void G4VisCommandSceneAddVolume::SetNewValue (G4UIcommand*,
std::vector<G4PhysicalVolumesSearchScene::Findings> findingsVector;
// When it comes to determining the extent of a physical volume we normally
// assume the user wishes to ignore "invisible" volumes. For example, most
// users make the world volume invisible. So we ask the physical volume
// model to traverse the geometry hierarchy, starting at the named physical
// volume, until it finds non-invisible ones, whose extents are accumulated
// to determine the overall extent. (Once a non-invisible volume is found,
// the search is curtailed - daughters are always contained within the mother
// so they have no subsequent influence on the extent of the mother - but the
// search continues at the same level until all highest level non-invisible
// volumes are found an their extents accumulated.) So the default is
G4bool useFullExtent = false;
// However, the above procedure can be time consuming in some situations, such
// as a nested parameterisation whose ultimate volumes are the first non-
// visible ones, which are typical of a medical "phantom". So we assume here
// below that if a user specifies a name other than "world" or "worlds" he/she
// wished the extent to be determined by the volume, whether it is visible
// or not. So we set useFullExtent true at that point below.
if (name == "world") {
findingsVector.push_back
@@ -3084,13 +3217,25 @@ void G4VisCommandSceneAddVolume::SetNewValue (G4UIcommand*,
} else { // Search all worlds...
// Use the model's full extent. This assumes the user wants these
// volumes in the findings vector (there could be more than one) to
// determine the scene's extent. Otherwise G4PhysicalVolumeModel would
// re-calculate each volume's extent based on visibility, etc., which
// could be time consuming.
useFullExtent = true;
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);
G4PhysicalVolumesSearchScene searchScene (&searchModel, name, copyNo);
G4PhysicalVolumeModel searchModel
(*iterWorld,
G4PhysicalVolumeModel::UNLIMITED,
G4Transform3D(),
&mp,
useFullExtent);
G4PhysicalVolumesSearchScene searchScene
(&searchModel, name, copyNo, requestedDepthOfDescent);
searchModel.DescribeYourselfTo (searchScene); // Initiate search.
for (const auto& findings: searchScene.GetFindings()) {
findingsVector.push_back(findings);
@@ -3101,19 +3246,18 @@ void G4VisCommandSceneAddVolume::SetNewValue (G4UIcommand*,
for (const auto& findings: findingsVector) {
// Set copy number from search findings for replicas and parameterisations.
findings.fpFoundPV->SetCopyNo(findings.fFoundPVCopyNo);
// Create a physical volume model...
G4PhysicalVolumeModel* foundPVModel = new G4PhysicalVolumeModel
(findings.fpFoundPV,
requestedDepthOfDescent,
findings.fFoundObjectTransformation,
0, // No modelling parameters (these are set later by the scene handler).
false, // Do not use full extent - only use non-culled extent.
useFullExtent,
findings.fFoundBasePVPath);
if (clippingSolid) {
foundPVModel->SetClippingSolid(clippingSolid);
foundPVModel->SetClippingMode(clippingMode);
}
if (!foundPVModel->Validate(warn)) return; // Calculates extent
if (!foundPVModel->Validate(warn)) return;
// ...so add it to the scene.
G4bool successful = pScene->AddRunDurationModel(foundPVModel,warn);
if (successful) {
@@ -147,7 +147,7 @@ G4VisCommandSceneHandlerCreate::G4VisCommandSceneHandlerCreate (): fId (0) {
parameter = new G4UIparameter ("graphics-system-name",
's', omitable = false);
const G4GraphicsSystemList& gslist =
fpVisManager -> GetAvailableGraphicsSystems ();
fpVisManager -> GetAvailableGraphicsSystems ();
G4String candidates;
for (const auto gs: gslist) {
const G4String& name = gs -> GetName ();
@@ -210,13 +210,13 @@ void G4VisCommandSceneHandlerCreate::SetNewValue (G4UIcommand* command,
fpVisManager -> GetAvailableGraphicsSystems ();
G4int nSystems = gsl.size ();
if (nSystems <= 0) {
if (verbosity >= G4VisManager::errors) {
G4cerr << "ERROR: G4VisCommandSceneHandlerCreate::SetNewValue:"
" no graphics systems available."
"\n Did you instantiate any in"
" YourVisManager::RegisterGraphicsSystems()?"
<< G4endl;
}
G4ExceptionDescription ed;
ed <<
"ERROR: G4VisCommandSceneHandlerCreate::SetNewValue:"
" no graphics systems available."
"\n Did you instantiate any in"
" YourVisManager::RegisterGraphicsSystems()?";
command->CommandFailed(ed);
return;
}
G4int iGS; // Selector index.
@@ -241,16 +241,28 @@ void G4VisCommandSceneHandlerCreate::SetNewValue (G4UIcommand* command,
}
}
if (!found) {
// Invalid command line argument or none.
// This shouldn't happen!!!!!!
if (verbosity >= G4VisManager::errors) {
G4cerr <<
"ERROR: G4VisCommandSceneHandlerCreate::SetNewValue:"
"\n invalid graphics system \""
<< graphicsSystem
<< "\" requested."
<< G4endl;
// Shouldn't happen, since graphicsSystem should be a candidate
// Use set to get alphabetical order
std::set<G4String> candidates;
for (const auto gs: fpVisManager -> GetAvailableGraphicsSystems()) {
// Just list nicknames, but exclude FALLBACK nicknames
for (const auto& nickname: gs->GetNicknames()) {
if (!nickname.contains("FALLBACK")) {
candidates.insert(nickname);
}
}
}
G4ExceptionDescription ed;
ed <<
"ERROR: G4VisCommandSceneHandlerCreate::SetNewValue:"
"\n Invalid graphics system \""
<< graphicsSystem
<< "\" requested."
<< "\n Candidates are:";
for (const auto& candidate: candidates) {
ed << ' ' << candidate;
};
command->CommandFailed(ed);
return;
}
@@ -276,15 +288,11 @@ void G4VisCommandSceneHandlerCreate::SetNewValue (G4UIcommand* command,
}
}
if (iGS < 0 || iGS >= nSystems || loopCounter >=3) {
std::ostringstream oss;
oss << "\"" << gsl[iGSBeingTested]->GetNickname()
G4ExceptionDescription ed;
ed << "\"" << gsl[iGSBeingTested]->GetNickname()
<< "\" is not compatible with your chosen session,"
" and no fallback system found.";
if (verbosity >= G4VisManager::errors) {
G4cerr << "ERROR: G4VisCommandSceneHandlerCreate::SetNewValue: "
<< oss.str() << G4endl;
}
command->CommandFailed(oss);
command->CommandFailed(ed);
return;
}
// A fallback system found...but go back and check this too.
@@ -328,10 +336,11 @@ void G4VisCommandSceneHandlerCreate::SetNewValue (G4UIcommand* command,
for (iScene = 0; iScene < list.size (); iScene++) {
G4VSceneHandler* sceneHandler = list [iScene];
if (sceneHandler -> GetName () == newName) {
if (verbosity >= G4VisManager::errors) {
G4cerr << "ERROR: Scene handler \"" << newName
<< "\" already exists." << G4endl;
}
G4ExceptionDescription ed;
ed <<
"ERROR: Scene handler \"" << newName
<< "\" already exists.";
command->CommandFailed(ed);
return;
}
}
@@ -339,24 +348,22 @@ void G4VisCommandSceneHandlerCreate::SetNewValue (G4UIcommand* command,
//Create scene handler.
fpVisManager -> CreateSceneHandler (newName);
if (fpVisManager -> GetCurrentSceneHandler () -> GetName () != newName) {
if (verbosity >= G4VisManager::errors) {
G4cerr << "ERROR: G4VisCommandSceneHandlerCreate::SetNewValue:"
" Curious name mismatch."
"\n Current name \""
<< fpVisManager -> GetCurrentSceneHandler () -> GetName ()
<< "\" is not the new name \""
<< newName
<< "\".\n Please report to vis coordinator."
<< G4endl;
}
G4ExceptionDescription ed;
ed <<
"ERROR: G4VisCommandSceneHandlerCreate::SetNewValue:"
" Curious name mismatch."
"\n Current name \""
<< fpVisManager -> GetCurrentSceneHandler () -> GetName ()
<< "\" is not the new name \""
<< newName
<< "\".\n Please report to vis coordinator.";
command->CommandFailed(ed);
return;
}
if (verbosity >= G4VisManager::confirmations) {
if (verbosity >= G4VisManager::confirmations)
G4cout << "New scene handler \"" << newName << "\" created." << G4endl;
}
// Attach scene.
if (fpVisManager -> GetCurrentScene ())
G4UImanager::GetUIpointer () -> ApplyCommand ("/vis/sceneHandler/attach");
}
@@ -151,26 +151,19 @@ G4VisCommandSetExtentForField::G4VisCommandSetExtentForField ()
("The default is a null extent, which is interpreted by the commands as the"
"\nextent of the whole scene.");
G4UIparameter* parameter;
parameter = new G4UIparameter ("xmin", 'd', omitable = true);
parameter->SetDefaultValue (0.);
parameter = new G4UIparameter ("xmin", 'd', omitable = false);
fpCommand->SetParameter (parameter);
parameter = new G4UIparameter ("xmax", 'd', omitable = true);
parameter->SetDefaultValue (0.);
parameter = new G4UIparameter ("xmax", 'd', omitable = false);
fpCommand->SetParameter (parameter);
parameter = new G4UIparameter ("ymin", 'd', omitable = true);
parameter->SetDefaultValue (0.);
parameter = new G4UIparameter ("ymin", 'd', omitable = false);
fpCommand->SetParameter (parameter);
parameter = new G4UIparameter ("ymax", 'd', omitable = true);
parameter->SetDefaultValue (0.);
parameter = new G4UIparameter ("ymax", 'd', omitable = false);
fpCommand->SetParameter (parameter);
parameter = new G4UIparameter ("zmin", 'd', omitable = true);
parameter->SetDefaultValue (0.);
parameter = new G4UIparameter ("zmin", 'd', omitable = false);
fpCommand->SetParameter (parameter);
parameter = new G4UIparameter ("zmax", 'd', omitable = true);
parameter->SetDefaultValue (0.);
parameter = new G4UIparameter ("zmax", 'd', omitable = false);
fpCommand->SetParameter (parameter);
parameter = new G4UIparameter ("unit", 's', omitable = true);
parameter->SetDefaultValue ("m");
parameter = new G4UIparameter ("unit", 's', omitable = false);
fpCommand->SetParameter (parameter);
}
@@ -449,7 +442,7 @@ void G4VisCommandSetTouchable::SetNewValue (G4UIcommand*, G4String newValue)
if (verbosity >= G4VisManager::warnings) {
G4cout <<
"WARNING: G4VisCommandSetTouchable::SetNewValue"
"\n A pair not found. (Did you have an even number of parameters?)"
"\n A pair not found. (There should be an even number of parameters.)"
"\n Command ignored."
<< G4endl;
return;
@@ -526,8 +519,7 @@ G4VisCommandSetVolumeForField::G4VisCommandSetVolumeForField ()
fpCommand->SetGuidance
("Takes a volume name or a /regular expression/ -- see guidance for"
"\n\"/vis/drawVolume\"");
parameter = new G4UIparameter ("physical-volume-name", 's', omitable = true);
parameter -> SetDefaultValue ("none");
parameter = new G4UIparameter ("physical-volume-name", 's', omitable = false);
fpCommand -> SetParameter (parameter);
parameter = new G4UIparameter ("copy-no", 'i', omitable = true);
parameter -> SetGuidance ("If negative, matches any copy no.");
@@ -559,15 +551,6 @@ void G4VisCommandSetVolumeForField::SetNewValue (G4UIcommand*, G4String newValue
is >> name >> copyNo >> drawString;
G4bool draw = G4UIcmdWithABool::ConvertToBool(drawString);
if (name == "none") {
fCurrrentPVFindingsForField.clear();
fCurrentExtentForField = G4VisExtent();
if (verbosity >= G4VisManager::warnings) {
G4cout << "Volume for field cleared" << G4endl;
}
return;
}
G4TransportationManager* transportationManager =
G4TransportationManager::GetTransportationManager ();
size_t nWorlds = transportationManager->GetNoWorlds();
@@ -579,6 +562,7 @@ void G4VisCommandSetVolumeForField::SetNewValue (G4UIcommand*, G4String newValue
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, name, copyNo);
searchModel.DescribeYourselfTo (searchScene); // Initiate search.
for (const auto& findings: searchScene.GetFindings()) {
@@ -39,6 +39,7 @@
#include "G4AttDef.hh"
#include "G4AttValue.hh"
#include "G4AttCheck.hh"
#include "G4AxesModel.hh"
G4VisCommandsTouchable::G4VisCommandsTouchable()
{
@@ -100,6 +101,11 @@ G4VisCommandsTouchable::G4VisCommandsTouchable()
parameter -> SetDefaultValue (-1);
fpCommandFindPath -> SetParameter (parameter);
fpCommandLocalAxes = new G4UIcmdWithoutParameter("/vis/touchable/localAxes",this);
fpCommandLocalAxes->SetGuidance("Draw local axes.");
// Pick up additional guidance from /vis/viewer/centreAndZoomInOn
CopyGuidanceFrom(fpCommandCentreAndZoomInOn,fpCommandLocalAxes,1);
fpCommandShowExtent = new G4UIcmdWithABool("/vis/touchable/showExtent",this);
fpCommandShowExtent->SetGuidance("Print extent of touchable.");
fpCommandShowExtent->SetGuidance("If parameter == true, also draw.");
@@ -120,6 +126,7 @@ G4VisCommandsTouchable::G4VisCommandsTouchable()
G4VisCommandsTouchable::~G4VisCommandsTouchable() {
delete fpCommandVolumeForField;
delete fpCommandShowExtent;
delete fpCommandLocalAxes;
delete fpCommandFindPath;
delete fpCommandExtentForField;
delete fpCommandDump;
@@ -338,6 +345,7 @@ void G4VisCommandsTouchable::SetNewValue
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()) {
@@ -365,6 +373,20 @@ void G4VisCommandsTouchable::SetNewValue
G4cout << " not found" << G4endl;
}
} else if (command == fpCommandLocalAxes) {
const auto& transform = fCurrentTouchableProperties.fTouchableGlobalTransform;
const auto& extent = fCurrentTouchableProperties.fpTouchablePV->GetLogicalVolume()->GetSolid()->GetExtent();
const G4double lengthMax = extent.GetExtentRadius()/2.;
const G4double intLog10LengthMax = std::floor(std::log10(lengthMax));
G4double length = std::pow(10,intLog10LengthMax);
if (5.*length < lengthMax) length *= 5.;
else if (2.*length < lengthMax) length *= 2.;
G4AxesModel axesModel(0.,0.,0.,length);
axesModel.SetTransformation(transform);
axesModel.SetGlobalTag("LocalAxesModel");
axesModel.DescribeYourselfTo(*fpVisManager->GetCurrentSceneHandler());
} else if (command == fpCommandShowExtent) {
G4PhysicalVolumeModel::TouchableProperties properties =
@@ -44,18 +44,15 @@
#include "G4Point3D.hh"
#include "G4SystemOfUnits.hh"
#include "G4UnitsTable.hh"
#include "G4ios.hh"
#include "G4Filesystem.hh"
#include <chrono>
#include <thread>
#include <sstream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <cstdio>
#ifdef WIN32
#include <regex>
#include <filesystem>
#endif //WIN32
#include <set>
////////////// /vis/viewer/addCutawayPlane ///////////////////////////////////////
@@ -217,6 +214,7 @@ void G4VisCommandViewerCentreOn::SetNewValue (G4UIcommand* command, G4String new
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()) {
@@ -961,7 +959,7 @@ G4String G4VisCommandViewerCreate::GetCurrentValue (G4UIcommand*) {
return currentValue;
}
void G4VisCommandViewerCreate::SetNewValue (G4UIcommand*, G4String newValue) {
void G4VisCommandViewerCreate::SetNewValue (G4UIcommand* command, G4String newValue) {
G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
@@ -991,12 +989,11 @@ void G4VisCommandViewerCreate::SetNewValue (G4UIcommand*, G4String newValue) {
fpVisManager -> GetAvailableSceneHandlers ();
G4int nHandlers = sceneHandlerList.size ();
if (nHandlers <= 0) {
if (verbosity >= G4VisManager::errors) {
G4cerr <<
"ERROR: G4VisCommandViewerCreate::SetNewValue: no scene handlers."
"\n Create a scene handler with \"/vis/sceneHandler/create\""
<< G4endl;
}
G4ExceptionDescription ed;
ed <<
"ERROR: G4VisCommandViewerCreate::SetNewValue: no scene handlers."
"\n Create a scene handler with \"/vis/sceneHandler/create\"";
command->CommandFailed(ed);
return;
}
@@ -1008,11 +1005,10 @@ void G4VisCommandViewerCreate::SetNewValue (G4UIcommand*, G4String newValue) {
if (iHandler < 0 || iHandler >= nHandlers) {
// Invalid command line argument or none.
// This shouldn't happen!!!!!!
if (verbosity >= G4VisManager::errors) {
G4cout << "G4VisCommandViewerCreate::SetNewValue:"
" invalid scene handler specified."
<< G4endl;
}
G4ExceptionDescription ed;
ed <<
"G4VisCommandViewerCreate::SetNewValue: invalid scene handler specified.";
command->CommandFailed(ed);
return;
}
@@ -1036,10 +1032,10 @@ void G4VisCommandViewerCreate::SetNewValue (G4UIcommand*, G4String newValue) {
const G4ViewerList& viewerList = sh -> GetViewerList ();
for (size_t iViewer = 0; iViewer < viewerList.size (); iViewer++) {
if (viewerList [iViewer] -> GetShortName () == newShortName ) {
if (verbosity >= G4VisManager::errors) {
G4cerr << "ERROR: Viewer \"" << newShortName << "\" already exists."
<< G4endl;
}
G4ExceptionDescription ed;
ed <<
"ERROR: Viewer \"" << newShortName << "\" already exists.";
command->CommandFailed(ed);
return;
}
}
@@ -1058,13 +1054,14 @@ void G4VisCommandViewerCreate::SetNewValue (G4UIcommand*, G4String newValue) {
}
}
else {
if (verbosity >= G4VisManager::errors) {
if (newViewer) {
G4cerr << "ERROR: New viewer doesn\'t match!!! Curious!!" << G4endl;
} else {
G4cout << "WARNING: No viewer created." << G4endl;
}
G4ExceptionDescription ed;
if (newViewer) {
ed << "ERROR: New viewer doesn\'t match!!! Curious!!";
} else {
ed << "WARNING: No viewer created.";
}
command->CommandFailed(ed);
return;
}
// Refresh if appropriate...
if (newViewer) {
@@ -1235,7 +1232,7 @@ G4VisCommandViewerInterpolate::G4VisCommandViewerInterpolate () {
("The default is to search the working directory for files with a .g4view "
"extension. Another procedure is to assemble view files in a subdirectory, "
"e.g., \"myviews\"; then they can be interpolated with\n"
"\"/vis/viewer/interpolate myviews/*\".");
"\"/vis/viewer/interpolate myviews\".");
fpCommand -> SetGuidance
("To export interpolated views to file for a future possible movie, "
"write \"export\" as 5th parameter (OpenGL only).");
@@ -1320,114 +1317,73 @@ void G4VisCommandViewerInterpolate::SetNewValue (G4UIcommand*, G4String newValue
non_auto.SetAutoRefresh(false);
currentViewer->SetViewParameters(non_auto);
// View vector of way points
std::vector<G4ViewParameters> viewVector;
const G4int safety = 9999;
const G4int safety = 99;
G4int safetyCount = 0;
G4String pathname;
G4fs::path pathPattern = pattern.c_str();
#ifndef WIN32
// Parent path - add "./" for empty directory
G4String parentPathString
(pathPattern.parent_path().string().length() ?
pathPattern.parent_path().string() :
std::string("./"));
G4fs::path parentPath = parentPathString.c_str();
// Execute pattern and get resulting list of files
G4String shellCommand = "echo " + pattern;
FILE *filelist = popen(shellCommand.c_str(), "r");
if (!filelist) {
// Fill selected paths
std::set<G4fs::path> paths; // Use std::set to ensure order
if (G4fs::is_directory(pathPattern)) {
// The user has specified a directory. Find all files.
for (const auto& path: G4fs::directory_iterator(pathPattern)) {
if (safetyCount++ >= safety) break;
paths.insert(path);
}
} else {
// Assume user has specified a Unix "glob" pattern in leaf
// Default pattern is *.g4view, which translates to ^.*\\.g4view
// Convert pattern into a regexp
G4String regexp_pattern('^');
for (size_t i = 0; i < pattern.length(); ++i) {
if (pattern[i] == '.') {
regexp_pattern += "\\.";
} else if (pattern[i] == '*') {
regexp_pattern += ".*";
} else if (pattern[i] == '?') {
regexp_pattern += "(.{1,1})";
} else {
regexp_pattern += pattern[i];
}
}
std::regex regexp(regexp_pattern, std::regex_constants::basic | std::regex_constants::icase);
for (const auto& path: G4fs::directory_iterator(parentPath)) {
const auto& pathname = path.path().relative_path().string();
if (std::regex_match(pathname, regexp)) {
if (safetyCount++ >= safety) break;
paths.insert(path);
}
}
}
if (safetyCount > safety) {
if (verbosity >= G4VisManager::errors) {
G4cerr
<< "ERROR: G4VisCommandViewerInterpolate::SetNewValue:"
<< "\n Error obtaining pipe."
<< G4endl;
}
return;
}
// Build view vector of way points
const size_t BUFLENGTH = 999999;
char buf[BUFLENGTH];
char* result = std::fgets(buf, BUFLENGTH, filelist);
if (result) {
std::istringstream fileliststream(result);
while (fileliststream >> pathname
&& safetyCount++ < safety) { // Loop checking, 16.02.2016, J.Allison
uiManager->ApplyCommand("/control/execute " + pathname);
G4ViewParameters vp = currentViewer->GetViewParameters();
// Set original auto-refresh status.
vp.SetAutoRefresh(saveVP.IsAutoRefresh());
viewVector.push_back(vp);
}
}
pclose(filelist);
#else // WIN32 (popen is not available in Windows)
std::filesystem::path filePattern = pattern.c_str();
// Default pattern : *.g4view
// Translated to a regexp : ^.*\\.g4view
// Convert pattern into a regexp
std::string regexp_pattern("^" + filePattern.filename().string());
std::string result_pattern = "";
// Replace '.' by "\\."
size_t currentPos = 0;
size_t nextPos = 0;
std::string currentReplacement = "";
size_t pos1 = regexp_pattern.find('.', nextPos);
size_t pos2 = regexp_pattern.find('*', nextPos);
size_t pos3 = regexp_pattern.find('?', nextPos);
while ((pos1 != std::string::npos) || (pos2 != std::string::npos) || (pos3 != std::string::npos)) {
nextPos = pos1;
currentReplacement = "\\.";
if (pos2 < nextPos) {
nextPos = pos2;
currentReplacement = ".*";
}
if (pos3 < nextPos) {
nextPos = pos3;
currentReplacement = "(.{1,1})";
}
result_pattern += regexp_pattern.substr(currentPos, nextPos - currentPos) + currentReplacement;
nextPos++;
currentPos = nextPos;
pos1 = regexp_pattern.find('.', currentPos);
pos2 = regexp_pattern.find('*', currentPos);
pos3 = regexp_pattern.find('?', currentPos);
}
result_pattern += regexp_pattern.substr(currentPos);
// Build view vector of way points
// Add "./" for empty paths
G4String parentPath(filePattern.parent_path().string().length() ? filePattern.parent_path().string() : std::string("./"));
std::filesystem::path parentPathPattern = parentPath.c_str();
// Iterate through files in directory and apply regex match to filter appropriate files
std::regex result_pattern_regex (result_pattern, std::regex_constants::basic | std::regex_constants::icase);
for (auto iter = std::filesystem::directory_iterator(parentPathPattern);
iter != std::filesystem::directory_iterator() && safetyCount++ < safety;
++iter)
{
const auto& file = iter->path();
G4String filename(file.filename().string());
if (std::regex_match(filename, result_pattern_regex))
{
uiManager->ApplyCommand("/control/execute " + filename);
G4ViewParameters vp = currentViewer->GetViewParameters();
// Set original auto-refresh status.
vp.SetAutoRefresh(saveVP.IsAutoRefresh());
viewVector.push_back(vp);
}
}
#endif // WIN32
if (safetyCount >= safety) {
if (verbosity >= G4VisManager::errors) {
G4cout <<
G4cerr <<
"/vis/viewer/interpolate:"
"\n the number of way points exceeds the maximum currently allowed: "
"\n the number of way points has been limited to the maximum currently allowed: "
<< safety << G4endl;
}
return;
}
// Fill view vector of way points
std::vector<G4ViewParameters> viewVector;
for (const auto& path: paths) {
uiManager->ApplyCommand("/control/execute " + path.relative_path().string());
G4ViewParameters vp = currentViewer->GetViewParameters();
// Set original auto-refresh status.
vp.SetAutoRefresh(saveVP.IsAutoRefresh());
viewVector.push_back(vp);
}
InterpolateViews
@@ -1869,7 +1825,7 @@ G4VisCommandViewerSave::G4VisCommandViewerSave () {
("If you are wanting to save views for future interpolation a recommended "
"procedure is: save views to \"g4_nn.g4view\", as above, then move the files "
"into a sub-directory, say, \"views\", then interpolate with"
"\"/vis/viewer/interpolate views/\" (note the trailing \'/\').");
"\"/vis/viewer/interpolate views\"");
fpCommand -> SetParameterName ("filename", omitable = true);
fpCommand -> SetDefaultValue ("");
}
@@ -368,6 +368,26 @@ fViewpointVector (G4ThreeVector(0.,0.,1.))
parameter -> SetGuidance ("Component of plane normal.");
fpCommandSectionPlane->SetParameter(parameter);
fpCommandSpecialMeshRendering = new G4UIcmdWithABool
("/vis/viewer/set/specialMeshRendering",this);
fpCommandSpecialMeshRendering -> SetGuidance
("Request special rendering of volumes (meshes) that use G4VNestedParameterisation.");
fpCommandSpecialMeshRendering->SetParameterName("render",omitable = true);
fpCommandSpecialMeshRendering->SetDefaultValue(true);
fpCommandSpecialMeshVolumes = new G4UIcommand
("/vis/viewer/set/specialMeshVolumes",this);
fpCommandSpecialMeshVolumes -> SetGuidance
("Specify the volumes for special rendering. No arguments resets the list"
"\nand is interpreted to mean \"all found meshes\".");
fpCommandSpecialMeshVolumes->SetGuidance
("Please provide a list of space-separated physical volume names and copy"
"\nnumber pairs. Negative copy number means \"all volumes of that name\".");
parameter = new G4UIparameter("volumes",'s',omitable = true);
parameter->SetGuidance
("List of physical volume names and copy number pairs");
fpCommandSpecialMeshVolumes->SetParameter(parameter);
fpCommandStyle = new G4UIcmdWithAString ("/vis/viewer/set/style",this);
fpCommandStyle->SetGuidance
("Set style of drawing - w[ireframe] or s[urface] or c[loud].");
@@ -609,6 +629,8 @@ G4VisCommandsViewerSet::~G4VisCommandsViewerSet() {
delete fpCommandUpThetaPhi;
delete fpCommandTargetPoint;
delete fpCommandStyle;
delete fpCommandSpecialMeshVolumes;
delete fpCommandSpecialMeshRendering;
delete fpCommandSectionPlane;
delete fpCommandRotationStyle;
delete fpCommandProjection;
@@ -1134,6 +1156,26 @@ void G4VisCommandsViewerSet::SetNewValue
}
}
else if (command == fpCommandRotationStyle) {
G4ViewParameters::RotationStyle style;
if (newValue == "constrainUpDirection")
style = G4ViewParameters::constrainUpDirection;
else if (newValue == "freeRotation")
style = G4ViewParameters::freeRotation;
else {
if (verbosity >= G4VisManager::errors) {
G4cerr << "ERROR: \"" << newValue << "\" not recognised." << G4endl;
}
return;
}
vp.SetRotationStyle(style);
if (verbosity >= G4VisManager::confirmations) {
G4cout << "Rotation style of viewer \"" << currentViewer->GetName()
<< "\" set to " << vp.GetRotationStyle()
<< G4endl;
}
}
else if (command == fpCommandSectionPlane) {
G4String choice, unit;
G4double x, y, z, nx, ny, nz, F = 1.;
@@ -1180,23 +1222,75 @@ void G4VisCommandsViewerSet::SetNewValue
}
}
else if (command == fpCommandRotationStyle) {
G4ViewParameters::RotationStyle style;
if (newValue == "constrainUpDirection")
style = G4ViewParameters::constrainUpDirection;
else if (newValue == "freeRotation")
style = G4ViewParameters::freeRotation;
else {
if (verbosity >= G4VisManager::errors) {
G4cerr << "ERROR: \"" << newValue << "\" not recognised." << G4endl;
}
return;
}
vp.SetRotationStyle(style);
else if (command == fpCommandSpecialMeshRendering) {
vp.SetSpecialMeshRendering(G4UIcommand::ConvertToBool(newValue));
if (verbosity >= G4VisManager::confirmations) {
G4cout << "Rotation style of viewer \"" << currentViewer->GetName()
<< "\" set to " << vp.GetRotationStyle()
<< G4endl;
G4cout << "Special mesh rendering ";
if (vp.IsSpecialMeshRendering()) G4cout << "requested.";
else G4cout << "inhibited.";
G4cout << G4endl;
}
}
else if (command == fpCommandSpecialMeshVolumes) {
std::vector<G4ModelingParameters::PVNameCopyNo> requestedMeshes;
if (newValue.isNull()) {
vp.SetSpecialMeshVolumes(requestedMeshes); // Empty list
} else {
// Algorithm from Josuttis p.476.
G4String::size_type iBegin, iEnd;
iBegin = newValue.find_first_not_of(' ');
while (iBegin != G4String::npos) {
iEnd = newValue.find_first_of(' ',iBegin);
if (iEnd == G4String::npos) {
iEnd = newValue.length();
}
G4String name(newValue.substr(iBegin,iEnd-iBegin));
iBegin = newValue.find_first_not_of(' ',iEnd);
if (iBegin == G4String::npos) {
if (verbosity >= G4VisManager::warnings) {
G4cout <<
"WARNING: G4VisCommandsViewerSet::SetNewValue: /vis/viewer/set/specialMeshVolumes"
"\n A pair not found. (There should be an even number of parameters.)"
"\n Command ignored."
<< G4endl;
return;
}
}
iEnd = newValue.find_first_of(' ',iBegin);
if (iEnd == G4String::npos) {
iEnd = newValue.length();
}
G4int copyNo;
std::istringstream iss(newValue.substr(iBegin,iEnd-iBegin));
if (!(iss >> copyNo)) {
if (verbosity >= G4VisManager::warnings) {
G4cout <<
"WARNING: G4VisCommandsViewerSet::SetNewValue: /vis/viewer/set/specialMeshVolumes"
"\n Error reading copy number - it was not numeric?"
"\n Command ignored."
<< G4endl;
return;
}
}
requestedMeshes.push_back(G4ModelingParameters::PVNameCopyNo(name,copyNo));
iBegin = newValue.find_first_not_of(' ',iEnd);
}
vp.SetSpecialMeshVolumes(requestedMeshes);
}
if (verbosity >= G4VisManager::confirmations) {
if (vp.GetSpecialMeshVolumes().empty()) {
G4cout <<
"Special mesh list empty, which means \"all meshes\"."
<< G4endl;
} else {
G4cout << "Selected special mesh volumes are:";
for (const auto& pvNameCopyNo: vp.GetSpecialMeshVolumes()) {
G4cout << "\n " << pvNameCopyNo.GetName();
if (pvNameCopyNo.GetCopyNo() >= 0) G4cout << ':' << pvNameCopyNo.GetCopyNo();
}
G4cout << G4endl;
}
}
}
@@ -202,7 +202,10 @@ G4VisManager::G4VisManager (const G4String& verbosityString):
RegisterMessenger(new G4VisCommandInitialize);
}
G4VisManager::~G4VisManager () {
G4VisManager::~G4VisManager()
{
G4UImanager* UImanager = G4UImanager::GetUIpointer();
UImanager->SetCoutDestination(nullptr);
fpInstance = 0;
size_t i;
for (i = 0; i < fSceneList.size (); ++i) {
@@ -528,6 +531,7 @@ void G4VisManager::RegisterMessengers () {
RegisterMessenger(new G4VisCommandSceneAddHits);
RegisterMessenger(new G4VisCommandSceneAddLine);
RegisterMessenger(new G4VisCommandSceneAddLine2D);
RegisterMessenger(new G4VisCommandSceneAddLocalAxes);
RegisterMessenger(new G4VisCommandSceneAddLogicalVolume);
RegisterMessenger(new G4VisCommandSceneAddLogo);
RegisterMessenger(new G4VisCommandSceneAddLogo2D);
@@ -1393,17 +1397,6 @@ void G4VisManager::DispatchToModel(const G4VTrajectory& trajectory)
}
}
void G4VisManager::SetUserAction
(G4VUserVisAction* pVisAction,
const G4VisExtent& extent) {
if (fVerbosity >= warnings) {
G4cout <<
"WARNING: SetUserAction is deprecated. Use RegisterRunDurationUserVisAction."
<< G4endl;
}
RegisterRunDurationUserVisAction("SetUserAction",pVisAction,extent);
}
void G4VisManager::RegisterRunDurationUserVisAction
(const G4String& name,
G4VUserVisAction* pVisAction,