64 ,
G4int requestedDepth
68 ,
const std::vector<G4PhysicalVolumeNodeID>& baseFullPVPath)
92 fType =
"G4PhysicalVolumeModel";
112 std::ostringstream oss;
127(
const std::vector<G4PhysicalVolumeNodeID>& path)
130 for (
const auto& node: path) {
131 PVNameCopyNoPath.push_back
133 (node.GetPhysicalVolume()->GetName(),node.GetCopyNo()));
135 return PVNameCopyNoPath;
139(
const std::vector<G4PhysicalVolumeNodeID>& path)
143 std::ostringstream oss;
199 (
"G4PhysicalVolumeModel::DescribeYourselfTo",
206 (
"G4PhysicalVolumeModel::DescribeYourselfTo",
219 ed <<
"More than one solid cutter/clipper:";
221 if (pSectionSolid) ed <<
"\nsectioner in force";
222 if (pCutawaySolid) ed <<
"\ncutaway in force";
234 startingTransformation,
262 std::ostringstream o;
267 return "WARNING: NO CURRENT VOLUME - global tag is " +
fGlobalTag;
278 G4int requestedDepth,
296 pSol = pLV -> GetSolid ();
297 pMaterial = pLV -> GetMaterial ();
299 theAT, sceneHandler);
310 G4int nEnd = nReplicas;
317 for (
int n = nBegin; n < nEnd; n++) {
318 pSol = pP -> ComputeSolid (n, pVPV);
319 pP -> ComputeTransformation (n, pVPV);
320 pSol -> ComputeDimensions (pP, n, pVPV);
327 pMaterial = pP -> ComputeMaterial (n, pVPV, &parentTouchable);
329 theAT, sceneHandler);
354 pSol = pLV -> GetSolid ();
355 pMaterial = pLV -> GetMaterial ();
356 G4ThreeVector originalTranslation = pVPV -> GetTranslation ();
358 G4double originalRMin = 0., originalRMax = 0.;
360 originalRMin = ((
G4Tubs*)pSol)->GetInnerRadius();
361 originalRMax = ((
G4Tubs*)pSol)->GetOuterRadius();
363 G4bool visualisable =
true;
364 for (
int n = nBegin; n < nEnd; n++) {
371 translation =
G4ThreeVector (-width*(nReplicas-1)*0.5+n*width,0,0);
374 translation =
G4ThreeVector (0,-width*(nReplicas-1)*0.5+n*width,0);
377 translation =
G4ThreeVector (0,0,-width*(nReplicas-1)*0.5+n*width);
384 if (
fpMP->IsWarning())
386 "G4PhysicalVolumeModel::VisitGeometryAndGetVisReps: WARNING:"
387 "\n built-in replicated volumes replicated in radius for "
389 "-type\n solids (your solid \""
391 "\") are not visualisable."
393 visualisable =
false;
400 pRotation = &rotation;
403 pVPV -> SetTranslation (translation);
404 pVPV -> SetRotation (pRotation);
409 theAT, sceneHandler);
413 pVPV -> SetTranslation (originalTranslation);
414 pVPV -> SetRotation (pOriginalRotation);
416 ((
G4Tubs*)pSol)->SetInnerRadius(originalRMin);
417 ((
G4Tubs*)pSol)->SetOuterRadius(originalRMax);
425 G4int requestedDepth,
447 const G4ThreeVector& translation = pVPV -> GetTranslation ();
465 if (
fpMP->GetDefaultVisAttributes()) {
471 if (
fpMP->GetCBDAlgorithmNumber() == 1) {
473 if (
fpMP->GetCBDParameters().size() != 3) {
474 G4Exception(
"G4PhysicalVolumeModelTouchable::DescribeAndDescend",
477 "Algorithm-parameter mismatch for Colour By Density");
488 red = (d1-d)/(d1-d0); green = (d-d0)/(d1-d0); blue = 0.;
490 red = 0.; green = (d2-d)/(d2-d1); blue = (d-d1)/(d2-d1);
492 red = 0.; green = 0.; blue = 1.;
497 }
else if (
fpMP->GetCBDAlgorithmNumber() == 2) {
501 pVisAttribs = tempVisAtts;
507 const auto& vams =
fpMP->GetVisAttributesModifiers();
510 for (
const auto& vam: vams) {
511 const auto& vamPath = vam.GetPVNameCopyNoPath();
515 auto iVAMNameCopyNo = vamPath.begin();
517 for (; iVAMNameCopyNo != vamPath.end(); ++iVAMNameCopyNo, ++iPVNodeId) {
519 iVAMNameCopyNo->GetName() ==
520 iPVNodeId->GetPhysicalVolume()->GetName() &&
521 iVAMNameCopyNo->GetCopyNo() ==
522 iPVNodeId->GetPhysicalVolume()->GetCopyNo()
528 if (iVAMNameCopyNo == vamPath.end()) {
534 modifiedVisAtts = *pVisAttribs;
535 pVisAttribs = &modifiedVisAtts;
537 switch (vam.GetVisAttributesSignifier()) {
599 if (
fpMP->IsSpecialMeshRendering()) {
600 G4bool potentialG4Mesh =
false;
601 if (
fpMP->GetSpecialMeshVolumes().empty()) {
603 potentialG4Mesh =
true;
606 for (
const auto& pvNameCopyNo:
fpMP->GetSpecialMeshVolumes()) {
607 if (pVPV->
GetName() == pvNameCopyNo.GetName()) {
609 if (pvNameCopyNo.GetCopyNo() < 0) {
611 potentialG4Mesh =
true;
613 if (pVPV->
GetCopyNo() == pvNameCopyNo.GetCopyNo()) {
615 potentialG4Mesh =
true;
621 if (potentialG4Mesh) {
624 G4Mesh mesh(pVPV,theNewAT);
645 const auto& transparencyByDepthParameter =
fpMP->GetTransparencyByDepth();
647 if (transparencyByDepthParameter > 0 && maxDepth > 0) {
648 const auto& option =
fpMP->GetTransparencyByDepthOption();
652 if (currentFullDepth <= transparencyByDepthParameter) alpha = 0.;
656 alpha = currentFullDepth - transparencyByDepthParameter;
657 alpha = std::min(1.,std::max(0.,alpha));
666 const auto& k = transparencyByDepthParameter;
667 alpha =
G4double(currentFullDepth) / maxDepth - 2 * k / maxDepth + 1;
668 alpha = std::min(1., std::max(0., alpha));
677 transparencyByDepthVisAtts = *pVisAttribs;
678 pVisAttribs = &transparencyByDepthVisAtts;
681 colour.
SetAlpha(colour.GetAlpha()*alpha);
682 transparencyByDepthVisAtts.
SetColour(colour);
687 G4bool thisToBeDrawn =
true;
692 G4bool cullingInvisible =
fpMP->IsCullingInvisible();
695 G4bool cullingLowDensity =
fpMP->IsDensityCulling();
702 if (cullingInvisible) {
704 if (!markedVisible) thisToBeDrawn =
false;
707 if (cullingLowDensity) {
709 if (density < densityCut) thisToBeDrawn =
false;
713 if (
fAbort) thisToBeDrawn =
false;
716 nodeID.SetDrawn(thisToBeDrawn);
739 explodeFactor * oldTranslation.
dy(),
740 explodeFactor * oldTranslation.
dz());
741 theNewAT = centering * newTranslation * oldRotation * oldScale;
753 G4bool daughtersToBeDrawn =
true;
755 if (!nDaughters) daughtersToBeDrawn =
false;
757 else if (requestedDepth == 0) daughtersToBeDrawn =
false;
759 else if (
fAbort) daughtersToBeDrawn =
false;
769 G4bool cullingCovered =
fpMP->IsCullingCovered();
784 if (cullingInvisible) {
786 if (daughtersInvisible) daughtersToBeDrawn =
false;
789 if (cullingCovered) {
791 if (surfaceDrawing) {
795 if (opaque) daughtersToBeDrawn =
false;
802 if (daughtersToBeDrawn) {
803 for (
G4int iDaughter = 0; iDaughter < nDaughters; iDaughter++) {
809 (pDaughterVPV, requestedDepth - 1, theNewAT, sceneHandler);
835 const auto& pSolA = target;
838 if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z()) {
851 const auto& pSolA = target;
852 const auto& pSolB = intersector;
854 pSolB->BoundingLimits(minB,maxB);
855 pMin.
set(std::max(minA.
x(),minB.
x()),
856 std::max(minA.
y(),minB.
y()),
857 std::max(minA.
z(),minB.
z()));
858 pMax.
set(std::min(maxA.
x(),maxB.
x()),
859 std::min(maxA.
y(),maxB.
y()),
860 std::min(maxA.
z(),maxB.
z()));
861 if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z()) {
888 G4VSolid* pResultantSolid =
nullptr;
895 if (SubtractionBoundingLimits(pSol)) {
897 (
"subtracted_clipped_solid", pSol, pDisplacedSolid);
901 if (IntersectionBoundingLimits(pSol, pDisplacedSolid)) {
903 (
"intersected_clipped_solid", pSol, pDisplacedSolid);
908 }
else if (pSectionSolid) {
910 if (IntersectionBoundingLimits(pSol, pDisplacedSolid)) {
914 }
else if (pCutawaySolid) {
916 switch (
fpMP->GetCutawayMode()) {
918 if (SubtractionBoundingLimits(pSol)) {
923 if (IntersectionBoundingLimits(pSol, pDisplacedSolid)) {
930 if (pResultantSolid) {
936 delete pResultantSolid;
937 delete pDisplacedSolid;
949 auto iterator = find(pvStore->begin(),pvStore->end(),
fpTopPV);
950 if (iterator == pvStore->end()) {
953 ed <<
"Attempt to validate a volume that is no longer in the physical volume store.";
965 std::map<G4String,G4AttDef>* store
969 G4AttDef(
"PVPath",
"Physical Volume Path",
"Physics",
"",
"G4String");
970 (*store)[
"BasePVPath"] =
971 G4AttDef(
"BasePVPath",
"Base Physical Volume Path",
"Physics",
"",
"G4String");
973 G4AttDef(
"LVol",
"Logical Volume",
"Physics",
"",
"G4String");
975 G4AttDef(
"Solid",
"Solid Name",
"Physics",
"",
"G4String");
977 G4AttDef(
"EType",
"Entity Type",
"Physics",
"",
"G4String");
979 G4AttDef(
"DmpSol",
"Dump of Solid properties",
"Physics",
"",
"G4String");
980 (*store)[
"LocalTrans"] =
981 G4AttDef(
"LocalTrans",
"Local transformation of volume",
"Physics",
"",
"G4String");
982 (*store)[
"LocalExtent"] =
983 G4AttDef(
"LocalExtent",
"Local extent of volume",
"Physics",
"",
"G4String");
984 (*store)[
"GlobalTrans"] =
985 G4AttDef(
"GlobalTrans",
"Global transformation of volume",
"Physics",
"",
"G4String");
986 (*store)[
"GlobalExtent"] =
987 G4AttDef(
"GlobalExtent",
"Global extent of volume",
"Physics",
"",
"G4String");
988 (*store)[
"Material"] =
989 G4AttDef(
"Material",
"Material Name",
"Physics",
"",
"G4String");
990 (*store)[
"Density"] =
991 G4AttDef(
"Density",
"Material Density",
"Physics",
"G4BestUnit",
"G4double");
993 G4AttDef(
"State",
"Material State (enum undefined,solid,liquid,gas)",
"Physics",
"",
"G4String");
995 G4AttDef(
"Radlen",
"Material Radiation Length",
"Physics",
"G4BestUnit",
"G4double");
997 G4AttDef(
"Region",
"Cuts Region",
"Physics",
"",
"G4String");
998 (*store)[
"RootRegion"] =
999 G4AttDef(
"RootRegion",
"Root Region (0/1 = false/true)",
"Physics",
"",
"G4bool");
1004static std::ostream& operator<< (std::ostream& o,
const G4Transform3D t)
1006 using namespace std;
1016 o << setw(w) << t.
xx() << setw(w) << t.
xy() << setw(w) << t.
xz() << setw(w) << t.
dx() << endl;
1017 o << setw(w) << t.
yx() << setw(w) << t.
yy() << setw(w) << t.
yz() << setw(w) << t.
dy() << endl;
1018 o << setw(w) << t.
zx() << setw(w) << t.
zy() << setw(w) << t.
zz() << setw(w) << t.
dz() << endl;
1021 o <<
"= translation:" << endl;
1022 o << setw(w) << tl.
dx() << setw(w) << tl.
dy() << setw(w) << tl.
dz() << endl;
1025 o <<
"* rotation:" << endl;
1026 o << setw(w) << r.
xx() << setw(w) << r.
xy() << setw(w) << r.
xz() << endl;
1027 o << setw(w) << r.
yx() << setw(w) << r.
yy() << setw(w) << r.
yz() << endl;
1028 o << setw(w) << r.
zx() << setw(w) << r.
zy() << setw(w) << r.
zz() << endl;
1031 o <<
"* scale:" << endl;
1032 o << setw(w) << sc.
xx() << setw(w) << sc.
yy() << setw(w) << sc.
zz() << endl;
1035 o <<
"Transformed axes:" << endl;
1036 o <<
"x': " << r *
G4Vector3D(1., 0., 0.) << endl;
1037 o <<
"y': " << r *
G4Vector3D(0., 1., 0.) << endl;
1038 o <<
"z': " << r *
G4Vector3D(0., 0., 1.) << endl;
1045 std::vector<G4AttValue>* values =
new std::vector<G4AttValue>;
1049 (
"G4PhysicalVolumeModel::CreateCurrentAttValues",
1052 "Current logical volume not defined.");
1057 values->push_back(
G4AttValue(
"PVPath", oss.str(),
""));
1060 values->push_back(
G4AttValue(
"BasePVPath", oss.str(),
""));
1069 oss.str(
""); oss <<
'\n' << *pSol;
1070 values->push_back(
G4AttValue(
"DmpSol", oss.str(),
""));
1074 oss.str(
""); oss <<
'\n' <<
G4Transform3D(localRotation,localTranslation);
1075 values->push_back(
G4AttValue(
"LocalTrans", oss.str(),
""));
1077 oss.str(
""); oss <<
'\n' << pSol->
GetExtent() << std::endl;
1078 values->push_back(
G4AttValue(
"LocalExtent", oss.str(),
""));
1081 values->push_back(
G4AttValue(
"GlobalTrans", oss.str(),
""));
1084 values->push_back(
G4AttValue(
"GlobalExtent", oss.str(),
""));
1087 values->push_back(
G4AttValue(
"Material", matName,
""));
1093 oss.str(
""); oss << matState;
1094 values->push_back(
G4AttValue(
"State", oss.str(),
""));
1101 values->push_back(
G4AttValue(
"Region", regionName,
""));
1104 values->push_back(
G4AttValue(
"RootRegion", oss.str(),
""));
1109G4bool G4PhysicalVolumeModel::G4PhysicalVolumeNodeID::operator<
1112 if (fpPV < right.fpPV)
return true;
1113 if (fpPV == right.fpPV) {
1114 if (fCopyNo < right.fCopyNo)
return true;
1115 if (fCopyNo == right.fCopyNo)
1116 return fNonCulledDepth < right.fNonCulledDepth;
1121G4bool G4PhysicalVolumeModel::G4PhysicalVolumeNodeID::operator!=
1124 if (fpPV != right.fpPV ||
1125 fCopyNo != right.fCopyNo ||
1126 fNonCulledDepth != right.fNonCulledDepth ||
1127 fTransform != right.fTransform ||
1128 fDrawn != right.fDrawn)
return true;
1132std::ostream&
operator<<
1138 <<
' ' << node.GetCopyNo()
1146 os <<
" (Null PV node)";
1151std::ostream&
operator<<
1152(std::ostream& os,
const std::vector<G4PhysicalVolumeModel::G4PhysicalVolumeNodeID>& path)
1157 for (
const auto& nodeID: path) {
1158 os <<
' ' << nodeID;
1165(
const std::vector<G4PhysicalVolumeNodeID>& fullPVPath):
1166 fFullPVPath(fullPVPath) {}
1170 size_t i = fFullPVPath.size() - depth - 1;
1171 if (i >= fFullPVPath.size()) {
1172 G4Exception(
"G4PhysicalVolumeModelTouchable::GetTranslation",
1175 "Index out of range. Asking for non-existent depth");
1178 tempTranslation = fFullPVPath[i].GetTransform().getTranslation();
1179 return tempTranslation;
1184 size_t i = fFullPVPath.size() - depth - 1;
1185 if (i >= fFullPVPath.size()) {
1186 G4Exception(
"G4PhysicalVolumeModelTouchable::GetRotation",
1189 "Index out of range. Asking for non-existent depth");
1192 tempRotation = fFullPVPath[i].GetTransform().getRotation();
1193 return &tempRotation;
1198 size_t i = fFullPVPath.size() - depth - 1;
1199 if (i >= fFullPVPath.size()) {
1200 G4Exception(
"G4PhysicalVolumeModelTouchable::GetVolume",
1203 "Index out of range. Asking for non-existent depth");
1205 return fFullPVPath[i].GetPhysicalVolume();
1210 size_t i = fFullPVPath.size() - depth - 1;
1211 if (i >= fFullPVPath.size()) {
1212 G4Exception(
"G4PhysicalVolumeModelTouchable::GetSolid",
1215 "Index out of range. Asking for non-existent depth");
1217 return fFullPVPath[i].GetPhysicalVolume()->GetLogicalVolume()->GetSolid();
1222 size_t i = fFullPVPath.size() - depth - 1;
1223 if (i >= fFullPVPath.size()) {
1224 G4Exception(
"G4PhysicalVolumeModelTouchable::GetReplicaNumber",
1227 "Index out of range. Asking for non-existent depth");
1229 return fFullPVPath[i].GetCopyNo();
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
G4ThreadLocal T * G4GeomSplitter< T >::offset
G4VPVParameterisation * GetParameterisation() const override
void GetReplicationData(EAxis &axis, G4int &nReplicas, G4double &width, G4double &offset, G4bool &consuming) const override
G4bool IsReplicated() const override
void SetCopyNo(G4int CopyNo) override
G4int GetCopyNo() const override
CLHEP::HepRotation G4RotationMatrix
CLHEP::Hep3Vector G4ThreeVector
HepGeom::Vector3D< G4double > G4Vector3D
void set(double x, double y, double z)
HepRotation & rotateZ(double delta)
const G4VisExtent & GetBoundingExtent() const
G4double GetAlpha() const
G4DisplacedSolid is a solid that has been shifted from its original frame of reference to a new one....
void BoundingLimits(G4ThreeVector &pMin, G4ThreeVector &pMax) const override
G4IntersectionSolid is a solid describing the Boolean intersection of two solids.
G4LogicalVolume represents a leaf node or unpositioned subtree in the geometry hierarchy....
const G4VisAttributes * GetVisAttributes() const
std::size_t GetNoDaughters() const
G4double GetDensity() const
G4VPhysicalVolume * GetParameterisedVolume() const
MeshType GetMeshType() const
std::vector< PVNameCopyNo > PVNameCopyNoPath
@ VASForceNumberOfCloudPoints
@ VASForceLineSegmentsPerCircle
void SetSpecialMeshRendering(G4bool)
G4VSolid * GetSolid(G4int depth) const
G4VPhysicalVolume * GetVolume(G4int depth) const
G4int GetReplicaNumber(G4int depth) const
const G4RotationMatrix * GetRotation(G4int depth) const
G4PhysicalVolumeModelTouchable(const std::vector< G4PhysicalVolumeNodeID > &fullPVPath)
const G4ThreeVector & GetTranslation(G4int depth) const
G4int fTotalAllTouchables
void DescribeAndDescend(G4VPhysicalVolume *, G4int requestedDepth, G4LogicalVolume *, G4VSolid *, G4Material *, const G4Transform3D &, G4VGraphicsScene &)
std::vector< G4PhysicalVolumeNodeID > fFullPVPath
G4VPhysicalVolume * fpTopPV
void VisitGeometryAndGetVisReps(G4VPhysicalVolume *, G4int requestedDepth, const G4Transform3D &, G4VGraphicsScene &)
std::map< G4int, G4int > fMapAllTouchables
std::vector< G4AttValue > * CreateCurrentAttValues() const
G4PhysicalVolumeModel(G4VPhysicalVolume *=0, G4int requestedDepth=UNLIMITED, const G4Transform3D &modelTransformation=G4Transform3D(), const G4ModelingParameters *=0, G4bool useFullExtent=false, const std::vector< G4PhysicalVolumeNodeID > &baseFullPVPath=std::vector< G4PhysicalVolumeNodeID >())
G4VSolid * fpClippingSolid
G4Material * fpCurrentMaterial
std::map< G4int, G4int > fMapDrawnTouchables
virtual ~G4PhysicalVolumeModel()
G4String GetCurrentTag() const
std::vector< G4PhysicalVolumeNodeID > fDrawnPVPath
G4Transform3D fCurrentTransform
G4bool Validate(G4bool warn)
virtual void DescribeSolid(const G4Transform3D &theAT, G4VSolid *pSol, const G4VisAttributes *pVisAttribs, G4VGraphicsScene &sceneHandler)
ClippingMode fClippingMode
static G4String GetPVNamePathString(const std::vector< G4PhysicalVolumeNodeID > &)
G4String GetCurrentDescription() const
void DescribeYourselfTo(G4VGraphicsScene &)
G4int fTotalDrawnTouchables
std::vector< G4PhysicalVolumeNodeID > fBaseFullPVPath
G4VPhysicalVolume * fpCurrentPV
const std::map< G4String, G4AttDef > * GetAttDefs() const
static G4ModelingParameters::PVNameCopyNoPath GetPVNameCopyNoPath(const std::vector< G4PhysicalVolumeNodeID > &)
G4LogicalVolume * fpCurrentLV
static G4PhysicalVolumeStore * GetInstance()
G4Region defines a region or a group of regions in the detector geometry setup, sharing properties as...
const G4String & GetName() const
G4SubtractionSolid is a solid describing the Boolean subtraction of two solids.
G4Tubs is a tube or tube segment with curved sides parallel to the Z-axis. The tube has a specified h...
G4int GetMaxGeometryDepth() const
virtual void AddCompound(const G4VTrajectory &)=0
virtual void PostAddSolid()=0
virtual void PreAddSolid(const G4Transform3D &objectTransformation, const G4VisAttributes &visAttribs)=0
G4String fGlobalDescription
const G4VisExtent & GetExtent() const
const G4ModelingParameters * fpMP
G4VModel(const G4ModelingParameters *=0)
G4VPVParameterisation ia an abstract base class for Parameterisation, able to compute the transformat...
G4VPhysicalVolume is an abstract base class for the representation of a positioned volume....
virtual G4int GetCopyNo() const =0
const G4String & GetName() const
G4VSolid is an abstract base class for solids, physical shapes that can be tracked through....
virtual G4VisExtent GetExtent() const
virtual void BoundingLimits(G4ThreeVector &pMin, G4ThreeVector &pMax) const
virtual G4GeometryType GetEntityType() const =0
G4int GetForcedNumberOfCloudPoints() const
G4double GetLineWidth() const
G4bool IsDaughtersInvisible() const
void SetColour(const G4Colour &)
void SetVisibility(G4bool=true)
void SetForceAuxEdgeVisible(G4bool=true)
void SetForceCloud(G4bool=true)
G4int GetForcedLineSegmentsPerCircle() const
void SetForceWireframe(G4bool=true)
void SetLineWidth(G4double)
LineStyle GetLineStyle() const
const G4Colour & GetColour() const
G4bool IsForceAuxEdgeVisible() const
G4bool IsForcedAuxEdgeVisible() const
ForcedDrawingStyle GetForcedDrawingStyle() const
void SetForceSolid(G4bool=true)
void SetLineStyle(LineStyle)
void SetForceLineSegmentsPerCircle(G4int nSegments)
void SetDaughtersInvisible(G4bool=true)
void SetForceNumberOfCloudPoints(G4int nPoints)
G4bool IsForceDrawingStyle() const
std::map< G4String, G4AttDef > * GetInstance(const G4String &storeKey, G4bool &isNew)
const axis_t axis_to_type< N >::axis