Import Geant4 11.2.0.beta source tree
This commit is contained in:
@@ -68,6 +68,7 @@
|
||||
#include "G4DisplacedSolid.hh"
|
||||
#include "G4UnionSolid.hh"
|
||||
#include "G4IntersectionSolid.hh"
|
||||
#include "G4SubtractionSolid.hh"
|
||||
#include "G4LogicalVolume.hh"
|
||||
#include "G4PhysicalVolumeModel.hh"
|
||||
#include "G4ModelingParameters.hh"
|
||||
@@ -88,6 +89,7 @@
|
||||
#include "G4Transform3D.hh"
|
||||
#include "G4AttHolder.hh"
|
||||
#include "G4AttDef.hh"
|
||||
#include "G4SceneTreeItem.hh"
|
||||
#include "G4VVisCommand.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
@@ -526,29 +528,58 @@ void G4VSceneHandler::RequestPrimitives (const G4VSolid& solid)
|
||||
{
|
||||
// Sometimes solids that have no substance get requested. They may
|
||||
// be part of the geometry tree but have been "spirited away", for
|
||||
// example by a Boolean subtraction in wich the original volume
|
||||
// is entirely inside the subtractor.
|
||||
// example by a Boolean subtraction in which the original volume
|
||||
// is entirely inside the subtractor or an intersection in which
|
||||
// the original volume is entirely outside the intersector.
|
||||
// The problem is that the Boolean Processor still returns a
|
||||
// polyhedron in these cases (IMHO it should not), so the
|
||||
// workaround is to return before the damage is done.
|
||||
// Algorithm by Evgueni Tcherniaev
|
||||
auto pSolid = &solid;
|
||||
auto pBooleanSolid = dynamic_cast<const G4BooleanSolid*>(pSolid);
|
||||
if (pBooleanSolid) {
|
||||
G4ThreeVector bmin, bmax;
|
||||
pBooleanSolid->BoundingLimits(bmin, bmax);
|
||||
G4bool isGood = false;
|
||||
for (G4int i=0; i<100000; ++i) {
|
||||
G4double x = bmin.x() + (bmax.x() - bmin.x())*G4QuickRand();
|
||||
G4double y = bmin.y() + (bmax.y() - bmin.y())*G4QuickRand();
|
||||
G4double z = bmin.z() + (bmax.z() - bmin.z())*G4QuickRand();
|
||||
if (pBooleanSolid->Inside(G4ThreeVector(x,y,z)) == kInside) {
|
||||
isGood = true;
|
||||
break;
|
||||
if (dynamic_cast<const G4SubtractionSolid*>(pBooleanSolid)) {
|
||||
auto ptrB = pBooleanSolid->GetConstituentSolid(1);
|
||||
for (G4int i=0; i<10; ++i) {
|
||||
G4double x = bmin.x() + (bmax.x() - bmin.x())*G4QuickRand();
|
||||
G4double y = bmin.y() + (bmax.y() - bmin.y())*G4QuickRand();
|
||||
G4double z = bmin.z() + (bmax.z() - bmin.z())*G4QuickRand();
|
||||
if (ptrB->Inside(G4ThreeVector(x,y,bmin.z())) != kInside) { isGood = true; break; }
|
||||
if (ptrB->Inside(G4ThreeVector(x,y,bmax.z())) != kInside) { isGood = true; break; }
|
||||
if (ptrB->Inside(G4ThreeVector(x,bmin.y(),z)) != kInside) { isGood = true; break; }
|
||||
if (ptrB->Inside(G4ThreeVector(x,bmax.y(),z)) != kInside) { isGood = true; break; }
|
||||
if (ptrB->Inside(G4ThreeVector(bmin.x(),y,z)) != kInside) { isGood = true; break; }
|
||||
if (ptrB->Inside(G4ThreeVector(bmax.x(),y,z)) != kInside) { isGood = true; break; }
|
||||
}
|
||||
} else if (dynamic_cast<const G4IntersectionSolid*>(pBooleanSolid)) {
|
||||
auto ptrB = pBooleanSolid->GetConstituentSolid(1);
|
||||
for (G4int i=0; i<10; ++i) {
|
||||
G4double x = bmin.x() + (bmax.x() - bmin.x())*G4QuickRand();
|
||||
G4double y = bmin.y() + (bmax.y() - bmin.y())*G4QuickRand();
|
||||
G4double z = bmin.z() + (bmax.z() - bmin.z())*G4QuickRand();
|
||||
if (ptrB->Inside(G4ThreeVector(x,y,bmin.z())) == kInside) { isGood = true; break; }
|
||||
if (ptrB->Inside(G4ThreeVector(x,y,bmax.z())) == kInside) { isGood = true; break; }
|
||||
if (ptrB->Inside(G4ThreeVector(x,bmin.y(),z)) == kInside) { isGood = true; break; }
|
||||
if (ptrB->Inside(G4ThreeVector(x,bmax.y(),z)) == kInside) { isGood = true; break; }
|
||||
if (ptrB->Inside(G4ThreeVector(bmin.x(),y,z)) == kInside) { isGood = true; break; }
|
||||
if (ptrB->Inside(G4ThreeVector(bmax.x(),y,z)) == kInside) { isGood = true; break; }
|
||||
}
|
||||
}
|
||||
if (!isGood)
|
||||
{
|
||||
for (G4int i=0; i<10000; ++i) {
|
||||
G4double x = bmin.x() + (bmax.x() - bmin.x())*G4QuickRand();
|
||||
G4double y = bmin.y() + (bmax.y() - bmin.y())*G4QuickRand();
|
||||
G4double z = bmin.z() + (bmax.z() - bmin.z())*G4QuickRand();
|
||||
if (pBooleanSolid->Inside(G4ThreeVector(x,y,z)) == kInside) { isGood = true; break; }
|
||||
}
|
||||
}
|
||||
if (!isGood) return;
|
||||
}
|
||||
|
||||
|
||||
const G4ViewParameters::DrawingStyle style = GetDrawingStyle(fpVisAttribs);
|
||||
const G4ViewParameters& vp = fpViewer->GetViewParameters();
|
||||
|
||||
@@ -684,6 +715,9 @@ void G4VSceneHandler::ProcessScene()
|
||||
G4cout << "Traversing scene data..." << G4endl;
|
||||
}
|
||||
|
||||
// Reset visibility of all objects to false - visible objects will then set to true
|
||||
fpViewer->AccessSceneTree().ResetVisibility();
|
||||
|
||||
BeginModeling();
|
||||
|
||||
// Create modeling parameters from view parameters...
|
||||
@@ -695,10 +729,24 @@ void G4VSceneHandler::ProcessScene()
|
||||
{
|
||||
fpModel = runDurationModelList[i].fpModel;
|
||||
fpModel->SetModelingParameters(pMP);
|
||||
fpModel->DescribeYourselfTo(*this);
|
||||
// To see the extents of each model represented as wireframe boxes,
|
||||
// uncomment the next line and DrawExtent in namespace above
|
||||
// DrawExtent(fpModel);
|
||||
|
||||
// Describe to the current scene handler
|
||||
fpModel->DescribeYourselfTo(*this);
|
||||
|
||||
// To see the extents of each model represented as wireframe boxes,
|
||||
// uncomment the next line and DrawExtent in namespace above.
|
||||
// DrawExtent(fpModel);
|
||||
|
||||
// Enter models in the scene tree, and for PV models, describe
|
||||
// the model to the scene tree, i.e., enter all the touchables.
|
||||
auto& sceneTreeScene = fpViewer->AccessSceneTreeScene();
|
||||
sceneTreeScene.SetViewer(fpViewer);
|
||||
sceneTreeScene.SetModel(fpModel);
|
||||
if (dynamic_cast<G4PhysicalVolumeModel*>(fpModel)) {
|
||||
fpModel->DescribeYourselfTo(sceneTreeScene);
|
||||
}
|
||||
|
||||
// Reset modeling parameters pointer
|
||||
fpModel->SetModelingParameters(0);
|
||||
}
|
||||
}
|
||||
@@ -729,6 +777,8 @@ void G4VSceneHandler::ProcessScene()
|
||||
if(runManager)
|
||||
{
|
||||
const G4Run* run = runManager->GetCurrentRun();
|
||||
// Draw a null event in order to pick up models for the scene tree even before a run
|
||||
if (run == nullptr) DrawEvent(0);
|
||||
const std::vector<const G4Event*>* events =
|
||||
run ? run->GetEventVector() : 0;
|
||||
std::size_t nKeptEvents = 0;
|
||||
@@ -797,9 +847,18 @@ void G4VSceneHandler::DrawEvent(const G4Event* event)
|
||||
pMP->SetEvent(event);
|
||||
for (std::size_t i = 0; i < nModels; ++i) {
|
||||
if (EOEModelList[i].fActive) {
|
||||
fpModel = EOEModelList[i].fpModel;
|
||||
fpModel -> SetModelingParameters(pMP);
|
||||
fpModel -> DescribeYourselfTo (*this);
|
||||
fpModel = EOEModelList[i].fpModel;
|
||||
fpModel -> SetModelingParameters(pMP);
|
||||
|
||||
// Describe to the current scene handler
|
||||
fpModel -> DescribeYourselfTo (*this);
|
||||
|
||||
// Enter models in the scene tree
|
||||
auto& sceneTreeScene = fpViewer->AccessSceneTreeScene();
|
||||
sceneTreeScene.SetViewer(fpViewer);
|
||||
sceneTreeScene.SetModel(fpModel);
|
||||
|
||||
// Reset modeling parameters pointer
|
||||
fpModel -> SetModelingParameters(0);
|
||||
}
|
||||
}
|
||||
@@ -819,9 +878,18 @@ void G4VSceneHandler::DrawEndOfRunModels()
|
||||
for (std::size_t i = 0; i < nModels; ++i) {
|
||||
if (EORModelList[i].fActive) {
|
||||
fpModel = EORModelList[i].fpModel;
|
||||
fpModel -> SetModelingParameters(pMP);
|
||||
fpModel -> SetModelingParameters(pMP);
|
||||
|
||||
// Describe to the current scene handler
|
||||
fpModel -> DescribeYourselfTo (*this);
|
||||
fpModel -> SetModelingParameters(0);
|
||||
|
||||
// Enter models in the scene tree
|
||||
auto& sceneTreeScene = fpViewer->AccessSceneTreeScene();
|
||||
sceneTreeScene.SetViewer(fpViewer);
|
||||
sceneTreeScene.SetModel(fpModel);
|
||||
|
||||
// Reset modeling parameters pointer
|
||||
fpModel -> SetModelingParameters(0);
|
||||
}
|
||||
}
|
||||
fpModel = 0;
|
||||
@@ -887,6 +955,13 @@ G4ModelingParameters* G4VSceneHandler::CreateModelingParameters ()
|
||||
pModelingParams->SetExplodeCentre(vp.GetExplodeCentre());
|
||||
|
||||
pModelingParams->SetSectionSolid(CreateSectionSolid());
|
||||
|
||||
if (vp.GetCutawayMode() == G4ViewParameters::cutawayUnion) {
|
||||
pModelingParams->SetCutawayMode(G4ModelingParameters::cutawayUnion);
|
||||
} else if (vp.GetCutawayMode() == G4ViewParameters::cutawayIntersection) {
|
||||
pModelingParams->SetCutawayMode(G4ModelingParameters::cutawayIntersection);
|
||||
}
|
||||
|
||||
pModelingParams->SetCutawaySolid(CreateCutawaySolid());
|
||||
// The polyhedron objects are deleted in the modeling parameters destructor.
|
||||
|
||||
@@ -909,27 +984,14 @@ G4DisplacedSolid* G4VSceneHandler::CreateSectionSolid()
|
||||
G4double safe = radius + fpScene->GetExtent().GetExtentCentre().mag();
|
||||
G4VSolid* sectionBox =
|
||||
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 ();
|
||||
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);
|
||||
G4ThreeVector normal = sp.normal();
|
||||
G4Transform3D requiredTransform = G4Translate3D(normal*(-sp.d())) *
|
||||
G4Rotate3D(G4ThreeVector(0,0,1), G4ThreeVector(0,1,0), normal, normal.orthogonal());
|
||||
|
||||
sectioner = new G4DisplacedSolid
|
||||
("_displaced_sectioning_box", sectionBox, requiredTransform);
|
||||
("_displaced_sectioning_box", sectionBox, requiredTransform);
|
||||
}
|
||||
|
||||
return sectioner;
|
||||
@@ -937,69 +999,82 @@ G4DisplacedSolid* G4VSceneHandler::CreateSectionSolid()
|
||||
|
||||
G4DisplacedSolid* G4VSceneHandler::CreateCutawaySolid()
|
||||
{
|
||||
const G4ViewParameters& vp = fpViewer->GetViewParameters();
|
||||
if (vp.IsCutaway()) {
|
||||
const auto& vp = fpViewer->GetViewParameters();
|
||||
const auto& nPlanes = vp.GetCutawayPlanes().size();
|
||||
|
||||
std::vector<G4DisplacedSolid*> cutaway_solids;
|
||||
if (nPlanes == 0) return nullptr;
|
||||
|
||||
G4double radius = fpScene->GetExtent().GetExtentRadius();
|
||||
G4double safe = radius + fpScene->GetExtent().GetExtentCentre().mag();
|
||||
G4VSolid* cutawayBox =
|
||||
new G4Box("_cutaway_box", safe, safe, safe); // world box...
|
||||
std::vector<G4DisplacedSolid*> cutaway_solids;
|
||||
|
||||
for (int plane_no = 0; plane_no < int(vp.GetCutawayPlanes().size()); plane_no++){
|
||||
G4double radius = fpScene->GetExtent().GetExtentRadius();
|
||||
G4double safe = radius + fpScene->GetExtent().GetExtentCentre().mag();
|
||||
auto cutawayBox = new G4Box("_cutaway_box", safe, safe, safe);
|
||||
|
||||
const G4Normal3D originalNormal(0,0,1); // ...so this is original normal.
|
||||
// if (vp.GetCutawayMode() == G4ViewParameters::cutawayUnion) we need a subtractor that is
|
||||
// the intersection of displaced cutaway boxes, displaced so that a subtraction keeps the
|
||||
// positive values a*x+b*y+c*z+d>0, so we have to invert the normal. This may appear
|
||||
// "back to front". The parameter "cutawayUnion" means "the union of volumes
|
||||
// that remain *after* cutaway", because we base the concept on OpenGL cutaway planes and make
|
||||
// a "union" of what remains by superimposing up to 3 passes - see G4OpenGLViewer::SetView
|
||||
// and G4OpenGLImmediate/StoredViewer::ProcessView. So we have to create a subtractor
|
||||
// that is the intersection of inverted cutaway planes.
|
||||
|
||||
const G4Plane3D& sp = vp.GetCutawayPlanes()[plane_no]; //];
|
||||
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); // Convention: keep a*x+b*y+c*z+d>=0
|
||||
// Not easy to see why the above gives the right convention, but it has been
|
||||
// arrived at by trial and error to agree with the OpenGL implementation
|
||||
// of clipping planes.
|
||||
// Conversely, if (vp.GetCutawayMode() == G4ViewParameters::cutawayIntersection) we have to
|
||||
// create an intersector that is the intersector of intersected non-inverted cutaway planes.
|
||||
|
||||
G4Transform3D requiredTransform; // Null transform
|
||||
// Calculate the rotation
|
||||
// If newNormal is (0,0,1), no need to do anything
|
||||
// Treat (0,0,-1) as a special case, since cannot define axis in this case
|
||||
if (newNormal == G4Normal3D(0,0,-1)) {
|
||||
requiredTransform = G4Rotate3D(pi,G4Vector3D(1,0,0));
|
||||
} else if (newNormal != originalNormal) {
|
||||
const G4double& angle = std::acos(newNormal.dot(originalNormal));
|
||||
const G4Vector3D& axis = originalNormal.cross(newNormal);
|
||||
requiredTransform = G4Rotate3D(angle, axis);
|
||||
}
|
||||
// Translation
|
||||
requiredTransform = requiredTransform * G4TranslateZ3D(d + safe);
|
||||
cutaway_solids.push_back
|
||||
(new G4DisplacedSolid("_displaced_cutaway_box", cutawayBox, requiredTransform));
|
||||
}
|
||||
|
||||
if (cutaway_solids.size() == 1){
|
||||
return (G4DisplacedSolid*) cutaway_solids[0];
|
||||
} else if (vp.GetCutawayMode() == G4ViewParameters::cutawayUnion) {
|
||||
G4UnionSolid* union2 =
|
||||
new G4UnionSolid("_union_2", cutaway_solids[0], cutaway_solids[1]);
|
||||
if (cutaway_solids.size() == 2)
|
||||
return (G4DisplacedSolid*)union2;
|
||||
else
|
||||
return (G4DisplacedSolid*)
|
||||
new G4UnionSolid("_union_3", union2, cutaway_solids[2]);
|
||||
} else if (vp.GetCutawayMode() == G4ViewParameters::cutawayIntersection){
|
||||
G4IntersectionSolid* intersection2 =
|
||||
new G4IntersectionSolid("_intersection_2", cutaway_solids[0], cutaway_solids[1]);
|
||||
if (cutaway_solids.size() == 2)
|
||||
return (G4DisplacedSolid*)intersection2;
|
||||
else
|
||||
return (G4DisplacedSolid*)
|
||||
new G4IntersectionSolid("_intersection_3", intersection2, cutaway_solids[2]);
|
||||
for (size_t plane_no = 0; plane_no < nPlanes; plane_no++)
|
||||
{
|
||||
const G4Plane3D& sp = vp.GetCutawayPlanes()[plane_no];
|
||||
G4Transform3D requiredTransform;
|
||||
G4ThreeVector normal;
|
||||
switch (vp.GetCutawayMode()) {
|
||||
case G4ViewParameters::cutawayUnion:
|
||||
normal = -sp.normal(); // Invert normal - we want a subtractor
|
||||
requiredTransform = G4Translate3D(normal*(safe + sp.d())) *
|
||||
G4Rotate3D(G4ThreeVector(0,0,1), G4ThreeVector(0,1,0), normal, normal.orthogonal());
|
||||
break;
|
||||
case G4ViewParameters::cutawayIntersection:
|
||||
normal = sp.normal();
|
||||
requiredTransform = G4Translate3D(normal*(safe - sp.d())) *
|
||||
G4Rotate3D(G4ThreeVector(0,0,1), G4ThreeVector(0,1,0), normal, normal.orthogonal());
|
||||
break;
|
||||
}
|
||||
cutaway_solids.push_back
|
||||
(new G4DisplacedSolid("_displaced_cutaway_box", cutawayBox, requiredTransform));
|
||||
}
|
||||
|
||||
return 0;
|
||||
if (nPlanes == 1) return (G4DisplacedSolid*) cutaway_solids[0];
|
||||
|
||||
G4IntersectionSolid *union2 = nullptr, *union3 = nullptr;
|
||||
G4IntersectionSolid *intersection2 = nullptr, *intersection3 = nullptr;
|
||||
switch (vp.GetCutawayMode()) {
|
||||
|
||||
case G4ViewParameters::cutawayUnion:
|
||||
// Here we make a subtractor of intersections of inverted cutaway planes.
|
||||
union2 = new G4IntersectionSolid("_union_2", cutaway_solids[0], cutaway_solids[1]);
|
||||
if (nPlanes == 2) return (G4DisplacedSolid*)union2;
|
||||
else if (nPlanes == 3) {
|
||||
union3 = new G4IntersectionSolid("_union_3", union2, cutaway_solids[2]);
|
||||
return (G4DisplacedSolid*)union3;
|
||||
}
|
||||
break;
|
||||
|
||||
case G4ViewParameters::cutawayIntersection:
|
||||
// And here we make an intersector of intersections of non-inverted cutaway planes.
|
||||
intersection2
|
||||
= new G4IntersectionSolid("_intersection_2", cutaway_solids[0], cutaway_solids[1]);
|
||||
if (nPlanes == 2) return (G4DisplacedSolid*)intersection2;
|
||||
else if (nPlanes == 3) {
|
||||
intersection3
|
||||
= new G4IntersectionSolid("_intersection_3", intersection2, cutaway_solids[2]);
|
||||
return (G4DisplacedSolid*)intersection3;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
G4Exception("G4VSceneHandler::CreateCutawaySolid", "visman107", JustWarning,
|
||||
"Not programmed for more than 3 cutaway planes");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void G4VSceneHandler::LoadAtts(const G4Visible& visible, G4AttHolder* holder)
|
||||
@@ -1220,10 +1295,10 @@ std::ostream& operator << (std::ostream& os, const G4VSceneHandler& sh) {
|
||||
}
|
||||
|
||||
void G4VSceneHandler::PseudoSceneFor3DRectMeshPositions::AddSolid(const G4Box&) {
|
||||
if (fpPVModel->GetCurrentDepth() == fDepth) { // Leaf-level cells only
|
||||
if (fpPVModel->GetCurrentDepth() == fpMesh->GetMeshDepth()) { // Leaf-level cells only
|
||||
const auto& material = fpPVModel->GetCurrentLV()->GetMaterial();
|
||||
const auto& name = material->GetName();
|
||||
const auto* pVisAtts = fpPVModel->GetCurrentLV()->GetVisAttributes();
|
||||
const auto& name = material? material->GetName(): fpMesh->GetContainerVolume()->GetName();
|
||||
const auto& pVisAtts = fpPVModel->GetCurrentLV()->GetVisAttributes();
|
||||
// Get position in world coordinates
|
||||
// As a parameterisation the box is transformed by the current transformation
|
||||
// and its centre, originally by definition at (0,0,0), is now translated.
|
||||
@@ -1236,13 +1311,13 @@ void G4VSceneHandler::PseudoSceneFor3DRectMeshPositions::AddSolid(const G4Box&)
|
||||
}
|
||||
|
||||
void G4VSceneHandler::PseudoSceneForTetVertices::AddSolid(const G4VSolid& solid) {
|
||||
if (fpPVModel->GetCurrentDepth() == fDepth) { // Leaf-level cells only
|
||||
if (fpPVModel->GetCurrentDepth() == fpMesh->GetMeshDepth()) { // Leaf-level cells only
|
||||
// Need to know it's a tet !!!! or implement G4VSceneHandler::AddSolid (const G4Tet&) !!!!
|
||||
try {
|
||||
const G4Tet& tet = dynamic_cast<const G4Tet&>(solid);
|
||||
const auto& tet = dynamic_cast<const G4Tet&>(solid);
|
||||
const auto& material = fpPVModel->GetCurrentLV()->GetMaterial();
|
||||
const auto& name = material->GetName();
|
||||
const auto* pVisAtts = fpPVModel->GetCurrentLV()->GetVisAttributes();
|
||||
const auto& name = material? material->GetName(): fpMesh->GetContainerVolume()->GetName();
|
||||
const auto& pVisAtts = fpPVModel->GetCurrentLV()->GetVisAttributes();
|
||||
// Transform into world coordinates if necessary
|
||||
if (fpCurrentObjectTransformation->xx() == 1. &&
|
||||
fpCurrentObjectTransformation->yy() == 1. &&
|
||||
@@ -1278,6 +1353,8 @@ void G4VSceneHandler::StandardSpecialMeshRendering(const G4Mesh& mesh)
|
||||
case G4Mesh::rectangle: [[fallthrough]];
|
||||
case G4Mesh::nested3DRectangular:
|
||||
switch (fpViewer->GetViewParameters().GetSpecialMeshRenderingOption()) {
|
||||
case G4ViewParameters::meshAsDefault:
|
||||
[[fallthrough]];
|
||||
case G4ViewParameters::meshAsDots:
|
||||
Draw3DRectMeshAsDots(mesh); // Rectangular 3-deep mesh as dots
|
||||
implemented = true;
|
||||
@@ -1290,6 +1367,8 @@ void G4VSceneHandler::StandardSpecialMeshRendering(const G4Mesh& mesh)
|
||||
break;
|
||||
case G4Mesh::tetrahedron:
|
||||
switch (fpViewer->GetViewParameters().GetSpecialMeshRenderingOption()) {
|
||||
case G4ViewParameters::meshAsDefault:
|
||||
[[fallthrough]];
|
||||
case G4ViewParameters::meshAsDots:
|
||||
DrawTetMeshAsDots(mesh); // Tetrahedron mesh as dots
|
||||
implemented = true;
|
||||
@@ -1378,7 +1457,7 @@ void G4VSceneHandler::Draw3DRectMeshAsDots(const G4Mesh& mesh)
|
||||
std::map<const G4Material*,G4VSceneHandler::NameAndVisAtts> nameAndVisAttsByMaterial;
|
||||
// Instantiate the pseudo scene
|
||||
PseudoSceneFor3DRectMeshPositions pseudoScene
|
||||
(&tmpPVModel,mesh.GetMeshDepth(),positionByMaterial,nameAndVisAttsByMaterial);
|
||||
(&tmpPVModel,&mesh,positionByMaterial,nameAndVisAttsByMaterial);
|
||||
// Make private descent into the parameterisation
|
||||
tmpPVModel.DescribeYourselfTo(pseudoScene);
|
||||
// Now we have a map of positions by material.
|
||||
@@ -1522,7 +1601,7 @@ void G4VSceneHandler::Draw3DRectMeshAsSurfaces(const G4Mesh& mesh)
|
||||
std::map<const G4Material*,G4VSceneHandler::NameAndVisAtts> nameAndVisAttsByMaterial;
|
||||
// Instantiate the pseudo scene
|
||||
PseudoSceneFor3DRectMeshPositions pseudoScene
|
||||
(&tmpPVModel,mesh.GetMeshDepth(),positionByMaterial,nameAndVisAttsByMaterial);
|
||||
(&tmpPVModel,&mesh,positionByMaterial,nameAndVisAttsByMaterial);
|
||||
// Make private descent into the parameterisation
|
||||
tmpPVModel.DescribeYourselfTo(pseudoScene);
|
||||
// Now we have a map of positions by material.
|
||||
@@ -1666,7 +1745,7 @@ void G4VSceneHandler::DrawTetMeshAsDots(const G4Mesh& mesh)
|
||||
std::map<const G4Material*,G4VSceneHandler::NameAndVisAtts> nameAndVisAttsByMaterial;
|
||||
// Instantiate a pseudo scene
|
||||
PseudoSceneForTetVertices pseudoScene
|
||||
(&tmpPVModel,mesh.GetMeshDepth(),verticesByMaterial,nameAndVisAttsByMaterial);
|
||||
(&tmpPVModel,&mesh,verticesByMaterial,nameAndVisAttsByMaterial);
|
||||
// Make private descent into the parameterisation
|
||||
tmpPVModel.DescribeYourselfTo(pseudoScene);
|
||||
// Now we have a map of vertices by material.
|
||||
@@ -1804,7 +1883,7 @@ void G4VSceneHandler::DrawTetMeshAsSurfaces(const G4Mesh& mesh)
|
||||
std::map<const G4Material*,G4VSceneHandler::NameAndVisAtts> nameAndVisAttsByMaterial;
|
||||
// Instantiate a pseudo scene
|
||||
PseudoSceneForTetVertices pseudoScene
|
||||
(&tmpPVModel,mesh.GetMeshDepth(),verticesByMaterial,nameAndVisAttsByMaterial);
|
||||
(&tmpPVModel,&mesh,verticesByMaterial,nameAndVisAttsByMaterial);
|
||||
// Make private descent into the parameterisation
|
||||
tmpPVModel.DescribeYourselfTo(pseudoScene);
|
||||
// Now we have a map of vertices by material.
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
#include "G4VPhysicalVolume.hh"
|
||||
#include "G4Transform3D.hh"
|
||||
#include "G4UImanager.hh"
|
||||
#include "G4UIsession.hh"
|
||||
#include "G4VInteractiveSession.hh"
|
||||
|
||||
G4VViewer::G4VViewer (G4VSceneHandler& sceneHandler,
|
||||
G4int id, const G4String& name):
|
||||
@@ -65,6 +67,8 @@ fNeedKernelVisit (true)
|
||||
|
||||
fVP = G4VisManager::GetInstance()->GetDefaultViewParameters();
|
||||
fDefaultVP = fVP;
|
||||
|
||||
fSceneTree.SetType(G4SceneTreeItem::root);
|
||||
}
|
||||
|
||||
G4VViewer::~G4VViewer () {
|
||||
@@ -118,6 +122,7 @@ void G4VViewer::ProcessView ()
|
||||
fNeedKernelVisit = false;
|
||||
fSceneHandler.ClearStore ();
|
||||
fSceneHandler.ProcessScene ();
|
||||
UpdateGUISceneTree();
|
||||
timer.Stop();
|
||||
fKernelVisitElapsedTimeSeconds = timer.GetRealElapsed();
|
||||
}
|
||||
@@ -139,7 +144,7 @@ void G4VViewer::SetTouchable
|
||||
if (iterator == pvStore->cend()) {
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Volume no longer in physical volume store.";
|
||||
G4Exception("G4VViewer::SetTouchable", "visman0501", JustWarning, ed);
|
||||
G4Exception("G4VViewer::SetTouchable", "visman0401", JustWarning, ed);
|
||||
} else {
|
||||
oss
|
||||
<< ' ' << pvNodeId.GetPhysicalVolume()->GetName()
|
||||
@@ -153,7 +158,7 @@ void G4VViewer::TouchableSetVisibility
|
||||
(const std::vector<G4PhysicalVolumeModel::G4PhysicalVolumeNodeID>& fullPath,
|
||||
G4bool visibiity)
|
||||
{
|
||||
// Changes the Vis Attribute Modifiers WITHOUT triggering a rebuild.
|
||||
// Changes the Vis Attribute Modifiers and scene tree WITHOUT triggering a rebuild.
|
||||
|
||||
// The following is equivalent to
|
||||
// G4UImanager::GetUIpointer()->ApplyCommand("/vis/touchable/set/visibility ...");
|
||||
@@ -172,13 +177,26 @@ void G4VViewer::TouchableSetVisibility
|
||||
// G4ModelingParameters::VASVisibility (VAS = Vis Attribute Signifier)
|
||||
// signifies that it is the visibility that should be picked out
|
||||
// and merged with the touchable's normal vis attributes.
|
||||
|
||||
// Find scene tree item and set visibility
|
||||
// The scene tree works with strings
|
||||
G4String fullPathString = G4PhysicalVolumeModel::GetPVNamePathString(fullPath);
|
||||
std::list<G4SceneTreeItem>::iterator foundIter;
|
||||
if (fSceneTree.FindTouchableFromRoot(fullPathString,foundIter)) {
|
||||
foundIter->AccessVisAttributes().SetVisibility(visibiity);
|
||||
UpdateGUISceneTree();
|
||||
} else {
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Touchable \"" << fullPath << "\" not found";
|
||||
G4Exception("G4VViewer::TouchableSetVisibility", "visman0402", JustWarning, ed);
|
||||
}
|
||||
}
|
||||
|
||||
void G4VViewer::TouchableSetColour
|
||||
(const std::vector<G4PhysicalVolumeModel::G4PhysicalVolumeNodeID>& fullPath,
|
||||
const G4Colour& colour)
|
||||
{
|
||||
// Changes the Vis Attribute Modifiers WITHOUT triggering a rebuild.
|
||||
// Changes the Vis Attribute Modifiers and scene tree WITHOUT triggering a rebuild.
|
||||
|
||||
// The following is equivalent to
|
||||
// G4UImanager::GetUIpointer()->ApplyCommand("/vis/touchable/set/colour ...");
|
||||
@@ -197,6 +215,201 @@ void G4VViewer::TouchableSetColour
|
||||
// G4ModelingParameters::VASColour (VAS = Vis Attribute Signifier)
|
||||
// signifies that it is the colour that should be picked out
|
||||
// and merged with the touchable's normal vis attributes.
|
||||
|
||||
// Find scene tree item and set colour
|
||||
// The scene tree works with strings
|
||||
G4String fullPathString = G4PhysicalVolumeModel::GetPVNamePathString(fullPath);
|
||||
std::list<G4SceneTreeItem>::iterator foundIter;
|
||||
if (fSceneTree.FindTouchableFromRoot(fullPathString,foundIter)) {
|
||||
foundIter->AccessVisAttributes().SetColour(colour);
|
||||
UpdateGUISceneTree();
|
||||
} else {
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Touchable \"" << fullPath << "\" not found";
|
||||
G4Exception("G4VViewer::TouchableSetColour", "visman0403", JustWarning, ed);
|
||||
}
|
||||
}
|
||||
|
||||
void G4VViewer::UpdateGUISceneTree()
|
||||
{
|
||||
G4UImanager* UI = G4UImanager::GetUIpointer();
|
||||
auto uiWindow = dynamic_cast<G4VInteractiveSession*>(UI->GetG4UIWindow());
|
||||
if (uiWindow) uiWindow->UpdateSceneTree(fSceneTree);
|
||||
}
|
||||
|
||||
void G4VViewer::SceneTreeScene::SetModel(G4VModel* pModel)
|
||||
{
|
||||
fpModel = pModel;
|
||||
auto& modelType = fpModel->GetType();
|
||||
auto& modelID = fpModel->GetGlobalDescription();
|
||||
FindOrInsertModel(modelType,modelID);
|
||||
}
|
||||
|
||||
std::list<G4SceneTreeItem>::iterator G4VViewer::SceneTreeScene::FindOrInsertModel
|
||||
(const G4String& modelType,const G4String& modelID)
|
||||
{
|
||||
G4SceneTreeItem::Type type = G4SceneTreeItem::unidentified;
|
||||
if (dynamic_cast<G4PhysicalVolumeModel*>(fpModel)) {
|
||||
type = G4SceneTreeItem::pvmodel;
|
||||
} else {
|
||||
type = G4SceneTreeItem::model;
|
||||
}
|
||||
|
||||
auto& rootItem = fpViewer->fSceneTree;
|
||||
rootItem.SetDescription(fpViewer->GetName());
|
||||
|
||||
// Find appropriate model
|
||||
auto& modelItems = rootItem.AccessChildren();
|
||||
auto modelIter = modelItems.begin();
|
||||
auto pvModelIter = modelItems.end();
|
||||
for (; modelIter != modelItems.end(); ++modelIter) {
|
||||
if (modelIter->GetType() == G4SceneTreeItem::pvmodel) {
|
||||
pvModelIter = modelIter; // Last PV model
|
||||
}
|
||||
if (modelIter->GetModelDescription() == modelID) break;
|
||||
}
|
||||
|
||||
if (modelIter == modelItems.end()) {
|
||||
|
||||
// Model not seen before
|
||||
G4SceneTreeItem modelItem(type);
|
||||
modelItem.SetDescription("model");
|
||||
modelItem.SetModelType(modelType);
|
||||
modelItem.SetModelDescription(modelID);
|
||||
if (pvModelIter != modelItems.end() && // There was pre-existing PV Model...
|
||||
type == G4SceneTreeItem::pvmodel) { // ...and the new model is also PV...
|
||||
modelIter = rootItem.InsertChild(++pvModelIter,modelItem); // ...insert after, else...
|
||||
} else {
|
||||
modelIter = rootItem.InsertChild(modelIter,modelItem); // ...insert at end
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// Existing model - mark visible == active
|
||||
modelIter->AccessVisAttributes().SetVisibility(true);
|
||||
}
|
||||
|
||||
return modelIter;
|
||||
}
|
||||
|
||||
std::list<G4SceneTreeItem>::iterator G4VViewer::SceneTreeScene::FindOrInsertTouchable
|
||||
(const G4String& modelID, G4SceneTreeItem& mother,
|
||||
G4int depth, const G4String& partialPathString, const G4String& fullPathString)
|
||||
{
|
||||
auto pPVModel = dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
|
||||
if (pPVModel == nullptr) {
|
||||
G4ExceptionDescription ed;
|
||||
ed << fpModel->GetType() << ": not a Physical VolumeModel";
|
||||
G4Exception("G4VViewer::SceneTreeScene::FindOrInsertTouchable", "visman0404", FatalException, ed);
|
||||
}
|
||||
auto& children = mother.AccessChildren();
|
||||
auto childIter = children.begin();
|
||||
for (; childIter != children.end(); ++childIter) {
|
||||
if (childIter->GetPVPath() == partialPathString) break;
|
||||
}
|
||||
if (childIter != children.end()) {
|
||||
|
||||
// Item already exists
|
||||
|
||||
if (childIter->GetType() == G4SceneTreeItem::ghost) {
|
||||
|
||||
// Previously it was a ghost - but maybe this time it's real
|
||||
|
||||
if (partialPathString == fullPathString) {
|
||||
// Partial path string refers to the actual volume so it's a touchable
|
||||
childIter->SetType(G4SceneTreeItem::touchable);
|
||||
// Populate with information
|
||||
childIter->SetDescription(fpModel->GetCurrentTag());
|
||||
childIter->SetModelType(fpModel->GetType());
|
||||
childIter->SetModelDescription(modelID);
|
||||
childIter->SetPVPath(partialPathString);
|
||||
if (fpVisAttributes) childIter->SetVisAttributes(*fpVisAttributes);
|
||||
if (pPVModel) childIter->SetAttDefs(pPVModel->GetAttDefs());
|
||||
if (pPVModel) childIter->SetAttValues(pPVModel->CreateCurrentAttValues());
|
||||
} // Partial path string refers to an ancester - do nothing
|
||||
|
||||
} else {
|
||||
|
||||
// Already a pre-existing full touchable
|
||||
|
||||
if (partialPathString == fullPathString) {
|
||||
// Partial path string refers to the actual volume
|
||||
// Replace vis attributes (if any) - they might have changed
|
||||
if (fpVisAttributes) childIter->SetVisAttributes(*fpVisAttributes);
|
||||
} // Partial path string refers to an ancester - do nothing
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// Item does not yet exist
|
||||
|
||||
if (partialPathString == fullPathString) {
|
||||
|
||||
// Partial path string refers to the actual volume
|
||||
// Insert new touchable item
|
||||
G4SceneTreeItem touchable(G4SceneTreeItem::touchable);
|
||||
touchable.SetExpanded(depth > 2? false: true);
|
||||
touchable.SetDescription(fpModel->GetCurrentTag());
|
||||
touchable.SetModelType(fpModel->GetType());
|
||||
touchable.SetModelDescription(modelID);
|
||||
touchable.SetPVPath(partialPathString);
|
||||
if (fpVisAttributes) touchable.SetVisAttributes(*fpVisAttributes);
|
||||
if (pPVModel) touchable.SetAttDefs(pPVModel->GetAttDefs());
|
||||
if (pPVModel) touchable.SetAttValues(pPVModel->CreateCurrentAttValues());
|
||||
childIter = mother.InsertChild(childIter,touchable);
|
||||
|
||||
} else {
|
||||
|
||||
// Partial path string refers to an ancester - it's what we call a "ghost"
|
||||
G4SceneTreeItem ghost(G4SceneTreeItem::ghost);
|
||||
ghost.SetExpanded(depth > 2? false: true);
|
||||
// Create a tag from the partial path
|
||||
std::istringstream iss(partialPathString);
|
||||
G4String name, copyNo;
|
||||
while (iss >> name >> copyNo);
|
||||
std::ostringstream oss;
|
||||
oss << name << ':' << copyNo;
|
||||
ghost.SetDescription(oss.str());
|
||||
ghost.SetModelType(fpModel->GetType());
|
||||
ghost.SetModelDescription(modelID);
|
||||
ghost.SetPVPath(partialPathString);
|
||||
ghost.AccessVisAttributes().SetVisibility(false);
|
||||
childIter = mother.InsertChild(childIter,ghost);
|
||||
}
|
||||
}
|
||||
|
||||
return childIter;
|
||||
}
|
||||
|
||||
void G4VViewer::SceneTreeScene::ProcessVolume(const G4VSolid&)
|
||||
{
|
||||
auto& modelType = fpModel->GetType();
|
||||
auto& modelID = fpModel->GetGlobalDescription();
|
||||
auto modelIter = FindOrInsertModel(modelType,modelID);
|
||||
|
||||
auto pPVModel = dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
|
||||
if (pPVModel) { // G4PhysicalVolumeModel
|
||||
|
||||
std::ostringstream oss; oss << pPVModel->GetFullPVPath();
|
||||
G4String fullPathString(oss.str()); // Has a leading space - OK
|
||||
|
||||
// Navigate scene tree and find or insert touchables one by one
|
||||
const auto& nodeIDs = pPVModel->GetFullPVPath(); // std::vector<G4PhysicalVolumeNodeID>
|
||||
|
||||
// Work down the path - "name id", then "name id name id", etc.
|
||||
G4String partialPathString;
|
||||
auto currentIter = modelIter;
|
||||
G4int depth = 0;
|
||||
for (const auto& nodeID: nodeIDs) {
|
||||
std::ostringstream oss1; oss1 << nodeID;
|
||||
partialPathString += ' ' + oss1.str(); // Has a leading space - OK
|
||||
currentIter = FindOrInsertTouchable
|
||||
(modelID, *currentIter, ++depth, partialPathString, fullPathString);
|
||||
}
|
||||
} else {
|
||||
// Orphan solid - what to do? Push an empty scene tree item????????????????????????
|
||||
}
|
||||
}
|
||||
|
||||
std::vector <G4ThreeVector> G4VViewer::ComputeFlyThrough(G4Vector3D* /*aVect*/)
|
||||
|
||||
@@ -55,6 +55,7 @@ G4VisExtent G4VVisCommand::fCurrentExten
|
||||
std::vector<G4PhysicalVolumesSearchScene::Findings> G4VVisCommand::fCurrrentPVFindingsForField;
|
||||
G4bool G4VVisCommand::fThereWasAViewer = false;
|
||||
G4ViewParameters G4VVisCommand::fExistingVP;
|
||||
G4SceneTreeItem G4VVisCommand::fExistingSceneTree;
|
||||
|
||||
G4VVisCommand::G4VVisCommand () {}
|
||||
|
||||
@@ -339,7 +340,6 @@ void G4VVisCommand::InterpolateToNewView
|
||||
|
||||
void G4VVisCommand::Twinkle
|
||||
// Twinkles the touchables in paths
|
||||
// /vis/viewer/centreOn to see its effect
|
||||
(G4VViewer* currentViewer,
|
||||
const G4ViewParameters& baseVP,
|
||||
const std::vector<std::vector<G4PhysicalVolumeModel::G4PhysicalVolumeNodeID>>& paths)
|
||||
@@ -379,16 +379,11 @@ void G4VVisCommand::Twinkle
|
||||
|
||||
// Twinkle
|
||||
std::vector<G4ViewParameters> viewVector;
|
||||
viewVector.push_back(loVP);
|
||||
viewVector.push_back(hiVP);
|
||||
viewVector.push_back(loVP);
|
||||
viewVector.push_back(hiVP);
|
||||
viewVector.push_back(loVP);
|
||||
viewVector.push_back(hiVP);
|
||||
viewVector.push_back(loVP);
|
||||
viewVector.push_back(hiVP);
|
||||
viewVector.push_back(loVP);
|
||||
viewVector.push_back(hiVP);
|
||||
// Just 5 twinkles is reasonable to get a human's attention
|
||||
for (G4int i = 0; i < 5; i++) {
|
||||
viewVector.push_back(loVP);
|
||||
viewVector.push_back(hiVP);
|
||||
}
|
||||
// Just 5 interpolation points for a reasonable twinkle rate
|
||||
InterpolateViews(currentViewer,viewVector,5);
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ G4ViewParameters::G4ViewParameters ():
|
||||
fDisplayLightFrontGreen(1.),
|
||||
fDisplayLightFrontBlue(0.),
|
||||
fSpecialMeshRendering(false),
|
||||
fSpecialMeshRenderingOption(meshAsDots)
|
||||
fSpecialMeshRenderingOption(meshAsDefault)
|
||||
{
|
||||
// Pick up default no of sides from G4Polyhedron.
|
||||
// Note that this parameter is variously called:
|
||||
@@ -896,6 +896,8 @@ std::ostream& operator <<
|
||||
(std::ostream& os, G4ViewParameters::SMROption option)
|
||||
{
|
||||
switch (option) {
|
||||
case G4ViewParameters::meshAsDefault:
|
||||
os << "default"; break;
|
||||
case G4ViewParameters::meshAsDots:
|
||||
os << "dots"; break;
|
||||
case G4ViewParameters::meshAsSurfaces:
|
||||
|
||||
@@ -324,10 +324,12 @@ void G4VisCommandSceneHandlerCreate::SetNewValue (G4UIcommand* command,
|
||||
}
|
||||
}
|
||||
|
||||
// If there is an existing viewer, store its view parameters
|
||||
// If there is an existing viewer, store its view parameters and scene tree
|
||||
if (fpVisManager->GetCurrentViewer()) {
|
||||
fThereWasAViewer = true;
|
||||
fExistingVP = fpVisManager->GetCurrentViewer()->GetViewParameters();
|
||||
auto viewer = fpVisManager->GetCurrentViewer();
|
||||
fExistingVP = viewer->GetViewParameters();
|
||||
fExistingSceneTree = viewer->AccessSceneTree();
|
||||
}
|
||||
|
||||
// Set current graphics system in preparation for
|
||||
|
||||
@@ -120,6 +120,11 @@ G4VisCommandsTouchable::G4VisCommandsTouchable()
|
||||
fpCommandShowExtent->SetParameterName("draw", omitable = true);
|
||||
fpCommandShowExtent->SetDefaultValue(false);
|
||||
|
||||
fpCommandTwinkle = new G4UIcmdWithoutParameter("/vis/touchable/twinkle",this);
|
||||
fpCommandTwinkle->SetGuidance("Cause touchable to twinkle.");
|
||||
// Pick up additional guidance from /vis/viewer/centreAndZoomInOn
|
||||
CopyGuidanceFrom(fpCommandCentreAndZoomInOn,fpCommandTwinkle,1);
|
||||
|
||||
fpCommandVolumeForField = new G4UIcmdWithABool("/vis/touchable/volumeForField",this);
|
||||
fpCommandVolumeForField->SetGuidance("Set volume for field.");
|
||||
fpCommandVolumeForField->SetGuidance("If parameter == true, also draw.");
|
||||
@@ -131,6 +136,7 @@ G4VisCommandsTouchable::G4VisCommandsTouchable()
|
||||
|
||||
G4VisCommandsTouchable::~G4VisCommandsTouchable() {
|
||||
delete fpCommandVolumeForField;
|
||||
delete fpCommandTwinkle;
|
||||
delete fpCommandShowExtent;
|
||||
delete fpCommandLocalAxes;
|
||||
delete fpCommandFindPath;
|
||||
@@ -255,7 +261,6 @@ void G4VisCommandsTouchable::SetNewValue
|
||||
} else {
|
||||
G4warn << "Touchable not found." << G4endl;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
} else if (command == fpCommandDraw) {
|
||||
@@ -263,7 +268,7 @@ void G4VisCommandsTouchable::SetNewValue
|
||||
G4PhysicalVolumeModel::TouchableProperties properties =
|
||||
G4TouchableUtils::FindTouchableProperties(fCurrentTouchableProperties.fTouchablePath);
|
||||
if (properties.fpTouchablePV) {
|
||||
// To handle paramaterisations we have to set the copy number
|
||||
// To handle parameterisations we have to set the copy number
|
||||
properties.fpTouchablePV->SetCopyNo(properties.fCopyNo);
|
||||
G4PhysicalVolumeModel* pvModel = new G4PhysicalVolumeModel
|
||||
(properties.fpTouchablePV,
|
||||
@@ -310,7 +315,7 @@ void G4VisCommandsTouchable::SetNewValue
|
||||
G4PhysicalVolumeModel::TouchableProperties properties =
|
||||
G4TouchableUtils::FindTouchableProperties(fCurrentTouchableProperties.fTouchablePath);
|
||||
if (properties.fpTouchablePV) {
|
||||
// To handle paramaterisations we have to set the copy number
|
||||
// To handle parameterisations we have to set the copy number
|
||||
properties.fpTouchablePV->SetCopyNo(properties.fCopyNo);
|
||||
G4PhysicalVolumeModel tempPVModel
|
||||
(properties.fpTouchablePV,
|
||||
@@ -398,19 +403,27 @@ void G4VisCommandsTouchable::SetNewValue
|
||||
if (copyNo >= 0) G4warn << ':' << copyNo;
|
||||
G4warn << " not found" << G4endl;
|
||||
}
|
||||
return;
|
||||
|
||||
} else if (command == fpCommandLocalAxes) {
|
||||
|
||||
const auto& transform = fCurrentTouchableProperties.fTouchableGlobalTransform;
|
||||
const auto& extent = fCurrentTouchableProperties.fpTouchablePV->GetLogicalVolume()->GetSolid()->GetExtent();
|
||||
const G4double lengthMax = extent.GetExtentRadius()/2.;
|
||||
const G4double intLog10LengthMax = std::floor(std::log10(lengthMax));
|
||||
G4double length = std::pow(10,intLog10LengthMax);
|
||||
if (5.*length < lengthMax) length *= 5.;
|
||||
else if (2.*length < lengthMax) length *= 2.;
|
||||
G4AxesModel axesModel(0.,0.,0.,length,transform);
|
||||
axesModel.SetGlobalTag("LocalAxesModel");
|
||||
axesModel.DescribeYourselfTo(*fpVisManager->GetCurrentSceneHandler());
|
||||
G4PhysicalVolumeModel::TouchableProperties properties =
|
||||
G4TouchableUtils::FindTouchableProperties(fCurrentTouchableProperties.fTouchablePath);
|
||||
if (properties.fpTouchablePV) {
|
||||
const auto& transform = fCurrentTouchableProperties.fTouchableGlobalTransform;
|
||||
const auto& extent = fCurrentTouchableProperties.fpTouchablePV->GetLogicalVolume()->GetSolid()->GetExtent();
|
||||
const G4double lengthMax = extent.GetExtentRadius()/2.;
|
||||
const G4double intLog10LengthMax = std::floor(std::log10(lengthMax));
|
||||
G4double length = std::pow(10,intLog10LengthMax);
|
||||
if (5.*length < lengthMax) length *= 5.;
|
||||
else if (2.*length < lengthMax) length *= 2.;
|
||||
G4AxesModel axesModel(0.,0.,0.,length,transform);
|
||||
axesModel.SetGlobalTag("LocalAxesModel");
|
||||
axesModel.DescribeYourselfTo(*fpVisManager->GetCurrentSceneHandler());
|
||||
} else {
|
||||
G4warn << "Touchable not found." << G4endl;
|
||||
}
|
||||
return;
|
||||
|
||||
} else if (command == fpCommandShowExtent) {
|
||||
|
||||
@@ -427,6 +440,24 @@ void G4VisCommandsTouchable::SetNewValue
|
||||
}
|
||||
return;
|
||||
|
||||
} else if (command == fpCommandTwinkle) {
|
||||
|
||||
G4PhysicalVolumeModel::TouchableProperties properties =
|
||||
G4TouchableUtils::FindTouchableProperties(fCurrentTouchableProperties.fTouchablePath);
|
||||
if (properties.fpTouchablePV) {
|
||||
std::vector<std::vector<G4PhysicalVolumeModel::G4PhysicalVolumeNodeID>> touchables;
|
||||
touchables.push_back(properties.fTouchableFullPVPath);
|
||||
auto keepVisVerbose = fpVisManager->GetVerbosity();
|
||||
fpVisManager->SetVerboseLevel(G4VisManager::errors);
|
||||
auto keepVP = currentViewer->GetViewParameters();
|
||||
Twinkle(currentViewer,currentViewer->GetViewParameters(),touchables);
|
||||
SetViewParameters(currentViewer, keepVP);
|
||||
fpVisManager->SetVerboseLevel(keepVisVerbose);
|
||||
} else {
|
||||
G4warn << "Touchable not found." << G4endl;
|
||||
}
|
||||
return;
|
||||
|
||||
} else if (command == fpCommandVolumeForField) {
|
||||
|
||||
G4PhysicalVolumeModel::TouchableProperties properties =
|
||||
|
||||
@@ -309,6 +309,20 @@ void G4VisCommandsTouchableSet::SetNewValue
|
||||
(workingVisAtts,
|
||||
G4ModelingParameters::VASVisibility,
|
||||
fCurrentTouchableProperties.fTouchablePath));
|
||||
if (verbosity >= G4VisManager::warnings) {
|
||||
static G4bool first = true;
|
||||
if (first) {
|
||||
first = false;
|
||||
G4warn << "WARNING: If \"/vis/touchable/set/visibility\" does not appear to"
|
||||
"\n work, check that opacity (4th component of colour) is non-zero." << G4endl;
|
||||
G4warn << "ALSO: The volume must be in a requested physical volume tree,"
|
||||
"\n not in the \"base path\". E.g., if"
|
||||
"\n /vis/drawVolume volume-name"
|
||||
"\n there is no way to make a parent of volume-name visible except by"
|
||||
"\n explicitly adding the parent:"
|
||||
"\n /vis/scene/add/volume parent-name" << G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
@@ -1067,6 +1067,7 @@ void G4VisCommandViewerCreate::SetNewValue (G4UIcommand* command, G4String newVa
|
||||
if (existingViewer) {
|
||||
// ...bring view parameters up to date...
|
||||
fExistingVP = existingViewer->GetViewParameters();
|
||||
fExistingSceneTree = existingViewer->AccessSceneTree();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1090,13 +1091,16 @@ void G4VisCommandViewerCreate::SetNewValue (G4UIcommand* command, G4String newVa
|
||||
fExistingVP.SetXGeometryString(vp.GetXGeometryString());
|
||||
vp = fExistingVP;
|
||||
newViewer->SetViewParameters(vp);
|
||||
newViewer->AccessSceneTree() = fExistingSceneTree;
|
||||
}
|
||||
if (verbosity >= G4VisManager::confirmations) {
|
||||
G4cout << "New viewer \"" << newName << "\" created." << G4endl;
|
||||
}
|
||||
// Keep for next time...
|
||||
fThereWasAViewer = true;
|
||||
fExistingVP = fpVisManager->GetCurrentViewer()->GetViewParameters();
|
||||
auto viewer = fpVisManager->GetCurrentViewer();
|
||||
fExistingVP = viewer->GetViewParameters();
|
||||
fExistingSceneTree = viewer->AccessSceneTree();
|
||||
} else {
|
||||
G4ExceptionDescription ed;
|
||||
if (newViewer) {
|
||||
@@ -2168,6 +2172,9 @@ void G4VisCommandViewerSelect::SetNewValue (G4UIcommand*, G4String newValue) {
|
||||
fpVisManager -> SetCurrentViewer (viewer);
|
||||
|
||||
RefreshIfRequired(viewer);
|
||||
|
||||
// Update GUI scene tree (make sure it's in sync)
|
||||
viewer->UpdateGUISceneTree();
|
||||
}
|
||||
|
||||
////////////// /vis/viewer/update ///////////////////////////////////////
|
||||
|
||||
@@ -388,10 +388,10 @@ fViewpointVector (G4ThreeVector(0.,0.,1.))
|
||||
fpCommandSpecialMeshRenderingOption = new G4UIcmdWithAString
|
||||
("/vis/viewer/set/specialMeshRenderingOption",this);
|
||||
fpCommandSpecialMeshRenderingOption->SetGuidance
|
||||
("Set special mesh rendering option - \"dots\" or \"surfaces\".");
|
||||
("Set special mesh rendering option - \"default\", \"dots\" or \"surfaces\".");
|
||||
fpCommandSpecialMeshRenderingOption->SetParameterName ("option",omitable = true);
|
||||
fpCommandSpecialMeshRenderingOption->SetCandidates("dots surfaces");
|
||||
fpCommandSpecialMeshRenderingOption->SetDefaultValue("dots");
|
||||
fpCommandSpecialMeshRenderingOption->SetCandidates("default dots surfaces");
|
||||
fpCommandSpecialMeshRenderingOption->SetDefaultValue("default");
|
||||
|
||||
fpCommandSpecialMeshVolumes = new G4UIcommand
|
||||
("/vis/viewer/set/specialMeshVolumes",this);
|
||||
@@ -1274,8 +1274,11 @@ void G4VisCommandsViewerSet::SetNewValue
|
||||
}
|
||||
|
||||
else if (command == fpCommandSpecialMeshRenderingOption) {
|
||||
G4ViewParameters::SMROption option = G4ViewParameters::meshAsDots;
|
||||
if (newValue == "surfaces") {
|
||||
G4ViewParameters::SMROption option = G4ViewParameters::meshAsDefault;
|
||||
if (newValue == "dots") {
|
||||
option = G4ViewParameters::meshAsDots;
|
||||
}
|
||||
else if(newValue == "surfaces") {
|
||||
option = G4ViewParameters::meshAsSurfaces;
|
||||
}
|
||||
vp.SetSpecialMeshRenderingOption(option);
|
||||
|
||||
Reference in New Issue
Block a user