Import Geant4 10.6.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2019-06-28 11:59:04 +02:00
parent 28a70706e0
commit d0f911957d
1056 changed files with 95168 additions and 78160 deletions
+156 -2
View File
@@ -23,9 +23,163 @@ committal in the CVS repository !
History file for visualization category
---------------------------------------
21 January 2019 John Allison (vis-V10-04-26)
13 June 2019 John Allison (vis-V10-05-20)
- modeling-V10-05-04: Add cloud parameters.
- visman-V10-05-06: Final changes for introduction of cloud drawing.
- OpenGL-V10-05-06: Final changes for introduction of cloud drawing.
- visXXX-V10-05-02: Final changes for introduction of cloud drawing.
- openinventor-V10-05-05: Test number of cloud points for kernel visit.
10 June 2019 John Allison (vis-V10-05-19)
- modeling-V10-05-03:
o Arrows and field models: Introduce further protection.
- OpenGL-V10-05-05:
o Force double buffer context for OGLIX.
o Force kernel visit on change of number of cloud points.
- openinventor-V10-05-04:
o Add missing #ifdef G4VIS_BUILD_OIX_DRIVER.
- visXXX-V10-05-01:
o Force kernel visit on change of number of cloud points
30 May 2019 John Allison (vis-V10-05-18)
- modeling-V10-05-02: Improve field modelling.
- visman-V10-05-05: Improve message.
04 April 2019 John Allison (vis-V10-05-17)
- Co-working tags visman-V10-05-04 and modeling-V10-05-01.
o Final (for now) corrections to /vis/viewer/set/sectionPlane.
Still some strange behaviour in small fraction of cases. See
comments in G4PhysicalVolumeModel::DescribeSolid around line 748.
29 March 2019 John Allison
- opengl-V10-05-04: Fix Coverity warning and bug in section plane.
- visman-V10-05-03: Minor tidying.
24 March 2019 John Allison (vis-V10-05-16)
- modeling-V10-05-00, visman-V10-05-02, opengl-V10-05-03:
o Fix bug in /vis/viewer/set/sectionPlane.
18 March 2019 Gabriele Cosmo (vis-V10-05-15)
- Corrected few typos in printout/comments.
10 February 2019 John Allison (vis-V10-05-14)
- visman-V10-05-00: Introduce cloud drawing style
New parameter candidate in /vis/viewer/set/style:
/vis/viewer/set/style cloud
Cloud drawing uses solid->GetPointOnSurface, i.e., it uses kernel
algorithms and by-passes polyhedral representations. The solid is
represented by a polymarker of dots. The default number of points
is 1000. This can be changed with
/vis/viewer/set/numberOfCloudPoints
(The minimum number is 100.)
Note that OpenGL has a fast algorithm for polymarker.
- This allows us to use cloud style both as a choice or as fallback when the
polyhedral representation fails, for example, when BooleanProcessor fails.
- See management/History for details.
- opengl-V10-05-00 and opengl-V10-05-01:
o Avoid re-using display lists for markers. They may have their own
position relative to the overall object transformation.
24 February 2019 John Allison (vis-V10-05-13)
- Remove Get/SetDrawOverlapsFlag from G4VVisManager.
- Fix bug in overlap drawing of parameterised volumes.
- Add /vis/touchable/extentForField and volumeForField.
19 February 2019 John Allison (vis-V10-05-12)
- In graphics reps (see graphics_reps/History for details):
o Implemented G4VisExtent::Transform(const G4Transform3D&).
- In modeling (see modeling/History for details):
o Introduced G4BoundingExtentScene. This allows one to accumulate extents
using the newly introduced G4VisExtent::Transform and is a better way
of determining the overall extent of a scene (or of any set of extents)
than by the bounding sphere approach.
o G4VFieldModel, G4ElectricFieldModel, G4MagneticFieldModel:
. Introduced volume for field.
o G4VModel: Introduced GetTransformedExtent.
o G4PhysicalVolumeModel:
. Use G4BoundingExtentScene instead of G4BoundingSphereScene.
. Fix bug whereby the local extent was incorrectly calculated - in fact
it was the transformed extent.
- In management (see management/History for details):
o Add /vis/scene/showExtents.
o Add /vis/set/volumeForField.
o Add /vis/touchable/showExtent.
o Add copy number parameter to /vis/touchable/findPath.
o Correct for fix to bug in G4PhysicalVolumeModel - see modeling/History.
13 February 2019 John Allison (vis-V10-05-11)
- Implement /vis/set/extentForField
o The default is a null extent, which is to be interpreted by the field
model as the whole extent of the current scene. Otherwise, with this
command, you can limit the extent over which the field is drawn. This
would help, for example, if drawing over the whole scene produced so
many arrows or lines that it clutters the scene.
o Changed the default spacing - the parameter nDataPointsPerHalfExtent
is changed from 10 to 3 - so as not to clutter the scene. See
guidance of /vis/scene/add/*Field commands for further explanation.
10 February 2019 John Allison (vis-V10-05-10)
- See manegement/History for details.
- New and improved commands:
o /vis/viewer/centreOn: Improved - it does not zoom.
o /vis/viewer/centreAndZoomInOn: New.
o /vis/touchable/centreOn: Improved - it does not zoom.
o /vis/touchable/centreAndZoomInOn: New.
08 February 2019 John Allison (vis-V10-05-09)
- Fix Coverity warnings.
03 February 2019 Michael Kelsey (vis-V10-05-08)
- See modeling/History and management/History for details.
o Add /vis/scene/add/electricField by analogy to existing .../magneticField.
o Refactor MagneticFieldModel class with new base to handle all kinds of
vector fields; existing, and new ElectricFieldModel only have to
implement a simple function to get the field vector at a location.
31 January 2019 Ivana Hrivnacova (vis-V10-05-07)
- Merged GitHub PR #4: all Boolean operators now return G4bool.
29 January 2019 John Allison (vis-V10-05-06)
- See modeling/History and management/History for details.
- Add /vis/touchable/draw.
- /vis/viewer/centreOn: Add copy number to parameter list.
- Several fixes to handle paramaterisations and replicas.
26 January 2019 John Allison
- Fix calculation of vis extent for parameterisations. See
modeling/History and management/History for details.
25 January 2019 John Allison
- Rationalise view interpolation
Encapsulate algorithm into base class G4VVisCommand. The commands
/vis/viewer/interpolate
/vis/viewer/centreOn
/vis/touchable/centerOn
now use this. Might consider use by all view changing commands.
25 January 2019 John Allison (vis-V10-05-05)
- Include parameterised volumes in overlap checking and visualisation
in G4LogicalVolumeModel
22 January 2019 John Allison (vis-V10-05-04)
- Introduce /vis/viewer/centreOn and /vis/touchable/centreOn
This allows one to centre the view (zoom in) on a volume.
Reset with /vis/viewer/reset.
21 January 2019 John Allison (vis-V10-05-03)
- Pick up default number of line-segments-per-circle from G4Polyhedron.
08 January 2019 John Allison (vis-V10-05-02)
- Correct History files after merge.
02 January 2019 John Allison (vis-V10-05-01)
- Minor improvements to vis manager - see management/History for details.
02 January 2019 John Allison (vis-V10-05-00)
- Improve volume handling.
o modeling: Add volume count (but comment out printing).
o management: Improve guidance for /vis/scene/add/volume.
14 November 2018 John Allison (vis-V10-04-25)
- modeling-V10-04-18: Fix Coverity warning.
@@ -3763,7 +3917,7 @@ To be included:
7th December 2004 Joseph Perl (vis-V06-02-08)
- Tagged right after migration to cmath
- All occurences of include <math.h> have now become include <cmath>.
- All occurrences of include <math.h> have now become include <cmath>.
- All math functions are now prefaced with std::
7th December 2004 Joseph Perl (vis-V06-02-07)
+38
View File
@@ -16,6 +16,44 @@ committal in the CVS repository !
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
13 June 2019 John Allison (OpenGL-V10-05-06)
- Part of vis-V10-05-20.
- Final changes for introduction of cloud drawing:
o Follow change of accessor name: GetNumberOfCloudPoints.
10 June 2019 John Allison (OpenGL-V10-05-05)
- Part of vis-V10-05-19.
- G4OpenGLImmediateXViewer:
Force double buffer context. (This can happen anyway when the display
list limit is reached in stored mode. Seems to be no problem.) We were
finding that the single buffer visual gave an X Error (BadMatch) on
some systems, so let us force the use if a double buffer. All systems
have double buffers nowadays.
- G4OpenGLStoredViewer and StoredQtViewer:
Force kernel visit on change of number of cloud points.
29 March 2019 John Allison (opengl-V10-05-04)
- G4OpenGLSceneHandler.cc: Fix Coverity warning. Minor tidying.
- G4OpenGLStoredViewer.cc and G4OpenGLStoredQtViewer.cc:
In CompareForKernelVisit require kernel visit if section plane changes.
Note this is required since *for now* sections are made in the base class
by using Boolean Processor.
24 March 2019 John Allison (opengl-V10-05-03)
- Fix bug in /vis/viewer/set/sectionPlane.
Involves using G4DisplacedSolid instead of plain G4VSolid.
18 March 2019 Gabriele Cosmo (opengl-V10-05-02)
- Corrected few typos in printout/comments.
10 March 2019 John Allison (opengl-V10-05-01)
- G4OpenGLStoredSceneHandler.cc: Tidy.
08 March 2019 John Allison (opengl-V10-05-00)
- G4OpenGLStoredSceneHandler.cc:
o Avoid re-using display lists for markers. They may have their own
position relative to the overall object transformation.
5 October 2018 John Allison (opengl-V10-04-10)
- In all header files, change
#ifdef G4VIS_BUILD_OPENGL_DRIVER
@@ -141,8 +141,8 @@ protected:
virtual ~G4OpenGLSceneHandler ();
void ProcessScene();
G4VSolid* CreateSectionSolid ();
G4VSolid* CreateCutawaySolid ();
G4DisplacedSolid* CreateSectionSolid ();
G4DisplacedSolid* CreateCutawaySolid ();
void ClearAndDestroyAtts(); // Destroys att holders and clears pick map.
@@ -61,7 +61,13 @@ G4OpenGLImmediateXViewer::~G4OpenGLImmediateXViewer () {}
void G4OpenGLImmediateXViewer::Initialise () {
CreateGLXContext (vi_immediate);
// CreateGLXContext (vi_immediate);
// Force double buffer context. (This can happen anyway when the display
// list limit is reached in stored mode. Seems to be no problem. We were
// finding that the single buffer visual gave an X Error (BadMatch) on
// some systems, so let us force the use if a double buffer. All systems
// have double buffers nowadays.
CreateGLXContext (vi_stored);
CreateMainWindow ();
CreateFontLists ();
@@ -321,19 +321,22 @@ void G4OpenGLSceneHandler::EndPrimitives2D ()
G4VSceneHandler::EndPrimitives2D ();
}
G4VSolid* G4OpenGLSceneHandler::CreateSectionSolid ()
G4DisplacedSolid* G4OpenGLSceneHandler::CreateSectionSolid ()
{
return G4VSceneHandler::CreateSectionSolid();
// If clipping done in G4OpenGLViewer::SetView
// return 0;
// Note: if you change this, you must also change
// G4OpenGLStoredViewer::CompareForKernelVisit
}
G4VSolid* G4OpenGLSceneHandler::CreateCutawaySolid ()
G4DisplacedSolid* G4OpenGLSceneHandler::CreateCutawaySolid ()
{
// Cutaway done in G4OpenGLViewer::SetView.
return 0;
// Else
// return G4VSceneHandler::CreateCutawaySolid();
// If cutaway done in G4OpenGLViewer::SetView.
return 0;
// Note: if you change this, you must also change
// G4OpenGLStoredViewer::CompareForKernelVisit
}
void G4OpenGLSceneHandler::AddPrimitive (const G4Polyline& line)
@@ -588,7 +591,8 @@ void G4OpenGLSceneHandler::AddPrimitive (const G4Polyhedron& polyhedron) {
// even if the colour is changed, for example, by interaction with a Qt
// window, current_colour does not change.
GLfloat* painting_colour;
GLfloat current_colour [4];
GLfloat clear_colour[4];
GLfloat current_colour[4];
glGetFloatv (GL_CURRENT_COLOR, current_colour);
G4bool isTransparent = false;
@@ -596,10 +600,8 @@ void G4OpenGLSceneHandler::AddPrimitive (const G4Polyhedron& polyhedron) {
isTransparent = true;
}
if (drawing_style == G4ViewParameters::hlr) {
// This is the colour used to paint surfaces in hlr mode.
GLfloat clear_colour[4];
glGetFloatv (GL_COLOR_CLEAR_VALUE, clear_colour);
painting_colour = clear_colour;
} else { // drawing_style == G4ViewParameters::hlhsr
@@ -676,7 +678,7 @@ void G4OpenGLSceneHandler::AddPrimitive (const G4Polyhedron& polyhedron) {
#ifndef G4OPENGL_VERSION_2
glEnable(GL_COLOR_MATERIAL);
#endif
glEnable (GL_CULL_FACE);
glEnable (GL_CULL_FACE);
glCullFace (GL_BACK);
glPolygonMode (GL_FRONT, GL_FILL);
}
@@ -870,14 +872,14 @@ void G4OpenGLSceneHandler::AddPrimitive (const G4Polyhedron& polyhedron) {
fEdgeFlag = false;
}
}
glNormal3d (normals[edgeCount].x(),
normals[edgeCount].y(),
normals[edgeCount].z());
glNormal3d (normals[edgeCount].x(),
normals[edgeCount].y(),
normals[edgeCount].z());
glVertex3d (vertex[edgeCount].x(),
vertex[edgeCount].y(),
vertex[edgeCount].z());
#else
fOglVertex.push_back(vertex[edgeCount].x());
fOglVertex.push_back(vertex[edgeCount].x());
fOglVertex.push_back(vertex[edgeCount].y());
fOglVertex.push_back(vertex[edgeCount].z());
@@ -71,7 +71,7 @@ G4bool G4OpenGLStoredQtSceneHandler::ExtraPOProcessing
// This call comes from a G4PhysicalVolumeModel. drawnPVPath is
// the path of the current drawn (non-culled) volume in terms of
// drawn (non-culled) ancesters. Each node is identified by a
// drawn (non-culled) ancestors. Each node is identified by a
// PVNodeID object, which is a physical volume and copy number. It
// is a vector of PVNodeIDs corresponding to the geometry hierarchy
// actually selected, i.e., not culled.
@@ -113,6 +113,7 @@ G4bool G4OpenGLStoredQtViewer::CompareForKernelVisit(G4ViewParameters& lastVP)
// modifiers (fTreeItemModels, etc.).
if (
(lastVP.GetDrawingStyle () != fVP.GetDrawingStyle ()) ||
(lastVP.GetNumberOfCloudPoints() != fVP.GetNumberOfCloudPoints()) ||
(lastVP.IsAuxEdgeVisible () != fVP.IsAuxEdgeVisible ()) ||
(lastVP.IsCulling () != fVP.IsCulling ()) ||
(lastVP.IsCullingInvisible () != fVP.IsCullingInvisible ()) ||
@@ -153,17 +154,15 @@ G4bool G4OpenGLStoredQtViewer::CompareForKernelVisit(G4ViewParameters& lastVP)
(lastVP.GetVisibleDensity () != fVP.GetVisibleDensity ()))
return true;
/**************************************************************
Section (DCUT) implemented locally. No need to visit kernel if
section plane itself changes.
if (lastVP.IsSection () &&
(lastVP.GetSectionPlane () != fVP.GetSectionPlane ()))
return true;
***************************************************************/
// /**************************************************************
// If section (DCUT) is implemented locally, comment this out.
if (lastVP.IsSection () &&
(lastVP.GetSectionPlane () != fVP.GetSectionPlane ()))
return true;
// ***************************************************************/
/**************************************************************
Cutaways implemented locally. No need to visit kernel if cutaway
planes themselves change.
If cutaways are implemented locally, comment this out.
if (lastVP.IsCutaway ()) {
if (lastVP.GetCutawayPlanes ().size () !=
fVP.GetCutawayPlanes ().size ()) return true;
@@ -181,7 +180,7 @@ G4bool G4OpenGLStoredQtViewer::CompareForKernelVisit(G4ViewParameters& lastVP)
if (lastVP.IsExplode () &&
(lastVP.GetExplodeFactor () != fVP.GetExplodeFactor ()))
return true;
return false;
}
@@ -274,64 +274,69 @@ G4bool G4OpenGLStoredSceneHandler::AddPrimitivePreambleInternal
fPickMap[fPickName] = holder;
}
// Can we re-use a display list?
const G4VSolid* pSolid = 0;
G4PhysicalVolumeModel* pPVModel =
dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
// Can we re-use a display list?
if (isMarker)
// It is a marker, which may have its own position relative to fObjectTransformation
goto end_of_display_list_reuse_test;
if (fpViewer->GetViewParameters().GetVisAttributesModifiers().size())
// Touchables have been modified - don't risk re-using display list.
goto end_of_display_list_reuse_test;
if (pPVModel) {
// Check that it isn't a G4LogicalVolumeModel (which is a sub-class of
// G4PhysicalVolumeModel).
G4LogicalVolumeModel* pLVModel =
dynamic_cast<G4LogicalVolumeModel*>(pPVModel);
if (pLVModel)
// Logical volume model - don't re-use.
goto end_of_display_list_reuse_test;
// If part of the geometry hierarchy, i.e., from a
// G4PhysicalVolumeModel, check if a display list already exists for
// this solid, re-use it if possible. We could be smarter, and
// recognise repeated branches of the geometry hierarchy, for
// example. But this algorithm should be secure, I think...
G4VPhysicalVolume* pPV = pPVModel->GetCurrentPV();
if (!pPV)
// It's probably a dummy model, e.g., for a user-drawn hit?
goto end_of_display_list_reuse_test;
G4LogicalVolume* pLV = pPV->GetLogicalVolume();
if (!pLV)
// Dummy model again?
goto end_of_display_list_reuse_test;
pSolid = pLV->GetSolid();
EAxis axis = kRho;
G4VPhysicalVolume* pCurrentPV = pPVModel->GetCurrentPV();
if (pCurrentPV -> IsReplicated ()) {
G4int nReplicas;
G4double width;
G4double offset;
G4bool consuming;
pCurrentPV->GetReplicationData(axis,nReplicas,width,offset,consuming);
}
// Provided it is not parametrised (because if so, the
// solid's parameters might have been changed)...
if (!(pCurrentPV -> IsParameterised ()) &&
// Provided it is not replicated radially (because if so, the
// solid's parameters will have been changed)...
!(pCurrentPV -> IsReplicated () && axis == kRho) &&
// ...and if the solid has already been rendered...
(fSolidMap.find (pSolid) != fSolidMap.end ())) {
fDisplayListId = fSolidMap [pSolid];
PO po(fDisplayListId,fObjectTransformation);
if (isPicking) po.fPickName = fPickName;
po.fColour = c;
po.fMarkerOrPolyline = isMarkerOrPolyline;
fPOList.push_back(po);
// No need to test if gl commands are used (result of
// ExtraPOProcessing) because we have already decided they will
// not, at least not here. Also, pass a dummy G4Visible since
// not relevant for G4PhysicalVolumeModel.
(void) ExtraPOProcessing(G4Visible(), fPOList.size() - 1);
return false; // No further processing.
{ // It is a viable candidate for display list re-use
G4PhysicalVolumeModel* pPVModel = dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
if (pPVModel) {
// Check that it isn't a G4LogicalVolumeModel (which is a sub-class of
// G4PhysicalVolumeModel).
G4LogicalVolumeModel* pLVModel =
dynamic_cast<G4LogicalVolumeModel*>(pPVModel);
if (pLVModel)
// Logical volume model - don't re-use.
goto end_of_display_list_reuse_test;
// If part of the geometry hierarchy, i.e., from a
// G4PhysicalVolumeModel, check if a display list already exists for
// this solid, re-use it if possible. We could be smarter, and
// recognise repeated branches of the geometry hierarchy, for
// example. But this algorithm should be secure, I think...
G4VPhysicalVolume* pPV = pPVModel->GetCurrentPV();
if (!pPV)
// It's probably a dummy model, e.g., for a user-drawn hit?
goto end_of_display_list_reuse_test;
G4LogicalVolume* pLV = pPV->GetLogicalVolume();
if (!pLV)
// Dummy model again?
goto end_of_display_list_reuse_test;
pSolid = pLV->GetSolid();
EAxis axis = kRho;
G4VPhysicalVolume* pCurrentPV = pPVModel->GetCurrentPV();
if (pCurrentPV -> IsReplicated ()) {
G4int nReplicas;
G4double width;
G4double offset;
G4bool consuming;
pCurrentPV->GetReplicationData(axis,nReplicas,width,offset,consuming);
}
// Provided it is not parametrised (because if so, the
// solid's parameters might have been changed)...
if (!(pCurrentPV -> IsParameterised ()) &&
// Provided it is not replicated radially (because if so, the
// solid's parameters will have been changed)...
!(pCurrentPV -> IsReplicated () && axis == kRho) &&
// ...and if the solid has already been rendered...
(fSolidMap.find (pSolid) != fSolidMap.end ())) {
fDisplayListId = fSolidMap [pSolid];
PO po(fDisplayListId,fObjectTransformation);
if (isPicking) po.fPickName = fPickName;
po.fColour = c;
po.fMarkerOrPolyline = isMarkerOrPolyline;
fPOList.push_back(po);
// No need to test if gl commands are used (result of
// ExtraPOProcessing) because we have already decided they will
// not, at least not here. Also, pass a dummy G4Visible since
// not relevant for G4PhysicalVolumeModel.
(void) ExtraPOProcessing(G4Visible(), fPOList.size() - 1);
return false; // No further processing.
}
}
}
end_of_display_list_reuse_test:
@@ -72,6 +72,7 @@ G4bool G4OpenGLStoredViewer::CompareForKernelVisit(G4ViewParameters& lastVP) {
if (
(lastVP.GetDrawingStyle () != fVP.GetDrawingStyle ()) ||
(lastVP.GetNumberOfCloudPoints() != fVP.GetNumberOfCloudPoints()) ||
(lastVP.IsAuxEdgeVisible () != fVP.IsAuxEdgeVisible ()) ||
(lastVP.IsCulling () != fVP.IsCulling ()) ||
(lastVP.IsCullingInvisible () != fVP.IsCullingInvisible ()) ||
@@ -103,17 +104,15 @@ G4bool G4OpenGLStoredViewer::CompareForKernelVisit(G4ViewParameters& lastVP) {
(lastVP.GetVisibleDensity () != fVP.GetVisibleDensity ()))
return true;
/**************************************************************
Section (DCUT) implemented locally. No need to visit kernel if
section plane itself changes.
if (lastVP.IsSection () &&
(lastVP.GetSectionPlane () != fVP.GetSectionPlane ()))
return true;
***************************************************************/
// /**************************************************************
// If section (DCUT) is implemented locally, comment this out.
if (lastVP.IsSection () &&
(lastVP.GetSectionPlane () != fVP.GetSectionPlane ()))
return true;
// ***************************************************************/
/**************************************************************
Cutaways implemented locally. No need to visit kernel if cutaway
planes themselves change.
If cutaways are implemented locally, comment this out.
if (lastVP.IsCutaway ()) {
if (lastVP.GetCutawayPlanes ().size () !=
fVP.GetCutawayPlanes ().size ()) return true;
@@ -130,7 +129,7 @@ G4bool G4OpenGLStoredViewer::CompareForKernelVisit(G4ViewParameters& lastVP) {
if (lastVP.IsExplode () &&
(lastVP.GetExplodeFactor () != fVP.GetExplodeFactor ()))
return true;
return true;
// Time window parameters operate on the existing database so no need
// to rebuild even if they change.
@@ -277,7 +277,7 @@ G4OpenGLViewerMessenger::G4OpenGLViewerMessenger()
new G4UIcommand("/vis/ogl/set/printSize", this);
fpCommandPrintSize->SetGuidance ("Set print size");
fpCommandPrintSize->SetGuidance ("Tip : -1 will mean 'print size' = 'window size'");
fpCommandPrintSize->SetGuidance (" Setting size greatter than your maximum graphic card capacity , will set the size to maximum size.");
fpCommandPrintSize->SetGuidance (" Setting size greater than your maximum graphic card capacity , will set the size to maximum size.");
G4UIparameter* parameterPrintSize;
parameterPrintSize = new G4UIparameter ("width", 'd', omitable = false);
parameterPrintSize->SetDefaultValue(-1);
+28
View File
@@ -19,6 +19,34 @@ committal in the CVS repository !
History file for visualization/OpenInventor
-------------------------------------------
14 June 2019 Gabriele Cosmo (openinventor-V10-05-06)
- Fixed compilation error in G4OpenInventorViewer::CompareForKernelVisit()
for typo introduced in previous tag...
13 June 2019 John Allison (openinventor-V10-05-05)
- Part of vis-V10-05-20.
- Test number of cloud points for kernel visit.
10 June 2019 John Allison (openinventor-V10-05-04)
- Part of vis-V10-05-19.
- G4OpenInventorXtExaminerViewer.cc and wheelmouse.cc:
Add #ifdef G4VIS_BUILD_OIX_DRIVER
16 May 2019 Gabriele Cosmo (openinventor-V10-05-03)
- Fixed compilation warning from gcc-9.1 in SoCounterAction for setting
of name, apparently not allowed in OpenInventor.
18 March 2019 Gabriele Cosmo (openinventor-V10-05-02)
- Corrected typo in comments.
12 March 2019 John Allison (openinventor-V10-05-01)
- Fix compiler warnings about new cloud style.
Note: this does not yet mean that OI can handle cloud style. In fact
I think it will render in wireframe if cloud is selected.
11 March 2019 Gabriele Cosmo (openinventor-V10-05-00)
- Fixed typos in printouts in SbPainterPS.
22 August 2018 Gabriele Cosmo (openinventor-V10-04-08)
- sources.cmake: make OIQT driver installation optional when QT is
selected for CMake configuration (SoQt library is not mandatory
@@ -278,7 +278,7 @@ private:
float distanceToBeamlineStart;
std::string name;
bool operator<(elementForSorting const &other) const
G4bool operator<(elementForSorting const &other) const
{
if (closestPointZCoord < other.closestPointZCoord)
return true;
@@ -42,7 +42,7 @@ public:
enum LookFor { NODE = 1,TYPE = 2, NAME = 3 };
void setLookFor(LookFor);
void setType(const SoType,SbBool = TRUE);
void setName(const SbName);
// void setName(const SbName);
public:
int getCount() const;
protected:
@@ -608,7 +608,7 @@ void G4OpenInventorSceneHandler::GeneratePrerequisites()
// This call comes from a G4PhysicalVolumeModel. drawnPVPath is
// the path of the current drawn (non-culled) volume in terms of
// drawn (non-culled) ancesters. Each node is identified by a
// drawn (non-culled) ancestors. Each node is identified by a
// PVNodeID object, which is a physical volume and copy number. It
// is a vector of PVNodeIDs corresponding to the geometry hierarchy
// actually selected, i.e., not culled.
@@ -682,6 +682,9 @@ void G4OpenInventorSceneHandler::GeneratePrerequisites()
case (G4ViewParameters::hlhsr):
fModelingSolid = true;
break;
case (G4ViewParameters::cloud):
fModelingSolid = false;
break;
}
SoMaterial* material =
@@ -792,6 +795,9 @@ void G4OpenInventorSceneHandler::AddProperties(const G4VisAttributes* visAtts)
case (G4ViewParameters::hlhsr):
fModelingSolid = true;
break;
case (G4ViewParameters::cloud):
fModelingSolid = false;
break;
}
// Edge visibility...
@@ -158,6 +158,7 @@ G4bool G4OpenInventorViewer::CompareForKernelVisit(G4ViewParameters& vp) {
if (
(vp.GetDrawingStyle () != fVP.GetDrawingStyle ()) ||
(vp.GetNumberOfCloudPoints() != fVP.GetNumberOfCloudPoints()) ||
(vp.IsAuxEdgeVisible () != fVP.IsAuxEdgeVisible ()) ||
(vp.IsCulling () != fVP.IsCulling ()) ||
(vp.IsCullingInvisible () != fVP.IsCullingInvisible ()) ||
@@ -667,6 +668,9 @@ void G4OpenInventorViewer::SetSolid() {
break;
case G4ViewParameters::hlhsr:
break;
case G4ViewParameters::cloud:
vp.SetDrawingStyle(G4ViewParameters::hsr);
break;
}
SetViewParameters(vp);
DrawDetector();
@@ -685,6 +689,9 @@ void G4OpenInventorViewer::SetWireFrame() {
case G4ViewParameters::hlhsr:
vp.SetDrawingStyle(G4ViewParameters::hlr);
break;
case G4ViewParameters::cloud:
vp.SetDrawingStyle(G4ViewParameters::wireframe);
break;
}
SetViewParameters(vp);
DrawDetector();
@@ -710,6 +717,9 @@ void G4OpenInventorViewer::SetReducedWireFrame(bool aValue) {
case G4ViewParameters::hlhsr:
vp.SetDrawingStyle(G4ViewParameters::hlr);
break;
case G4ViewParameters::cloud:
vp.SetDrawingStyle(G4ViewParameters::wireframe);
break;
}
SetViewParameters(vp);
NeedKernelVisit(); // Just in case it was alread in wire framw.
@@ -27,6 +27,8 @@
// Open Inventor Xt Extended Viewer - 30 Oct 2012
// Rastislav Ondrasek, Pierre-Luc Gagnon, Frederick Jones TRIUMF
#ifdef G4VIS_BUILD_OIX_DRIVER
#include <stdio.h>
#include <string.h>
#include <string>
@@ -4936,3 +4938,5 @@ G4bool HookEventProcState::Notify(G4ApplicationState requiredState)
}
return true;
}
#endif // G4VIS_BUILD_OIX_DRIVER
@@ -1011,7 +1011,7 @@ void SbPainterPS::putImageInStream (
}
}
if(status==0)
::printf("SbPainterPS::putImageInStream: problem to retreive some pixel rgb.\n");
::printf("SbPainterPS::putImageInStream: problem to retrieve some pixel rgb.\n");
putRestoreStateInStream();
}
//////////////////////////////////////////////////////////////////////////////
@@ -95,9 +95,9 @@ void SoCounterAction::setType(const SoType aType,SbBool aCheckDerived) {
fType = aType;
fCheckDerived = aCheckDerived;
}
void SoCounterAction::setName(const SbName aName){
fName = aName;
}
//void SoCounterAction::setName(const SbName aName){
// fName = aName;
//}
int SoCounterAction::getCount() const {
return fCount;
}
@@ -22,6 +22,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef G4VIS_BUILD_OIX_DRIVER
#include <X11/Intrinsic.h>
#include <X11/Xlib.h>
#include <Xm/Xm.h>
@@ -141,3 +143,5 @@ void xmAddMouseEventHandler(Widget w)
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
#endif // G4VIS_BUILD_OIX_DRIVER
@@ -55,7 +55,7 @@ class G4RayTrajectoryPoint :public G4VTrajectoryPoint
inline void *operator new(size_t);
inline void operator delete(void *aTrajectoryPoint);
// inline int operator==(const G4RayTrajectoryPoint& right) const
// inline G4bool operator==(const G4RayTrajectoryPoint& right) const
// { return (this==&right); };
private:
+3
View File
@@ -24,6 +24,9 @@ committal in the CVS repository !
History file for visualization/Tree sub-category
------------------------------------------------
18 March 2019 Gabriele Cosmo (vistree-V10-05-00)
- Corrected few typos in comments.
11th March 2018 John Allison (vistree-V10-04-00)
- G4ASCIITreeSceneHandler.cc:
o Fix bug in suppressed writing of repeated parameterised volumes.
@@ -197,7 +197,7 @@ void G4ASCIITreeSceneHandler::RequestPrimitives(const G4VSolid& solid) {
// This call comes from a G4PhysicalVolumeModel. drawnPVPath is
// the path of the current drawn (non-culled) volume in terms of
// drawn (non-culled) ancesters. Each node is identified by a
// drawn (non-culled) ancestors. Each node is identified by a
// PVNodeID object, which is a physical volume and copy number. It
// is a vector of PVNodeIDs corresponding to the geometry hierarchy
// actually selected, i.e., not culled.
@@ -68,7 +68,7 @@ void G4VTreeSceneHandler::PreAddSolid
// This call comes from a G4PhysicalVolumeModel, drawnPVPath is
// the path of the current drawn (non-culled) volume in terms of
// drawn (non-culled) ancesters. Each node is identified by a
// drawn (non-culled) ancestors. Each node is identified by a
// PVNodeID object, which is a physical volume and copy number. It
// is a vector of PVNodeIDs corresponding to the geometry hierarchy
// actually selected, i.e., not culled.
+13
View File
@@ -19,6 +19,19 @@ committal in the CVS repository !
History file for visualization/XXX sub-category (a template graphics system)
---------------------------------------------------------------------------
13 June 2019 John Allison (visXXX-V10-05-02)
- Part of vis-V10-05-20.
- Final changes for introduction of cloud drawing:
o Follow change of accessor name: GetNumberOfCloudPoints.
10 June 2019 John Allison (visXXX-V10-05-01)
- Part of vis-V10-05-19.
- G4XXXSGViewer.cc and G4XXXStoredViewer.cc:
Force kernel visit on change of number of cloud points.
18 March 2019 Gabriele Cosmo (visXXX-V10-05-00)
- Corrected typo in comments.
25 April 2015 John Allison (visXXX-V10-04-00)
- G4XXXStoredViewer::CompareForKernelVisit, G4XXXSGViewer::CompareForKernelVisit
o Implement comparison for "colour by density".
@@ -97,7 +97,7 @@ void G4XXXSGSceneHandler::CreateCurrentItem(const G4String& /*header*/) {
// This call comes from a G4PhysicalVolumeModel. drawnPVPath is
// the path of the current drawn (non-culled) volume in terms of
// drawn (non-culled) ancesters. Each node is identified by a
// drawn (non-culled) ancestors. Each node is identified by a
// PVNodeID object, which is a physical volume and copy number. It
// is a vector of PVNodeIDs corresponding to the geometry hierarchy
// actually selected, i.e., not culled.
@@ -116,6 +116,7 @@ G4bool G4XXXSGViewer::CompareForKernelVisit(G4ViewParameters& lastVP)
// Typical comparison. Taken from OpenGL.
if (
(lastVP.GetDrawingStyle () != fVP.GetDrawingStyle ()) ||
(lastVP.GetNumberOfCloudPoints() != fVP.GetNumberOfCloudPoints()) ||
(lastVP.IsAuxEdgeVisible () != fVP.IsAuxEdgeVisible ()) ||
(lastVP.IsCulling () != fVP.IsCulling ()) ||
(lastVP.IsCullingInvisible () != fVP.IsCullingInvisible ()) ||
@@ -114,6 +114,7 @@ G4bool G4XXXStoredViewer::CompareForKernelVisit(G4ViewParameters& lastVP)
// Typical comparison. Taken from OpenGL.
if (
(lastVP.GetDrawingStyle () != fVP.GetDrawingStyle ()) ||
(lastVP.GetNumberOfCloudPoints() != fVP.GetNumberOfCloudPoints()) ||
(lastVP.IsAuxEdgeVisible () != fVP.IsAuxEdgeVisible ()) ||
(lastVP.IsCulling () != fVP.IsCulling ()) ||
(lastVP.IsCullingInvisible () != fVP.IsCullingInvisible ()) ||
+3
View File
@@ -17,6 +17,9 @@ committal in the CVS repository !
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
20 February 2019 Ben Morgan (visexternals-V10-05-00)
- visexternalgl2ps-V10-05-00: Add include path for generated G4GlobalConfig.hh
28 May 2018 Gabriele Cosmo (visexternals-V10-04-01)
- visexternalgl2ps-V10-04-01: Corrected GNUmakefile, now requiring dependency
on global module.
+3
View File
@@ -16,6 +16,9 @@ committal in the CVS repository !
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
20 February 2019 Ben Morgan (visexternalgl2ps-V10-05-00)
- Add include path for generated G4GlobalConfig.hh
28 May 2018 Gabriele Cosmo (visexternalgl2ps-V10-04-01)
- Corrected GNUmakefile, now requiring dependency on global module.
+5 -1
View File
@@ -19,7 +19,11 @@ include_directories(${CLHEP_INCLUDE_DIRS})
include_directories(${ZLIB_INCLUDE_DIRS})
# List internal includes needed.
include_directories(${CMAKE_SOURCE_DIR}/source/global/management/include)
include_directories(${PROJECT_SOURCE_DIR}/source/global/management/include)
# WORKAROUND: Now have a generated header, so must add include directory,
# but not that we lose one directory level because the management subcategory
# is merged into the main global one!
include_directories(${PROJECT_BINARY_DIR}/source/global/include)
# Must have GL headers available
include_directories(${OPENGL_INCLUDE_DIR})
+3
View File
@@ -19,6 +19,9 @@ committal in the CVS repository !
History file for visualization/gMocren sub-category
---------------------------------------------------
19 December 2018 Gabriele Cosmo (gMocren-V10-05-00)
- Fixed shadowing compilation warning in G4GMocrenFileSceneHandler.
13 July 2018 Gabriele Cosmo (gMocren-V10-04-01)
- Fixed remaining gcc-8 compilation warnings in G4GMocrenFileViewer.
@@ -42,8 +42,6 @@
#include <iomanip>
#include "globals.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include "G4VisManager.hh"
#include "G4GMocrenFile.hh"
@@ -90,6 +88,9 @@
#include "G4ScoringManager.hh"
#include "G4ScoringBox.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
//----- constants
const char GDD_FILE_HEADER [] = "g4_";
const char DEFAULT_GDD_FILE_NAME[] = "g4_00.gdd";
+191 -1
View File
@@ -25,9 +25,199 @@ committal in the CVS repository !
History file for visualization management sub-category
------------------------------------------------------
21 January 2019 John Allison (visman-V10-04-29)
13 June 2019 John Allison (visman-V10-05-06)
- Part of vis-V10-05-20.
- G4VSceneHandler:
o Final changes for introduction of cloud drawing.
o Add GetNumberOfCloudPoints:
Returns no of cloud points from current view parameters, unless the user
has forced through the vis attributes, thereby over-riding the
current view parameter.
- G4ViewParameters:
o Add accessors for number of cloud points.
- G4VisCommandsGeometrySet: Tidy.
- G4VisCommandsTouchableSet: Add commands for cloud style.
- G4VisCommandsViewerSet: Add commands for cloud style.
- G4VisCommandsCompound.cc: Tidy.
- G4VisCommandsGeometrySet.cc: Tidy.
- G4VisCommandsTouchable.cc: Improve printing.
29 May 2019 John Allison (visman-V10-05-05)
- G4VisManager.cc:
o Removed the word "WARNING" from message about number of events
kept for refreshing and/or reviewing.
04 April 2019 John Allison (visman-V10-05-04)
- Co-works modeling-V10-05-01.
- Final (for now) corrections to /vis/viewer/set/sectionPlane.
Still some strange behaviour in small fraction of cases. See
comments in G4PhysicalVolumeModel::DescribeSolid around line 748.
29 March 2019 John Allison (visman-V10-05-03)
- G4VSceneHandler.hh:
o BeginPrimitives/2D: Added default argument G4Transform3D() to
correspond to base class G4VGraphicsScene.
- G4ViewParameters.hh:
o Improved comments.
- G4Scene.cc: Improved operator<<.
24 March 2019 John Allison (visman-V10-05-02)
- Fix bug in /vis/viewer/set/sectionPlane.
Involves using G4DisplacedSolid instead of plain G4VSolid.
18 March 2019 Gabriele Cosmo (visman-V10-05-01)
- Corrected few typos in printout/comments.
10 March 2019 John Allison (visman-V10-05-00)
- Introduce cloud drawing style:
New parameter candidate in /vis/viewer/set/style:
/vis/viewer/set/style cloud
Cloud drawing uses solid->GetPointOnSurface, i.e., it uses kernel
algorithms and by-passes polyhedral representations. The solid is
represented by a polymarker of dots. The default number of points
is 1000. This can be changed with
/vis/viewer/set/numberOfCloudPoints
(The minimum number is 100.)
Note that OpenGL has a fast algorithm for polymarker.
- This allows us to use cloud style both as a choice or as fallback when the
polyhedral representation fails, for example, when BooleanProcessor fails.
- Many files affected:
o G4ViewParameters.hh/icc/cc
enum DrawingStyle {
wireframe, // Draw edges - no hidden line removal.
hlr, // Draw edges - hidden lines removed.
hsr, // Draw surfaces - hidden surfaces removed.
hlhsr, // Draw surfaces and edges - hidden removed.
cloud // Draw volume as a cloud of dots.
};
and consequential augmentation of access function, test functions and
stream output functions.
o G4VisCommandsViewerSet.hh/cc
. Add /vis/viewer/set/numberOfCloudPoints.
. Augment /vis/viewer/set/style to handle "c[loud]".
. Note: G4VisCommandsViewerSet.cc: Indentations recomputed (Xcode has
a slightly different algorithm to emacs). Many hundreds of lines changed.
o G4VSceneHandler::RequestPrimitives: Augmented to handle cloud.
o G4VisCommandsCompound.cc: Augment message from /vis/drawLogicalVolume.
o G4VisCommandsViewerDefault: Augment /vis/viewer/default/style.
- Other developments:
o void G4VSceneHandler::AddPrimitive (const G4Polymarker& polymarker)
Functionally unchanged but algorithmetically improved.
Note, as stated above, OpenGL does not use this default function -
it has its own version.
24 February 2019 John Allison
- Included in vis-V10-05-13
- Add /vis/touchable/extentForField and volumeForField.
19 February 2019 John Allison
- Included in vis-V10-05-12
- G4VVisCommand:
o Introduced fCurrrentPVFindingsForField.
o Added DrawExtent to utility functions.
- G4VisCommandsScene: Add /vis/scene/showExtents.
- G4VisCommandsSet: Add /vis/set/volumeForField.
- G4VisCommandsTouchable:
o Add /vis/touchable/showExtent.
o Add copy number parameter to /vis/touchable/findPath.
- G4Scene:
o Use G4BoundingExtentScene instead of G4BoundingSphereScene.
o Use G4VisExtent::GetTransformedExtent to correct for fix to bug in
G4PhysicalVolumeModel - see modeling/History.
- G4ViewParameters: Improve message.
- G4VisManager: Register the new commands.
13 February 2019 John Allison
- Included in vis-V10-05-11
- Implement /vis/set/extentForField - see visualisation/History.
10 February 2019 John Allison
- Included in vis-V10-05-10
- G4VisCommandsViewer:
o Improved /vis/viewer/centreOn (it does not zoom).
o Introduced /vis/viewer/centreAndZoomInOn.
- G4VisCommandsTouchable:
o Improved /vis/touchable/centreOn (it does not zoom).
o Introduced /vis/touchable/centreAndZoomInOn.
- G4VVisCommand:
o Introduced utility functions CopyGuidanceFrom and CopyParametersFrom.
- G4VisCommandsCompound:
o Made use of above-mentioned utility functions.
08 February 2019 John Allison
- Included in vis-V10-05-09
- Fix Coverity warnings.
31 January 2019 Michael Kelsey
- Included in vis-V10-05-08
- Provide ability to draw electric fields, and eventually any other field.
Refactor G4MagneticFieldModel to have an intermediate base class, which
implements DescribeYourselfTo(). Concrete class only implements a utility
function to get value from field. Add new G4ElectricFieldModel which does
the same thing. Add commands for the latter.
29 January 2019 John Allison
- Included in vis-V10-05-06
- G4VisCommandsTochable:
o Add /vis/touchable/draw.
- G4VisCommandsViewer: /vis/viewer/centreOn:
o Add copy number to parameter list.
- CheckSceneAndNotifyHandlers: move from xx to G4VVisCommand so that it
can be used by any messenger.
26 January 2019 John Allison
- Included in vis-V10-05-06
- Fix calculation of vis extent for parameterisations.
- Some minor tidying.
25 January 2019 John Allison
- Included in vis-V10-05-06
- Rationalise view interpolation
Encapsulate algorithm into base class G4VVisCommand. The commands
/vis/viewer/interpolate
/vis/viewer/centreOn
/vis/touchable/centerOn
now use this. Might consider use by all view changing commands.
25 January 2019 John Allison
- Included in vis-V10-05-05
- Include parameterised volumes in overlap checking and visualisation
in G4LogicalVolumeModel (in addition to ordinary placements).
22 January 2019 John Allison
- Included in vis-V10-05-04
- Introduce /vis/viewer/centreOn and /vis/touchable/centreOn
This allows one to centre the view (zoom in) on a volume.
Reset with /vis/viewer/reset.
- Moved
void SetViewParameters(G4VViewer* viewer, const G4ViewParameters& viewParams);
void RefreshIfRequired(G4VViewer* viewer);
from G4VisCommandsViewer to the higher level G4VVisCommand so that all
vis commands may make use. In so doing eliminated the intermediate class
G4VVisCommandViewer (which did not have a .hh file of its own and was anyhow
obscurely buried in G4VisComandsViewer). Much cleaner now.
21 January 2019 John Allison
- Included in vis-V10-05-03.
- Pick up default number of line-segments-per-circle from G4Polyhedron.
08 January 2019 John Allison
- Correct History files after merge
02 January 2019 John Allison
- Included in vis-V10-05-01.
- Minor improvements to vis manager.
- Added confirmation printing when registering models with the scene.
- At start of run:
// Check to see if the user has created a trajectory model. If not, create
// a default one. To avoid code duplication the following function is used
// and its result (a const G4VTrajectoryModel*) is thrown away at this point.
// The function is called again later when needed.
02 January 2019 John Allison
- Included in vis-V10-05-00.
- G4VisCommandsSceneAdd.cc: Improve guidance for /vis/scene/add/volume.
14 November 2018 John Allison (visman-V10-04-28)
- G4VisCommandsSceneAdd.cc: /vis/scene/add/userAction:
o Fix bug whereby success was branded unsuccessful when verbosity <= warnings.
@@ -56,6 +56,7 @@ class G4VPhysicalVolume;
class G4Material;
class G4Event;
class G4AttHolder;
class G4DisplacedSolid;
class G4VSceneHandler: public G4VGraphicsScene {
@@ -156,7 +157,7 @@ public: // With description
// }
virtual void BeginPrimitives
(const G4Transform3D& objectTransformation);
(const G4Transform3D& objectTransformation = G4Transform3D());
// IMPORTANT: invoke this from your polymorphic versions, e.g.:
// void MyXXXSceneHandler::BeginPrimitives
// (const G4Transform3D& objectTransformation) {
@@ -172,7 +173,7 @@ public: // With description
// }
virtual void BeginPrimitives2D
(const G4Transform3D& objectTransformation);
(const G4Transform3D& objectTransformation = G4Transform3D());
// The x,y coordinates of the primitives passed to AddPrimitive are
// intrepreted as screen coordinates, -1 < x,y < 1. The
// z-coordinate is ignored.
@@ -249,6 +250,11 @@ public: // With description
// has forced through the vis attributes, thereby over-riding the
// current view parameter.
G4int GetNumberOfCloudPoints (const G4VisAttributes*) const;
// Returns no of cloud points from current view parameters, unless the user
// has forced through the vis attributes, thereby over-riding the
// current view parameter.
G4bool GetAuxEdgeVisible (const G4VisAttributes*);
// Returns auxiliary edge visibility from current view parameters,
// unless the user has forced through the vis attributes, thereby
@@ -315,8 +321,8 @@ protected:
//////////////////////////////////////////////////////////////
// Other internal routines...
virtual G4VSolid* CreateSectionSolid ();
virtual G4VSolid* CreateCutawaySolid ();
virtual G4DisplacedSolid* CreateSectionSolid ();
virtual G4DisplacedSolid* CreateCutawaySolid ();
// Generic clipping using the BooleanProcessor in graphics_reps is
// implemented in this class. Subclasses that implement their own
// clipping should provide an override that returns zero.
@@ -38,28 +38,49 @@
#include "G4VisAttributes.hh"
#include "G4VMarker.hh"
#include "G4ModelingParameters.hh"
#include "G4PhysicalVolumesSearchScene.hh"
#include <vector>
class G4UIcommand;
class G4UIcmdWithAString;
class G4VVisCommand: public G4UImessenger {
class G4VVisCommand: public G4UImessenger
{
public:
// Uses compiler defaults for copy constructor and assignment.
G4VVisCommand ();
virtual ~G4VVisCommand ();
static void SetVisManager (G4VisManager*);
static const G4Colour& GetCurrentColour() {return fCurrentColour;}
//static G4VMarker::FillStyle GetCurrentFillStyle() {return fCurrentFillStyle;}
//static G4VMarker::SizeType GetCurrentSizeType() {return fCurrentSizeType;}
static G4double GetCurrentLineWidth() {return fCurrentLineWidth;}
//static G4VisAttributes::LineStyle GetCurrentLineStyle() {return fCurrentLineStyle;}
static const G4Colour& GetCurrentTextColour() {return fCurrentTextColour;}
static G4Text::Layout GetCurrentTextLayout() {return fCurrentTextLayout;}
static G4double GetCurrentTextSize() {return fCurrentTextSize;}
static void SetVisManager (G4VisManager* pVisManager)
{fpVisManager = pVisManager;}
static const G4Colour& GetCurrentTextColour()
{return fCurrentTextColour;}
protected:
// Utility functions
void SetViewParameters(G4VViewer* viewer, const G4ViewParameters& viewParams);
void RefreshIfRequired(G4VViewer* viewer);
void InterpolateViews
(G4VViewer* currentViewer,
std::vector<G4ViewParameters> viewVector,
const G4int nInterpolationPoints = 50,
const G4int waitTimePerPointmilliseconds = 20,
const G4String exportString = "");
void InterpolateToNewView
(G4VViewer* currentViewer,
const G4ViewParameters& oldVP,
const G4ViewParameters& newVP,
const G4int nInterpolationPoints = 50,
const G4int waitTimePerPointmilliseconds = 20,
const G4String exportString = "");
// Conversion routines augmenting those in G4UIcommand.
static G4String ConvertToString(G4double x, G4double y,
@@ -93,13 +114,24 @@ protected:
G4double& value);
// Return false if there's a problem
// Other utilities.
// Other utilities
void CheckSceneAndNotifyHandlers (G4Scene* = nullptr);
// Data members.
void G4VisCommandsSceneAddUnsuccessful(G4VisManager::Verbosity verbosity);
void CopyGuidanceFrom
(const G4UIcommand* fromCmd, G4UIcommand* toCmd, G4int startLine = 0);
void CopyParametersFrom
(const G4UIcommand* fromCmd, G4UIcommand* toCmd);
void DrawExtent(const G4VisExtent&);
// Data members
static G4VisManager* fpVisManager;
// Error management
static G4int fErrorCode;
// Current quantities for use in appropriate commands
@@ -113,8 +145,8 @@ protected:
static G4Text::Layout fCurrentTextLayout;
static G4double fCurrentTextSize;
static G4PhysicalVolumeModel::TouchableProperties fCurrentTouchableProperties;
static G4VisExtent fCurrentExtentForField;
static std::vector<G4PhysicalVolumesSearchScene::Findings> fCurrrentPVFindingsForField;
};
#include "G4VVisCommand.icc"
#endif
@@ -37,11 +37,11 @@
// In GEANT4 visualization, we have the concept of a "Standard
// View". This is the view when the complete set of objects being
// viewed is comfortably in view from any viewpoint. It is defined by
// the "Bounding Sphere" of "visible" objects when initially
// the "Bounding Extent" of "visible" objects when initially
// registered in the scene, and by the View Parameters.
//
// There is also the "Standard Target Point", which is the centre of
// the Bounding Sphere (note that this belongs to the scene and is
// the Bounding Extent (note that this belongs to the scene and is
// stored in the G4Scene object). The "Current Target Point", defined
// relative to the Standard Target Point, is changed by the
// "dolly" and "zoom" commands, and can be reset to the Standard
@@ -50,7 +50,7 @@
// Also, the "Standard Camera Position" is the "Standard Camera
// Distance" along the Viewpoint Direction vector from the Standard
// Target Point. The Standard Camera Distance is the radius of the
// Bounding Sphere divided by fFieldHalfAngle. It is not stored
// Bounding Extent divided by fFieldHalfAngle. It is not stored
// explicitly because of the singularity at fFieldHalfAngle = 0,
// which implies parallel projection.
//
@@ -62,7 +62,8 @@
// conceptually possible, but which might give some problems when
// setting up the view matrix - see, for example, G4OpenGLView::SetView ().
//
// All viewers are expected to keep the "Up Vector" vertical.
// All viewers are expected to keep the "Up Vector" vertical unless
// RotationStyle is freeRotation.
//
// Finally, the view is magnified by the "Zoom Factor" which is
// reset to 1 by the "/vis/viewer/reset" command.
@@ -94,7 +95,8 @@ public: // With description
wireframe, // Draw edges - no hidden line removal.
hlr, // Draw edges - hidden lines removed.
hsr, // Draw surfaces - hidden surfaces removed.
hlhsr // Draw surfaces and edges - hidden removed.
hlhsr, // Draw surfaces and edges - hidden removed.
cloud // Draw volume as a cloud of dots.
};
enum CutawayMode {
@@ -122,6 +124,7 @@ public: // With description
// Get and Is functions.
DrawingStyle GetDrawingStyle () const;
G4int GetNumberOfCloudPoints () const;
G4bool IsAuxEdgeVisible () const;
G4bool IsCulling () const;
G4bool IsCullingInvisible () const;
@@ -200,7 +203,7 @@ public: // With description
G4double GetDisplayLightFrontBlue () const;
// Here Follow functions to evaluate useful quantities as a
// function of the radius of the Bounding Sphere of the object being
// function of the radius of the Bounding Extent of the object being
// viewed. Call them in the order given - for efficiency, later
// functions depend on the results of earlier ones (Store the
// results of earlier functions in your own temporary variables -
@@ -213,6 +216,7 @@ public: // With description
// Set, Add, Multiply, Increment, Unset and Clear functions.
void SetDrawingStyle (G4ViewParameters::DrawingStyle style);
G4int SetNumberOfCloudPoints (G4int); // Returns number actually set.
void SetAuxEdgeVisible (G4bool);
void SetCulling (G4bool);
void SetCullingInvisible (G4bool);
@@ -230,7 +234,7 @@ public: // With description
void SetExplodeFactor (G4double explodeFactor);
void UnsetExplodeFactor ();
void SetExplodeCentre (const G4Point3D& explodeCentre);
G4int SetNoOfSides (G4int nSides); // Returns actual number set.
G4int SetNoOfSides (G4int nSides); // Returns number actually set.
void SetViewpointDirection (const G4Vector3D& viewpointDirection);
// Calls the following to get lightpoint direction right too.
void SetViewAndLights (const G4Vector3D& viewpointDirection);
@@ -321,6 +325,8 @@ private:
G4int ReadInteger(char *string, char **NextString);
DrawingStyle fDrawingStyle; // Drawing style.
G4int fNumberOfCloudPoints; // For drawing in cloud style.
// <= 0 means use viewer default.
G4bool fAuxEdgeVisible; // Auxiliary edge visibility.
G4bool fCulling; // Culling requested.
G4bool fCullInvisible; // Cull (don't Draw) invisible objects.
@@ -291,6 +291,10 @@ inline G4double G4ViewParameters::GetDisplayLightFrontBlue () const {
return fDisplayLightFrontBlue;
}
inline G4int G4ViewParameters::GetNumberOfCloudPoints () const {
return fNumberOfCloudPoints;
}
inline void
G4ViewParameters::SetDrawingStyle (G4ViewParameters::DrawingStyle style) {
fDrawingStyle = style;
@@ -74,13 +74,13 @@ class G4VisCommandGeometrySetForceAuxEdgeVisibleFunction:
public:
virtual ~G4VisCommandGeometrySetForceAuxEdgeVisibleFunction() {}
G4VisCommandGeometrySetForceAuxEdgeVisibleFunction
(G4bool forceAuxEdgeVisible):
fForceAuxEdgeVisible(forceAuxEdgeVisible) {}
(G4bool force):
fForce(force) {}
void operator()
(G4VisAttributes* visAtts) const
{visAtts->SetForceAuxEdgeVisible(fForceAuxEdgeVisible);}
{visAtts->SetForceAuxEdgeVisible(fForce);}
private:
G4bool fForceAuxEdgeVisible;
G4bool fForce;
};
class G4VisCommandGeometrySetForceLineSegmentsPerCircleFunction:
@@ -102,13 +102,13 @@ class G4VisCommandGeometrySetForceSolidFunction:
public:
virtual ~G4VisCommandGeometrySetForceSolidFunction() {}
G4VisCommandGeometrySetForceSolidFunction
(G4bool forceSolid):
fForceSolid(forceSolid) {}
(G4bool force):
fForce(force) {}
void operator()
(G4VisAttributes* visAtts) const
{visAtts->SetForceSolid(fForceSolid);}
{visAtts->SetForceSolid(fForce);}
private:
G4bool fForceSolid;
G4bool fForce;
};
class G4VisCommandGeometrySetForceWireframeFunction:
@@ -116,13 +116,13 @@ class G4VisCommandGeometrySetForceWireframeFunction:
public:
virtual ~G4VisCommandGeometrySetForceWireframeFunction() {}
G4VisCommandGeometrySetForceWireframeFunction
(G4bool forceWireframe):
fForceWireframe(forceWireframe) {}
(G4bool force):
fForce(force) {}
void operator()
(G4VisAttributes* visAtts) const
{visAtts->SetForceWireframe(fForceWireframe);}
{visAtts->SetForceWireframe(fForce);}
private:
G4bool fForceWireframe;
G4bool fForce;
};
class G4VisCommandGeometrySetLineStyleFunction:
@@ -137,4 +137,16 @@ private:
G4UIcmdWithAString* fpCommand;
};
class G4VisCommandSceneShowExtents: public G4VVisCommandScene {
public:
G4VisCommandSceneShowExtents ();
virtual ~G4VisCommandSceneShowExtents ();
G4String GetCurrentValue (G4UIcommand* command);
void SetNewValue (G4UIcommand* command, G4String newValue);
private:
G4VisCommandSceneShowExtents (const G4VisCommandSceneShowExtents&);
G4VisCommandSceneShowExtents& operator = (const G4VisCommandSceneShowExtents&);
G4UIcmdWithoutParameter* fpCommand;
};
#endif
@@ -26,6 +26,7 @@
//
// /vis/scene commands - John Allison 9th August 1998
// Michael Kelsey 31 Jan 2019 -- Add new command for electric field
#ifndef G4VISCOMMANDSSCENEADD_HH
#define G4VISCOMMANDSSCENEADD_HH
@@ -169,6 +170,18 @@ private:
G4UIcommand* fpCommand;
};
class G4VisCommandSceneAddElectricField: public G4VVisCommandScene {
public:
G4VisCommandSceneAddElectricField ();
virtual ~G4VisCommandSceneAddElectricField ();
G4String GetCurrentValue (G4UIcommand* command);
void SetNewValue (G4UIcommand* command, G4String newValue);
private:
G4VisCommandSceneAddElectricField (const G4VisCommandSceneAddElectricField&);
G4VisCommandSceneAddElectricField& operator = (const G4VisCommandSceneAddElectricField&);
G4UIcommand* fpCommand;
};
class G4VisCommandSceneAddFrame: public G4VVisCommandScene {
public:
G4VisCommandSceneAddFrame ();
@@ -62,6 +62,18 @@ private:
G4UIcommand* fpCommand;
};
class G4VisCommandSetExtentForField: public G4VVisCommand {
public:
G4VisCommandSetExtentForField ();
virtual ~G4VisCommandSetExtentForField ();
G4String GetCurrentValue (G4UIcommand* command);
void SetNewValue (G4UIcommand* command, G4String newValue);
private:
G4VisCommandSetExtentForField (const G4VisCommandSetExtentForField&);
G4VisCommandSetExtentForField& operator = (const G4VisCommandSetExtentForField&);
G4UIcommand* fpCommand;
};
class G4VisCommandSetLineWidth: public G4VVisCommand {
public:
G4VisCommandSetLineWidth ();
@@ -122,4 +134,16 @@ private:
G4UIcommand* fpCommand;
};
class G4VisCommandSetVolumeForField: public G4VVisCommand {
public:
G4VisCommandSetVolumeForField ();
virtual ~G4VisCommandSetVolumeForField ();
G4String GetCurrentValue (G4UIcommand* command);
void SetNewValue (G4UIcommand* command, G4String newValue);
private:
G4VisCommandSetVolumeForField (const G4VisCommandSetVolumeForField&);
G4VisCommandSetVolumeForField& operator = (const G4VisCommandSetVolumeForField&);
G4UIcommand* fpCommand;
};
#endif
@@ -34,6 +34,7 @@
class G4UIcmdWithAString;
class G4UIcmdWithoutParameter;
class G4UIcmdWithABool;
class G4VisCommandsTouchable: public G4VVisCommand {
public:
@@ -44,8 +45,14 @@ public:
private:
G4VisCommandsTouchable (const G4VisCommandsTouchable&);
G4VisCommandsTouchable& operator = (const G4VisCommandsTouchable&);
G4UIcmdWithoutParameter* fpCommandCentreOn;
G4UIcmdWithoutParameter* fpCommandCentreAndZoomInOn;
G4UIcmdWithoutParameter* fpCommandDraw;
G4UIcmdWithoutParameter* fpCommandDump;
G4UIcmdWithAString* fpCommandFindPath;
G4UIcmdWithABool* fpCommandExtentForField;
G4UIcommand* fpCommandFindPath;
G4UIcmdWithABool* fpCommandShowExtent;
G4UIcmdWithABool* fpCommandVolumeForField;
};
#endif
@@ -38,7 +38,7 @@ class G4UIcmdWithADouble;
class G4UIcmdWithAnInteger;
class G4UIcmdWithAString;
class G4VisCommandsTouchableSet: public G4VVisCommandViewer {
class G4VisCommandsTouchableSet: public G4VVisCommand {
public:
G4VisCommandsTouchableSet ();
virtual ~G4VisCommandsTouchableSet ();
@@ -51,10 +51,12 @@ private:
G4UIcmdWithABool* fpCommandSetDaughtersInvisible;
G4UIcmdWithABool* fpCommandSetForceAuxEdgeVisible;
G4UIcmdWithAnInteger* fpCommandSetLineSegmentsPerCircle;
G4UIcmdWithABool* fpCommandSetForceCloud;
G4UIcmdWithABool* fpCommandSetForceSolid;
G4UIcmdWithABool* fpCommandSetForceWireframe;
G4UIcmdWithAString* fpCommandSetLineStyle;
G4UIcmdWithADouble* fpCommandSetLineWidth;
G4UIcmdWithAnInteger* fpCommandSetNumberOfCloudPoints;
G4UIcmdWithABool* fpCommandSetVisibility;
};
@@ -41,19 +41,7 @@ class G4UIcmdWithADouble;
class G4UIcmdWithADoubleAndUnit;
class G4UIcmdWith3Vector;
class G4VVisCommandViewer: public G4VVisCommand {
public:
G4VVisCommandViewer ();
virtual ~G4VVisCommandViewer ();
protected:
void SetViewParameters(G4VViewer*, const G4ViewParameters&);
void RefreshIfRequired(G4VViewer*);
private:
G4VVisCommandViewer (const G4VVisCommandViewer&);
G4VVisCommandViewer& operator = (const G4VVisCommandViewer&);
};
class G4VisCommandViewerAddCutawayPlane: public G4VVisCommandViewer {
class G4VisCommandViewerAddCutawayPlane: public G4VVisCommand {
public:
G4VisCommandViewerAddCutawayPlane ();
virtual ~G4VisCommandViewerAddCutawayPlane ();
@@ -65,7 +53,20 @@ private:
G4UIcommand* fpCommand;
};
class G4VisCommandViewerChangeCutawayPlane: public G4VVisCommandViewer {
class G4VisCommandViewerCentreOn: public G4VVisCommand {
public:
G4VisCommandViewerCentreOn ();
virtual ~G4VisCommandViewerCentreOn ();
G4String GetCurrentValue (G4UIcommand* command);
void SetNewValue (G4UIcommand* command, G4String newValue);
private:
G4VisCommandViewerCentreOn (const G4VisCommandViewerCentreOn&);
G4VisCommandViewerCentreOn& operator = (const G4VisCommandViewerCentreOn&);
G4UIcommand* fpCommandCentreOn;
G4UIcommand* fpCommandCentreAndZoomInOn;
};
class G4VisCommandViewerChangeCutawayPlane: public G4VVisCommand {
public:
G4VisCommandViewerChangeCutawayPlane ();
virtual ~G4VisCommandViewerChangeCutawayPlane ();
@@ -77,7 +78,7 @@ private:
G4UIcommand* fpCommand;
};
class G4VisCommandViewerClear: public G4VVisCommandViewer {
class G4VisCommandViewerClear: public G4VVisCommand {
public:
G4VisCommandViewerClear ();
virtual ~G4VisCommandViewerClear ();
@@ -89,7 +90,7 @@ private:
G4UIcmdWithAString* fpCommand;
};
class G4VisCommandViewerClearCutawayPlanes: public G4VVisCommandViewer {
class G4VisCommandViewerClearCutawayPlanes: public G4VVisCommand {
public:
G4VisCommandViewerClearCutawayPlanes ();
virtual ~G4VisCommandViewerClearCutawayPlanes ();
@@ -101,7 +102,7 @@ private:
G4UIcmdWithoutParameter* fpCommand;
};
class G4VisCommandViewerClearTransients: public G4VVisCommandViewer {
class G4VisCommandViewerClearTransients: public G4VVisCommand {
public:
G4VisCommandViewerClearTransients ();
virtual ~G4VisCommandViewerClearTransients ();
@@ -114,7 +115,7 @@ private:
G4UIcmdWithAString* fpCommand;
};
class G4VisCommandViewerClearVisAttributesModifiers: public G4VVisCommandViewer {
class G4VisCommandViewerClearVisAttributesModifiers: public G4VVisCommand {
public:
G4VisCommandViewerClearVisAttributesModifiers ();
virtual ~G4VisCommandViewerClearVisAttributesModifiers ();
@@ -126,7 +127,7 @@ private:
G4UIcmdWithoutParameter* fpCommand;
};
class G4VisCommandViewerClone: public G4VVisCommandViewer {
class G4VisCommandViewerClone: public G4VVisCommand {
public:
G4VisCommandViewerClone ();
virtual ~G4VisCommandViewerClone ();
@@ -139,7 +140,7 @@ private:
G4UIcommand* fpCommand;
};
class G4VisCommandViewerColourByDensity: public G4VVisCommandViewer {
class G4VisCommandViewerColourByDensity: public G4VVisCommand {
public:
G4VisCommandViewerColourByDensity ();
virtual ~G4VisCommandViewerColourByDensity ();
@@ -151,7 +152,7 @@ private:
G4UIcommand* fpCommand;
};
class G4VisCommandViewerCopyViewFrom: public G4VVisCommandViewer {
class G4VisCommandViewerCopyViewFrom: public G4VVisCommand {
public:
G4VisCommandViewerCopyViewFrom ();
virtual ~G4VisCommandViewerCopyViewFrom ();
@@ -164,7 +165,7 @@ private:
G4UIcmdWithAString* fpCommand;
};
class G4VisCommandViewerCreate: public G4VVisCommandViewer {
class G4VisCommandViewerCreate: public G4VVisCommand {
public:
G4VisCommandViewerCreate ();
virtual ~G4VisCommandViewerCreate ();
@@ -178,7 +179,7 @@ private:
G4int fId;
};
class G4VisCommandViewerDolly: public G4VVisCommandViewer {
class G4VisCommandViewerDolly: public G4VVisCommand {
public:
G4VisCommandViewerDolly ();
virtual ~G4VisCommandViewerDolly ();
@@ -193,7 +194,7 @@ private:
G4double fDollyTo;
};
class G4VisCommandViewerFlush: public G4VVisCommandViewer {
class G4VisCommandViewerFlush: public G4VVisCommand {
public:
G4VisCommandViewerFlush ();
virtual ~G4VisCommandViewerFlush ();
@@ -205,7 +206,7 @@ private:
G4UIcmdWithAString* fpCommand;
};
class G4VisCommandViewerInterpolate: public G4VVisCommandViewer {
class G4VisCommandViewerInterpolate: public G4VVisCommand {
public:
G4VisCommandViewerInterpolate ();
virtual ~G4VisCommandViewerInterpolate ();
@@ -217,7 +218,7 @@ private:
G4UIcommand* fpCommand;
};
class G4VisCommandViewerList: public G4VVisCommandViewer {
class G4VisCommandViewerList: public G4VVisCommand {
public:
G4VisCommandViewerList ();
virtual ~G4VisCommandViewerList ();
@@ -229,7 +230,7 @@ private:
G4UIcommand* fpCommand;
};
class G4VisCommandViewerPan: public G4VVisCommandViewer {
class G4VisCommandViewerPan: public G4VVisCommand {
public:
G4VisCommandViewerPan ();
virtual ~G4VisCommandViewerPan ();
@@ -244,7 +245,7 @@ private:
G4double fPanToRight, fPanToUp;
};
class G4VisCommandViewerReset: public G4VVisCommandViewer {
class G4VisCommandViewerReset: public G4VVisCommand {
public:
G4VisCommandViewerReset ();
virtual ~G4VisCommandViewerReset ();
@@ -256,7 +257,7 @@ private:
G4UIcmdWithAString* fpCommand;
};
class G4VisCommandViewerRefresh: public G4VVisCommandViewer {
class G4VisCommandViewerRefresh: public G4VVisCommand {
public:
G4VisCommandViewerRefresh ();
virtual ~G4VisCommandViewerRefresh ();
@@ -268,7 +269,7 @@ private:
G4UIcmdWithAString* fpCommand;
};
class G4VisCommandViewerRebuild: public G4VVisCommandViewer {
class G4VisCommandViewerRebuild: public G4VVisCommand {
public:
G4VisCommandViewerRebuild ();
virtual ~G4VisCommandViewerRebuild ();
@@ -280,7 +281,7 @@ private:
G4UIcmdWithAString* fpCommand;
};
class G4VisCommandViewerSave: public G4VVisCommandViewer {
class G4VisCommandViewerSave: public G4VVisCommand {
public:
G4VisCommandViewerSave ();
virtual ~G4VisCommandViewerSave ();
@@ -292,7 +293,7 @@ private:
G4UIcmdWithAString* fpCommand;
};
class G4VisCommandViewerScale: public G4VVisCommandViewer {
class G4VisCommandViewerScale: public G4VVisCommand {
public:
G4VisCommandViewerScale ();
virtual ~G4VisCommandViewerScale ();
@@ -307,7 +308,7 @@ private:
G4Vector3D fScaleTo;
};
class G4VisCommandViewerSelect: public G4VVisCommandViewer {
class G4VisCommandViewerSelect: public G4VVisCommand {
public:
G4VisCommandViewerSelect ();
virtual ~G4VisCommandViewerSelect ();
@@ -319,7 +320,7 @@ private:
G4UIcmdWithAString* fpCommand;
};
class G4VisCommandViewerUpdate: public G4VVisCommandViewer {
class G4VisCommandViewerUpdate: public G4VVisCommand {
public:
G4VisCommandViewerUpdate ();
virtual ~G4VisCommandViewerUpdate ();
@@ -331,7 +332,7 @@ private:
G4UIcmdWithAString* fpCommand;
};
class G4VisCommandViewerZoom: public G4VVisCommandViewer {
class G4VisCommandViewerZoom: public G4VVisCommand {
public:
G4VisCommandViewerZoom ();
virtual ~G4VisCommandViewerZoom ();
@@ -42,7 +42,7 @@ class G4UIcmdWithAnInteger;
class G4UIcmdWithADouble;
class G4UIcmdWith3VectorAndUnit;
class G4VisCommandsViewerSet: public G4VVisCommandViewer {
class G4VisCommandsViewerSet: public G4VVisCommand {
public:
G4VisCommandsViewerSet ();
virtual ~G4VisCommandsViewerSet ();
@@ -65,11 +65,12 @@ private:
G4UIcmdWithADouble* fpCommandGlobalLineWidthScale;
G4UIcmdWithABool* fpCommandHiddenEdge;
G4UIcmdWithABool* fpCommandHiddenMarker;
G4UIcmdWithAnInteger* fpCommandLineSegments;
G4UIcmdWithAString* fpCommandLightsMove;
G4UIcommand* fpCommandLightsThetaPhi;
G4UIcommand* fpCommandLightsVector;
G4ThreeVector fLightsVector;
G4UIcmdWithAnInteger* fpCommandLineSegments;
G4UIcmdWithAnInteger* fpCommandNumberOfCloudPoints;
G4UIcmdWithABool* fpCommandPicking;
G4UIcommand* fpCommandProjection;
G4UIcmdWithAString* fpCommandRotationStyle;
@@ -63,7 +63,6 @@ GEANT4_DEFINE_MODULE(NAME G4vis_management
G4VViewer.hh
G4VViewer.icc
G4VVisCommand.hh
G4VVisCommand.icc
G4ViewParameters.hh
G4ViewParameters.icc
G4ViewerList.hh
+34 -43
View File
@@ -31,7 +31,7 @@
#include "G4Scene.hh"
#include "G4Vector3D.hh"
#include "G4BoundingSphereScene.hh"
#include "G4BoundingExtentScene.hh"
#include "G4VisAttributes.hh"
#include "G4PhysicalVolumeModel.hh"
#include "G4TransportationManager.hh"
@@ -94,28 +94,30 @@ G4bool G4Scene::AddRunDurationModel (G4VModel* pModel, G4bool warn)
return true;
}
namespace {
void PrintInvalidModel(const G4VModel* model)
{
G4ExceptionDescription ed;
ed << "Invalid model \"" << model->GetGlobalDescription()
<< "\".\n Not included in extent calculation.";
G4Exception
("G4Scene::CalculateExtent",
"visman0201", JustWarning, ed);
}
}
void G4Scene::CalculateExtent ()
{
G4BoundingSphereScene boundingSphereScene;
G4BoundingExtentScene boundingExtentScene;
for (size_t i = 0; i < fRunDurationModelList.size(); i++) {
if (fRunDurationModelList[i].fActive) {
G4VModel* model = fRunDurationModelList[i].fpModel;
if (model -> Validate()) { // Validates and also recomputes extent.
const G4VisExtent& thisExtent = model -> GetExtent ();
G4double thisRadius = thisExtent.GetExtentRadius ();
if (thisRadius > 0.) {
G4Point3D thisCentre = thisExtent.GetExtentCentre ();
thisCentre.transform (model -> GetTransformation ());
boundingSphereScene.AccrueBoundingSphere (thisCentre, thisRadius);
}
const G4VisExtent& thisExtent = model -> GetTransformedExtent ();
boundingExtentScene.AccrueBoundingExtent(thisExtent);
} else {
G4ExceptionDescription ed;
ed << "Invalid model \"" << model->GetGlobalDescription()
<< "\".\n Not included in extent calculation.";
G4Exception
("G4Scene::CalculateExtent",
"visman0201", JustWarning, ed);
PrintInvalidModel(model);
}
}
}
@@ -124,20 +126,10 @@ void G4Scene::CalculateExtent ()
if (fEndOfEventModelList[i].fActive) {
G4VModel* model = fEndOfEventModelList[i].fpModel;
if (model -> Validate()) { // Validates and also recomputes extent.
const G4VisExtent& thisExtent = model -> GetExtent ();
G4double thisRadius = thisExtent.GetExtentRadius ();
if (thisRadius > 0.) {
G4Point3D thisCentre = thisExtent.GetExtentCentre ();
thisCentre.transform (model -> GetTransformation ());
boundingSphereScene.AccrueBoundingSphere (thisCentre, thisRadius);
}
const G4VisExtent& thisExtent = model -> GetTransformedExtent ();
boundingExtentScene.AccrueBoundingExtent(thisExtent);
} else {
G4ExceptionDescription ed;
ed << "Invalid model \"" << model->GetGlobalDescription()
<< "\".\n Not included in extent calculation.";
G4Exception
("G4Scene::CalculateExtent",
"visman0201", JustWarning, ed);
PrintInvalidModel(model);
}
}
}
@@ -146,25 +138,15 @@ void G4Scene::CalculateExtent ()
if (fEndOfRunModelList[i].fActive) {
G4VModel* model = fEndOfRunModelList[i].fpModel;
if (model -> Validate()) { // Validates and also recomputes extent.
const G4VisExtent& thisExtent = model -> GetExtent ();
G4double thisRadius = thisExtent.GetExtentRadius ();
if (thisRadius > 0.) {
G4Point3D thisCentre = thisExtent.GetExtentCentre ();
thisCentre.transform (model -> GetTransformation ());
boundingSphereScene.AccrueBoundingSphere (thisCentre, thisRadius);
}
const G4VisExtent& thisExtent = model -> GetTransformedExtent ();
boundingExtentScene.AccrueBoundingExtent(thisExtent);
} else {
G4ExceptionDescription ed;
ed << "Invalid model \"" << model->GetGlobalDescription()
<< "\".\n Not included in extent calculation.";
G4Exception
("G4Scene::CalculateExtent",
"visman0201", JustWarning, ed);
PrintInvalidModel(model);
}
}
}
fExtent = boundingSphereScene.GetBoundingSphereExtent ();
fExtent = boundingExtentScene.GetBoundingExtent ();
fStandardTargetPoint = fExtent.GetExtentCentre ();
if (fExtent.GetExtentRadius() <= 0.) {
G4Exception
@@ -261,6 +243,9 @@ std::ostream& operator << (std::ostream& os, const G4Scene& scene) {
os << "Scene data:";
os << "\n Run-duration model list:";
if (scene.fRunDurationModelList.size () == 0) {
os << " none";
}
for (i = 0; i < scene.fRunDurationModelList.size (); i++) {
if (scene.fRunDurationModelList[i].fActive) os << "\n Active: ";
else os << "\n Inactive: ";
@@ -268,6 +253,9 @@ std::ostream& operator << (std::ostream& os, const G4Scene& scene) {
}
os << "\n End-of-event model list:";
if (scene.fEndOfEventModelList.size () == 0) {
os << " none";
}
for (i = 0; i < scene.fEndOfEventModelList.size (); i++) {
if (scene.fEndOfEventModelList[i].fActive) os << "\n Active: ";
else os << "\n Inactive: ";
@@ -275,13 +263,16 @@ std::ostream& operator << (std::ostream& os, const G4Scene& scene) {
}
os << "\n End-of-run model list:";
if (scene.fEndOfRunModelList.size () == 0) {
os << " none";
}
for (i = 0; i < scene.fEndOfRunModelList.size (); i++) {
if (scene.fEndOfRunModelList[i].fActive) os << "\n Active: ";
else os << "\n Inactive: ";
os << *(scene.fEndOfRunModelList[i].fpModel);
}
os << "\n Extent or bounding box: " << scene.fExtent;
os << "\n Overall extent or bounding box: " << scene.fExtent;
os << "\n Standard target point: " << scene.fStandardTargetPoint;
@@ -90,6 +90,8 @@
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include <set>
G4VSceneHandler::G4VSceneHandler (G4VGraphicsSystem& system, G4int id, const G4String& name):
fSystem (system),
fSceneHandlerId (id),
@@ -526,36 +528,36 @@ void G4VSceneHandler::AddPrimitive (const G4Scale& scale) {
void G4VSceneHandler::AddPrimitive (const G4Polymarker& polymarker) {
switch (polymarker.GetMarkerType()) {
default:
case G4Polymarker::dots:
default:
case G4Polymarker::dots:
{
G4Circle dot (polymarker);
dot.SetWorldSize (0.);
dot.SetScreenSize (0.1); // Very small circle.
for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) {
G4Circle dot (polymarker);
dot.SetPosition (polymarker[iPoint]);
dot.SetWorldSize (0.);
dot.SetScreenSize (0.1); // Very small circle.
AddPrimitive (dot);
AddPrimitive (dot);
}
}
break;
case G4Polymarker::circles:
break;
case G4Polymarker::circles:
{
G4Circle circle (polymarker); // Default circle
for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) {
G4Circle circle (polymarker);
circle.SetPosition (polymarker[iPoint]);
AddPrimitive (circle);
circle.SetPosition (polymarker[iPoint]);
AddPrimitive (circle);
}
}
break;
case G4Polymarker::squares:
break;
case G4Polymarker::squares:
{
G4Square square (polymarker); // Default square
for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) {
G4Square square (polymarker);
square.SetPosition (polymarker[iPoint]);
AddPrimitive (square);
square.SetPosition (polymarker[iPoint]);
AddPrimitive (square);
}
}
break;
break;
}
}
@@ -572,38 +574,79 @@ void G4VSceneHandler::SetScene (G4Scene* pScene) {
}
}
void G4VSceneHandler::RequestPrimitives (const G4VSolid& solid) {
G4Polyhedron::SetNumberOfRotationSteps (GetNoOfSides (fpVisAttribs));
G4Polyhedron* pPolyhedron = solid.GetPolyhedron ();
G4Polyhedron::ResetNumberOfRotationSteps ();
if (pPolyhedron) {
pPolyhedron -> SetVisAttributes (fpVisAttribs);
BeginPrimitives (fObjectTransformation);
AddPrimitive (*pPolyhedron);
EndPrimitives ();
}
else {
G4VisManager::Verbosity verbosity = G4VisManager::GetVerbosity();
if (verbosity >= G4VisManager::errors) {
G4cerr <<
"ERROR: G4VSceneHandler::RequestPrimitives"
"\n Polyhedron not available for " << solid.GetName () <<
"\n Touchable path: ";
G4PhysicalVolumeModel* pPVModel = dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
if (pPVModel) {
G4cerr << pPVModel->GetFullPVPath();
void G4VSceneHandler::RequestPrimitives (const G4VSolid& solid)
{
const G4ViewParameters::DrawingStyle style = GetDrawingStyle(fpVisAttribs);
const G4ViewParameters& vp = fpViewer->GetViewParameters();
switch (style) {
default:
case G4ViewParameters::wireframe:
case G4ViewParameters::hlr:
case G4ViewParameters::hsr:
case G4ViewParameters::hlhsr:
{
// Use polyhedral representation
G4Polyhedron::SetNumberOfRotationSteps (GetNoOfSides (fpVisAttribs));
G4Polyhedron* pPolyhedron = solid.GetPolyhedron ();
G4Polyhedron::ResetNumberOfRotationSteps ();
if (pPolyhedron) {
pPolyhedron -> SetVisAttributes (fpVisAttribs);
BeginPrimitives (fObjectTransformation);
AddPrimitive (*pPolyhedron);
EndPrimitives ();
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);
G4cerr <<
"ERROR: G4VSceneHandler::RequestPrimitives"
"\n Polyhedron not available for " << solid.GetName ();
G4PhysicalVolumeModel* pPVModel = dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
if (pPVModel) {
G4cerr << "\n Touchable path: " << pPVModel->GetFullPVPath();
}
static G4bool explanation = false;
if (!explanation) {
explanation = true;
G4cerr <<
"\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.";
}
G4cerr << "\n Drawing solid with cloud of points.";
G4cerr << G4endl;
}
}
static G4bool explanation = false;
if (!explanation) {
explanation = true;
G4cerr <<
"\n This means it cannot be visualized on most systems (try RayTracer)."
"\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.";
} // fallthrough
case G4ViewParameters::cloud:
{
// Form solid out of cloud of dots
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.
// And anyway, in Qt, in the latter case each circle would be a scene-tree
// entry, something we would want to avoid.
dots.SetVisAttributes(fpVisAttribs);
dots.SetMarkerType(G4Polymarker::dots);
dots.SetSize(G4VMarker::screen,1.);
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);
}
G4cerr << G4endl;
BeginPrimitives (fObjectTransformation);
AddPrimitive(dots);
EndPrimitives ();
}
break;
}
}
@@ -790,21 +833,24 @@ G4ModelingParameters* G4VSceneHandler::CreateModelingParameters ()
// Convert drawing styles...
G4ModelingParameters::DrawingStyle modelDrawingStyle =
G4ModelingParameters::wf;
G4ModelingParameters::wf;
switch (vp.GetDrawingStyle ()) {
default:
case G4ViewParameters::wireframe:
modelDrawingStyle = G4ModelingParameters::wf;
break;
case G4ViewParameters::hlr:
modelDrawingStyle = G4ModelingParameters::hlr;
break;
case G4ViewParameters::hsr:
modelDrawingStyle = G4ModelingParameters::hsr;
break;
case G4ViewParameters::hlhsr:
modelDrawingStyle = G4ModelingParameters::hlhsr;
break;
default:
case G4ViewParameters::wireframe:
modelDrawingStyle = G4ModelingParameters::wf;
break;
case G4ViewParameters::hlr:
modelDrawingStyle = G4ModelingParameters::hlr;
break;
case G4ViewParameters::hsr:
modelDrawingStyle = G4ModelingParameters::hsr;
break;
case G4ViewParameters::hlhsr:
modelDrawingStyle = G4ModelingParameters::hlhsr;
break;
case G4ViewParameters::cloud:
modelDrawingStyle = G4ModelingParameters::cloud;
break;
}
// Decide if covered daughters are really to be culled...
@@ -825,6 +871,7 @@ G4ModelingParameters* G4VSceneHandler::CreateModelingParameters ()
vp.GetNoOfSides ()
);
pModelingParams->SetNumberOfCloudPoints(vp.GetNumberOfCloudPoints());
pModelingParams->SetWarning
(G4VisManager::GetVerbosity() >= G4VisManager::warnings);
@@ -843,34 +890,44 @@ G4ModelingParameters* G4VSceneHandler::CreateModelingParameters ()
return pModelingParams;
}
G4VSolid* G4VSceneHandler::CreateSectionSolid()
G4DisplacedSolid* G4VSceneHandler::CreateSectionSolid()
{
G4VSolid* sectioner = 0;
G4DisplacedSolid* sectioner = 0;
const G4ViewParameters& vp = fpViewer->GetViewParameters();
if (vp.IsSection () ) {
G4double radius = fpScene->GetExtent().GetExtentRadius();
G4double safe = radius + fpScene->GetExtent().GetExtentCentre().mag();
G4VSolid* sectionBox =
new G4Box("_sectioner", safe, safe, 1.e-5 * radius); // Thin in z-plane.
new G4Box("_sectioner", safe, safe, 1.e-5 * radius); // Thin in z-plane...
const G4Normal3D originalNormal(0,0,1); // ...so this is original normal.
const G4Plane3D& sp = vp.GetSectionPlane ();
G4double a = sp.a();
G4double b = sp.b();
G4double c = sp.c();
G4double d = sp.d();
G4Transform3D transform = G4TranslateZ3D(-d);
const G4Normal3D normal(a,b,c);
if (normal != G4Normal3D(0,0,1)) {
const G4double angle = std::acos(normal.dot(G4Normal3D(0,0,1)));
const G4Vector3D axis = G4Normal3D(0,0,1).cross(normal);
transform = G4Rotate3D(angle, axis) * transform;
const G4double& a = sp.a();
const G4double& b = sp.b();
const G4double& c = sp.c();
const G4double& d = sp.d();
const G4Normal3D newNormal(a,b,c);
G4Transform3D requiredTransform;
// Rotate
if (newNormal != originalNormal) {
const G4double& angle = std::acos(newNormal.dot(originalNormal));
const G4Vector3D& axis = originalNormal.cross(newNormal);
requiredTransform = G4Rotate3D(angle, axis);
}
// Translate
requiredTransform = requiredTransform * G4TranslateZ3D(-d);
sectioner = new G4DisplacedSolid
("_displaced_sectioning_box", sectionBox, transform);
("_displaced_sectioning_box", sectionBox, requiredTransform);
}
return sectioner;
}
G4VSolid* G4VSceneHandler::CreateCutawaySolid()
G4DisplacedSolid* G4VSceneHandler::CreateCutawaySolid()
{
// To be reviewed.
return 0;
@@ -882,7 +939,7 @@ G4VSolid* G4VSceneHandler::CreateCutawaySolid()
main geometry tree (material world) is added. If "worlds", the
top of all worlds - material world and parallel worlds, if any - are
added. Otherwise a search of all worlds is made, taking the first
matching occurence only. To see a representation of the geometry
matching occurrence only. To see a representation of the geometry
hierarchy of the worlds, try "/vis/drawTree [worlds]" or one of the
driver/browser combinations that have the required functionality, e.g., HepRep.
If clip-volume-type is specified, the subsequent parameters are used to
@@ -983,41 +1040,58 @@ G4ViewParameters::DrawingStyle G4VSceneHandler::GetDrawingStyle
// Drawing style is normally determined by the view parameters, but
// it can be overriddden by the ForceDrawingStyle flag in the vis
// attributes.
G4ViewParameters::DrawingStyle style =
fpViewer->GetViewParameters().GetDrawingStyle();
const G4ViewParameters& vp = fpViewer->GetViewParameters();
G4ViewParameters::DrawingStyle style = vp.GetDrawingStyle();
if (pVisAttribs -> IsForceDrawingStyle ()) {
G4VisAttributes::ForcedDrawingStyle forcedStyle =
pVisAttribs -> GetForcedDrawingStyle ();
pVisAttribs -> GetForcedDrawingStyle ();
// This is complicated because if hidden line and surface removal
// has been requested we wish to preserve this sometimes.
switch (forcedStyle) {
case (G4VisAttributes::solid):
switch (style) {
case (G4ViewParameters::hlr):
style = G4ViewParameters::hlhsr;
break;
case (G4ViewParameters::wireframe):
style = G4ViewParameters::hsr;
break;
case (G4ViewParameters::hlhsr):
case (G4ViewParameters::hsr):
case (G4VisAttributes::solid):
switch (style) {
case (G4ViewParameters::hlr):
style = G4ViewParameters::hlhsr;
break;
case (G4ViewParameters::wireframe):
style = G4ViewParameters::hsr;
break;
case (G4ViewParameters::cloud):
style = G4ViewParameters::hsr;
break;
case (G4ViewParameters::hlhsr):
case (G4ViewParameters::hsr):
break;
}
break;
case (G4VisAttributes::cloud):
style = G4ViewParameters::cloud;
break;
case (G4VisAttributes::wireframe):
default:
break;
}
break;
case (G4VisAttributes::wireframe):
default:
// But if forced style is wireframe, do it, because one of its
// main uses is in displaying the consituent solids of a Boolean
// solid and their surfaces overlap with the resulting Booean
// solid, making a mess if hlr is specified.
style = G4ViewParameters::wireframe;
break;
// But if forced style is wireframe, do it, because one of its
// main uses is in displaying the consituent solids of a Boolean
// solid and their surfaces overlap with the resulting Booean
// solid, making a mess if hlr is specified.
style = G4ViewParameters::wireframe;
break;
}
}
return style;
}
G4int G4VSceneHandler::GetNumberOfCloudPoints
(const G4VisAttributes* pVisAttribs) const {
// Returns no of cloud points from current view parameters, unless the user
// has forced through the vis attributes, thereby over-riding the
// current view parameter.
G4int numberOfCloudPoints = fpViewer->GetViewParameters().GetNumberOfCloudPoints();
if (pVisAttribs -> GetForcedNumberOfCloudPoints() > 0) {
numberOfCloudPoints = pVisAttribs -> GetForcedNumberOfCloudPoints();
}
return numberOfCloudPoints;
}
G4bool G4VSceneHandler::GetAuxEdgeVisible (const G4VisAttributes* pVisAttribs) {
G4bool isAuxEdgeVisible = fpViewer->GetViewParameters().IsAuxEdgeVisible ();
if (pVisAttribs -> IsForceAuxEdgeVisible()) {
@@ -47,7 +47,9 @@ G4double G4VVisCommand::fCurrentLineWidth = 1.; // pixels
// Not yet used: G4VisAttributes::LineStyle G4VVisCommand::fCurrentLineStyle = G4VisAttributes::unbroken;
// Not yet used: G4VMarker::FillStyle G4VVisCommand::fCurrentFillStyle = G4VMarker::filled;
// Not yet used: G4VMarker::SizeType G4VVisCommand::fCurrentSizeType = G4VMarker::screen;
G4PhysicalVolumeModel::TouchableProperties G4VVisCommand::fCurrentTouchableProperties;
G4PhysicalVolumeModel::TouchableProperties G4VVisCommand::fCurrentTouchableProperties;
G4VisExtent G4VVisCommand::fCurrentExtentForField;
std::vector<G4PhysicalVolumesSearchScene::Findings> G4VVisCommand::fCurrrentPVFindingsForField;
G4VVisCommand::G4VVisCommand () {}
@@ -216,3 +218,126 @@ void G4VVisCommand::CheckSceneAndNotifyHandlers(G4Scene* pScene)
}
}
void G4VVisCommand::G4VisCommandsSceneAddUnsuccessful
(G4VisManager::Verbosity verbosity) {
// Some frequently used error printing...
if (verbosity >= G4VisManager::warnings) {
G4cout <<
"WARNING: For some reason, possibly mentioned above, it has not been"
"\n possible to add to the scene."
<< G4endl;
}
}
void G4VVisCommand::SetViewParameters
(G4VViewer* viewer, const G4ViewParameters& viewParams) {
viewer->SetViewParameters(viewParams);
RefreshIfRequired(viewer);
}
void G4VVisCommand::RefreshIfRequired(G4VViewer* viewer) {
G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
G4VSceneHandler* sceneHandler = viewer->GetSceneHandler();
const G4ViewParameters& viewParams = viewer->GetViewParameters();
if (sceneHandler && sceneHandler->GetScene()) {
if (viewParams.IsAutoRefresh()) {
G4UImanager::GetUIpointer()->ApplyCommand("/vis/viewer/refresh");
}
else {
if (verbosity >= G4VisManager::warnings) {
G4cout << "Issue /vis/viewer/refresh or flush to see effect."
<< G4endl;
}
}
}
}
void G4VVisCommand::InterpolateViews
(G4VViewer* currentViewer,
std::vector<G4ViewParameters> viewVector,
const G4int nInterpolationPoints,
const G4int waitTimePerPointmilliseconds,
const G4String exportString)
{
const G4int safety = viewVector.size()*nInterpolationPoints;
G4int safetyCount = 0;
do {
G4ViewParameters* vp =
G4ViewParameters::CatmullRomCubicSplineInterpolation(viewVector,nInterpolationPoints);
if (!vp) break; // Finished.
currentViewer->SetViewParameters(*vp);
currentViewer->RefreshView();
if (exportString == "export" &&
currentViewer->GetName().contains("OpenGL")) {
G4UImanager::GetUIpointer()->ApplyCommand("/vis/ogl/export");
}
// File-writing viewers need to close the file
currentViewer->ShowView();
#ifdef G4VIS_USE_STD11
if (waitTimePerPointmilliseconds > 0)
std::this_thread::sleep_for(std::chrono::milliseconds(waitTimePerPointmilliseconds));
#endif
} while (safetyCount++ < safety); // Loop checking, 16.02.2016, J.Allison
}
void G4VVisCommand::InterpolateToNewView
(G4VViewer* currentViewer,
const G4ViewParameters& oldVP,
const G4ViewParameters& newVP,
const G4int nInterpolationPoints,
const G4int waitTimePerPointmilliseconds,
const G4String exportString)
{
std::vector<G4ViewParameters> viewVector;
viewVector.push_back(oldVP);
viewVector.push_back(oldVP);
viewVector.push_back(newVP);
viewVector.push_back(newVP);
InterpolateViews
(currentViewer,
viewVector,
nInterpolationPoints,
waitTimePerPointmilliseconds,
exportString);
}
void G4VVisCommand::CopyGuidanceFrom
(const G4UIcommand* fromCmd, G4UIcommand* toCmd, G4int startLine)
{
if (fromCmd && toCmd) {
const G4int nGuideEntries = fromCmd->GetGuidanceEntries();
for (G4int i = startLine; i < nGuideEntries; ++i) {
const G4String& guidance = fromCmd->GetGuidanceLine(i);
toCmd->SetGuidance(guidance);
}
}
}
void G4VVisCommand::CopyParametersFrom
(const G4UIcommand* fromCmd, G4UIcommand* toCmd)
{
if (fromCmd && toCmd) {
const G4int nParEntries = fromCmd->GetParameterEntries();
for (G4int i = 0; i < nParEntries; ++i) {
G4UIparameter* parameter = new G4UIparameter(*(fromCmd->GetParameter(i)));
toCmd->SetParameter(parameter);
}
}
}
void G4VVisCommand::DrawExtent(const G4VisExtent& extent)
{
if (fpVisManager) {
const G4double halfX = (extent.GetXmax() - extent.GetXmin()) / 2.;
const G4double halfY = (extent.GetYmax() - extent.GetYmin()) / 2.;
const G4double halfZ = (extent.GetZmax() - extent.GetZmin()) / 2.;
if (halfX > 0. && halfY > 0. && halfZ > 0.) {
const G4Box box("vis_extent",halfX,halfY,halfZ);
const G4VisAttributes visAtts(G4Color::Red());
const G4Point3D& centre = extent.GetExtentCenter();
fpVisManager->Draw(box,visAtts,G4Translate3D(centre));
}
}
}
@@ -41,6 +41,7 @@
G4ViewParameters::G4ViewParameters ():
fDrawingStyle (wireframe),
fNumberOfCloudPoints(10000),
fAuxEdgeVisible (false),
fCulling (true),
fCullInvisible (true),
@@ -219,13 +220,25 @@ G4int G4ViewParameters::SetNoOfSides (G4int nSides) {
if (nSides < nSidesMin) {
nSides = nSidesMin;
G4cout << "G4ViewParameters::SetNoOfSides: attempt to set the"
"\nnumber of sides per circle < " << nSidesMin
<< "; forced to " << nSides << G4endl;
"\nnumber of sides per circle < " << nSidesMin
<< "; forced to " << nSides << G4endl;
}
fNoOfSides = nSides;
return fNoOfSides;
}
G4int G4ViewParameters::SetNumberOfCloudPoints(G4int nPoints) {
const G4int nPointsMin = 100;
if (nPoints < nPointsMin) {
nPoints = nPointsMin;
G4cout << "G4ViewParameters::SetNumberOfCloudPoints:"
"\nnumber of points per cloud set to minimum " << nPoints
<< G4endl;
}
fNumberOfCloudPoints = nPoints;
return fNumberOfCloudPoints;
}
void G4ViewParameters::SetViewAndLights
(const G4Vector3D& viewpointDirection) {
@@ -239,7 +252,7 @@ void G4ViewParameters::SetViewAndLights
firstTime = false;
G4cout <<
"WARNING: Viewpoint direction is very close to the up vector direction."
"\n Consider setting the up vector to obtain definable behaviour."
"\n Change the up vector or \"/vis/viewer/set/rotationStyle freeRotation\"."
<< G4endl;
}
}
@@ -393,12 +406,20 @@ G4String G4ViewParameters::DrawingStyleCommands() const
oss << "#\n# Drawing style commands";
oss << "\n/vis/viewer/set/style ";
if (fDrawingStyle == wireframe || fDrawingStyle == hlr) {
oss << "wireframe";
} else {
oss << "surface";
switch (fDrawingStyle) {
case wireframe:
case hlr:
oss << "wireframe";
break;
case hsr:
case hlhsr:
oss << "surface";
break;
case cloud:
oss << "cloud";
break;
}
oss << "\n/vis/viewer/set/hiddenEdge ";
if (fDrawingStyle == hlr || fDrawingStyle == hlhsr) {
oss << "true";
@@ -425,7 +446,10 @@ G4String G4ViewParameters::DrawingStyleCommands() const
oss << "\n/vis/viewer/set/globalMarkerScale "
<< fGlobalMarkerScale;
oss << "\n/vis/viewer/set/numberOfCloudPoints "
<< fNumberOfCloudPoints;
oss << std::endl;
return oss.str();
@@ -619,6 +643,18 @@ G4String G4ViewParameters::TouchableCommands() const
}
}
break;
case G4ModelingParameters::VASForceCloud:
if (vamVisAtts.IsForceDrawingStyle()) {
if (vamVisAtts.GetForcedDrawingStyle() == G4VisAttributes::cloud) {
oss << "\n/vis/touchable/set/forceCloud ";
if (vamVisAtts.IsForceDrawingStyle()) {
oss << "true";
} else {
oss << "false";
}
}
}
break;
case G4ModelingParameters::VASForceAuxEdgeVisible:
if (vamVisAtts.IsForceAuxEdgeVisible()) {
oss << "\n/vis/touchable/set/forceAuxEdgeVisible ";
@@ -630,10 +666,12 @@ G4String G4ViewParameters::TouchableCommands() const
}
break;
case G4ModelingParameters::VASForceLineSegmentsPerCircle:
if (vamVisAtts.GetForcedLineSegmentsPerCircle() > 0) {
oss << "\n/vis/touchable/set/lineSegmentsPerCircle "
<< vamVisAtts.GetForcedLineSegmentsPerCircle();
}
oss << "\n/vis/touchable/set/lineSegmentsPerCircle "
<< vamVisAtts.GetForcedLineSegmentsPerCircle();
break;
case G4ModelingParameters::VASForceNumberOfCloudPoints:
oss << "\n/vis/touchable/set/numberOfCloudPoints "
<< vamVisAtts.GetForcedNumberOfCloudPoints();
break;
}
}
@@ -707,6 +745,7 @@ void G4ViewParameters::PrintDifferences (const G4ViewParameters& v) const {
// No particular order from here on.
(fDrawingStyle != v.fDrawingStyle) ||
(fNumberOfCloudPoints != v.fNumberOfCloudPoints) ||
(fAuxEdgeVisible != v.fAuxEdgeVisible) ||
(fCulling != v.fCulling) ||
(fCullInvisible != v.fCullInvisible) ||
@@ -826,6 +865,8 @@ std::ostream& operator <<
os << "hsr - hidden surfaces removed"; break;
case G4ViewParameters::hlhsr:
os << "hlhsr - hidden line, hidden surface removed"; break;
case G4ViewParameters::cloud:
os << "cloud - draw volume as a cloud of dots"; break;
default: os << "unrecognised"; break;
}
return os;
@@ -834,18 +875,9 @@ std::ostream& operator <<
std::ostream& operator << (std::ostream& os, const G4ViewParameters& v) {
os << "View parameters and options:";
os << "\n Drawing style: ";
switch (v.fDrawingStyle) {
case G4ViewParameters::wireframe:
os << "edges, wireframe"; break;
case G4ViewParameters::hlr:
os << "edges, hidden line removal"; break;
case G4ViewParameters::hsr:
os << "surfaces, hidden surface removal"; break;
case G4ViewParameters::hlhsr:
os << "surfaces and edges, hidden line and surface removal"; break;
default: os << "unrecognised"; break;
}
os << "\n Drawing style: " << v.fDrawingStyle;
os << "\n Number of cloud points: " << v.fNumberOfCloudPoints;
os << "\n Auxiliary edges: ";
if (!v.fAuxEdgeVisible) os << "in";
@@ -1029,6 +1061,7 @@ G4bool G4ViewParameters::operator != (const G4ViewParameters& v) const {
// No particular order from here on.
(fDrawingStyle != v.fDrawingStyle) ||
(fNumberOfCloudPoints != v.fNumberOfCloudPoints) ||
(fAuxEdgeVisible != v.fAuxEdgeVisible) ||
(fCulling != v.fCulling) ||
(fCullInvisible != v.fCullInvisible) ||
@@ -212,17 +212,9 @@ G4VisCommandDrawLogicalVolume::G4VisCommandDrawLogicalVolume() {
const G4UIcommandTree* tree = G4UImanager::GetUIpointer()->GetTree();
const G4UIcommand* addLogVolCmd = tree->FindPath("/vis/scene/add/logicalVolume");
// Pick up guidance from /vis/scene/add/logicalVolume
G4int nGuideEntries = addLogVolCmd->GetGuidanceEntries();
for (G4int i = 0; i < nGuideEntries; ++i) {
const G4String& guidance = addLogVolCmd->GetGuidanceLine(i);
fpCommand->SetGuidance(guidance);
}
CopyGuidanceFrom(addLogVolCmd,fpCommand);
// Pick up parameters from /vis/scene/add/logicalVolume
G4int nParEntries = addLogVolCmd->GetParameterEntries();
for (G4int i = 0; i < nParEntries; ++i) {
G4UIparameter* parameter = new G4UIparameter(*(addLogVolCmd->GetParameter(i)));
fpCommand->SetParameter(parameter);
}
CopyParametersFrom(addLogVolCmd,fpCommand);
}
G4VisCommandDrawLogicalVolume::~G4VisCommandDrawLogicalVolume() {
@@ -245,7 +237,8 @@ void G4VisCommandDrawLogicalVolume::SetNewValue(G4UIcommand*, G4String newValue)
UImanager->ApplyCommand(G4String("/vis/scene/add/logicalVolume " + newValue));
UImanager->ApplyCommand("/vis/sceneHandler/attach");
G4ViewParameters::DrawingStyle keepDrawingStyle = currentViewParams.GetDrawingStyle();
if(keepDrawingStyle != G4ViewParameters::wireframe) UImanager->ApplyCommand("/vis/viewer/set/style wireframe");
if(keepDrawingStyle != G4ViewParameters::wireframe)
UImanager->ApplyCommand("/vis/viewer/set/style wireframe");
G4bool keepMarkerNotHidden = currentViewParams.IsMarkerNotHidden();
if (!keepMarkerNotHidden) UImanager->ApplyCommand("/vis/viewer/set/hiddenMarker false");
if (keepAutoRefresh) UImanager->ApplyCommand("/vis/viewer/set/autoRefresh true");
@@ -264,11 +257,12 @@ void G4VisCommandDrawLogicalVolume::SetNewValue(G4UIcommand*, G4String newValue)
style = "surface"; edge = "false"; break;
case G4ViewParameters::hlhsr:
style = "surface"; edge = "true"; break;
case G4ViewParameters::cloud:
style = "cloud"; edge = ""; break;
}
G4cout
<< "\n /vis/viewer/set/style " + style
<< "\n /vis/viewer/set/hiddenEdge " + edge
<< G4endl;
G4cout << "\n /vis/viewer/set/style " + style;
if (!edge.empty()) G4cout << "\n /vis/viewer/set/hiddenEdge " + edge;
G4cout << G4endl;
}
if (keepMarkerNotHidden != currentViewParams.IsMarkerNotHidden()) {
G4cout
@@ -297,17 +291,9 @@ G4VisCommandDrawVolume::G4VisCommandDrawVolume() {
const G4UIcommandTree* tree = G4UImanager::GetUIpointer()->GetTree();
const G4UIcommand* addVolCmd = tree->FindPath("/vis/scene/add/volume");
// Pick up guidance from /vis/scene/add/volume
G4int nGuideEntries = addVolCmd->GetGuidanceEntries();
for (G4int i = 0; i < nGuideEntries; ++i) {
const G4String& guidance = addVolCmd->GetGuidanceLine(i);
fpCommand->SetGuidance(guidance);
}
CopyGuidanceFrom(addVolCmd,fpCommand);
// Pick up parameters from /vis/scene/add/volume
G4int nParEntries = addVolCmd->GetParameterEntries();
for (G4int i = 0; i < nParEntries; ++i) {
G4UIparameter* parameter = new G4UIparameter(*(addVolCmd->GetParameter(i)));
fpCommand->SetParameter(parameter);
}
CopyParametersFrom(addVolCmd,fpCommand);
}
G4VisCommandDrawVolume::~G4VisCommandDrawVolume() {
@@ -356,7 +356,7 @@ G4VisCommandGeometrySetForceSolid::G4VisCommandGeometrySetForceSolid()
parameter->SetGuidance
("Depth of propagation (-1 means unlimited depth).");
fpCommand->SetParameter(parameter);
parameter = new G4UIparameter("forceSolid", 'b', omitable = true);
parameter = new G4UIparameter("force", 'b', omitable = true);
parameter->SetDefaultValue(true);
fpCommand->SetParameter(parameter);
}
@@ -377,12 +377,12 @@ void G4VisCommandGeometrySetForceSolid::SetNewValue
{
G4String name;
G4int requestedDepth;
G4String forceSolidString;
G4String forceString;
std::istringstream iss(newValue);
iss >> name >> requestedDepth >> forceSolidString;
G4bool forceSolid = G4UIcommand::ConvertToBool(forceSolidString);
iss >> name >> requestedDepth >> forceString;
G4bool force = G4UIcommand::ConvertToBool(forceString);
G4VisCommandGeometrySetForceSolidFunction setForceSolid(forceSolid);
G4VisCommandGeometrySetForceSolidFunction setForceSolid(force);
Set(name, setForceSolid, requestedDepth);
}
@@ -41,6 +41,7 @@
#include "G4UImanager.hh"
#include "G4UIcommand.hh"
#include "G4UIcmdWithAString.hh"
#include "G4UIcmdWithoutParameter.hh"
#include "G4ios.hh"
#include <sstream>
@@ -780,9 +781,9 @@ G4VisCommandSceneSelect::G4VisCommandSceneSelect () {
G4bool omitable;
fpCommand = new G4UIcmdWithAString ("/vis/scene/select", this);
fpCommand -> SetGuidance ("Selects a scene");
fpCommand -> SetGuidance
("Makes the scene current. \"/vis/scene/list\" to see"
"\n possible scene names.");
fpCommand -> SetGuidance
("Makes the scene current. \"/vis/scene/list\" to see"
"\n possible scene names.");
fpCommand -> SetParameterName ("scene-name", omitable = false);
}
@@ -807,16 +808,111 @@ void G4VisCommandSceneSelect::SetNewValue (G4UIcommand*, G4String newValue) {
if (iScene >= nScenes) {
if (verbosity >= G4VisManager::warnings) {
G4cout << "WARNING: Scene \"" << selectName
<< "\" not found - \"/vis/scene/list\" to see possibilities."
<< G4endl;
<< "\" not found - \"/vis/scene/list\" to see possibilities."
<< G4endl;
}
return;
}
if (verbosity >= G4VisManager::confirmations) {
G4cout << "Scene \"" << selectName
<< "\" selected." << G4endl;
<< "\" selected." << G4endl;
}
CheckSceneAndNotifyHandlers (sceneList [iScene]);
}
////////////// /vis/scene/showExtents ///////////////////////////////////////
G4VisCommandSceneShowExtents::G4VisCommandSceneShowExtents () {
fpCommand = new G4UIcmdWithoutParameter ("/vis/scene/showExtents", this);
fpCommand -> SetGuidance ("Prints and draws extents of models in a scene");
}
G4VisCommandSceneShowExtents::~G4VisCommandSceneShowExtents () {
delete fpCommand;
}
G4String G4VisCommandSceneShowExtents::GetCurrentValue (G4UIcommand*) {
return "";
}
void G4VisCommandSceneShowExtents::SetNewValue (G4UIcommand*, G4String) {
G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
G4VSceneHandler* pCurrentSceneHandler =
fpVisManager -> GetCurrentSceneHandler();
if (!pCurrentSceneHandler) {
if (verbosity >= G4VisManager::warnings) {
G4cout << "WARNING: No current scene handler."
<< G4endl;
}
return;
}
G4VViewer* pCurrentViewer = fpVisManager -> GetCurrentViewer();
if (!pCurrentViewer) {
if (verbosity >= G4VisManager::warnings) {
G4cout << "WARNING: No current viewer."
<< G4endl;
}
return;
}
G4Scene* pCurrentScene = fpVisManager -> GetCurrentScene();
if (!pCurrentScene) {
if (verbosity >= G4VisManager::warnings) {
G4cout << "WARNING: No current scene."
<< G4endl;
}
return;
}
G4cout << "\n Run-duration models:";
G4int nRunModels = pCurrentScene -> GetRunDurationModelList ().size ();
if (nRunModels == 0) {
G4cout << " none.";
}
for (G4int i = 0; i < nRunModels; i++) {
if (pCurrentScene -> GetRunDurationModelList()[i].fActive)
G4cout << "\n Active: ";
else G4cout << "\n Inactive: ";
G4VModel* pModel = pCurrentScene -> GetRunDurationModelList()[i].fpModel;
const G4VisExtent& transformedExtent = pModel -> GetTransformedExtent();
G4cout << pModel -> GetGlobalDescription ()
<< "\n" << transformedExtent;
DrawExtent(transformedExtent);
}
G4cout << "\n End-of-event models:";
G4int nEOEModels = pCurrentScene -> GetEndOfEventModelList ().size ();
if (nEOEModels == 0) {
G4cout << " none.";
}
for (G4int i = 0; i < nEOEModels; i++) {
if (pCurrentScene -> GetEndOfEventModelList()[i].fActive)
G4cout << "\n Active: ";
else G4cout << "\n Inactive: ";
G4VModel* pModel = pCurrentScene -> GetEndOfEventModelList()[i].fpModel;
const G4VisExtent& transformedExtent = pModel -> GetTransformedExtent();
G4cout << pModel -> GetGlobalDescription ()
<< "\n" << transformedExtent;
DrawExtent(transformedExtent);
}
G4cout << "\n End-of-run models:";
G4int nEORModels = pCurrentScene -> GetEndOfRunModelList ().size ();
if (nEORModels == 0) {
G4cout << " none.";
}
for (G4int i = 0; i < nEORModels; i++) {
if (pCurrentScene -> GetEndOfRunModelList()[i].fActive)
G4cout << "\n Active: ";
else G4cout << "\n Inactive: ";
G4VModel* pModel = pCurrentScene -> GetEndOfRunModelList()[i].fpModel;
const G4VisExtent& transformedExtent = pModel -> GetTransformedExtent();
G4cout << pModel -> GetGlobalDescription ()
<< "\n" << transformedExtent;
DrawExtent(transformedExtent);
}
G4cout << "Overall extent:\n";
DrawExtent(pCurrentScene->GetExtent());
G4cout << G4endl;
}
@@ -36,6 +36,7 @@
#include "G4HitsModel.hh"
#include "G4DigiModel.hh"
#include "G4GPSModel.hh"
#include "G4ElectricFieldModel.hh"
#include "G4MagneticFieldModel.hh"
#include "G4PSHitsModel.hh"
#include "G4TrajectoriesModel.hh"
@@ -53,6 +54,7 @@
#include "G4SubtractionSolid.hh"
#include "G4Polyhedron.hh"
#include "G4UImanager.hh"
#include "G4UIcommandTree.hh"
#include "G4UIcommand.hh"
#include "G4UIcmdWithAString.hh"
#include "G4UIcmdWithoutParameter.hh"
@@ -81,17 +83,6 @@
#include <sstream>
// Local function with some frequently used error printing...
static void G4VisCommandsSceneAddUnsuccessful
(G4VisManager::Verbosity verbosity) {
if (verbosity >= G4VisManager::warnings) {
G4cout <<
"WARNING: For some reason, possibly mentioned above, it has not been"
"\n possible to add to the scene."
<< G4endl;
}
}
////////////// /vis/scene/add/arrow ///////////////////////////////////////
G4VisCommandSceneAddArrow::G4VisCommandSceneAddArrow () {
@@ -536,6 +527,100 @@ void G4VisCommandSceneAddDigis::SetNewValue (G4UIcommand*, G4String) {
CheckSceneAndNotifyHandlers (pScene);
}
////////////// /vis/scene/add/electricField ///////////////////////////////////////
G4VisCommandSceneAddElectricField::G4VisCommandSceneAddElectricField () {
G4bool omitable;
fpCommand = new G4UIcommand ("/vis/scene/add/electricField", this);
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"
"\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"
"\nyou can do:"
"\n- reduce the number of data points per half scene (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"
"\n \"/vis/scene/activateModel Field false\" and re-issue"
"\n \"/vis/scene/add/...Field\" command again.");
fpCommand -> SetGuidance
("In the arrow representation, the length of the arrow is proportional"
"\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 blue->green->red.");
G4UIparameter* parameter;
parameter = new G4UIparameter ("nDataPointsPerHalfScene", 'i', omitable = true);
parameter -> SetDefaultValue (10);
fpCommand -> SetParameter (parameter);
parameter = new G4UIparameter ("representation", 's', omitable = true);
parameter -> SetParameterCandidates("fullArrow lightArrow");
parameter -> SetDefaultValue ("fullArrow");
fpCommand -> SetParameter (parameter);
}
G4VisCommandSceneAddElectricField::~G4VisCommandSceneAddElectricField () {
delete fpCommand;
}
G4String G4VisCommandSceneAddElectricField::GetCurrentValue (G4UIcommand*) {
return "";
}
void G4VisCommandSceneAddElectricField::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;
}
G4int nDataPointsPerHalfScene;
G4String representation;
std::istringstream iss(newValue);
iss >> nDataPointsPerHalfScene >> representation;
G4ElectricFieldModel::Representation
modelRepresentation = G4ElectricFieldModel::fullArrow;
if (representation == "lightArrow") {
modelRepresentation = G4ElectricFieldModel::lightArrow;
}
G4VModel* model;
model = new G4ElectricFieldModel
(nDataPointsPerHalfScene,modelRepresentation,
fCurrentArrow3DLineSegmentsPerCircle,
fCurrentExtentForField,
fCurrrentPVFindingsForField);
const G4String& currentSceneName = pScene -> GetName ();
G4bool successful = pScene -> AddRunDurationModel (model, warn);
if (successful) {
if (verbosity >= G4VisManager::confirmations) {
G4cout
<< "Electric field, if any, will be drawn in scene \""
<< currentSceneName
<< "\"\n with "
<< nDataPointsPerHalfScene
<< " data points per half scene and with representation \""
<< representation
<< '\"'
<< G4endl;
}
}
else G4VisCommandsSceneAddUnsuccessful(verbosity);
CheckSceneAndNotifyHandlers (pScene);
}
////////////// /vis/scene/add/eventID ///////////////////////////////////////
G4VisCommandSceneAddEventID::G4VisCommandSceneAddEventID () {
@@ -869,75 +954,75 @@ void G4VisCommandSceneAddFrame::Frame::operator()
sceneHandler.EndPrimitives2D();
}
////////////// /vis/scene/add/gps ///////////////////////////////////////
////////////// /vis/scene/add/gps ///////////////////////////////////////
G4VisCommandSceneAddGPS::G4VisCommandSceneAddGPS () {
G4bool omitable;
G4UIparameter* parameter;
fpCommand = new G4UIcommand ("/vis/scene/add/gps", this);
fpCommand -> SetGuidance
("A representation of the source(s) of the General Particle Source"
"\nwill be added to current scene and drawn, if applicable.");
fpCommand->SetGuidance(ConvertToColourGuidance());
fpCommand->SetGuidance("Default: red and transparent.");
parameter = new G4UIparameter("red_or_string", 's', omitable = true);
parameter -> SetDefaultValue ("1.");
fpCommand -> SetParameter (parameter);
parameter = new G4UIparameter("green", 'd', omitable = true);
parameter -> SetDefaultValue (0.);
fpCommand -> SetParameter (parameter);
parameter = new G4UIparameter ("blue", 'd', omitable = true);
parameter -> SetDefaultValue (0.);
fpCommand -> SetParameter (parameter);
parameter = new G4UIparameter ("opacity", 'd', omitable = true);
parameter -> SetDefaultValue (0.3);
fpCommand -> SetParameter (parameter);
}
G4VisCommandSceneAddGPS::G4VisCommandSceneAddGPS () {
G4bool omitable;
G4UIparameter* parameter;
fpCommand = new G4UIcommand ("/vis/scene/add/gps", this);
fpCommand -> SetGuidance
("A representation of the source(s) of the General Particle Source"
"\nwill be added to current scene and drawn, if applicable.");
fpCommand->SetGuidance(ConvertToColourGuidance());
fpCommand->SetGuidance("Default: red and transparent.");
parameter = new G4UIparameter("red_or_string", 's', omitable = true);
parameter -> SetDefaultValue ("1.");
fpCommand -> SetParameter (parameter);
parameter = new G4UIparameter("green", 'd', omitable = true);
parameter -> SetDefaultValue (0.);
fpCommand -> SetParameter (parameter);
parameter = new G4UIparameter ("blue", 'd', omitable = true);
parameter -> SetDefaultValue (0.);
fpCommand -> SetParameter (parameter);
parameter = new G4UIparameter ("opacity", 'd', omitable = true);
parameter -> SetDefaultValue (0.3);
fpCommand -> SetParameter (parameter);
}
G4VisCommandSceneAddGPS::~G4VisCommandSceneAddGPS () {
delete fpCommand;
}
G4VisCommandSceneAddGPS::~G4VisCommandSceneAddGPS () {
delete fpCommand;
}
G4String G4VisCommandSceneAddGPS::GetCurrentValue (G4UIcommand*) {
return "";
}
G4String G4VisCommandSceneAddGPS::GetCurrentValue (G4UIcommand*) {
return "";
}
void G4VisCommandSceneAddGPS::SetNewValue (G4UIcommand*, G4String newValue) {
void G4VisCommandSceneAddGPS::SetNewValue (G4UIcommand*, G4String newValue) {
G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
G4bool warn(verbosity >= G4VisManager::warnings);
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;
G4Scene* pScene = fpVisManager->GetCurrentScene();
if (!pScene) {
if (verbosity >= G4VisManager::errors) {
G4cerr << "ERROR: No current scene. Please create one." << G4endl;
}
G4String redOrString;
G4double green, blue, opacity;
std::istringstream iss(newValue);
iss >> redOrString >> green >> blue >> opacity;
G4Colour colour(1.,0.,0.,0.3); // Default red and transparent.
ConvertToColour(colour, redOrString, green, blue, opacity);
G4VModel* model = new G4GPSModel(colour);
const G4String& currentSceneName = pScene -> GetName ();
G4bool successful = pScene -> AddRunDurationModel (model, warn);
if (successful) {
if (verbosity >= G4VisManager::confirmations) {
G4cout <<
"A representation of the source(s) of the General Particle Source will be drawn"
"\n in colour " << colour << " for scene \""
<< currentSceneName << "\" if applicable."
<< G4endl;
}
}
else G4VisCommandsSceneAddUnsuccessful(verbosity);
CheckSceneAndNotifyHandlers (pScene);
return;
}
G4String redOrString;
G4double green, blue, opacity;
std::istringstream iss(newValue);
iss >> redOrString >> green >> blue >> opacity;
G4Colour colour(1.,0.,0.,0.3); // Default red and transparent.
ConvertToColour(colour, redOrString, green, blue, opacity);
G4VModel* model = new G4GPSModel(colour);
const G4String& currentSceneName = pScene -> GetName ();
G4bool successful = pScene -> AddRunDurationModel (model, warn);
if (successful) {
if (verbosity >= G4VisManager::confirmations) {
G4cout <<
"A representation of the source(s) of the General Particle Source will be drawn"
"\n in colour " << colour << " for scene \""
<< currentSceneName << "\" if applicable."
<< G4endl;
}
}
else G4VisCommandsSceneAddUnsuccessful(verbosity);
CheckSceneAndNotifyHandlers (pScene);
}
////////////// /vis/scene/add/hits ///////////////////////////////////////
@@ -1828,31 +1913,15 @@ void G4VisCommandSceneAddLogo2D::Logo2D::operator()
////////////// /vis/scene/add/magneticField ///////////////////////////////////////
G4VisCommandSceneAddMagneticField::G4VisCommandSceneAddMagneticField () {
G4bool omitable;
fpCommand = new G4UIcommand ("/vis/scene/add/magneticField", this);
fpCommand -> SetGuidance
("Adds magnetic field representation to current scene.");
fpCommand -> SetGuidance
("The first parameter is no. of data points per half scene. So, possibly, at"
"\nmaximum, the number of data points sampled is (2*n+1)^3, which can grow"
"\nlarge--be warned!"
"\nYou might find that your scene is cluttered by thousands of arrows for"
"\nthe default number of data points, so try reducing to 2 or 3, e.g:"
"\n /vis/scene/add/magneticField 3"
"\nor, if only a small part of the scene has a field:"
"\n /vis/scene/add/magneticField 50 or more");
fpCommand -> SetGuidance
("In the arrow representation, the length of the arrow is proportional"
"\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 blue->green->red.");
G4UIparameter* parameter;
parameter = new G4UIparameter ("nDataPointsPerHalfScene", 'i', omitable = true);
parameter -> SetDefaultValue (10);
fpCommand -> SetParameter (parameter);
parameter = new G4UIparameter ("representation", 's', omitable = true);
parameter -> SetParameterCandidates("fullArrow lightArrow");
parameter -> SetDefaultValue ("fullArrow");
fpCommand -> SetParameter (parameter);
const G4UIcommandTree* tree = G4UImanager::GetUIpointer()->GetTree();
const G4UIcommand* addElecFieldCmd = tree->FindPath("/vis/scene/add/electricField");
// Pick up additional guidance from /vis/scene/add/electricField
CopyGuidanceFrom(addElecFieldCmd,fpCommand,1);
// Pick up parameters from /vis/scene/add/electricField
CopyParametersFrom(addElecFieldCmd,fpCommand);
}
G4VisCommandSceneAddMagneticField::~G4VisCommandSceneAddMagneticField () {
@@ -1872,7 +1941,7 @@ void G4VisCommandSceneAddMagneticField::SetNewValue
G4Scene* pScene = fpVisManager->GetCurrentScene();
if (!pScene) {
if (verbosity >= G4VisManager::errors) {
G4cerr << "ERROR: No current scene. Please create one." << G4endl;
G4cerr << "ERROR: No current scene. Please create one." << G4endl;
}
return;
}
@@ -1881,23 +1950,27 @@ void G4VisCommandSceneAddMagneticField::SetNewValue
G4String representation;
std::istringstream iss(newValue);
iss >> nDataPointsPerHalfScene >> representation;
G4MagneticFieldModel::Representation
modelRepresentation = G4MagneticFieldModel::fullArrow;
G4ElectricFieldModel::Representation
modelRepresentation = G4ElectricFieldModel::fullArrow;
if (representation == "lightArrow") {
modelRepresentation = G4MagneticFieldModel::lightArrow;
modelRepresentation = G4ElectricFieldModel::lightArrow;
}
G4VModel* model =
new G4MagneticFieldModel(nDataPointsPerHalfScene,modelRepresentation,
fCurrentArrow3DLineSegmentsPerCircle);
G4VModel* model;
model = new G4MagneticFieldModel
(nDataPointsPerHalfScene,modelRepresentation,
fCurrentArrow3DLineSegmentsPerCircle,
fCurrentExtentForField,
fCurrrentPVFindingsForField);
const G4String& currentSceneName = pScene -> GetName ();
G4bool successful = pScene -> AddRunDurationModel (model, warn);
if (successful) {
if (verbosity >= G4VisManager::confirmations) {
G4cout << "Magnetic field, if any, will be drawn in scene \""
G4cout
<< "Magnetic field, if any, will be drawn in scene \""
<< currentSceneName
<< "\"\n with "
<< nDataPointsPerHalfScene
<< " data points per half scene and with representation \""
<< " data points per half extent and with representation \""
<< representation
<< '\"'
<< G4endl;
@@ -2320,7 +2393,6 @@ void G4VisCommandSceneAddScale::SetNewValue (G4UIcommand*, G4String newValue) {
transform = G4Translate3D(sxmid,symid,szmid) * transform;
///////// G4VisExtent scaleExtent(sxmin, sxmax, symin, symax, szmin, szmax);
model->SetTransformation(transform);
// Note: it is the responsibility of the model to act upon this, but
// the extent is in local coordinates...
@@ -2830,32 +2902,32 @@ G4VisCommandSceneAddVolume::G4VisCommandSceneAddVolume () {
("Adds a physical volume to current scene, with optional clipping volume.");
fpCommand -> SetGuidance
("If physical-volume-name is \"world\" (the default), the top of the"
"\nmain geometry tree (material world) is added. If \"worlds\", the"
"\ntop of all worlds - material world and parallel worlds, if any - are"
"\nadded. Otherwise a search of all worlds is made.");
"\nmain geometry tree (material world) is added. If \"worlds\", the"
"\ntops of all worlds - material world and parallel worlds, if any - are"
"\nadded. Otherwise a search of all worlds is made.");
fpCommand -> SetGuidance
("In the last case (a search of all worlds) all physical volume names are"
"\nmatched against the first argument of this command. If this is of the"
"\nform \"/regexp/\", where regexp is a regular expression (see C++ regex),"
"\nthe physical volume name is matched against regexp by the usual rules"
"\nof regular expression matching. Otherwise an exact match is required."
"\nFor example, \"/Shap/\" matches \"Shape1\" and \"Shape2\".");
("In the last case the names of all volumes in all worlds are matched"
"\nagainst physical-volume-name. If this is of the form \"/regexp/\","
"\nwhere regexp is a regular expression (see C++ regex), the match uses"
"\nthe usual rules of regular expression matching. Otherwise an exact"
"\nmatch is required."
"\nFor example, \"/Shap/\" adds \"Shape1\" and \"Shape2\".");
fpCommand -> SetGuidance
("It may help to see a textual representation of the geometry hierarchy of"
"\nthe worlds. Try \"/vis/drawTree [worlds]\" or one of the driver/browser"
"\ncombinations that have the required functionality, e.g., HepRep.");
"\ncombinations that have the required functionality, e.g., HepRepFile.");
fpCommand -> SetGuidance
("If clip-volume-type is specified, the subsequent parameters are used to"
"\nto define a clipping volume. For example,"
"\nto define a clipping volume. For example,"
"\n\"/vis/scene/add/volume ! ! ! -box km 0 1 0 1 0 1\" will draw the world"
"\nwith the positive octant cut away. (If the Boolean Processor issues"
"\nwith the positive octant cut away. (If the Boolean Processor issues"
"\nwarnings try replacing 0 by 0.000000001 or something.)");
fpCommand -> SetGuidance
("If clip-volume-type is prepended with '-', the clip-volume is subtracted"
"\n(cutaway). (This is the default if there is no prepended character.)"
"\nIf '*' is prepended, the intersection of the physical-volume and the"
"\nclip-volume is made. (You can make a section/DCUT with a thin box, for"
"\nexample).");
"\nclip-volume is made. (You can make a section through the detector with"
"\na thin box, for example).");
fpCommand -> SetGuidance
("For \"box\", the parameters are xmin,xmax,ymin,ymax,zmin,zmax."
"\nOnly \"box\" is programmed at present.");
@@ -2864,8 +2936,7 @@ G4VisCommandSceneAddVolume::G4VisCommandSceneAddVolume () {
parameter -> SetDefaultValue ("world");
fpCommand -> SetParameter (parameter);
parameter = new G4UIparameter ("copy-no", 'i', omitable = true);
parameter -> SetGuidance
("If negative, matches any copy no. First name match is taken.");
parameter -> SetGuidance ("If negative, matches any copy no.");
parameter -> SetDefaultValue (-1);
fpCommand -> SetParameter (parameter);
parameter = new G4UIparameter ("depth-of-descent", 'i', omitable = true);
@@ -3037,7 +3108,7 @@ void G4VisCommandSceneAddVolume::SetNewValue (G4UIcommand*,
}
for (const auto& findings: findingsVector) {
// Set copy number from search findings to cope with replicas.
// Set copy number from search findings for replicas and parameterisations.
findings.fpFoundPV->SetCopyNo(findings.fFoundPVCopyNo);
// Create a physical volume model...
G4PhysicalVolumeModel* foundPVModel = new G4PhysicalVolumeModel
@@ -3051,7 +3122,8 @@ void G4VisCommandSceneAddVolume::SetNewValue (G4UIcommand*,
foundPVModel->SetClippingSolid(clippingSolid);
foundPVModel->SetClippingMode(clippingMode);
}
// ...and add it to the scene.
if (!foundPVModel->Validate(warn)) return; // Calculates extent
// ...so add it to the scene.
G4bool successful = pScene->AddRunDurationModel(foundPVModel,warn);
if (successful) {
if (verbosity >= G4VisManager::confirmations) {
@@ -34,8 +34,10 @@
#include "G4UIcmdWithAnInteger.hh"
#include "G4UIcmdWithADouble.hh"
#include "G4UIcmdWithAString.hh"
#include "G4UIcmdWithABool.hh"
#include "G4TouchablePropertiesScene.hh"
#include "G4TransportationManager.hh"
#include "G4BoundingExtentScene.hh"
#include <sstream>
////////////// /vis/set/arrow3DLineSegmentsPerCircle ////////////////////////////////////
@@ -84,15 +86,15 @@ G4VisCommandSetColour::G4VisCommandSetColour ()
G4bool omitable;
fpCommand = new G4UIcommand("/vis/set/colour", this);
fpCommand->SetGuidance
("Defines colour and opacity for future \"/vis/scene/add/\" commands.");
("Defines colour and opacity for future \"/vis/scene/add/\" commands.");
fpCommand->SetGuidance
("(Except \"/vis/scene/add/text\" commands - see \"/vis/set/textColour\".)");
("(Except \"/vis/scene/add/text\" commands - see \"/vis/set/textColour\".)");
fpCommand->SetGuidance(ConvertToColourGuidance());
fpCommand->SetGuidance("Default: white and opaque.");
G4UIparameter* parameter;
parameter = new G4UIparameter ("red", 's', omitable = true);
parameter->SetGuidance
("Red component or a string, e.g., \"cyan\" (green and blue parameters are ignored).");
("Red component or a string, e.g., \"cyan\" (green and blue parameters are ignored).");
parameter->SetDefaultValue ("1.");
fpCommand->SetParameter (parameter);
parameter = new G4UIparameter ("green", 'd', omitable = true);
@@ -130,10 +132,80 @@ void G4VisCommandSetColour::SetNewValue (G4UIcommand*, G4String newValue)
if (verbosity >= G4VisManager::confirmations) {
G4cout <<
"Colour for future \"/vis/scene/add/\" commands has been set to "
<< fCurrentColour <<
".\n(Except \"/vis/scene/add/text\" commands - use \"/vis/set/textColour\".)"
<< G4endl;
"Colour for future \"/vis/scene/add/\" commands has been set to "
<< fCurrentColour <<
".\n(Except \"/vis/scene/add/text\" commands - use \"/vis/set/textColour\".)"
<< G4endl;
}
}
////////////// /vis/set/extentForField ////////////////////////////////////
G4VisCommandSetExtentForField::G4VisCommandSetExtentForField ()
{
G4bool omitable;
fpCommand = new G4UIcommand("/vis/set/extentForField", this);
fpCommand->SetGuidance
("Sets an extent for future \"/vis/scene/add/*Field\" commands.");
fpCommand->SetGuidance
("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.);
fpCommand->SetParameter (parameter);
parameter = new G4UIparameter ("xmax", 'd', omitable = true);
parameter->SetDefaultValue (0.);
fpCommand->SetParameter (parameter);
parameter = new G4UIparameter ("ymin", 'd', omitable = true);
parameter->SetDefaultValue (0.);
fpCommand->SetParameter (parameter);
parameter = new G4UIparameter ("ymax", 'd', omitable = true);
parameter->SetDefaultValue (0.);
fpCommand->SetParameter (parameter);
parameter = new G4UIparameter ("zmin", 'd', omitable = true);
parameter->SetDefaultValue (0.);
fpCommand->SetParameter (parameter);
parameter = new G4UIparameter ("zmax", 'd', omitable = true);
parameter->SetDefaultValue (0.);
fpCommand->SetParameter (parameter);
parameter = new G4UIparameter ("unit", 's', omitable = true);
parameter->SetDefaultValue ("m");
fpCommand->SetParameter (parameter);
}
G4VisCommandSetExtentForField::~G4VisCommandSetExtentForField ()
{
delete fpCommand;
}
G4String G4VisCommandSetExtentForField::GetCurrentValue (G4UIcommand*)
{
return G4String();
}
void G4VisCommandSetExtentForField::SetNewValue (G4UIcommand*, G4String newValue)
{
G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
G4double xmin, xmax, ymin, ymax, zmin, zmax;
G4String unitString;
std::istringstream iss(newValue);
iss >> xmin >> xmax >> ymin >> ymax >> zmin >> zmax >> unitString;
G4double unit = G4UIcommand::ValueOf(unitString);
xmin *= unit; xmax *= unit;
ymin *= unit; ymax *= unit;
zmin *= unit; zmax *= unit;
fCurrentExtentForField = G4VisExtent(xmin,xmax,ymin,ymax,zmin,zmax);
fCurrrentPVFindingsForField.clear();
if (verbosity >= G4VisManager::confirmations) {
G4cout <<
"Extent for future \"/vis/scene/add/*Field\" commands has been set to "
<< fCurrentExtentForField
<< "\nVolume for field has been cleared."
<< G4endl;
}
}
@@ -289,7 +361,7 @@ G4VisCommandSetTextSize::G4VisCommandSetTextSize ()
("Defines text size (pixels) for future \"/vis/scene/add/\" commands.");
fpCommand->SetParameterName ("textSize", omitable = true);
fpCommand->SetDefaultValue (12.); // pixels
fpCommand->SetRange("textSize >= 1.");
fpCommand->SetRange("textSize >= 8.");
}
G4VisCommandSetTextSize::~G4VisCommandSetTextSize ()
@@ -331,7 +403,7 @@ G4VisCommandSetTouchable::G4VisCommandSetTouchable ()
"\n /vis/set/touchable World 0 Envelope 0 Shape1 0"
"\n(To get list of touchables, use \"/vis/drawTree\")"
"\n(To save, use \"/vis/viewer/save\")");
parameter = new G4UIparameter ("list", 's', omitable = false);
parameter = new G4UIparameter ("list", 's', omitable = true);
parameter->SetGuidance
("List of physical volume names and copy number pairs");
fpCommand->SetParameter (parameter);
@@ -350,9 +422,19 @@ G4String G4VisCommandSetTouchable::GetCurrentValue (G4UIcommand*)
void G4VisCommandSetTouchable::SetNewValue (G4UIcommand*, G4String newValue)
{
G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
if (newValue.isNull()) {
fCurrentTouchableProperties = G4PhysicalVolumeModel::TouchableProperties();
if (verbosity >= G4VisManager::confirmations) {
G4cout <<
"Current touchable reset to: " << fCurrentTouchableProperties.fTouchablePath
<< G4endl;
}
return;
}
G4ModelingParameters::PVNameCopyNoPath currentTouchablePath;
// Algorithm from Josuttis p.476.
G4String::size_type iBegin, iEnd;
iBegin = newValue.find_first_not_of(' ');
@@ -431,3 +513,105 @@ void G4VisCommandSetTouchable::SetNewValue (G4UIcommand*, G4String newValue)
}
}
}
////////////// /vis/set/volumeForField ////////////////////////////////////
G4VisCommandSetVolumeForField::G4VisCommandSetVolumeForField ()
{
G4bool omitable;
G4UIparameter* parameter;
fpCommand = new G4UIcommand("/vis/set/volumeForField", this);
fpCommand->SetGuidance
("Sets a volume and optional copy number \"/vis/scene/add/*Field\" commands.");
parameter = new G4UIparameter ("physical-volume-name", 's', omitable = true);
parameter -> SetDefaultValue ("none");
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);
parameter = new G4UIparameter ("draw", 'b', omitable = true);
parameter -> SetGuidance ("If true, draw extent of found volumes.");
parameter -> SetDefaultValue (false);
fpCommand -> SetParameter (parameter);
}
G4VisCommandSetVolumeForField::~G4VisCommandSetVolumeForField ()
{
delete fpCommand;
}
G4String G4VisCommandSetVolumeForField::GetCurrentValue (G4UIcommand*)
{
return G4String();
}
void G4VisCommandSetVolumeForField::SetNewValue (G4UIcommand*, G4String newValue)
{
G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
G4String name, drawString;
G4int copyNo;
std::istringstream is (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();
std::vector<G4VPhysicalVolume*>::iterator iterWorld =
transportationManager->GetWorldsIterator();
fCurrrentPVFindingsForField.clear();
G4BoundingExtentScene extentScene;
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);
searchModel.DescribeYourselfTo (searchScene); // Initiate search.
for (const auto& findings: searchScene.GetFindings()) {
fCurrrentPVFindingsForField.push_back(findings);
G4VisExtent extent = findings.fpFoundPV->GetLogicalVolume()->GetSolid()->GetExtent();
extent.Transform(findings.fFoundObjectTransformation);
extentScene.AccrueBoundingExtent(extent);
}
}
if (fCurrrentPVFindingsForField.empty()) {
if (verbosity >= G4VisManager::errors) {
G4cerr << "ERROR: Volume \"" << name << "\"";
if (copyNo >= 0) {
G4cerr << ", copy no. " << copyNo << ",";
}
G4cerr << " not found." << G4endl;
}
return;
}
fCurrentExtentForField = extentScene.GetExtent();
if (draw) DrawExtent(fCurrentExtentForField);
if (verbosity >= G4VisManager::confirmations) {
for (const auto& findings: fCurrrentPVFindingsForField) {
G4cout
<< "\"" << findings.fpFoundPV->GetName()
<< "\", copy no. " << findings.fFoundPVCopyNo
<< ", found\nin searched volume \""
<< findings.fpSearchPV->GetName()
<< "\" at depth " << findings.fFoundDepth
<< ",\nbase path: \"" << findings.fFoundBasePVPath
<< "\",\nand has been set as volume for field."
<< G4endl;
}
}
}
@@ -29,8 +29,10 @@
#include "G4VisCommandsTouchable.hh"
#include "G4UImanager.hh"
#include "G4UIcmdWithAString.hh"
#include "G4UIcmdWithoutParameter.hh"
#include "G4UIcmdWithABool.hh"
#include "G4TransportationManager.hh"
#include "G4TouchableUtils.hh"
#include "G4PhysicalVolumesSearchScene.hh"
@@ -40,17 +42,44 @@
G4VisCommandsTouchable::G4VisCommandsTouchable()
{
fpCommandDump = new G4UIcmdWithoutParameter("/vis/touchable/dump",this);
fpCommandDump->SetGuidance("Dump touchable attributes.");
fpCommandDump->SetGuidance
G4bool omitable;
fpCommandCentreAndZoomInOn = new G4UIcmdWithoutParameter("/vis/touchable/centreAndZoomInOn",this);
fpCommandCentreAndZoomInOn->SetGuidance ("Centre and zoom in on the current touchable.");
fpCommandCentreAndZoomInOn->SetGuidance
("Use \"/vis/set/touchable\" to set current touchable.");
fpCommandDump->SetGuidance
fpCommandCentreAndZoomInOn->SetGuidance
("You may also need \"/vis/touchable/findPath\".");
fpCommandCentreAndZoomInOn->SetGuidance
("Use \"/vis/touchable/set\" to set attributes.");
fpCommandFindPath = new G4UIcmdWithAString("/vis/touchable/findPath",this);
fpCommandCentreOn = new G4UIcmdWithoutParameter("/vis/touchable/centreOn",this);
fpCommandCentreOn->SetGuidance ("Centre the view on the current touchable.");
// Pick up additional guidance from /vis/viewer/centreAndZoomInOn
CopyGuidanceFrom(fpCommandCentreAndZoomInOn,fpCommandCentreOn,1);
fpCommandDraw = new G4UIcmdWithoutParameter("/vis/touchable/draw",this);
fpCommandDraw->SetGuidance("Draw touchable.");
// Pick up additional guidance from /vis/viewer/centreAndZoomInOn
CopyGuidanceFrom(fpCommandCentreAndZoomInOn,fpCommandDraw,1);
fpCommandDump = new G4UIcmdWithoutParameter("/vis/touchable/dump",this);
fpCommandDump->SetGuidance("Dump touchable attributes.");
// Pick up additional guidance from /vis/viewer/centreAndZoomInOn
CopyGuidanceFrom(fpCommandCentreAndZoomInOn,fpCommandDump,1);
fpCommandExtentForField = new G4UIcmdWithABool("/vis/touchable/extentForField",this);
fpCommandExtentForField->SetGuidance("Set extent for field.");
fpCommandExtentForField->SetGuidance("If parameter == true, also draw.");
// Pick up additional guidance from /vis/viewer/centreAndZoomInOn
CopyGuidanceFrom(fpCommandCentreAndZoomInOn,fpCommandExtentForField,1);
fpCommandExtentForField->SetParameterName("draw", omitable = true);
fpCommandExtentForField->SetDefaultValue(false);
fpCommandFindPath = new G4UIcommand("/vis/touchable/findPath",this);
fpCommandFindPath->SetGuidance
("Prints the path to touchable and its logical volume mother"
"\ngiven a physical volume name.");
"\ngiven a physical volume name and copy no.");
fpCommandFindPath -> SetGuidance
("A search of all worlds is made and all physical volume names are"
"\nmatched against the argument of this command. If this is of the"
@@ -62,10 +91,41 @@ G4VisCommandsTouchable::G4VisCommandsTouchable()
("It may help to see a textual representation of the geometry hierarchy of"
"\nthe worlds. Try \"/vis/drawTree [worlds]\" or one of the driver/browser"
"\ncombinations that have the required functionality, e.g., HepRep.");
G4UIparameter* parameter;
parameter = new G4UIparameter ("physical-volume-name", 's', omitable = true);
parameter -> SetDefaultValue ("world");
fpCommandFindPath -> SetParameter (parameter);
parameter = new G4UIparameter ("copy-no", 'i', omitable = true);
parameter -> SetGuidance ("If negative, matches any copy no.");
parameter -> SetDefaultValue (-1);
fpCommandFindPath -> SetParameter (parameter);
fpCommandShowExtent = new G4UIcmdWithABool("/vis/touchable/showExtent",this);
fpCommandShowExtent->SetGuidance("Print extent of touchable.");
fpCommandShowExtent->SetGuidance("If parameter == true, also draw.");
// Pick up additional guidance from /vis/viewer/centreAndZoomInOn
CopyGuidanceFrom(fpCommandCentreAndZoomInOn,fpCommandShowExtent,1);
fpCommandShowExtent->SetParameterName("draw", omitable = true);
fpCommandShowExtent->SetDefaultValue(false);
fpCommandVolumeForField = new G4UIcmdWithABool("/vis/touchable/volumeForField",this);
fpCommandVolumeForField->SetGuidance("Set volume for field.");
fpCommandVolumeForField->SetGuidance("If parameter == true, also draw.");
// Pick up additional guidance from /vis/viewer/centreAndZoomInOn
CopyGuidanceFrom(fpCommandCentreAndZoomInOn,fpCommandVolumeForField,1);
fpCommandVolumeForField->SetParameterName("draw", omitable = true);
fpCommandVolumeForField->SetDefaultValue(false);
}
G4VisCommandsTouchable::~G4VisCommandsTouchable() {
delete fpCommandVolumeForField;
delete fpCommandShowExtent;
delete fpCommandFindPath;
delete fpCommandExtentForField;
delete fpCommandDump;
delete fpCommandDraw;
delete fpCommandCentreAndZoomInOn;
delete fpCommandCentreOn;
}
G4String G4VisCommandsTouchable::GetCurrentValue(G4UIcommand*) {
@@ -76,6 +136,9 @@ void G4VisCommandsTouchable::SetNewValue
(G4UIcommand* command, G4String newValue)
{
G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
G4bool warn = verbosity >= G4VisManager::warnings;
G4UImanager* UImanager = G4UImanager::GetUIpointer();
G4TransportationManager* transportationManager =
G4TransportationManager::GetTransportationManager ();
@@ -94,26 +157,144 @@ void G4VisCommandsTouchable::SetNewValue
return;
}
if (command == fpCommandDump) {
G4VViewer* currentViewer = fpVisManager -> GetCurrentViewer ();
if (!currentViewer) {
if (verbosity >= G4VisManager::errors) {
G4cerr <<
"ERROR: No current viewer - \"/vis/viewer/list\" to see possibilities."
<< G4endl;
}
return;
}
G4Scene* currentScene = fpVisManager->GetCurrentScene();
if (!currentScene) {
if (verbosity >= G4VisManager::errors) {
G4cerr <<
"ERROR: No current scene - \"/vis/scene/list\" to see possibilities."
<< G4endl;
}
return;
}
if (command == fpCommandCentreOn || command == fpCommandCentreAndZoomInOn) {
G4PhysicalVolumeModel::TouchableProperties properties =
G4TouchableUtils::FindTouchableProperties(fCurrentTouchableProperties.fTouchablePath);
if (properties.fpTouchablePV) {
G4PhysicalVolumeModel pvModel
// To handle parameterisations, set 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 = pvModel.GetAttDefs();
std::vector<G4AttValue>* attValues = pvModel.CreateCurrentAttValues();
// Use a temporary scene in order to find vis extent
G4Scene tempScene("Centre Scene");
G4bool successful = tempScene.AddRunDurationModel(&tempPVModel,warn);
if (successful) {
if (verbosity >= G4VisManager::confirmations) {
G4cout
<< "Touchable " << fCurrentTouchableProperties.fTouchablePath
<< ",\n has been added to temporary scene \"" << tempScene.GetName() << "\"."
<< G4endl;
}
}
const G4VisExtent& newExtent = tempScene.GetExtent();
const G4ThreeVector& newTargetPoint = newExtent.GetExtentCentre();
G4ViewParameters saveVP = currentViewer->GetViewParameters();
G4ViewParameters newVP = saveVP;
if (command == fpCommandCentreAndZoomInOn) {
// Calculate the new zoom factor
const G4double zoomFactor
= currentScene->GetExtent().GetExtentRadius()/newExtent.GetExtentRadius();
newVP.SetZoomFactor(zoomFactor);
}
// Change the target point
const G4Point3D& standardTargetPoint = currentScene->GetStandardTargetPoint();
newVP.SetCurrentTargetPoint(newTargetPoint - standardTargetPoint);
// Interpolate
InterpolateToNewView(currentViewer, saveVP, newVP);
if (verbosity >= G4VisManager::confirmations) {
G4cout
<< "Viewer \"" << currentViewer->GetName()
<< "\" centred ";
if (fpCommandCentreAndZoomInOn) {
G4cout << "and zoomed in";
}
G4cout << " on touchable\n" << fCurrentTouchableProperties.fTouchablePath
<< G4endl;
}
SetViewParameters(currentViewer, newVP);
} else {
G4cout << "Touchable not found." << G4endl;
}
return;
} else if (command == fpCommandDraw) {
G4PhysicalVolumeModel::TouchableProperties properties =
G4TouchableUtils::FindTouchableProperties(fCurrentTouchableProperties.fTouchablePath);
if (properties.fpTouchablePV) {
// To handle paramaterisations we have to set the copy number
properties.fpTouchablePV->SetCopyNo(properties.fCopyNo);
G4PhysicalVolumeModel* pvModel = new G4PhysicalVolumeModel
(properties.fpTouchablePV,
G4PhysicalVolumeModel::UNLIMITED,
properties.fTouchableGlobalTransform,
nullptr, // Modelling parameters (not used)
true, // use full extent (prevents calculating own extent, which crashes)
properties.fTouchableBaseFullPVPath);
G4int keepVerbose = UImanager->GetVerboseLevel();
G4int newVerbose(0);
if (keepVerbose >= 2 || verbosity >= G4VisManager::confirmations)
newVerbose = 2;
UImanager->SetVerboseLevel(newVerbose);
UImanager->ApplyCommand("/vis/scene/create");
currentScene = fpVisManager->GetCurrentScene(); // New current scene
G4bool successful = currentScene->AddRunDurationModel(pvModel,warn);
UImanager->ApplyCommand("/vis/sceneHandler/attach");
UImanager->SetVerboseLevel(keepVerbose);
if (successful) {
if (verbosity >= G4VisManager::confirmations) {
G4cout << "\"" << properties.fpTouchablePV->GetName()
<< "\", copy no. " << properties.fCopyNo << " drawn"
<< G4endl;
}
} else {
G4VisCommandsSceneAddUnsuccessful(verbosity);
}
} else {
G4cout << "Touchable not found." << G4endl;
}
return;
} else if (command == fpCommandDump) {
G4PhysicalVolumeModel::TouchableProperties properties =
G4TouchableUtils::FindTouchableProperties(fCurrentTouchableProperties.fTouchablePath);
if (properties.fpTouchablePV) {
// To handle paramaterisations 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;
G4Polyhedron* polyhedron =
properties.fpTouchablePV->GetLogicalVolume()->GetSolid()->GetPolyhedron();
G4cout << "\nLocal polyhedron coordinates:\n" << *polyhedron;
G4Transform3D* transform = pvModel.GetCurrentTransform();
G4Transform3D* transform = tempPVModel.GetCurrentTransform();
polyhedron->Transform(*transform);
G4cout << "\nGlobal polyhedron coordinates:\n" << *polyhedron;
} else {
@@ -121,8 +302,35 @@ void G4VisCommandsTouchable::SetNewValue
}
return;
} else if (command == fpCommandExtentForField) {
G4PhysicalVolumeModel::TouchableProperties properties =
G4TouchableUtils::FindTouchableProperties(fCurrentTouchableProperties.fTouchablePath);
if (properties.fpTouchablePV) {
G4VisExtent extent
= properties.fpTouchablePV->GetLogicalVolume()->GetSolid()->GetExtent();
extent.Transform(properties.fTouchableGlobalTransform);
fCurrentExtentForField = extent;
fCurrrentPVFindingsForField.clear();
if (verbosity >= G4VisManager::confirmations) {
G4cout << "Extent for field set to " << extent
<< "\nVolume for field has been cleared."
<< G4endl;
}
if (fpCommandExtentForField->GetNewBoolValue(newValue)) {
DrawExtent(extent);
}
} else {
G4cout << "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();
@@ -130,7 +338,7 @@ void G4VisCommandsTouchable::SetNewValue
G4PhysicalVolumeModel searchModel (*iterWorld); // Unlimited depth.
G4ModelingParameters mp; // Default - no culling.
searchModel.SetModelingParameters (&mp);
G4PhysicalVolumesSearchScene searchScene (&searchModel, newValue);
G4PhysicalVolumesSearchScene searchScene (&searchModel, pvName, copyNo);
searchModel.DescribeYourselfTo (searchScene); // Initiate search.
for (const auto& findings: searchScene.GetFindings()) {
findingsVector.push_back(findings);
@@ -152,9 +360,53 @@ void G4VisCommandsTouchable::SetNewValue
<< "\nor to see overlaps: \"/vis/drawLogicalVolume <mother-logical-volume-name>\""
<< G4endl;
} else {
G4cout << newValue << " not found" << G4endl;
G4cout << pvName;
if (copyNo >= 0) G4cout << ':' << copyNo;
G4cout << " not found" << G4endl;
}
} else if (command == fpCommandShowExtent) {
G4PhysicalVolumeModel::TouchableProperties properties =
G4TouchableUtils::FindTouchableProperties(fCurrentTouchableProperties.fTouchablePath);
if (properties.fpTouchablePV) {
G4VisExtent extent
= properties.fpTouchablePV->GetLogicalVolume()->GetSolid()->GetExtent();
extent.Transform(properties.fTouchableGlobalTransform);
G4cout << extent << G4endl;
if (fpCommandShowExtent->GetNewBoolValue(newValue)) DrawExtent(extent);
} else {
G4cout << "Touchable not found." << G4endl;
}
return;
} else if (command == fpCommandVolumeForField) {
G4PhysicalVolumeModel::TouchableProperties properties =
G4TouchableUtils::FindTouchableProperties(fCurrentTouchableProperties.fTouchablePath);
if (properties.fpTouchablePV) {
G4VisExtent extent
= properties.fpTouchablePV->GetLogicalVolume()->GetSolid()->GetExtent();
extent.Transform(properties.fTouchableGlobalTransform);
fCurrentExtentForField = extent;
fCurrrentPVFindingsForField.clear();
fCurrrentPVFindingsForField.push_back
(G4PhysicalVolumesSearchScene::Findings(properties));
if (verbosity >= G4VisManager::confirmations) {
G4cout
<< "Volume for field set to " << properties.fpTouchablePV->GetName()
<< ':' << properties.fCopyNo
<< " at " << properties.fTouchableBaseFullPVPath
<< G4endl;
}
if (fpCommandVolumeForField->GetNewBoolValue(newValue)) {
DrawExtent(extent);
}
} else {
G4cout << "Touchable not found." << G4endl;
}
return;
} else {
if (verbosity >= G4VisManager::errors) {
@@ -94,13 +94,22 @@ G4VisCommandsTouchableSet::G4VisCommandsTouchableSet()
fpCommandSetLineSegmentsPerCircle->SetParameterName("lineSegmentsPerCircle", omitable = true);
fpCommandSetLineSegmentsPerCircle->SetDefaultValue(0);
fpCommandSetForceCloud = new G4UIcmdWithABool
("/vis/touchable/set/forceCloud", this);
fpCommandSetForceCloud->SetGuidance
("Force current touchable always to be drawn as a cloud.");
fpCommandSetForceCloud->SetGuidance
("Use \"/vis/set/touchable\" to set current touchable.");
fpCommandSetForceCloud->SetParameterName("force", omitable = true);
fpCommandSetForceCloud->SetDefaultValue(true);
fpCommandSetForceSolid = new G4UIcmdWithABool
("/vis/touchable/set/forceSolid", this);
fpCommandSetForceSolid->SetGuidance
("Force current touchable always to be drawn solid (surface drawing).");
fpCommandSetForceSolid->SetGuidance
("Use \"/vis/set/touchable\" to set current touchable.");
fpCommandSetForceSolid->SetParameterName("forceSolid", omitable = true);
fpCommandSetForceSolid->SetParameterName("force", omitable = true);
fpCommandSetForceSolid->SetDefaultValue(true);
fpCommandSetForceWireframe = new G4UIcmdWithABool
@@ -129,6 +138,18 @@ G4VisCommandsTouchableSet::G4VisCommandsTouchableSet()
fpCommandSetLineWidth->SetParameterName("lineWidth", omitable = true);
fpCommandSetLineWidth->SetDefaultValue(1.);
fpCommandSetNumberOfCloudPoints = new G4UIcmdWithAnInteger
("/vis/touchable/set/numberOfCloudPoints", this);
fpCommandSetNumberOfCloudPoints->SetGuidance
("For current touchable, set number of line segments per circle, the"
"\nprecision with which a curved line or surface is represented by a"
"\npolygon or polyhedron, regardless of the view parameters."
"\nNegative to pick up G4Polyhedron default value.");
fpCommandSetNumberOfCloudPoints->SetGuidance
("Use \"/vis/set/touchable\" to set current touchable.");
fpCommandSetNumberOfCloudPoints->SetParameterName("lineSegmentsPerCircle", omitable = true);
fpCommandSetNumberOfCloudPoints->SetDefaultValue(0);
fpCommandSetVisibility = new G4UIcmdWithABool
("/vis/touchable/set/visibility", this);
fpCommandSetVisibility->SetGuidance
@@ -141,10 +162,12 @@ G4VisCommandsTouchableSet::G4VisCommandsTouchableSet()
G4VisCommandsTouchableSet::~G4VisCommandsTouchableSet() {
delete fpCommandSetVisibility;
delete fpCommandSetNumberOfCloudPoints;
delete fpCommandSetLineWidth;
delete fpCommandSetLineStyle;
delete fpCommandSetForceWireframe;
delete fpCommandSetForceSolid;
delete fpCommandSetForceCloud;
delete fpCommandSetLineSegmentsPerCircle;
delete fpCommandSetForceAuxEdgeVisible;
delete fpCommandSetDaughtersInvisible;
@@ -217,6 +240,15 @@ void G4VisCommandsTouchableSet::SetNewValue
fCurrentTouchableProperties.fTouchablePath));
}
else if (command == fpCommandSetForceCloud) {
workingVisAtts.SetForceCloud(G4UIcommand::ConvertToBool(newValue));
workingVP.AddVisAttributesModifier
(G4ModelingParameters::VisAttributesModifier
(workingVisAtts,
G4ModelingParameters::VASForceCloud,
fCurrentTouchableProperties.fTouchablePath));
}
else if (command == fpCommandSetForceSolid) {
workingVisAtts.SetForceSolid(G4UIcommand::ConvertToBool(newValue));
workingVP.AddVisAttributesModifier
@@ -225,7 +257,7 @@ void G4VisCommandsTouchableSet::SetNewValue
G4ModelingParameters::VASForceSolid,
fCurrentTouchableProperties.fTouchablePath));
}
else if (command == fpCommandSetForceWireframe) {
workingVisAtts.SetForceWireframe(G4UIcommand::ConvertToBool(newValue));
workingVP.AddVisAttributesModifier
@@ -260,6 +292,16 @@ void G4VisCommandsTouchableSet::SetNewValue
fCurrentTouchableProperties.fTouchablePath));
}
else if (command == fpCommandSetNumberOfCloudPoints) {
workingVisAtts.SetForceNumberOfCloudPoints
(G4UIcommand::ConvertToInt(newValue));
workingVP.AddVisAttributesModifier
(G4ModelingParameters::VisAttributesModifier
(workingVisAtts,
G4ModelingParameters::VASForceNumberOfCloudPoints,
fCurrentTouchableProperties.fTouchablePath));
}
else if (command == fpCommandSetVisibility) {
workingVisAtts.SetVisibility(G4UIcommand::ConvertToBool(newValue));
workingVP.AddVisAttributesModifier
@@ -39,6 +39,8 @@
#include "G4UIcmdWithADouble.hh"
#include "G4UIcmdWithADoubleAndUnit.hh"
#include "G4UIcmdWith3Vector.hh"
#include "G4PhysicalVolumesSearchScene.hh"
#include "G4TransportationManager.hh"
#include "G4Point3D.hh"
#include "G4SystemOfUnits.hh"
#include "G4UnitsTable.hh"
@@ -57,33 +59,6 @@
#include <filesystem>
#endif //WIN32
G4VVisCommandViewer::G4VVisCommandViewer () {}
G4VVisCommandViewer::~G4VVisCommandViewer () {}
void G4VVisCommandViewer::SetViewParameters
(G4VViewer* viewer, const G4ViewParameters& viewParams) {
viewer->SetViewParameters(viewParams);
RefreshIfRequired(viewer);
}
void G4VVisCommandViewer::RefreshIfRequired(G4VViewer* viewer) {
G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
G4VSceneHandler* sceneHandler = viewer->GetSceneHandler();
const G4ViewParameters& viewParams = viewer->GetViewParameters();
if (sceneHandler && sceneHandler->GetScene()) {
if (viewParams.IsAutoRefresh()) {
G4UImanager::GetUIpointer()->ApplyCommand("/vis/viewer/refresh");
}
else {
if (verbosity >= G4VisManager::warnings) {
G4cout << "Issue /vis/viewer/refresh or flush to see effect."
<< G4endl;
}
}
}
}
////////////// /vis/viewer/addCutawayPlane ///////////////////////////////////////
G4VisCommandViewerAddCutawayPlane::G4VisCommandViewerAddCutawayPlane () {
@@ -164,6 +139,173 @@ void G4VisCommandViewerAddCutawayPlane::SetNewValue (G4UIcommand*, G4String newV
SetViewParameters(viewer, vp);
}
////////////// /vis/viewer/centreOn ///////////////////////////////////////
G4VisCommandViewerCentreOn::G4VisCommandViewerCentreOn () {
G4bool omitable;
fpCommandCentreAndZoomInOn = new G4UIcommand ("/vis/viewer/centreAndZoomInOn", this);
fpCommandCentreAndZoomInOn->SetGuidance
("Centre and zoom in on the given physical volume.");
fpCommandCentreAndZoomInOn->SetGuidance
("The names of all volumes in all worlds are matched against pv-name. If"
"\ncopy-no is supplied, it matches the copy number too. If pv-name is of the"
"\nform \"/regexp/\", where regexp is a regular expression (see C++ regex),"
"\nthe match uses the usual rules of regular expression matching."
"\nOtherwise an exact match is required."
"\nFor example, \"/Shap/\" matches \"Shape1\" and \"Shape2\".");
fpCommandCentreAndZoomInOn->SetGuidance
("It may help to see a textual representation of the geometry hierarchy of"
"\nthe worlds. Try \"/vis/drawTree [worlds]\" or one of the driver/browser"
"\ncombinations that have the required functionality, e.g., HepRepFile.");
fpCommandCentreAndZoomInOn->SetGuidance
("If there are more than one matching physical volumes they will all be"
"\nincluded. If this is not what you want, and what you want is to centre on a"
"\nparticular touchable, then select the touchable (\"/vis/set/touchable\") and"
"\nuse \"/vis/touchable/centreOn\". (You may need \"/vis/touchable/findPath\".)");
G4UIparameter* parameter;
parameter = new G4UIparameter("pv-name",'s',omitable = false);
parameter->SetGuidance ("Physical volume name.");
fpCommandCentreAndZoomInOn->SetParameter(parameter);
parameter = new G4UIparameter("copy-no",'i',omitable = true);
parameter->SetDefaultValue (-1);
parameter->SetGuidance ("Copy number. -1 means any or all copy numbers");
fpCommandCentreAndZoomInOn->SetParameter(parameter);
fpCommandCentreOn = new G4UIcommand ("/vis/viewer/centreOn", this);
fpCommandCentreOn->SetGuidance ("Centre the view on the given physical volume.");
// Pick up additional guidance from /vis/viewer/centreAndZoomInOn
CopyGuidanceFrom(fpCommandCentreAndZoomInOn,fpCommandCentreOn,1);
// Pick up parameters from /vis/viewer/centreAndZoomInOn
CopyParametersFrom(fpCommandCentreAndZoomInOn,fpCommandCentreOn);
}
G4VisCommandViewerCentreOn::~G4VisCommandViewerCentreOn () {
delete fpCommandCentreAndZoomInOn;
delete fpCommandCentreOn;
}
G4String G4VisCommandViewerCentreOn::GetCurrentValue (G4UIcommand*) {
return "";
}
void G4VisCommandViewerCentreOn::SetNewValue (G4UIcommand* command, G4String newValue) {
G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
G4bool warn = verbosity >= G4VisManager::warnings;
G4VViewer* currentViewer = fpVisManager -> GetCurrentViewer ();
if (!currentViewer) {
if (verbosity >= G4VisManager::errors) {
G4cerr <<
"ERROR: No current viewer - \"/vis/viewer/list\" to see possibilities."
<< G4endl;
}
return;
}
G4String pvName;
G4int copyNo;
std::istringstream is (newValue);
is >> pvName >> copyNo;
// Find physical volumes
G4TransportationManager* transportationManager =
G4TransportationManager::GetTransportationManager ();
size_t nWorlds = transportationManager->GetNoWorlds();
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);
G4PhysicalVolumesSearchScene searchScene (&searchModel, pvName, copyNo);
searchModel.DescribeYourselfTo (searchScene); // Initiate search.
for (const auto& findings: searchScene.GetFindings()) {
findingsVector.push_back(findings);
}
}
if (findingsVector.empty()) {
if (verbosity >= G4VisManager::warnings) {
G4cerr
<< "WARNING: Volume \"" << pvName << "\" ";
if (copyNo > 0) {
G4cerr << "copy number " << copyNo;
}
G4cerr << " not found." << G4endl;
}
return;
}
// Use a temporary scene in order to find vis extent
G4Scene tempScene("Centre Scene");
for (const auto& findings: findingsVector) {
// To handle paramaterisations we have to set the copy number
findings.fpFoundPV->SetCopyNo(findings.fFoundPVCopyNo);
// Create a temporary physical volume model.
// They have to be created on the heap because they have
// to hang about long enough to be conflated.
G4PhysicalVolumeModel* tempPVModel = new G4PhysicalVolumeModel
(findings.fpFoundPV,
0, // Only interested in top volume
findings.fFoundObjectTransformation,
0, // No modelling parameters (these are set later by the scene handler).
true, // Use full extent
findings.fFoundBasePVPath);
// ...and add it to the scene.
G4bool successful = tempScene.AddRunDurationModel(tempPVModel,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 has been added to temporary scene \"" << tempScene.GetName() << "\"."
<< G4endl;
}
}
}
// Delete temporary physical volume models
for (const auto& sceneModel: tempScene.GetRunDurationModelList()) {
delete sceneModel.fpModel;
}
// Relevant results
const G4VisExtent& newExtent = tempScene.GetExtent();
const G4ThreeVector& newTargetPoint = newExtent.GetExtentCentre();
G4Scene* currentScene = currentViewer->GetSceneHandler()->GetScene();
G4ViewParameters saveVP = currentViewer->GetViewParameters();
G4ViewParameters newVP = saveVP;
if (command == fpCommandCentreAndZoomInOn) {
// Calculate the new zoom factor
const G4double zoomFactor
= currentScene->GetExtent().GetExtentRadius()/newExtent.GetExtentRadius();
newVP.SetZoomFactor(zoomFactor);
}
// Change the target point
const G4Point3D& standardTargetPoint = currentScene->GetStandardTargetPoint();
newVP.SetCurrentTargetPoint(newTargetPoint - standardTargetPoint);
// Interpolate
InterpolateToNewView(currentViewer, saveVP, newVP);
if (verbosity >= G4VisManager::confirmations) {
G4cout
<< "Viewer \"" << currentViewer->GetName()
<< "\" centred ";
if (fpCommandCentreAndZoomInOn) {
G4cout << "and zoomed in";
}
G4cout << " on physical volume(s) \"" << pvName << '\"'
<< G4endl;
}
SetViewParameters(currentViewer, newVP);
}
////////////// /vis/viewer/changeCutawayPlane ///////////////////////////////////////
G4VisCommandViewerChangeCutawayPlane::G4VisCommandViewerChangeCutawayPlane () {
@@ -1211,7 +1353,10 @@ void G4VisCommandViewerInterpolate::SetNewValue (G4UIcommand*, G4String newValue
while (fileliststream >> pathname
&& safetyCount++ < safety) { // Loop checking, 16.02.2016, J.Allison
uiManager->ApplyCommand("/control/execute " + pathname);
viewVector.push_back(currentViewer->GetViewParameters());
G4ViewParameters vp = currentViewer->GetViewParameters();
// Set original auto-refresh status.
vp.SetAutoRefresh(saveVP.IsAutoRefresh());
viewVector.push_back(vp);
}
}
pclose(filelist);
@@ -1267,7 +1412,10 @@ void G4VisCommandViewerInterpolate::SetNewValue (G4UIcommand*, G4String newValue
if (std::regex_match(filename, result_pattern_regex))
{
uiManager->ApplyCommand("/control/execute " + filename);
viewVector.push_back(currentViewer->GetViewParameters());
G4ViewParameters vp = currentViewer->GetViewParameters();
// Set original auto-refresh status.
vp.SetAutoRefresh(saveVP.IsAutoRefresh());
viewVector.push_back(vp);
}
}
@@ -1283,27 +1431,9 @@ void G4VisCommandViewerInterpolate::SetNewValue (G4UIcommand*, G4String newValue
return;
}
// Interpolate views
safetyCount = 0;
do {
G4ViewParameters* vp =
G4ViewParameters::CatmullRomCubicSplineInterpolation(viewVector,nInterpolationPoints);
if (!vp) break; // Finished.
// Set original auto-refresh status.
vp->SetAutoRefresh(saveVP.IsAutoRefresh());
currentViewer->SetViewParameters(*vp);
currentViewer->RefreshView();
if (exportString == "export" &&
currentViewer->GetName().contains("OpenGL")) {
uiManager->ApplyCommand("/vis/ogl/export");
}
// File-writing viewers need to close the file
currentViewer->ShowView();
#ifdef G4VIS_USE_STD11
if (waitTimePerPointmilliseconds > 0)
std::this_thread::sleep_for(std::chrono::milliseconds(waitTimePerPointmilliseconds));
#endif
} while (safetyCount++ < safety); // Loop checking, 16.02.2016, J.Allison
InterpolateViews
(currentViewer,viewVector,
nInterpolationPoints,waitTimePerPointmilliseconds,exportString);
// Restore original verbosities
uiManager->SetVerboseLevel(keepUIVerbosity);
@@ -65,31 +65,37 @@ void G4VisCommandViewerDefaultHiddenEdge::SetNewValue(G4UIcommand*, G4String new
G4ViewParameters::DrawingStyle existingStyle = vp.GetDrawingStyle();
if (G4UIcommand::ConvertToBool(newValue)) {
switch (existingStyle) {
case G4ViewParameters::wireframe:
vp.SetDrawingStyle(G4ViewParameters::hlr);
break;
case G4ViewParameters::hlr:
break;
case G4ViewParameters::hsr:
vp.SetDrawingStyle(G4ViewParameters::hlhsr);
break;
case G4ViewParameters::hlhsr:
break;
switch (existingStyle) { // true
case G4ViewParameters::wireframe:
vp.SetDrawingStyle(G4ViewParameters::hlr);
break;
case G4ViewParameters::hlr:
break;
case G4ViewParameters::hsr:
vp.SetDrawingStyle(G4ViewParameters::hlhsr);
break;
case G4ViewParameters::hlhsr:
break;
case G4ViewParameters::cloud:
G4cout << "No effect in cloud style" << G4endl;
break;
}
}
else {
switch (existingStyle) {
case G4ViewParameters::wireframe:
break;
case G4ViewParameters::hlr:
vp.SetDrawingStyle(G4ViewParameters::wireframe);
break;
case G4ViewParameters::hsr:
break;
case G4ViewParameters::hlhsr:
vp.SetDrawingStyle(G4ViewParameters::hsr);
break;
switch (existingStyle) { // false
case G4ViewParameters::wireframe:
break;
case G4ViewParameters::hlr:
vp.SetDrawingStyle(G4ViewParameters::wireframe);
break;
case G4ViewParameters::hsr:
break;
case G4ViewParameters::hlhsr:
vp.SetDrawingStyle(G4ViewParameters::hsr);
break;
case G4ViewParameters::cloud:
G4cout << "No effect in cloud style" << G4endl;
break;
}
}
@@ -109,11 +115,11 @@ G4VisCommandViewerDefaultStyle::G4VisCommandViewerDefaultStyle()
fpCommand = new G4UIcmdWithAString("/vis/viewer/default/style", this);
fpCommand->SetGuidance("Default drawing style for future viewers.");
fpCommand->SetGuidance
("Set style of drawing - w[ireframe] or s[urface].");
("Set style of drawing - w[ireframe] or s[urface] or c[loud].");
fpCommand->SetGuidance
("(Default hidden line drawing is controlled by \"/vis/viewer/default/hiddenEdge\".)");
fpCommand->SetParameterName ("style",omitable = false);
fpCommand->SetCandidates("w wireframe s surface");
fpCommand->SetCandidates("w wireframe s surface c cloud");
}
G4VisCommandViewerDefaultStyle::~G4VisCommandViewerDefaultStyle()
@@ -137,36 +143,60 @@ void G4VisCommandViewerDefaultStyle::SetNewValue(G4UIcommand*, G4String newValue
const size_t iPos0 = 0;
if (newValue[iPos0] == 'w') { // "wireframe"
switch (existingStyle) {
case G4ViewParameters::wireframe:
break;
case G4ViewParameters::hlr:
break;
case G4ViewParameters::hsr:
vp.SetDrawingStyle(G4ViewParameters::wireframe);
break;
case G4ViewParameters::hlhsr:
vp.SetDrawingStyle(G4ViewParameters::hlr);
break;
case G4ViewParameters::wireframe:
break;
case G4ViewParameters::hlr:
break;
case G4ViewParameters::hsr:
vp.SetDrawingStyle(G4ViewParameters::wireframe);
break;
case G4ViewParameters::hlhsr:
vp.SetDrawingStyle(G4ViewParameters::hlr);
break;
case G4ViewParameters::cloud:
vp.SetDrawingStyle(G4ViewParameters::wireframe);
break;
}
}
else if (newValue[iPos0] == 's') { // "surface"
switch (existingStyle) {
case G4ViewParameters::wireframe:
vp.SetDrawingStyle(G4ViewParameters::hsr);
break;
case G4ViewParameters::hlr:
vp.SetDrawingStyle(G4ViewParameters::hlhsr);
break;
case G4ViewParameters::hsr:
break;
case G4ViewParameters::hlhsr:
break;
case G4ViewParameters::wireframe:
vp.SetDrawingStyle(G4ViewParameters::hsr);
break;
case G4ViewParameters::hlr:
vp.SetDrawingStyle(G4ViewParameters::hlhsr);
break;
case G4ViewParameters::hsr:
break;
case G4ViewParameters::hlhsr:
break;
case G4ViewParameters::cloud:
vp.SetDrawingStyle(G4ViewParameters::hsr);
break;
}
}
else if (newValue[iPos0] == 'c') { // "cloud"
switch (existingStyle) {
case G4ViewParameters::wireframe:
vp.SetDrawingStyle(G4ViewParameters::cloud);
break;
case G4ViewParameters::hlr:
vp.SetDrawingStyle(G4ViewParameters::cloud);
break;
case G4ViewParameters::hsr:
vp.SetDrawingStyle(G4ViewParameters::cloud);
break;
case G4ViewParameters::hlhsr:
vp.SetDrawingStyle(G4ViewParameters::cloud);
break;
case G4ViewParameters::cloud:
break;
}
}
else {
if (verbosity >= G4VisManager::errors) {
G4cerr << "ERROR: \"" << newValue << "\" not recognised."
" Looking for 'w' or 's' first character." << G4endl;
" Looking for 'w' or 's' or 'c' first character." << G4endl;
}
return;
}
File diff suppressed because it is too large Load Diff
@@ -26,6 +26,7 @@
//
//
// GEANT4 Visualization Manager - John Allison 02/Jan/1996.
// Michael Kelsey 31 Jan 2019 -- Add new command for electric field
#include "G4VisManager.hh"
@@ -496,12 +497,14 @@ void G4VisManager::RegisterMessengers () {
fDirectoryList.push_back (directory);
RegisterMessenger(new G4VisCommandSetArrow3DLineSegmentsPerCircle);
RegisterMessenger(new G4VisCommandSetColour);
RegisterMessenger(new G4VisCommandSetExtentForField);
RegisterMessenger(new G4VisCommandSetLineWidth);
RegisterMessenger(new G4VisCommandSetTextColour);
RegisterMessenger(new G4VisCommandSetTextLayout);
RegisterMessenger(new G4VisCommandSetTextSize);
RegisterMessenger(new G4VisCommandSetTouchable);
RegisterMessenger(new G4VisCommandSetVolumeForField);
directory = new G4UIdirectory ("/vis/scene/");
directory -> SetGuidance ("Operations on Geant4 scenes.");
fDirectoryList.push_back (directory);
@@ -512,7 +515,8 @@ void G4VisManager::RegisterMessengers () {
RegisterMessenger(new G4VisCommandSceneList);
RegisterMessenger(new G4VisCommandSceneNotifyHandlers);
RegisterMessenger(new G4VisCommandSceneSelect);
RegisterMessenger(new G4VisCommandSceneShowExtents);
directory = new G4UIdirectory ("/vis/scene/add/");
directory -> SetGuidance ("Add model to current scene.");
fDirectoryList.push_back (directory);
@@ -523,6 +527,7 @@ void G4VisManager::RegisterMessengers () {
RegisterMessenger(new G4VisCommandSceneAddDigis);
RegisterMessenger(new G4VisCommandSceneAddEventID);
RegisterMessenger(new G4VisCommandSceneAddExtent);
RegisterMessenger(new G4VisCommandSceneAddElectricField);
RegisterMessenger(new G4VisCommandSceneAddFrame);
RegisterMessenger(new G4VisCommandSceneAddGPS);
RegisterMessenger(new G4VisCommandSceneAddHits);
@@ -562,6 +567,7 @@ void G4VisManager::RegisterMessengers () {
directory -> SetGuidance ("Operations on Geant4 viewers.");
fDirectoryList.push_back (directory);
RegisterMessenger(new G4VisCommandViewerAddCutawayPlane);
RegisterMessenger(new G4VisCommandViewerCentreOn);
RegisterMessenger(new G4VisCommandViewerChangeCutawayPlane);
RegisterMessenger(new G4VisCommandViewerClear);
RegisterMessenger(new G4VisCommandViewerClearCutawayPlanes);
@@ -1404,6 +1410,11 @@ void G4VisManager::RegisterRunDurationUserVisAction
<< G4endl;
}
}
if (fVerbosity >= confirmations) {
G4cout
<< "Run duration user vis action \"" << name << "\" registered"
<< G4endl;
}
}
void G4VisManager::RegisterEndOfEventUserVisAction
@@ -1420,6 +1431,11 @@ void G4VisManager::RegisterEndOfEventUserVisAction
<< G4endl;
}
}
if (fVerbosity >= confirmations) {
G4cout
<< "End of event user vis action \"" << name << "\" registered"
<< G4endl;
}
}
void G4VisManager::RegisterEndOfRunUserVisAction
@@ -1436,6 +1452,11 @@ void G4VisManager::RegisterEndOfRunUserVisAction
<< G4endl;
}
}
if (fVerbosity >= confirmations) {
G4cout
<< "End of run user vis action \"" << name << "\" registered"
<< G4endl;
}
}
void G4VisManager::SetCurrentScene (G4Scene* pScene) {
@@ -1884,6 +1905,12 @@ void G4VisManager::BeginOfRun ()
if (fpSceneHandler) fpSceneHandler->SetTransientsDrawnThisRun(false);
fNoOfEventsDrawnThisRun = 0;
// Check to see if the user has created a trajectory model. If not, create
// a default one. To avoid code duplication the following function is used
// and its result (a const G4VTrajectoryModel*) is thrown away at this point.
// The function is called again later when needed.
CurrentTrajDrawModel();
#ifdef G4MULTITHREADED
// There is a static method G4Threading::IsMultithreadedApplication()
// that returns true only if G4MTRunManager is instantiated with MT
@@ -2206,7 +2233,7 @@ void G4VisManager::EndOfRun ()
if (events) nKeptEvents = events->size();
if (nKeptEvents && !fKeptLastEvent) {
if (fVerbosity >= warnings) {
G4cout << "WARNING: " << nKeptEvents;
G4cout << nKeptEvents;
if (nKeptEvents == 1) G4cout << " event has";
else G4cout << " events have";
G4cout << " been kept for refreshing and/or reviewing." << G4endl;
+108 -1
View File
@@ -19,6 +19,113 @@ committal in the CVS repository !
History file for visualization/modeling
---------------------------------------
13 June 2019 John Allison (modeling-V10-05-04)
- Part of vis-V10-05-20.
- G4ModelingParameters:
o Add cloud to enum options and updated operators != and <<:
o Similarly added to VisAttributesSignifier
- G4PhysicalVolumeModel.cc:
o Handle new VisAttributesSignifiers.
10 June 2019 John Allison (modeling-V10-05-03)
- Part of vis-V10-05-19.
- G4ArrowModel: Further use of const and introduce further protection.
- G4VFieldModel.cc: Further use of const.
29 May 2019 John Allison (modeling-V10-05-02)
- Improve field modelling:
o G4VFieldModel: Improve so even the smallest non-zero sample is visible:
. Values < 10% max are drawn as lines of width 2.
. Values < 1% max have their length fixed at 1% max.
. Reverse colour code. Now, where f = fieldStrength/maxStrength:
0 -> f/2 -> f is coded as red -> green -> blue.
For a uniform field this means arrows are now blue instead of red.
o G4ArrowModel:
. Place checks on dimensions to prevent G4Exceptions in used solids.
. Model arrow head as G4Tet.
- G4PhysicalVolumeModel.cc:
o Improve printing from operator<< for nodeID path.
04 April 2019 John Allison (modeling-V10-05-01)
- Co-works visman-V10-05-04.
- Final (for now) corrections to /vis/viewer/set/sectionPlane.
Still some strange behaviour in small fraction of cases. See
comments in G4PhysicalVolumeModel::DescribeSolid around line 748.
24 March 2019 John Allison (modeling-V10-05-00)
- Fix bug in /vis/viewer/set/sectionPlane.
Involves using G4DisplacedSolid instead of plain G4VSolid.
18 March 2019 Gabriele Cosmo
- Included in vis-V10-05-15
- Corrected few typos comments.
24 February 2019 John Allison
- Included in vis-V10-05-13
- Add constructor to G4PhysicalVolumesSearchScene::Findings from
G4PhysicalVolumeModel::TouchableProperties.
- Fix bug in overlap drawing of parameterised volumes.
19 February 2019 John Allison
- Included in vis-V10-05-12
- Introduced G4BoundingExtentScene. This allows one to accumulate extents
using the newly introduced G4VisExtent::Transform and is a better way
of determining the overall extent of a scene (or of any set of extents)
than by the bounding sphere approach.
- G4VFieldModel, G4ElectricFieldModel, G4MagneticFieldModel:
o Introduced volume for field.
- G4VModel: Introduced GetTransformedExtent. This calculates the extent as
it appears to the user, based on the local extent and the transformation.
- G4PhysicalVolumeModel:
o Use G4BoundingExtentScene instead of G4BoundingSphereScene.
o Fix bug whereby the local extent was incorrectly calculated - in fact
it was the transformed extent. Corresponding corrections to all cases
where the extent is needed, for example, in defining the view
parameters, have been made in this commit.
13 February 2019 John Allison
- Included in vis-V10-05-11
- Implement /vis/set/extentForField - see visualisation/History.
08 February 2019 John Allison
- Included in vis-V10-05-09
- Fix Coverity warnings.
31 January 2019 Michael Kelsey
- Included in vis-V01-05-08
- G4VFieldModel.hh/cc: NEW intermediate base class for magnetic, electric
and gravitational fields. Contains all of DescribeYourselfTo() moved from
G4MagneticFieldModel, plus a pure virtual function (GetFieldAtLocation) to
fetch the field vector (differently by each subclass). Constructor now
takes two strings to let subclasses customize diagnostics and arrow labels.
- G4ElectricFieldModel: NEW concrete class implementing GetFieldAtLocation()
for electric field access.
- G4MagneticFieldModel: Move all of DescribeYourselfTo() to new base class
G4VFieldModel. Implement old contents of "if (field) { ..." block as new
GetFieldAtLocation() function.
29 January 2019 John Allison
- Included in vis-V10-05-06
- G4PhysicalVolumeModel.cc:
o If the top volume is parameterised or a replica describe only one
of them, namely the one specified by the copy number.
26 January 2019 John Allison
- Included in vis-V10-05-06
- Fix calculation of vis extent for parameterisations. This involved
extending G4PhysicalVolumeModel::TouchableProperties to include copy
number and initialising the copy number in the constructor. Then in
G4PhysicalVolumeModel::CalculateExtent solid->ComputeDimensions is
invoked if it is a parameterised volume.
- Some minor tidying.
02 January 2019 John Allison
- Included in vis-V10-05-00.
- G4PhysicalVolumeModel.cc: Add volume count (but comment out printing).
14 November 2018 John Allison (modeling-V10-04-18)
- G4PhysicalVolumeModel.cc: Fix Coverity warning.
@@ -964,7 +1071,7 @@ History file for visualization/modeling
26th January 2006 John Allison (modeling-V08-00-01)
- G4PhysicalVolumeModel: Added capability of maintaining path of the
current drawn (non-culled) volume in terms of drawn (non-culled)
ancesters. See G4PhysicalVolumeModel.hh for detailed description.
ancestors. See G4PhysicalVolumeModel.hh for detailed description.
- Removed some unnecessary data members and other small tidying.
11th January 2006 John Allison (modeling-V08-00-00)
@@ -0,0 +1,69 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
//
// John Allison 15th February 2019
// An artificial scene to reuse G4VScene code to calculate a bounding extent.
#ifndef G4BOUNDINGEXTENTSCENE_HH
#define G4BOUNDINGEXTENTSCENE_HH
#include "G4PseudoScene.hh"
#include "G4VisExtent.hh"
class G4VModel;
class G4BoundingExtentScene: public G4PseudoScene {
public:
G4BoundingExtentScene (G4VModel* pModel = 0);
virtual ~G4BoundingExtentScene ();
const G4VisExtent& GetExtent () const
{return fExtent;}
const G4VisExtent& GetBoundingExtent () const
{return fExtent;}
////////////////////////////////////////////////////////////////
// The following 2 functions can be used by any code which wishes to
// accrue a bounding sphere. Just instantiate a
// G4BoundingExtentScene and use AccrueBoundingExtent.
void ResetBoundingExtent ();
void AccrueBoundingExtent (const G4VisExtent&);
private:
void ProcessVolume (const G4VSolid& solid);
G4VModel* fpModel;
G4VisExtent fExtent;
};
#endif
@@ -0,0 +1,72 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
//
// Michael Kelsey 31st January 2019 -- Adapted from new G4MagneticFieldModel
//
// Class Description:
//
// Model that knows how to draw the electric field.
#ifndef G4ELECTRICFIELDMODEL_HH
#define G4ELECTRICFIELDMODEL_HH
#include "G4VFieldModel.hh"
class G4ElectricFieldModel: public G4VFieldModel {
public: // With description
// Constructor just passes through to base
G4ElectricFieldModel
(G4int nDataPointsPerHalfExtent = 3,
Representation representation = Representation::fullArrow,
G4int arrow3DLineSegmentsPerCircle = 6,
const G4VisExtent& extentForField = G4VisExtent(),
const std::vector<G4PhysicalVolumesSearchScene::Findings>& pvFindings
= std::vector<G4PhysicalVolumesSearchScene::Findings>())
: G4VFieldModel
("Electric","E", extentForField, pvFindings,
nDataPointsPerHalfExtent, representation, arrow3DLineSegmentsPerCircle)
{}
virtual ~G4ElectricFieldModel() {;}
protected:
virtual void GetFieldAtLocation(const G4Field* field,
const G4Point3D& position, G4double time,
G4Point3D& result) const;
// The appropriate output from GetFieldValue should be filled into result.
// If (field==0), the function should do nothing; returning without error.
private:
// Private copy contructor and assignment to forbid use...
G4ElectricFieldModel(const G4ElectricFieldModel&);
G4ElectricFieldModel& operator=(const G4ElectricFieldModel&);
};
#endif
@@ -26,7 +26,8 @@
//
//
//
// John Allison 17th August 2013
// John Allison 17th August 2013
// Michael Kelsey 31st January 2019 -- Move functionality to G4VFieldModel
//
// Class Description:
//
@@ -35,40 +36,38 @@
#ifndef G4MAGNETICFIELDMODEL_HH
#define G4MAGNETICFIELDMODEL_HH
#include "G4VModel.hh"
#include "G4VFieldModel.hh"
class G4Colour;
class G4Polyhedron;
class G4MagneticFieldModel: public G4VModel {
public: // With description
enum Representation {fullArrow, lightArrow};
class G4MagneticFieldModel: public G4VFieldModel {
public: // With description
// Constructor just passes through to base
G4MagneticFieldModel
(G4int nDataPointsPerHalfScene = 10,
(G4int nDataPointsPerHalfExtent = 3,
Representation representation = Representation::fullArrow,
G4int arrow3DLineSegmentsPerCircle = 6);
virtual ~G4MagneticFieldModel ();
G4int arrow3DLineSegmentsPerCircle = 6,
const G4VisExtent& extentForField = G4VisExtent(),
const std::vector<G4PhysicalVolumesSearchScene::Findings>& pvFindings
= std::vector<G4PhysicalVolumesSearchScene::Findings>())
: G4VFieldModel
("Magnetic","B", extentForField, pvFindings,
nDataPointsPerHalfExtent, representation, arrow3DLineSegmentsPerCircle)
{}
virtual void DescribeYourselfTo (G4VGraphicsScene&);
// The main task of a model is to describe itself to the graphics scene.
virtual ~G4MagneticFieldModel() {;}
protected:
virtual void GetFieldAtLocation(const G4Field* field,
const G4Point3D& position, G4double time,
G4Point3D& result) const;
// The appropriate output from GetFieldValue should be filled into result.
// If (field==0), the function should do nothing; returning without error.
private:
// Private copy contructor and assignment to forbid use...
G4MagneticFieldModel (const G4MagneticFieldModel&);
G4MagneticFieldModel& operator = (const G4MagneticFieldModel&);
// No. of data points sampled per maximum half scene extent.
// Note that total number of data poinrs sampled can be as high as
// (2*n+1)^3, which can get very big very soon.
G4int fNDataPointsPerMaxHalfScene;
Representation fRepresentation;
G4int fArrow3DLineSegmentsPerCircle;
G4MagneticFieldModel(const G4MagneticFieldModel&);
G4MagneticFieldModel& operator=(const G4MagneticFieldModel&);
};
#endif
@@ -46,6 +46,7 @@
class G4LogicalVolume;
class G4VisAttributes;
class G4VSolid;
class G4DisplacedSolid;
class G4Event;
class G4ModelingParameters {
@@ -57,7 +58,8 @@ public: // With description
wf, // Draw edges - no hidden line removal (wireframe).
hlr, // Draw edges - hidden lines removed.
hsr, // Draw surfaces - hidden surfaces removed.
hlhsr // Draw surfaces and edges - hidden removed.
hlhsr, // Draw surfaces and edges - hidden removed.
cloud // Draw as a cloud of points
};
// enums and nested class for communicating a modification to the vis
@@ -70,6 +72,8 @@ public: // With description
VASLineWidth,
VASForceWireframe,
VASForceSolid,
VASForceCloud,
VASForceNumberOfCloudPoints,
VASForceAuxEdgeVisible,
VASForceLineSegmentsPerCircle
};
@@ -157,6 +161,7 @@ public: // With description
G4bool IsWarning () const;
const G4VisAttributes* GetDefaultVisAttributes () const;
DrawingStyle GetDrawingStyle () const;
G4int GetNumberOfCloudPoints () const;
G4bool IsCulling () const;
G4bool IsCullingInvisible () const;
G4bool IsDensityCulling () const;
@@ -168,8 +173,8 @@ public: // With description
G4double GetExplodeFactor () const;
const G4Point3D& GetExplodeCentre () const;
G4int GetNoOfSides () const;
G4VSolid* GetSectionSolid () const;
G4VSolid* GetCutawaySolid () const;
G4DisplacedSolid* GetSectionSolid () const;
G4DisplacedSolid* GetCutawaySolid () const;
const G4Event* GetEvent () const;
const std::vector<VisAttributesModifier>& GetVisAttributesModifiers() const;
@@ -177,6 +182,7 @@ public: // With description
void SetWarning (G4bool);
void SetDefaultVisAttributes (const G4VisAttributes* pDefaultVisAttributes);
void SetDrawingStyle (DrawingStyle);
void SetNumberOfCloudPoints (G4int);
void SetCulling (G4bool);
void SetCullingInvisible (G4bool);
void SetDensityCulling (G4bool);
@@ -187,8 +193,8 @@ public: // With description
void SetExplodeFactor (G4double explodeFactor);
void SetExplodeCentre (const G4Point3D& explodeCentre);
G4int SetNoOfSides (G4int); // Returns actual number set.
void SetSectionSolid (G4VSolid* pSectionSolid);
void SetCutawaySolid (G4VSolid* pCutawaySolid);
void SetSectionSolid (G4DisplacedSolid* pSectionSolid);
void SetCutawaySolid (G4DisplacedSolid* pCutawaySolid);
void SetEvent (const G4Event* pEvent);
void SetVisAttributesModifiers(const std::vector<VisAttributesModifier>&);
@@ -211,6 +217,8 @@ private:
G4bool fWarning; // Print warnings if true.
const G4VisAttributes* fpDefaultVisAttributes;
DrawingStyle fDrawingStyle; // Drawing style.
G4int fNumberOfCloudPoints; // For drawing in cloud style.
// <= 0 means use viewer default.
G4bool fCulling; // Culling requested.
G4bool fCullInvisible; // Cull (don't Draw) invisible objects.
G4bool fDensityCulling; // Density culling requested. If so...
@@ -221,8 +229,8 @@ private:
G4double fExplodeFactor; // Explode along radius by this factor...
G4Point3D fExplodeCentre; // ...about this centre.
G4int fNoOfSides; // ...if polygon approximates circle.
G4VSolid* fpSectionSolid; // For generic section (DCUT).
G4VSolid* fpCutawaySolid; // For generic cutaways.
G4DisplacedSolid* fpSectionSolid; // For generic section (DCUT).
G4DisplacedSolid* fpCutawaySolid; // For generic cutaways.
const G4Event* fpEvent; // Event being processed.
std::vector<VisAttributesModifier> fVisAttributesModifiers;
};
@@ -43,6 +43,10 @@ G4ModelingParameters::GetDrawingStyle () const {
return fDrawingStyle;
}
inline G4int G4ModelingParameters::GetNumberOfCloudPoints () const {
return fNumberOfCloudPoints;
}
inline G4bool G4ModelingParameters::IsCulling () const {
return fCulling;
}
@@ -87,10 +91,10 @@ inline G4int G4ModelingParameters::GetNoOfSides () const {
return fNoOfSides;
}
inline G4VSolid* G4ModelingParameters::GetSectionSolid () const
inline G4DisplacedSolid* G4ModelingParameters::GetSectionSolid () const
{return fpSectionSolid;}
inline G4VSolid* G4ModelingParameters::GetCutawaySolid () const
inline G4DisplacedSolid* G4ModelingParameters::GetCutawaySolid () const
{return fpCutawaySolid;}
inline const G4Event* G4ModelingParameters::GetEvent () const
@@ -116,6 +120,10 @@ G4ModelingParameters::SetDrawingStyle
fDrawingStyle = style;
}
inline void G4ModelingParameters::SetNumberOfCloudPoints (G4int n) {
fNumberOfCloudPoints = n;
}
inline void G4ModelingParameters::SetCulling (G4bool value) {
fCulling = value;
}
@@ -48,7 +48,7 @@
// number but also by its position in the geometry hierarchy.
//
// It is guaranteed that touchables are presented to the scene handler
// in top-down hierarchy order, i.e., ancesters first, mothers before
// in top-down hierarchy order, i.e., ancestors first, mothers before
// daughters, so the scene handler can be assured that, if it is
// building its own scene graph tree, a mother, if any, will have
// already been encountered and there will already be a node in place
@@ -133,9 +133,10 @@ public: // With description
// Nested struct for encapsulating touchable properties
struct TouchableProperties {
TouchableProperties(): fpTouchablePV(nullptr) {}
TouchableProperties(): fpTouchablePV(nullptr), fCopyNo(0) {}
G4ModelingParameters::PVNameCopyNoPath fTouchablePath;
G4VPhysicalVolume* fpTouchablePV;
G4int fCopyNo;
G4Transform3D fTouchableGlobalTransform;
std::vector<G4PhysicalVolumeNodeID> fTouchableBaseFullPVPath;
};
@@ -204,7 +205,7 @@ public: // With description
const std::vector<G4PhysicalVolumeNodeID>& GetDrawnPVPath() const
{return fDrawnPVPath;}
// Path of the current drawn (non-culled) touchable in terms of
// drawn (non-culled) ancesters. It is a vector of physical volume
// drawn (non-culled) ancestors. It is a vector of physical volume
// node identifiers corresponding to the geometry hierarchy actually
// selected, i.e., with "culled" volumes NOT included.
@@ -28,8 +28,8 @@
//
// John Allison 5th September 2018, based on G4PhysicalVolumeSearchScene
// An artificial scene to find physical volumes. Instead of returning the
// first occurence (G4PhysicalVolumeSearchScene) this class (note the extra
// 's' in the name of this class) returns a vector of all occurences.
// first occurrence (G4PhysicalVolumeSearchScene) this class (note the extra
// 's' in the name of this class) returns a vector of all occurrences.
// It can match a physical volume name with the required match. The latter can
// be of the form "/regexp/", where regexp is a regular expression (see C++
// regex), or a plain string, in which case there must be an exact match.
@@ -70,6 +70,13 @@ public:
, fFoundDepth(foundDepth)
, fFoundBasePVPath(foundBasePVPath)
, fFoundObjectTransformation(foundObjectTransformation) {}
Findings(const G4PhysicalVolumeModel::TouchableProperties& tp)
: fpSearchPV(nullptr)
, fpFoundPV(tp.fpTouchablePV)
, fFoundPVCopyNo(tp.fCopyNo)
, fFoundDepth(0)
, fFoundBasePVPath(tp.fTouchableBaseFullPVPath)
, fFoundObjectTransformation(tp.fTouchableGlobalTransform) {}
G4VPhysicalVolume* fpSearchPV; // Searched physical volume.
G4VPhysicalVolume* fpFoundPV; // Found physical volume.
G4int fFoundPVCopyNo; // Found Copy number.
@@ -0,0 +1,107 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// Michael Kelsey 31 January 2019
//
// Class Description:
//
// Abstract base class to implement drawing vector field geometries
// (e.g., electric, magnetic or gravity). Implementation extracted
// from G4MagneticFieldModel, with field-value access left pure
// virtual for implementation by base classes.
#ifndef G4VFIELDMODEL_HH
#define G4VFIELDMODEL_HH
#include "G4VModel.hh"
#include "G4Point3D.hh"
#include "G4PhysicalVolumesSearchScene.hh"
#include <vector>
class G4Field;
class G4VFieldModel: public G4VModel {
public: // With description
enum Representation {fullArrow, lightArrow};
G4VFieldModel
(const G4String& typeOfField, const G4String& symbol="",
const G4VisExtent& extentForField = G4VisExtent(),
const std::vector<G4PhysicalVolumesSearchScene::Findings>& pvFindings
= std::vector<G4PhysicalVolumesSearchScene::Findings>(),
G4int nDataPointsPerHalfScene = 10,
Representation representation = Representation::fullArrow,
G4int arrow3DLineSegmentsPerCircle = 6);
// typeOfField is "Electric" or "Magnetic" etc.
// symbol is "E" or "B" etc.
virtual ~G4VFieldModel();
virtual void DescribeYourselfTo(G4VGraphicsScene& sceneHandler);
// The main task of a model is to describe itself to the graphics scene.
// Note: It is in this function that the extent for drawing the filed must
// be calcualted. If fExtentForField is null, pick up the extent from
// the sceneHandler.
protected:
// Subclasses MUST implement this for their particular kind of field
virtual void GetFieldAtLocation(const G4Field* field,
const G4Point3D& position, G4double time,
G4Point3D& result) const = 0;
// The appropriate output from GetFieldValue should be filled into result.
// If (field==0), the function should do nothing; returning without error.
private:
// Private copy contructor and assignment to forbid use...
G4VFieldModel(const G4VFieldModel&);
G4VFieldModel& operator=(const G4VFieldModel&);
G4VisExtent fExtentForField;
// If null, get extent from scene handler in DescribeYourselfTo.
std::vector<G4PhysicalVolumesSearchScene::Findings> fPVFindings;
// If empty, use fExtentForField alone for sampling and drawing.
// If non-empty, use fExtentForField alone for sampling, but only
// draw if sampling point is in the specified physical volume(s).
G4int fNDataPointsPerMaxHalfScene;
// No. of data points sampled per maximum half scene.
// Note that total number of sampling points can be as high as
// (2*n+1)^3, which can get very big. However, fields are usually
// confined to only parts of the scene, so this may not be a problem.
// Sampling can be further limited with fExtentForField and/or fPVFindings.
Representation fRepresentation; // Big arrows or just lines
G4int fArrow3DLineSegmentsPerCircle;
G4String fTypeOfField; // "Electric" or "Magnetic" etc.
G4String fArrowPrefix; // For attaching text label to arrows
};
#endif
@@ -80,6 +80,9 @@ public: // With description
const G4VisExtent& GetExtent () const;
// Extent of visible objects in local coordinate system.
const G4VisExtent& GetTransformedExtent () const;
// Extent of visible objects in transformed coordinate system.
const G4String& GetGlobalDescription () const;
// A description which does not change and lasts the life of the model.
@@ -55,10 +55,12 @@ GEANT4_DEFINE_MODULE(NAME G4modeling
G4AttValueFilterT.hh
G4AttributeFilterT.hh
G4AxesModel.hh
G4BoundingExtentScene.hh
G4BoundingSphereScene.hh
G4CallbackModel.hh
G4DigiFilterFactories.hh
G4DigiModel.hh
G4ElectricFieldModel.hh
G4GPSModel.hh
G4HitFilterFactories.hh
G4HitsModel.hh
@@ -97,6 +99,7 @@ GEANT4_DEFINE_MODULE(NAME G4modeling
G4TrajectoryParticleFilter.hh
G4TrajectoryEncounteredVolumeFilter.hh
G4VAttValueFilter.hh
G4VFieldModel.hh
G4VModel.hh
G4VModel.icc
G4VModelCommand.hh
@@ -108,9 +111,11 @@ GEANT4_DEFINE_MODULE(NAME G4modeling
G4ArrowModel.cc
G4AttFilterUtils.cc
G4AxesModel.cc
G4BoundingExtentScene.cc
G4BoundingSphereScene.cc
G4DigiFilterFactories.cc
G4DigiModel.cc
G4ElectricFieldModel.cc
G4GPSModel.cc
G4HitFilterFactories.cc
G4HitsModel.cc
@@ -141,6 +146,7 @@ GEANT4_DEFINE_MODULE(NAME G4modeling
G4TrajectoryOriginVolumeFilter.cc
G4TrajectoryParticleFilter.cc
G4TrajectoryEncounteredVolumeFilter.cc
G4VFieldModel.cc
G4VModel.cc
G4VTrajectoryModel.cc
G4VisTrajContext.cc
@@ -35,11 +35,12 @@
#include "G4VGraphicsScene.hh"
#include "G4VisAttributes.hh"
#include "G4Tubs.hh"
#include "G4GenericPolycone.hh"
#include "G4Tet.hh"
#include "G4Polyhedron.hh"
#include "G4Vector3D.hh"
#include "G4Point3D.hh"
#include "G4Transform3D.hh"
#include "G4GeometryTolerance.hh"
G4ArrowModel::~G4ArrowModel ()
{
@@ -53,6 +54,8 @@ G4ArrowModel::G4ArrowModel
G4double width, const G4Colour& colour,
const G4String& description,
G4int lineSegmentsPerCircle)
: fpShaftPolyhedron(nullptr)
, fpHeadPolyhedron(nullptr)
{
fType = "G4ArrowModel";
fGlobalTag = fType;
@@ -71,28 +74,33 @@ G4ArrowModel::G4ArrowModel
// Make a cylinder slightly shorter than the arrow length so that it
// doesn't stick out of the head.
const G4double shaftLength = std::sqrt
const G4double tolerance = G4GeometryTolerance::GetInstance()->GetRadialTolerance();
G4double shaftLength = std::sqrt
(std::pow(x2-x1,2)+std::pow(y2-y1,2)+std::pow(z2-z1,2));
if (shaftLength < tolerance) shaftLength = tolerance;
G4double shaftRadius = width/2.;
// Limit the radius
if (shaftRadius > shaftLength/100.) shaftRadius = shaftLength/100.;
if (shaftRadius < tolerance) shaftRadius = tolerance;
const G4double halfShaftLength = shaftLength/2.;
const G4double halfReduction = 4.*shaftRadius;
const G4double halfLength = halfShaftLength-halfReduction;
G4Tubs shaft("shaft",0.,shaftRadius,halfLength,0.,twopi);
G4double halfLength = halfShaftLength - halfReduction;
if (halfLength < tolerance) halfLength = tolerance;
const G4Tubs shaft("shaft",0.,shaftRadius,halfLength,0.,twopi);
fpShaftPolyhedron = shaft.CreatePolyhedron();
// Move it a little so that the tail is at z = -halfShaftLength.
fpShaftPolyhedron->Transform(G4Translate3D(0,0,-halfReduction));
if (fpShaftPolyhedron)
fpShaftPolyhedron->Transform(G4Translate3D(0,0,-halfReduction));
// Locate the head at +halfShaftLength.
const G4int numRZ = 3;
G4double r[] = {0,4,0};
G4double z[] = {0,-6,-4};
for (G4int i = 0; i < numRZ; i++) {
r[i] *= 2.*shaftRadius;
z[i] = halfShaftLength + z[i] * 2.*shaftRadius;
}
G4GenericPolycone head("head",0,twopi,numRZ,r,z);
const G4double zHi = halfShaftLength;
const G4double zLow = halfShaftLength - 12.*shaftRadius;
const G4double rExt = 8. * shaftRadius;
const G4double xExt = std::sqrt(3.)*rExt/2.;
const G4Tet head("head",
G4ThreeVector(0.,0.,zHi),
G4ThreeVector(0.,rExt,zLow),
G4ThreeVector(xExt,-rExt/2.,zLow),
G4ThreeVector(-xExt,-rExt/2.,zLow));
fpHeadPolyhedron = head.CreatePolyhedron();
// Transform to position
@@ -102,14 +110,14 @@ G4ArrowModel::G4ArrowModel
const G4Point3D arrowCentre(0.5*(x1+x2),0.5*(y1+y2),0.5*(z1+z2));
const G4Transform3D tr =
G4Translate3D(arrowCentre) * G4RotateZ3D(phi) * G4RotateY3D(theta);
fpShaftPolyhedron->Transform(tr);
fpHeadPolyhedron->Transform(tr);
if (fpShaftPolyhedron) fpShaftPolyhedron->Transform(tr);
if (fpHeadPolyhedron) fpHeadPolyhedron->Transform(tr);
G4VisAttributes va;
va.SetColour(colour);
va.SetForceSolid(true);
fpShaftPolyhedron->SetVisAttributes(va);
fpHeadPolyhedron->SetVisAttributes(va);
if (fpShaftPolyhedron) fpShaftPolyhedron->SetVisAttributes(va);
if (fpHeadPolyhedron) fpHeadPolyhedron->SetVisAttributes(va);
// Restore number of line segments per circle
G4Polyhedron::SetNumberOfRotationSteps(tempN);
@@ -118,7 +126,7 @@ G4ArrowModel::G4ArrowModel
void G4ArrowModel::DescribeYourselfTo (G4VGraphicsScene& sceneHandler)
{
sceneHandler.BeginPrimitives();
sceneHandler.AddPrimitive(*fpShaftPolyhedron);
sceneHandler.AddPrimitive(*fpHeadPolyhedron);
if (fpShaftPolyhedron) sceneHandler.AddPrimitive(*fpShaftPolyhedron);
if (fpHeadPolyhedron) sceneHandler.AddPrimitive(*fpHeadPolyhedron);
sceneHandler.EndPrimitives();
}
@@ -0,0 +1,80 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
//
// John Allison 15th February 2019
// An artificial scene to reuse G4VScene code to calculate a bounding extent.
#include "G4BoundingExtentScene.hh"
#include "G4VSolid.hh"
#include "G4PhysicalVolumeModel.hh"
G4BoundingExtentScene::G4BoundingExtentScene (G4VModel* pModel)
:fpModel(pModel)
{}
G4BoundingExtentScene::~G4BoundingExtentScene () {}
void G4BoundingExtentScene::ProcessVolume(const G4VSolid& solid)
{
G4VisExtent newExtent = solid.GetExtent ();
if (fpCurrentObjectTransformation) {
newExtent.Transform (*fpCurrentObjectTransformation);
}
AccrueBoundingExtent (newExtent);
// Curtail descent - can assume daughters are contained within mother...
G4PhysicalVolumeModel* pPVM = dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
if (pPVM) pPVM->CurtailDescent();
}
void G4BoundingExtentScene::ResetBoundingExtent ()
{
fExtent = G4VisExtent();
fpCurrentObjectTransformation = 0;
}
void G4BoundingExtentScene::AccrueBoundingExtent (const G4VisExtent& newExtent)
{
if (fExtent == G4VisExtent()) { // First time.
fExtent = newExtent;
} else {
if (newExtent.GetXmin() < fExtent.GetXmin()) fExtent.SetXmin(newExtent.GetXmin());
if (newExtent.GetYmin() < fExtent.GetYmin()) fExtent.SetYmin(newExtent.GetYmin());
if (newExtent.GetZmin() < fExtent.GetZmin()) fExtent.SetZmin(newExtent.GetZmin());
if (newExtent.GetXmax() > fExtent.GetXmax()) fExtent.SetXmax(newExtent.GetXmax());
if (newExtent.GetYmax() > fExtent.GetYmax()) fExtent.SetYmax(newExtent.GetYmax());
if (newExtent.GetZmax() > fExtent.GetZmax()) fExtent.SetZmax(newExtent.GetZmax());
}
}
@@ -24,10 +24,30 @@
// ********************************************************************
//
//
//
//
// Michael Kelsey 31st January 2019 -- Adapted from new G4MagneticFieldModel
//
// Class Description:
//
// Model that knows how to draw the electric field.
// Base class for visualization commands - John Allison 9th August 1998
// It is really a messenger - we have one command per messenger.
#include "G4ElectricFieldModel.hh"
#include "G4Field.hh"
#include "G4Point3D.hh"
inline void G4VVisCommand::SetVisManager (G4VisManager* pVisManager) {
fpVisManager = pVisManager;
// Return electric field vector for display
void G4ElectricFieldModel::
GetFieldAtLocation(const G4Field* field, const G4Point3D& position,
G4double time, G4Point3D& result) const {
if (!field) return; // No action if no field
G4double xyzt[4] = { position.x(), position.y(), position.z(), time };
G4double BEvals[6] = {0.}; // Field returns {Bx,By,Bz,Ex,Ey,Ez}
field->GetFieldValue(xyzt, BEvals);
result.set(BEvals[3], BEvals[4], BEvals[5]);
return;
}
@@ -34,6 +34,8 @@
#include "G4VSolid.hh"
#include "G4LogicalVolume.hh"
#include "G4PVPlacement.hh"
#include "G4PVParameterised.hh"
#include "G4VPVParameterisation.hh"
#include "G4ModelingParameters.hh"
#include "G4VGraphicsScene.hh"
#include "G4DrawVoxels.hh"
@@ -86,53 +88,35 @@ G4LogicalVolumeModel::G4LogicalVolumeModel
G4LogicalVolumeModel::~G4LogicalVolumeModel () {}
namespace {
// Keep a vector of solid-transform pairs to avoid duplication.
typedef std::pair<G4VSolid*,G4Transform3D> solidTransformPair;
std::vector<solidTransformPair> solidTransformVector;
void drawSolidsAndPoint
// Vis attributes
const G4Colour highlightSolidColour(1.0,0.8,0.8);
const G4double highlightSolidLineWidth(10./*pixels*/);
const G4Colour highlightPointColour(0.5,0.5,1.0);
const G4double highlightPointDiameter(20./*pixels*/);
// Keep a vector of solid-copy number pairs to avoid duplication.
typedef std::pair<G4VSolid*,G4int> solidCopyNoPair;
std::vector<solidCopyNoPair> solidCopyNoVector;
void DrawSolid
(G4VGraphicsScene& sceneHandler,
const G4ThreeVector& point,
G4VSolid* sol1, const G4Transform3D& t1,
G4VSolid* sol2, const G4Transform3D& t2)
{
const G4Colour highlightSolidColour(1.0,0.8,0.8);
const G4double highlightSolidLineWidth(10./*pixels*/);
const G4Colour highlightPointColour(0.5,0.5,1.0);
const G4double highlightPointDiameter(20./*pixels*/);
// Draw first solid. Avoid duplication.
std::pair<G4VSolid*,G4Transform3D> pair1(sol1,t1);
auto iter1 = solidTransformVector.begin();
for ( ; iter1 != solidTransformVector.end(); ++iter1) {
if (iter1->first == pair1.first &&
iter1->second == pair1.second) break;
G4VSolid* sol, G4int copyNo, const G4Transform3D& t) {
// Avoid duplication.
std::pair<G4VSolid*,G4int> pair(sol,copyNo);
auto iter = solidCopyNoVector.begin();
for ( ; iter != solidCopyNoVector.end(); ++iter) {
if (*iter == pair) break;
}
if (iter1 == solidTransformVector.end()) {
solidTransformVector.push_back(pair1);
if (iter == solidCopyNoVector.end()) {
solidCopyNoVector.push_back(pair);
G4VisAttributes highlightSolidVisAtts(highlightSolidColour);
highlightSolidVisAtts.SetLineWidth(highlightSolidLineWidth);
sceneHandler.PreAddSolid(t1,highlightSolidVisAtts);
sceneHandler.AddSolid(*sol1);
sceneHandler.PreAddSolid(t,highlightSolidVisAtts);
sceneHandler.AddSolid(*sol);
sceneHandler.PostAddSolid();
}
// Draw second solid. Avoid duplication.
std::pair<G4VSolid*,G4Transform3D> pair2(sol2,t2);
auto iter2 = solidTransformVector.begin();
for ( ; iter2 != solidTransformVector.end(); ++iter2) {
if (iter2->first == pair2.first &&
iter2->second == pair2.second) break;
}
if (iter2 == solidTransformVector.end()) {
solidTransformVector.push_back(pair2);
G4VisAttributes highlightSolidVisAtts(highlightSolidColour);
highlightSolidVisAtts.SetLineWidth(highlightSolidLineWidth);
sceneHandler.PreAddSolid(t2,highlightSolidVisAtts);
sceneHandler.AddSolid(*sol2);
sceneHandler.PostAddSolid();
}
// Draw points. Draw them all.
}
void DrawPoint
(G4VGraphicsScene& sceneHandler,
const G4ThreeVector& point) {
G4VisAttributes highlightPointVisAtts(highlightPointColour);
G4Circle overlapPoint;
overlapPoint.SetVisAttributes(highlightPointVisAtts);
@@ -207,38 +191,95 @@ void G4LogicalVolumeModel::DescribeYourselfTo
fOverlapsPrinted = true;
}
// Draw overlaps. This algorithm is based on G4PVPlacement::CheckOverlaps.
solidTransformVector.clear();
// Draw overlaps
solidCopyNoVector.clear();
for (G4int iDaughter = 0; iDaughter < nDaughters; ++iDaughter) {
G4VPhysicalVolume* daughterPhys = motherLog->GetDaughter(iDaughter);
// Replicas and paramaterisations not presently processed
if (!dynamic_cast<G4PVPlacement*>(daughterPhys)) continue;
G4AffineTransform tDaughter(daughterPhys->GetRotation(),daughterPhys->GetTranslation());
G4VSolid* daughterSolid = daughterPhys->GetLogicalVolume()->GetSolid();
const G4int nTrials = 1000;
for (G4int i = 0; i < nTrials; ++i) {
G4ThreeVector p = daughterSolid->GetPointOnSurface();
// Transform to mother's coordinate system
G4ThreeVector pMother = tDaughter.TransformPoint(p);
// Check overlaps with the mother volume
if (motherSolid->Inside(pMother)==kOutside) {
// Draw mother and daughter and point
drawSolidsAndPoint
(sceneHandler,pMother,motherSolid,G4Transform3D(),daughterSolid,tDaughter);
G4PVPlacement* daughterPVPlace = dynamic_cast<G4PVPlacement*>(daughterPhys);
G4PVParameterised* daughterPVParam = dynamic_cast<G4PVParameterised*>(daughterPhys);
const G4int nPoints = 1000;
if (daughterPVPlace) {
// This algorithm is based on G4PVPlacement::CheckOverlaps.
G4AffineTransform tDaughter(daughterPhys->GetRotation(),daughterPhys->GetTranslation());
G4VSolid* daughterSolid = daughterPhys->GetLogicalVolume()->GetSolid();
for (G4int i = 0; i < nPoints; ++i) {
G4ThreeVector point = daughterSolid->GetPointOnSurface();
// Transform to mother's coordinate system
G4ThreeVector motherPoint = tDaughter.TransformPoint(point);
// Check overlaps with the mother volume
if (motherSolid->Inside(motherPoint)==kOutside) {
// Draw mother and daughter and point
DrawSolid(sceneHandler,motherSolid,0,G4Transform3D());
DrawSolid(sceneHandler,daughterSolid,daughterPhys->GetCopyNo(),tDaughter);
DrawPoint(sceneHandler,motherPoint);
}
// Check other daughters
for (G4int iSister = 0; iSister < nDaughters; ++iSister) {
if (iSister == iDaughter) continue;
G4VPhysicalVolume* sisterPhys = motherLog->GetDaughter(iSister);
G4AffineTransform tSister(sisterPhys->GetRotation(),sisterPhys->GetTranslation());
// Transform to sister's coordinate system
G4ThreeVector sisterPoint = tSister.InverseTransformPoint(motherPoint);
G4LogicalVolume* sisterLog = sisterPhys->GetLogicalVolume();
G4VSolid* sisterSolid = sisterLog->GetSolid();
if (sisterSolid->Inside(sisterPoint)==kInside) {
// Draw daughter and sister and point
DrawSolid(sceneHandler,daughterSolid,daughterPhys->GetCopyNo(),tDaughter);
DrawSolid(sceneHandler,sisterSolid,sisterPhys->GetCopyNo(),tSister);
DrawPoint(sceneHandler,motherPoint);
}
}
}
// Check other daughters
for (G4int iSister = 0; iSister < nDaughters; ++iSister) {
if (iSister == iDaughter) continue;
G4VPhysicalVolume* sisterPhys = motherLog->GetDaughter(iSister);
G4AffineTransform tSister(sisterPhys->GetRotation(),sisterPhys->GetTranslation());
// Transform to sister's coordinate system
G4ThreeVector pSister = tSister.InverseTransformPoint(pMother);
G4LogicalVolume* sisterLog = sisterPhys->GetLogicalVolume();
G4VSolid* sisterSolid = sisterLog->GetSolid();
if (sisterSolid->Inside(pSister)==kInside) {
// Draw daughter and sister and point
drawSolidsAndPoint
(sceneHandler,pMother,daughterSolid,tDaughter,sisterSolid,tSister);
} else if (daughterPVParam) {
// This algorithm is based on G4PVParameterised::CheckOverlaps
const G4int multiplicity = daughterPVParam->GetMultiplicity();
auto* param = daughterPVParam->GetParameterisation();
// Cache points for later checking against other parameterisations
std::vector<G4ThreeVector> motherPoints;
for (G4int iP = 0; iP < multiplicity; iP++) {
G4VSolid* daughterSolid = param->ComputeSolid(iP, daughterPhys);
daughterSolid->ComputeDimensions(param, iP, daughterPhys);
param->ComputeTransformation(iP, daughterPhys);
G4AffineTransform tDaughter(daughterPVParam->GetRotation(),daughterPVParam->GetTranslation());
for (G4int i = 0; i < nPoints; ++i) {
G4ThreeVector point = daughterSolid->GetPointOnSurface();
// Transform to mother's coordinate system
G4ThreeVector motherPoint = tDaughter.TransformPoint(point);
// Check overlaps with the mother volume
if (motherSolid->Inside(motherPoint)==kOutside) {
// Draw mother and daughter and point
DrawSolid(sceneHandler,motherSolid,0,G4Transform3D());
DrawSolid(sceneHandler,daughterSolid,iP,tDaughter);
DrawPoint(sceneHandler,motherPoint);
}
motherPoints.push_back(motherPoint);
}
// Check sister parameterisations
for (G4int iPP = iP + 1; iPP < multiplicity; iPP++) {
G4VSolid* sisterSolid = param->ComputeSolid(iPP, daughterPhys);
sisterSolid->ComputeDimensions(param, iPP, daughterPhys);
param->ComputeTransformation(iPP, daughterPhys);
G4AffineTransform tSister
(daughterPVParam->GetRotation(),daughterPVParam->GetTranslation());
for (const auto& motherPoint: motherPoints) {
// Transform each point into daughter's frame
G4ThreeVector sisterPoint = tSister.InverseTransformPoint(motherPoint);
if (sisterSolid->Inside(sisterPoint)==kInside) {
// Draw sister
DrawSolid(sceneHandler,sisterSolid,iPP,tSister);
// Recompute daughter parameterisation before drawing
daughterSolid->ComputeDimensions(param, iP, daughterPhys);
param->ComputeTransformation(iP, daughterPhys);
tDaughter = G4AffineTransform
(daughterPVParam->GetRotation(),daughterPVParam->GetTranslation());
DrawSolid(sceneHandler,daughterSolid,iP,tDaughter);
DrawPoint(sceneHandler,motherPoint);
}
}
}
}
}
@@ -27,262 +27,28 @@
//
//
// John Allison 17th August 2013
// Michael Kelsey 31st January 2019 -- Move functionality to G4VFieldModel
//
// Class Description:
//
// Model that knows how to draw the magnetic field.
#include "G4MagneticFieldModel.hh"
#include "G4VGraphicsScene.hh"
#include "G4TransportationManager.hh"
#include "G4FieldManager.hh"
#include "G4Field.hh"
#include "G4Colour.hh"
#include "G4VPhysicalVolume.hh"
#include "G4ArrowModel.hh"
#include "G4Polyline.hh"
#include "G4VisAttributes.hh"
#include "G4SystemOfUnits.hh"
#include "G4Point3D.hh"
#include <sstream>
#include <limits>
#include <vector>
G4MagneticFieldModel::~G4MagneticFieldModel () {}
// Return magnetic field vector for display
G4MagneticFieldModel::G4MagneticFieldModel
(G4int nDataPointsPerMaxHalfScene,
Representation representation,
G4int arrow3DLineSegmentsPerCircle)
: fNDataPointsPerMaxHalfScene(nDataPointsPerMaxHalfScene)
, fRepresentation(representation)
, fArrow3DLineSegmentsPerCircle(arrow3DLineSegmentsPerCircle)
{
fType = "G4MagneticFieldModel";
fGlobalTag = fType;
std::ostringstream oss;
oss << ':' << fNDataPointsPerMaxHalfScene
<< ':' << fArrow3DLineSegmentsPerCircle;
if (fRepresentation == Representation::fullArrow) {
oss << " full arrow";
} else if (fRepresentation == Representation::lightArrow) {
oss << " light arrow";
}
fGlobalDescription = fType + oss.str();
}
void G4MagneticFieldModel::DescribeYourselfTo (G4VGraphicsScene& sceneHandler)
{
// G4cout << "G4MagneticFieldModel::DescribeYourselfTo" << G4endl;
const G4VisExtent& extent = sceneHandler.GetExtent();
const G4double xMin = extent.GetXmin();
const G4double yMin = extent.GetYmin();
const G4double zMin = extent.GetZmin();
const G4double xMax = extent.GetXmax();
const G4double yMax = extent.GetYmax();
const G4double zMax = extent.GetZmax();
const G4double xHalfScene = 0.5 * (xMax - xMin);
const G4double yHalfScene = 0.5 * (yMax - yMin);
const G4double zHalfScene = 0.5 * (zMax - zMin);
const G4double xSceneCentre = 0.5 * (xMax + xMin);
const G4double ySceneCentre = 0.5 * (yMax + yMin);
const G4double zSceneCentre = 0.5 * (zMax + zMin);
const G4double maxHalfScene =
std::max(xHalfScene,std::max(yHalfScene,zHalfScene));
if (maxHalfScene <= 0.) {
G4cout
<< "Extent non-positive."
<< G4endl;
return;
}
G4TransportationManager* tMgr =
G4TransportationManager::GetTransportationManager();
assert(tMgr);
G4Navigator* navigator = tMgr->GetNavigatorForTracking();
assert(navigator);
G4FieldManager* globalFieldMgr = tMgr->GetFieldManager();
const G4Field* globalField = 0;
const G4String intro = "G4MagneticFieldModel::DescribeYourselfTo: ";
if (globalFieldMgr) {
if (globalFieldMgr->DoesFieldExist()) {
globalField = globalFieldMgr->GetDetectorField();
if (!globalField) {
static G4bool warned = false;
if (!warned) {
G4cout << intro
<< "Null global field pointer."
<< G4endl;
warned = true;
}
}
}
} else {
static G4bool warned = false;
if (!warned) {
G4cout << intro
<< "No global field manager."
<< G4endl;
warned = true;
}
}
// Constants
const G4double interval = maxHalfScene / fNDataPointsPerMaxHalfScene;
const G4int nDataPointsPerXHalfScene = G4int(xHalfScene / interval);
const G4int nDataPointsPerYHalfScene = G4int(yHalfScene / interval);
const G4int nDataPointsPerZHalfScene = G4int(zHalfScene / interval);
const G4int nXSamples = 2 * nDataPointsPerXHalfScene + 1;
const G4int nYSamples = 2 * nDataPointsPerYHalfScene + 1;
const G4int nZSamples = 2 * nDataPointsPerZHalfScene + 1;
const G4int nSamples = nXSamples * nYSamples * nZSamples;
const G4int nSamples3 = nSamples * 3;
const G4double arrowLengthMax = 0.8 * interval;
const G4int nResults = 6; // 3 B-field + 3 E-field.
// Working space for GetFieldValue.
double position_time[4] = {0,0,0,0};
double result[nResults];
// Working vectors for field values, etc.
std::vector<G4double> BField(nSamples3); // Initialises to zero.
std::vector<G4double> BFieldMagnitude(nSamples); // Initialises to zero.
std::vector<G4double> xyz(nSamples3); // Initialises to zero.
// Get field values and ascertain maximum field.
G4double BFieldMagnitudeMax = -std::numeric_limits<G4double>::max();
for (G4int i = 0; i < nXSamples; i++) {
G4double x = xSceneCentre + (i - nDataPointsPerXHalfScene) * interval;
position_time[0] = x;
for (G4int j = 0; j < nYSamples; j++) {
G4double y = ySceneCentre + (j - nDataPointsPerYHalfScene) * interval;
position_time[1] = y;
for (G4int k = 0; k < nZSamples; k++) {
G4double z = zSceneCentre + (k - nDataPointsPerZHalfScene) * interval;
position_time[2] = z;
// Calculate indices into working vectors
const G4int ijk = i * nYSamples * nZSamples + j * nZSamples + k;
const G4int ijk3 = ijk * 3;
// Find volume at this location.
G4ThreeVector pos(x,y,z);
const G4VPhysicalVolume* pPV =
navigator->LocateGlobalPointAndSetup(pos,0,false,true);
const G4Field* field = globalField;
if (pPV) {
// Get logical volume.
const G4LogicalVolume* pLV = pPV->GetLogicalVolume();
if (pLV) {
// Value for Region, if any, overrides
G4Region* pRegion = pLV->GetRegion();
if (pRegion) {
G4FieldManager* pRegionFieldMgr = pRegion->GetFieldManager();
if (pRegionFieldMgr) {
field = pRegionFieldMgr->GetDetectorField();
// G4cout << "Region with field" << G4endl;
}
}
// 'Local' value from logical volume, if any, overrides
G4FieldManager* pLVFieldMgr = pLV->GetFieldManager();
if (pLVFieldMgr) {
field = pLVFieldMgr->GetDetectorField();
// G4cout << "Logical volume with field" << G4endl;
}
}
}
// If field found, get values and store in working vectors.
if (field) {
// Get field values in result array.
field->GetFieldValue(position_time,result);
// G4cout
// << "BField/T:"
// << " " << result[0]/tesla
// << " " << result[1]/tesla
// << " " << result[2]/tesla
// << G4endl;
// Store B-field components.
for (G4int l = 0; l < 3; l++) {
BField[ijk3 + l] = result[l];
}
// Calculate magnitude and store.
G4double mag = sqrt
(result[0]*result[0]+result[1]*result[1]+result[2]*result[2]);
BFieldMagnitude[ijk] = mag;
// Store position.
xyz[ijk3] = x;
xyz[ijk3 + 1] = y;
xyz[ijk3 + 2] = z;
// Find maximum field magnitude.
if (mag > BFieldMagnitudeMax) {
BFieldMagnitudeMax = mag;
}
}
}
}
}
if (BFieldMagnitudeMax <= 0) {
G4cout
<< "No field in this scene."
<< G4endl;
return;
}
if (fRepresentation == Representation::lightArrow) sceneHandler.BeginPrimitives();
for (G4int i = 0; i < nSamples; i++) {
if (BFieldMagnitude[i] > 0) {
const G4int i3 = i * 3;
// Field (Bx,By,Bz) at (x,y,z).
const G4double Bx = BField[i3];
const G4double By = BField[i3 + 1];
const G4double Bz = BField[i3 + 2];
const G4double x = xyz[i3];
const G4double y = xyz[i3 + 1];
const G4double z = xyz[i3 + 2];
const G4double B = BFieldMagnitude[i];
// G4cout
// << "Position/mm, BField/T unpacked:"
// << ' ' << x/mm
// << ' ' << y/mm
// << ' ' << z/mm
// << " " << Bx/tesla
// << " " << By/tesla
// << " " << Bz/tesla
// << G4endl;
if (B > 0.) {
const G4double f = B / BFieldMagnitudeMax;
G4double red = 0., green = 0., blue = 0., alpha = 1.;
if (f < 0.5) { // Linear colour scale: 0->0.5->1 is blue->green->red.
green = 2. * f;
blue = 2. * (0.5 - f);
} else {
red = 2. * (f - 0.5);
green = 2. * (1.0 - f);
}
const G4Colour arrowColour(red,green,blue,alpha);
const G4double arrowLength = arrowLengthMax * f;
// Base of arrow is at (x,y,z).
const G4double& x1 = x;
const G4double& y1 = y;
const G4double& z1 = z;
// Head of arrow depends on field direction and strength.
const G4double x2 = x1 + arrowLength * Bx / B;
const G4double y2 = y1 + arrowLength * By / B;
const G4double z2 = z1 + arrowLength * Bz / B;
if (fRepresentation == Representation::fullArrow) {
G4ArrowModel BArrow(x1,y1,z1,x2,y2,z2,arrowLength/5,arrowColour,
"BField",
fArrow3DLineSegmentsPerCircle);
BArrow.DescribeYourselfTo(sceneHandler);
} else if (fRepresentation == Representation::lightArrow) {
G4Polyline BArrowLite;
G4VisAttributes va(arrowColour);
BArrowLite.SetVisAttributes(va);
BArrowLite.push_back(G4Point3D(x1,y1,z1));
BArrowLite.push_back(G4Point3D(x2,y2,z2));
sceneHandler.AddPrimitive(BArrowLite);
}
}
}
}
if (fRepresentation == Representation::lightArrow) sceneHandler.EndPrimitives();
void G4MagneticFieldModel::
GetFieldAtLocation(const G4Field* field, const G4Point3D& position,
G4double time, G4Point3D& result) const {
if (!field) return; // No action if no field
G4double xyzt[4] = { position.x(), position.y(), position.z(), time };
G4double BEvals[6] = {0.}; // Field returns {Bx,By,Bz,Ex,Ey,Ez}
field->GetFieldValue(xyzt, BEvals);
result.set(BEvals[0], BEvals[1], BEvals[2]);
return;
}
@@ -36,6 +36,7 @@
#include "G4ExceptionSeverity.hh"
#include "G4SystemOfUnits.hh"
#include "G4VSolid.hh"
#include "G4DisplacedSolid.hh"
#include "G4VPhysicalVolume.hh"
#include "G4PhysicalVolumeModel.hh"
#include "G4UnitsTable.hh"
@@ -44,6 +45,7 @@ G4ModelingParameters::G4ModelingParameters ():
fWarning (true),
fpDefaultVisAttributes (0),
fDrawingStyle (wf),
fNumberOfCloudPoints (10000),
fCulling (false),
fCullInvisible (false),
fDensityCulling (false),
@@ -70,12 +72,13 @@ G4ModelingParameters::G4ModelingParameters
fWarning (true),
fpDefaultVisAttributes (pDefaultVisAttributes),
fDrawingStyle (drawingStyle),
fNumberOfCloudPoints (10000),
fCulling (isCulling),
fCullInvisible (isCullingInvisible),
fDensityCulling (isDensityCulling),
fVisibleDensity (visibleDensity),
fCullCovered (isCullingCovered),
fCBDAlgorithmNumber(0),
fCBDAlgorithmNumber (0),
fExplodeFactor (1.),
fNoOfSides (noOfSides),
fpSectionSolid (0),
@@ -140,13 +143,13 @@ G4int G4ModelingParameters::SetNoOfSides (G4int nSides) {
}
void G4ModelingParameters::SetSectionSolid
(G4VSolid* pSectionSolid) {
(G4DisplacedSolid* pSectionSolid) {
delete fpSectionSolid;
fpSectionSolid = pSectionSolid;
}
void G4ModelingParameters::SetCutawaySolid
(G4VSolid* pCutawaySolid) {
(G4DisplacedSolid* pCutawaySolid) {
delete fpCutawaySolid;
fpCutawaySolid = pCutawaySolid;
}
@@ -165,17 +168,21 @@ std::ostream& operator << (std::ostream& os, const G4ModelingParameters& mp)
os << "\n Current requested drawing style: ";
switch (mp.fDrawingStyle) {
case G4ModelingParameters::wf:
os << "wireframe"; break;
case G4ModelingParameters::hlr:
os << "hidden line removal (hlr)"; break;
case G4ModelingParameters::hsr:
os << "surface (hsr)"; break;
case G4ModelingParameters::hlhsr:
os << "surface and edges (hlhsr)"; break;
default: os << "unrecognised"; break;
case G4ModelingParameters::wf:
os << "wireframe"; break;
case G4ModelingParameters::hlr:
os << "hidden line removal (hlr)"; break;
case G4ModelingParameters::hsr:
os << "surface (hsr)"; break;
case G4ModelingParameters::hlhsr:
os << "surface and edges (hlhsr)"; break;
case G4ModelingParameters::cloud:
os << "cloud"; break;
default: os << "unrecognised"; break;
}
os << "\n Number of cloud points: " << mp.fNumberOfCloudPoints;
os << "\n Culling: ";
if (mp.fCulling) os << "on";
else os << "off";
@@ -211,11 +218,11 @@ std::ostream& operator << (std::ostream& os, const G4ModelingParameters& mp)
os << "\n No. of sides used in circle polygon approximation: "
<< mp.fNoOfSides;
os << "\n Section (DCUT) shape (G4VSolid) pointer: ";
os << "\n Section (DCUT) shape (G4DisplacedSolid) pointer: ";
if (!mp.fpSectionSolid) os << "non-";
os << "null";
os << "\n Cutaway (DCUT) shape (G4VSolid) pointer: ";
os << "\n Cutaway (DCUT) shape (G4DisplacedSolid) pointer: ";
if (!mp.fpCutawaySolid) os << "non-";
os << "null";
@@ -239,6 +246,8 @@ G4bool G4ModelingParameters::operator !=
if (
(fWarning != mp.fWarning) ||
(*fpDefaultVisAttributes != *mp.fpDefaultVisAttributes) ||
(fDrawingStyle != mp.fDrawingStyle) ||
(fNumberOfCloudPoints != mp.fNumberOfCloudPoints) ||
(fCulling != mp.fCulling) ||
(fCullInvisible != mp.fCullInvisible) ||
(fDensityCulling != mp.fDensityCulling) ||
@@ -295,13 +304,15 @@ G4bool G4ModelingParameters::VisAttributesModifier::operator!=
return true;
break;
case G4ModelingParameters::VASForceWireframe:
case G4ModelingParameters::VASForceSolid:
case G4ModelingParameters::VASForceCloud:
if (fVisAtts.GetForcedDrawingStyle() !=
rhs.fVisAtts.GetForcedDrawingStyle())
return true;
break;
case G4ModelingParameters::VASForceSolid:
if (fVisAtts.GetForcedDrawingStyle() !=
rhs.fVisAtts.GetForcedDrawingStyle())
case G4ModelingParameters::VASForceNumberOfCloudPoints:
if (fVisAtts.GetForcedNumberOfCloudPoints() !=
rhs.fVisAtts.GetForcedNumberOfCloudPoints())
return true;
break;
case G4ModelingParameters::VASForceAuxEdgeVisible:
@@ -331,13 +342,18 @@ G4bool G4ModelingParameters::PVNameCopyNo::operator!=
std::ostream& operator <<
(std::ostream& os, const G4ModelingParameters::PVNameCopyNoPath& path)
{
os << "Touchable path: physical-volume-name:copy-number pairs:\n ";
G4ModelingParameters::PVNameCopyNoPathConstIterator i;
for (i = path.begin(); i != path.end(); ++i) {
if (i != path.begin()) {
os << ',';
os << "Touchable path: ";
if (path.empty()) {
os << "empty";
} else {
os << "physical-volume-name:copy-number pairs:\n ";
G4ModelingParameters::PVNameCopyNoPathConstIterator i;
for (i = path.begin(); i != path.end(); ++i) {
if (i != path.begin()) {
os << ',';
}
os << i->GetName() << ':' << i->GetCopyNo();
}
os << i->GetName() << ':' << i->GetCopyNo();
}
return os;
}
@@ -440,6 +456,20 @@ std::ostream& operator <<
}
}
break;
case G4ModelingParameters::VASForceCloud:
if (vamVisAtts.GetForcedDrawingStyle() == G4VisAttributes::cloud) {
os << " forceCloud ";
if (vamVisAtts.IsForceDrawingStyle()) {
os << "true";
} else {
os << "false";
}
}
break;
case G4ModelingParameters::VASForceNumberOfCloudPoints:
os << " numberOfCloudPoints "
<< vamVisAtts.GetForcedNumberOfCloudPoints();
break;
case G4ModelingParameters::VASForceAuxEdgeVisible:
os << " forceAuxEdgeVisible: ";
if (!vamVisAtts.IsForceDrawingStyle()) {
@@ -40,7 +40,7 @@
#include "G4IntersectionSolid.hh"
#include "G4Material.hh"
#include "G4VisAttributes.hh"
#include "G4BoundingSphereScene.hh"
#include "G4BoundingExtentScene.hh"
#include "G4PhysicalVolumeSearchScene.hh"
#include "G4TransportationManager.hh"
#include "G4Polyhedron.hh"
@@ -54,6 +54,10 @@
#include <sstream>
#include <iomanip>
namespace {
G4int volumeCount = 0;
}
G4PhysicalVolumeModel::G4PhysicalVolumeModel
(G4VPhysicalVolume* pVPV
, G4int requestedDepth
@@ -63,7 +67,7 @@ G4PhysicalVolumeModel::G4PhysicalVolumeModel
, const std::vector<G4PhysicalVolumeNodeID>& baseFullPVPath)
: G4VModel (modelTransformation,pMP)
, fpTopPV (pVPV)
, fTopPVCopyNo (0)
, fTopPVCopyNo (pVPV? pVPV->GetCopyNo(): 0)
, fRequestedDepth (requestedDepth)
, fUseFullExtent (useFullExtent)
, fCurrentDepth (0)
@@ -126,14 +130,26 @@ G4ModelingParameters::PVNameCopyNoPath G4PhysicalVolumeModel::GetPVNameCopyNoPat
void G4PhysicalVolumeModel::CalculateExtent ()
{
// To handle paramaterisations, set copy number and compute dimensions
// to get extent right
G4VPVParameterisation* pP = fpTopPV -> GetParameterisation ();
if (pP) {
fpTopPV -> SetCopyNo (fTopPVCopyNo);
G4VSolid* solid = pP -> ComputeSolid (fTopPVCopyNo, fpTopPV);
solid -> ComputeDimensions (pP, fTopPVCopyNo, fpTopPV);
}
if (fUseFullExtent) {
fExtent = fpTopPV -> GetLogicalVolume () -> GetSolid () -> GetExtent ();
}
else {
G4BoundingSphereScene bsScene(this);
} else {
// Calculate extent of *drawn* volumes, i.e., ignoring culled, e.g.,
// invisible volumes, by traversing the whole geometry hierarchy below
// this physical volume.
G4BoundingExtentScene beScene(this);
const G4int tempRequestedDepth = fRequestedDepth;
fRequestedDepth = -1; // Always search to all depths to define extent.
const G4Transform3D tempTransform = fTransform;
const G4ModelingParameters* tempMP = fpMP;
fRequestedDepth = -1; // Always search to all depths to define extent.
fTransform = G4Transform3D(); // Extent is in local cooridinates
G4ModelingParameters mParams
(0, // No default vis attributes needed.
G4ModelingParameters::wf, // wireframe (not relevant for this).
@@ -144,23 +160,16 @@ void G4PhysicalVolumeModel::CalculateExtent ()
true, // Cull daughters of opaque mothers.
24); // No of sides (not relevant for this operation).
fpMP = &mParams;
DescribeYourselfTo (bsScene);
G4double radius = bsScene.GetRadius();
if (radius < 0.) { // Nothing in the scene.
fExtent = fpTopPV -> GetLogicalVolume () -> GetSolid () -> GetExtent ();
} else {
// Transform back to coordinates relative to the top
// transformation, which is in G4VModel::fTransform. This makes
// it conform to all models, which are defined by a
// transformation and an extent relative to that
// transformation...
G4Point3D centre = bsScene.GetCentre();
centre.transform(fTransform.inverse());
fExtent = G4VisExtent(centre, radius);
}
DescribeYourselfTo (beScene);
fExtent = beScene.GetBoundingExtent();
fpMP = tempMP;
fTransform = tempTransform;
fRequestedDepth = tempRequestedDepth;
}
G4double radius = fExtent.GetExtentRadius();
if (radius < 0.) { // Nothing in the scene - revert to top extent
fExtent = fpTopPV -> GetLogicalVolume () -> GetSolid () -> GetExtent ();
}
}
void G4PhysicalVolumeModel::DescribeYourselfTo
@@ -176,12 +185,19 @@ void G4PhysicalVolumeModel::DescribeYourselfTo
G4Transform3D startingTransformation = fTransform;
volumeCount = 0;
VisitGeometryAndGetVisReps
(fpTopPV,
fRequestedDepth,
startingTransformation,
sceneHandler);
// G4cout
// << "G4PhysicalVolumeModel::DescribeYourselfTo: volume count: "
// << volumeCount
// << G4endl;
// Reset or clear data...
fCurrentDepth = 0;
fpCurrentPV = fpTopPV;
@@ -245,10 +261,15 @@ void G4PhysicalVolumeModel::VisitGeometryAndGetVisReps
G4double offset;
G4bool consuming;
pVPV -> GetReplicationData (axis, nReplicas, width, offset, consuming);
if (fCurrentDepth == 0) nReplicas = 1; // Just draw first
G4int nBegin = 0;
G4int nEnd = nReplicas;
if (fCurrentDepth == 0) { // i.e., top volume
nBegin = fTopPVCopyNo; // Describe only one volume, namely the one
nEnd = nBegin + 1; // specified by the given copy number.
}
G4VPVParameterisation* pP = pVPV -> GetParameterisation ();
if (pP) { // Parametrised volume.
for (int n = 0; n < nReplicas; n++) {
for (int n = nBegin; n < nEnd; n++) {
pSol = pP -> ComputeSolid (n, pVPV);
pP -> ComputeTransformation (n, pVPV);
pSol -> ComputeDimensions (pP, n, pVPV);
@@ -295,7 +316,7 @@ void G4PhysicalVolumeModel::VisitGeometryAndGetVisReps
originalRMax = ((G4Tubs*)pSol)->GetOuterRadius();
}
G4bool visualisable = true;
for (int n = 0; n < nReplicas; n++) {
for (int n = nBegin; n < nEnd; n++) {
G4ThreeVector translation; // Identity.
G4RotationMatrix rotation; // Identity - life enough for visualizing.
G4RotationMatrix* pRotation = 0;
@@ -464,7 +485,7 @@ void G4PhysicalVolumeModel::DescribeAndDescend
// Initialise it with the current vis atts and reset the pointer.
modifiedVisAtts = *pVisAttribs;
pVisAttribs = &modifiedVisAtts;
const G4VisAttributes& transVisAtts = vam.GetVisAttributes();
const G4VisAttributes& transVisAtts = vam.GetVisAttributes();
switch (vam.GetVisAttributesSignifier()) {
case G4ModelingParameters::VASVisibility:
modifiedVisAtts.SetVisibility(transVisAtts.IsVisible());
@@ -498,6 +519,18 @@ void G4PhysicalVolumeModel::DescribeAndDescend
}
}
break;
case G4ModelingParameters::VASForceCloud:
if (transVisAtts.IsForceDrawingStyle()) {
if (transVisAtts.GetForcedDrawingStyle() ==
G4VisAttributes::cloud) {
modifiedVisAtts.SetForceCloud(true);
}
}
break;
case G4ModelingParameters::VASForceNumberOfCloudPoints:
modifiedVisAtts.SetForceNumberOfCloudPoints
(transVisAtts.GetForcedNumberOfCloudPoints());
break;
case G4ModelingParameters::VASForceAuxEdgeVisible:
if (transVisAtts.IsForceAuxEdgeVisible()) {
modifiedVisAtts.SetForceAuxEdgeVisible
@@ -565,6 +598,7 @@ void G4PhysicalVolumeModel::DescribeAndDescend
theNewAT = centering * newTranslation * oldRotation * oldScale;
}
volumeCount++;
DescribeSolid (theNewAT, pSol, pVisAttribs, sceneHandler);
}
@@ -653,14 +687,14 @@ void G4PhysicalVolumeModel::DescribeSolid
const G4VisAttributes* pVisAttribs,
G4VGraphicsScene& sceneHandler)
{
sceneHandler.PreAddSolid (theAT, *pVisAttribs);
G4VSolid* pSectionSolid = fpMP->GetSectionSolid();
G4VSolid* pCutawaySolid = fpMP->GetCutawaySolid();
G4DisplacedSolid* pSectionSolid = fpMP->GetSectionSolid();
G4DisplacedSolid* pCutawaySolid = fpMP->GetCutawaySolid();
if (!fpClippingSolid && !pSectionSolid && !pCutawaySolid) {
sceneHandler.PreAddSolid (theAT, *pVisAttribs);
pSol -> DescribeYourselfTo (sceneHandler); // Standard treatment.
sceneHandler.PostAddSolid ();
} else {
@@ -672,10 +706,10 @@ void G4PhysicalVolumeModel::DescribeSolid
(pVisAttribs->GetForcedLineSegmentsPerCircle());
else
G4Polyhedron::SetNumberOfRotationSteps(fpMP->GetNoOfSides());
const G4Polyhedron* pOriginal = pSol->GetPolyhedron();
const G4Polyhedron* pOriginalPolyhedron = pSol->GetPolyhedron();
G4Polyhedron::ResetNumberOfRotationSteps();
if (!pOriginal) {
if (!pOriginalPolyhedron) {
if (fpMP->IsWarning())
G4cout <<
@@ -687,57 +721,66 @@ void G4PhysicalVolumeModel::DescribeSolid
} else {
G4Polyhedron resultant(*pOriginal);
G4VisAttributes resultantVisAttribs(*pVisAttribs);
G4VSolid* resultantSolid = 0;
G4VSolid* pResultantSolid = 0;
if (fpClippingSolid) {
switch (fClippingMode) {
default:
case subtraction:
resultantSolid = new G4SubtractionSolid
("resultant_solid", pSol, fpClippingSolid, theAT.inverse());
pResultantSolid = new G4SubtractionSolid
("subtracted_clipped_solid", pSol, fpClippingSolid, theAT.inverse());
break;
case intersection:
resultantSolid = new G4IntersectionSolid
("resultant_solid", pSol, fpClippingSolid, theAT.inverse());
pResultantSolid = new G4IntersectionSolid
("intersected_clipped_solid", pSol, fpClippingSolid, theAT.inverse());
break;
}
}
if (pSectionSolid) {
resultantSolid = new G4IntersectionSolid
pResultantSolid = new G4IntersectionSolid
("sectioned_solid", pSol, pSectionSolid, theAT.inverse());
}
if (pCutawaySolid) {
resultantSolid = new G4SubtractionSolid
// Follow above...
pResultantSolid = new G4SubtractionSolid
("cutaway_solid", pSol, pCutawaySolid, theAT.inverse());
}
G4Polyhedron* tmpResultant = resultantSolid->GetPolyhedron();
if (tmpResultant) resultant = *tmpResultant;
else {
if (fpMP->IsWarning())
G4cout <<
"WARNING: G4PhysicalVolumeModel::DescribeSolid: resultant polyhedron for"
"\n solid \"" << pSol->GetName() <<
"\" not defined due to error during Boolean processing."
"\n Original will be drawn in red."
<< G4endl;
resultantVisAttribs.SetColour(G4Colour::Red());
const G4Polyhedron* pResultantPolyhedron = pResultantSolid->GetPolyhedron();
if (!pResultantPolyhedron) {
if (fpMP->IsWarning())
G4cout <<
"WARNING: G4PhysicalVolumeModel::DescribeSolid: resultant polyhedron for"
"\n solid \"" << pSol->GetName() <<
"\" not defined due to error during Boolean processing."
<< G4endl;
} else {
// It seems that if the sectioning solid does not intersect the
// original solid the Boolean Processor returns the original
// polyhedron, or a copy thereof. We do not want it.
// Check the number of facets, etc. If same, ignore.
// What we need from the Boolean Processor is a null pointer or a
// null polyhedron. It seems to return the original or a copy of it.
if (pResultantPolyhedron->GetNoFacets() == pOriginalPolyhedron->GetNoFacets())
// This works in most cases but I still get a box in test202 with
// /vis/viewer/set/sectionPlane on 0 0 0 m 0.1 0.1 1
{
pResultantPolyhedron = nullptr;
}
}
delete resultantSolid;
if (pResultantPolyhedron) {
// Finally, draw polyhedron...
sceneHandler.BeginPrimitives(theAT);
sceneHandler.AddPrimitive(*pResultantPolyhedron);
sceneHandler.EndPrimitives();
}
// Finally, force polyhedron drawing...
resultant.SetVisAttributes(resultantVisAttribs);
sceneHandler.BeginPrimitives(theAT);
sceneHandler.AddPrimitive(resultant);
sceneHandler.EndPrimitives();
delete pResultantSolid;
}
}
sceneHandler.PostAddSolid ();
}
G4bool G4PhysicalVolumeModel::Validate (G4bool warn)
@@ -953,7 +996,7 @@ std::ostream& operator<<
(std::ostream& os, const std::vector<G4PhysicalVolumeModel::G4PhysicalVolumeNodeID>& path)
{
if (path.empty()) {
os << " NULL PATH";
os << " TOP";
} else {
for (const auto& nodeID: path) {
os << ' ' << nodeID;
@@ -28,8 +28,8 @@
//
// John Allison 5th September 2018, based on G4PhysicalVolumeSearchScene
// An artificial scene to find physical volumes. Instead of returning the
// first occurence (G4PhysicalVolumeSearchScene) this class (note the extra
// 's' in the name of this class) returns a vector of all occurences.
// first occurrence (G4PhysicalVolumeSearchScene) this class (note the extra
// 's' in the name of this class) returns a vector of all occurrences.
#include "G4PhysicalVolumesSearchScene.hh"
@@ -49,6 +49,7 @@ void G4PhysicalVolumesSearchScene::ProcessVolume (const G4VSolid&)
G4VPhysicalVolume* pCurrentPV = fpSearchVolumesModel->GetCurrentPV();
const G4String& name = pCurrentPV->GetName();
G4int copyNo = fpSearchVolumesModel->GetCurrentPVCopyNo();
// Match the name with the required physical volume name. The latter can be of
// the form "/regexp/", where regexp is a regular expression (see C++ regex),
// or a plain name, in which case there must be an exact match.
@@ -66,6 +66,7 @@ void G4TouchablePropertiesScene::ProcessVolume (const G4VSolid& /*solid*/) {
if (iNameCopyNo == fRequiredTouchable.end()) {
fFoundTouchableProperties.fTouchablePath = fRequiredTouchable;
fFoundTouchableProperties.fpTouchablePV = fpSearchPVModel->GetCurrentPV();
fFoundTouchableProperties.fCopyNo = fpSearchPVModel->GetCurrentPVCopyNo();
fFoundTouchableProperties.fTouchableGlobalTransform = *fpSearchPVModel->GetCurrentTransform();
fFoundTouchableProperties.fTouchableBaseFullPVPath = fpSearchPVModel->GetFullPVPath();
// Base path is one down from found PV
@@ -0,0 +1,325 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// Michael Kelsey 31 January 2019
//
// Class Description:
//
// Abstract base class to implement drawing vector field geometries
// (e.g., electric, magnetic or gravity). Implementation extracted
// from G4MagneticFieldModel, with field-value access left pure
// virtual for implementation by base classes.
#include "G4VFieldModel.hh"
#include "G4ArrowModel.hh"
#include "G4Colour.hh"
#include "G4Field.hh"
#include "G4FieldManager.hh"
#include "G4PVPlacement.hh"
#include "G4PVParameterised.hh"
#include "G4Point3D.hh"
#include "G4Polyline.hh"
#include "G4SystemOfUnits.hh"
#include "G4TransportationManager.hh"
#include "G4VGraphicsScene.hh"
#include "G4VPhysicalVolume.hh"
#include "G4VisAttributes.hh"
#include <sstream>
#include <limits>
#include <vector>
// Constructor and destructor
G4VFieldModel::~G4VFieldModel() {;}
G4VFieldModel::G4VFieldModel
(const G4String& typeOfField, const G4String& symbol,
const G4VisExtent& extentForField,
const std::vector<G4PhysicalVolumesSearchScene::Findings>& pvFindings,
G4int nDataPointsPerMaxHalfScene,
Representation representation,
G4int arrow3DLineSegmentsPerCircle)
: fExtentForField(extentForField)
, fPVFindings(pvFindings)
, fNDataPointsPerMaxHalfScene(nDataPointsPerMaxHalfScene)
, fRepresentation(representation)
, fArrow3DLineSegmentsPerCircle(arrow3DLineSegmentsPerCircle)
, fTypeOfField(typeOfField)
, fArrowPrefix(symbol)
{
fType = "G4"+typeOfField+"FieldModel";
fGlobalTag = fType;
std::ostringstream oss;
oss << ':' << fNDataPointsPerMaxHalfScene
<< ':' << fArrow3DLineSegmentsPerCircle;
if (fExtentForField == G4VisExtent::GetNullExtent()) {
oss << " whole scene";
} else {
oss
<< ':' << fExtentForField.GetXmin()
<< ':' << fExtentForField.GetXmax()
<< ':' << fExtentForField.GetYmin()
<< ':' << fExtentForField.GetYmax()
<< ':' << fExtentForField.GetZmin()
<< ':' << fExtentForField.GetZmax();
}
for (const auto& findings: fPVFindings) {
oss
<< ',' << findings.fpFoundPV->GetName()
<< ':' << findings.fFoundPVCopyNo;
}
if (fRepresentation == Representation::fullArrow) {
oss << " full arrow";
} else if (fRepresentation == Representation::lightArrow) {
oss << " light arrow";
}
fGlobalDescription = fType + oss.str();
}
// The main task of a model is to describe itself to the graphics scene.
void G4VFieldModel::DescribeYourselfTo(G4VGraphicsScene& sceneHandler) {
// G4cout << "G4VFieldModel::DescribeYourselfTo" << G4endl;
G4TransportationManager* tMgr =
G4TransportationManager::GetTransportationManager();
assert(tMgr);
G4Navigator* navigator = tMgr->GetNavigatorForTracking();
assert(navigator);
G4FieldManager* globalFieldMgr = tMgr->GetFieldManager();
const G4Field* globalField = 0;
const G4String intro = "G4VFieldModel::DescribeYourselfTo: ";
if (globalFieldMgr) {
if (globalFieldMgr->DoesFieldExist()) {
globalField = globalFieldMgr->GetDetectorField();
if (!globalField) {
static G4bool warned = false;
if (!warned) {
G4cout << intro << "Null global field pointer." << G4endl;
warned = true;
}
}
}
} else {
static G4bool warned = false;
if (!warned) {
G4cout << intro << "No global field manager." << G4endl;
warned = true;
}
}
G4VisExtent sceneExtent = sceneHandler.GetExtent();
const G4double& xMin = sceneExtent.GetXmin();
const G4double& yMin = sceneExtent.GetYmin();
const G4double& zMin = sceneExtent.GetZmin();
const G4double& xMax = sceneExtent.GetXmax();
const G4double& yMax = sceneExtent.GetYmax();
const G4double& zMax = sceneExtent.GetZmax();
const G4double xHalfScene = 0.5 * (xMax - xMin);
const G4double yHalfScene = 0.5 * (yMax - yMin);
const G4double zHalfScene = 0.5 * (zMax - zMin);
const G4double xSceneCentre = 0.5 * (xMax + xMin);
const G4double ySceneCentre = 0.5 * (yMax + yMin);
const G4double zSceneCentre = 0.5 * (zMax + zMin);
const G4double maxHalfScene =
std::max(xHalfScene,std::max(yHalfScene,zHalfScene));
if (maxHalfScene <= 0.) {
G4cout << "Scene extent non-positive." << G4endl;
return;
}
// Constants
const G4double interval = maxHalfScene / fNDataPointsPerMaxHalfScene;
const G4int nDataPointsPerXHalfScene = G4int(xHalfScene / interval);
const G4int nDataPointsPerYHalfScene = G4int(yHalfScene / interval);
const G4int nDataPointsPerZHalfScene = G4int(zHalfScene / interval);
const G4int nXSamples = 2 * nDataPointsPerXHalfScene + 1;
const G4int nYSamples = 2 * nDataPointsPerYHalfScene + 1;
const G4int nZSamples = 2 * nDataPointsPerZHalfScene + 1;
const G4int nSamples = nXSamples * nYSamples * nZSamples;
const G4double arrowLengthMax = 0.8 * interval;
// Working vectors for field values, etc.
std::vector<G4Point3D> Field(nSamples); // Initialises to (0,0,0)
std::vector<G4Point3D> xyz(nSamples); // Initialises to (0,0,0)
G4double FieldMagnitudeMax = -std::numeric_limits<G4double>::max();
// Get field values and ascertain maximum field.
for (G4int i = 0; i < nXSamples; i++) {
G4double x = xSceneCentre + (i - nDataPointsPerXHalfScene) * interval;
for (G4int j = 0; j < nYSamples; j++) {
G4double y = ySceneCentre + (j - nDataPointsPerYHalfScene) * interval;
for (G4int k = 0; k < nZSamples; k++) {
G4double z = zSceneCentre + (k - nDataPointsPerZHalfScene) * interval;
// Calculate indices into working vectors
const G4int ijk = i * nYSamples * nZSamples + j * nZSamples + k;
xyz[ijk].set(x,y,z);
G4ThreeVector pos(x,y,z);
// Check if point is in extent for field
if (fExtentForField != G4VisExtent::GetNullExtent()) {
const auto& ext = fExtentForField; // Alias
if (x < ext.GetXmin() || x > ext.GetXmax() ||
y < ext.GetYmin() || y > ext.GetYmax() ||
z < ext.GetZmin() || z > ext.GetZmax())
continue;
}
// Check if point is in findings
if (!fPVFindings.empty()) {
G4bool isInPV = false;
for (const auto& findings: fPVFindings) {
G4VPhysicalVolume* pv = findings.fpFoundPV;
G4int copyNo = findings.fFoundPVCopyNo;
G4VSolid* solid = pv->GetLogicalVolume()->GetSolid();
G4PVParameterised* pvParam = dynamic_cast<G4PVParameterised*>(pv);
if (pvParam) {
auto* param = pvParam->GetParameterisation();
solid = param->ComputeSolid(copyNo,pvParam);
solid->ComputeDimensions(param,copyNo,pvParam);
}
// Transform point to local coordinate system
const auto& transform = findings.fFoundObjectTransformation;
auto rotation = transform.getRotation();
auto translation = transform.getTranslation();
G4ThreeVector lPos = pos; lPos -= translation; lPos.transform(rotation.invert());
if (solid->Inside(lPos)==kInside) {
isInPV = true;
break;
}
}
if (!isInPV) continue;
}
// Point is in findings - or there were no findings
// Find volume and field at this location.
const G4VPhysicalVolume* pPV =
navigator->LocateGlobalPointAndSetup(pos,0,false,true);
const G4Field* field = globalField;
if (pPV) {
// Get logical volume.
const G4LogicalVolume* pLV = pPV->GetLogicalVolume();
if (pLV) {
// Value for Region, if any, overrides
G4Region* pRegion = pLV->GetRegion();
if (pRegion) {
G4FieldManager* pRegionFieldMgr = pRegion->GetFieldManager();
if (pRegionFieldMgr) {
field = pRegionFieldMgr->GetDetectorField();
// G4cout << "Region with field" << G4endl;
}
}
// 'Local' value from logical volume, if any, overrides
G4FieldManager* pLVFieldMgr = pLV->GetFieldManager();
if (pLVFieldMgr) {
field = pLVFieldMgr->GetDetectorField();
// G4cout << "Logical volume with field" << G4endl;
}
}
}
G4double time = 0.; // FIXME: Can we get event time in some way?
// Subclasses will have implemented this for their own field
GetFieldAtLocation(field, xyz[ijk], time, Field[ijk]);
G4double mag = Field[ijk].mag();
if (mag > FieldMagnitudeMax) FieldMagnitudeMax = mag;
} // for (k, z
} // for (j, y
} // for (i, x
if (FieldMagnitudeMax <= 0.) {
G4cout << "No " << fTypeOfField << " field in this extent." << G4endl;
return;
}
for (G4int i = 0; i < nSamples; i++) {
const G4double Fmag = Field[i].mag();
const G4double f = Fmag / FieldMagnitudeMax;
if (f <= 0.) continue; // Skip zero field locations
G4double red = 0., green = 0., blue = 0., alpha = 1.;
if (f < 0.5) { // Linear colour scale: 0->0.5->1 is red->green->blue.
green = 2. * f;
red = 2. * (0.5 - f);
} else {
blue = 2. * (f - 0.5);
green = 2. * (1.0 - f);
}
const G4Colour arrowColour(red,green,blue,alpha);
// Very small arrows are difficult to see. Better to draw a line.
G4bool drawAsLine = false;
switch (fRepresentation) {
case Representation::fullArrow:
if (f < 0.1) {
drawAsLine = true;
}
break;
case Representation::lightArrow:
drawAsLine = true;
break;
default:
break;
}
// Head of arrow depends on field direction and strength...
G4double arrowLength = arrowLengthMax * f;
// ...but limit the length so it's visible.
if (f < 0.01) arrowLength = arrowLengthMax * 0.01;
const G4Point3D head = xyz[i] + arrowLength*Field[i]/Fmag;
if (drawAsLine) {
G4Polyline FArrowLite;
G4VisAttributes va(arrowColour);
va.SetLineWidth(2.);
FArrowLite.SetVisAttributes(va);
FArrowLite.push_back(xyz[i]);
FArrowLite.push_back(head);
sceneHandler.BeginPrimitives();
sceneHandler.AddPrimitive(FArrowLite);
sceneHandler.EndPrimitives();
} else {
G4ArrowModel FArrow(xyz[i].x(), xyz[i].y(), xyz[i].z(),
head.x(), head.y(), head.z(),
arrowLength/5, arrowColour,
fArrowPrefix+"Field",
fArrow3DLineSegmentsPerCircle);
FArrow.DescribeYourselfTo(sceneHandler);
}
} // for (i, nSamples
}
@@ -55,6 +55,13 @@ G4String G4VModel::GetCurrentDescription () const {
return fGlobalDescription;
}
const G4VisExtent& G4VModel::GetTransformedExtent () const {
static G4VisExtent transformedExtent;
transformedExtent = fExtent;
transformedExtent.Transform(fTransform);
return transformedExtent;
}
G4bool G4VModel::Validate (G4bool) {
return true;
}