58 G4int volumeCount = 0;
63 ,
G4int requestedDepth
67 ,
const std::vector<G4PhysicalVolumeNodeID>& baseFullPVPath)
70 , fTopPVCopyNo (pVPV? pVPV->
GetCopyNo(): 0)
71 , fRequestedDepth (requestedDepth)
72 , fUseFullExtent (useFullExtent)
74 , fpCurrentPV (fpTopPV)
75 , fCurrentPVCopyNo (fpTopPV? fpTopPV->GetCopyNo(): 0)
76 , fpCurrentLV (fpTopPV? fpTopPV->GetLogicalVolume(): 0)
77 , fpCurrentMaterial (fpCurrentLV? fpCurrentLV->GetMaterial(): 0)
78 , fpCurrentTransform (const_cast<G4Transform3D*>(&modelTransformation))
79 , fBaseFullPVPath (baseFullPVPath)
81 , fCurtailDescent (
false)
83 , fClippingMode (subtraction)
85 fType =
"G4PhysicalVolumeModel";
100 fGlobalDescription =
"G4PhysicalVolumeModel " + fGlobalTag;
104 fTopPVName = fpTopPV -> GetName ();
105 std::ostringstream oss;
106 oss << fpTopPV->GetName() <<
':' << fpTopPV->GetCopyNo()
107 <<
" BasePath:" << fBaseFullPVPath;
108 fGlobalTag = oss.str();
109 fGlobalDescription =
"G4PhysicalVolumeModel " + fGlobalTag;
120 (
const std::vector<G4PhysicalVolumeNodeID>& path)
123 for (
const auto& node: path) {
124 PVNameCopyNoPath.push_back
126 (node.GetPhysicalVolume()->GetName(),node.GetCopyNo()));
128 return PVNameCopyNoPath;
179 (
"G4PhysicalVolumeModel::DescribeYourselfTo",
183 (
"G4PhysicalVolumeModel::DescribeYourselfTo",
190 VisitGeometryAndGetVisReps
193 startingTransformation,
203 fpCurrentPV = fpTopPV;
204 fCurrentPVCopyNo = fpTopPV->GetCopyNo();
205 fpCurrentLV = fpTopPV->GetLogicalVolume();
206 fpCurrentMaterial = fpCurrentLV? fpCurrentLV->GetMaterial(): 0;
207 fFullPVPath = fBaseFullPVPath;
208 fDrawnPVPath.clear();
210 fCurtailDescent =
false;
216 std::ostringstream o;
221 return "WARNING: NO CURRENT VOLUME - global tag is " +
fGlobalTag;
232 G4int requestedDepth,
249 if (!(pVPV -> IsReplicated ())) {
251 pSol = pLV -> GetSolid ();
252 pMaterial = pLV -> GetMaterial ();
253 DescribeAndDescend (pVPV, requestedDepth, pLV, pSol, pMaterial,
254 theAT, sceneHandler);
263 pVPV -> GetReplicationData (axis, nReplicas, width, offset, consuming);
265 G4int nEnd = nReplicas;
266 if (fCurrentDepth == 0) {
267 nBegin = fTopPVCopyNo;
272 for (
int n = nBegin;
n < nEnd;
n++) {
273 pSol = pP -> ComputeSolid (
n, pVPV);
274 pP -> ComputeTransformation (
n, pVPV);
275 pSol -> ComputeDimensions (pP,
n, pVPV);
276 pVPV -> SetCopyNo (
n);
277 fCurrentPVCopyNo =
n;
282 pMaterial = pP -> ComputeMaterial (
n, pVPV, &parentTouchable);
283 DescribeAndDescend (pVPV, requestedDepth, pLV, pSol, pMaterial,
284 theAT, sceneHandler);
309 pSol = pLV -> GetSolid ();
310 pMaterial = pLV -> GetMaterial ();
311 G4ThreeVector originalTranslation = pVPV -> GetTranslation ();
313 G4double originalRMin = 0., originalRMax = 0.;
315 originalRMin = ((
G4Tubs*)pSol)->GetInnerRadius();
316 originalRMax = ((
G4Tubs*)pSol)->GetOuterRadius();
318 G4bool visualisable =
true;
319 for (
int n = nBegin;
n < nEnd;
n++) {
326 translation =
G4ThreeVector (-width*(nReplicas-1)*0.5+
n*width,0,0);
329 translation =
G4ThreeVector (0,-width*(nReplicas-1)*0.5+
n*width,0);
332 translation =
G4ThreeVector (0,0,-width*(nReplicas-1)*0.5+
n*width);
336 ((
G4Tubs*)pSol)->SetInnerRadius(width*
n+offset);
337 ((
G4Tubs*)pSol)->SetOuterRadius(width*(
n+1)+offset);
339 if (fpMP->IsWarning())
341 "G4PhysicalVolumeModel::VisitGeometryAndGetVisReps: WARNING:"
342 "\n built-in replicated volumes replicated in radius for "
344 "-type\n solids (your solid \""
346 "\") are not visualisable."
348 visualisable =
false;
352 rotation.
rotateZ (-(offset+(
n+0.5)*width));
355 pRotation = &rotation;
358 pVPV -> SetTranslation (translation);
359 pVPV -> SetRotation (pRotation);
360 pVPV -> SetCopyNo (
n);
361 fCurrentPVCopyNo =
n;
363 DescribeAndDescend (pVPV, requestedDepth, pLV, pSol, pMaterial,
364 theAT, sceneHandler);
368 pVPV -> SetTranslation (originalTranslation);
369 pVPV -> SetRotation (pOriginalRotation);
371 ((
G4Tubs*)pSol)->SetInnerRadius(originalRMin);
372 ((
G4Tubs*)pSol)->SetOuterRadius(originalRMax);
380 G4int requestedDepth,
391 fpCurrentMaterial = pMaterial;
394 const G4ThreeVector& translation = pVPV -> GetTranslation ();
405 if (fCurrentDepth != 0) theNewAT = theAT * theLT;
406 fpCurrentTransform = &theNewAT;
414 if (fpMP->GetCBDAlgorithmNumber() == 1) {
416 if (fpMP->GetCBDParameters().size() != 3) {
417 G4Exception(
"G4PhysicalVolumeModelTouchable::DescribeAndDescend",
420 "Algorithm-parameter mismatch for Colour By Density");
423 const G4double d0 = fpMP->GetCBDParameters()[0];
424 const G4double d1 = fpMP->GetCBDParameters()[1];
425 const G4double d2 = fpMP->GetCBDParameters()[2];
431 red = (d1-
d)/(d1-d0); green = (d-d0)/(d1-d0); blue = 0.;
433 red = 0.; green = (d2-
d)/(d2-d1); blue = (d-
d1)/(d2-d1);
435 red = 0.; green = 0.; blue = 1.;
440 }
else if (fpMP->GetCBDAlgorithmNumber() == 2) {
444 pVisAttribs = tempVisAtts;
450 G4bool thisToBeDrawn =
true;
453 G4int copyNo = fpCurrentPV->GetCopyNo();
454 fFullPVPath.push_back
456 (fpCurrentPV,copyNo,fCurrentDepth,*fpCurrentTransform));
459 const auto& vams = fpMP->GetVisAttributesModifiers();
462 for (
const auto& vam: vams) {
463 const auto& vamPath = vam.GetPVNameCopyNoPath();
464 if (vamPath.size() == fFullPVPath.size()) {
467 auto iVAMNameCopyNo = vamPath.begin();
468 auto iPVNodeId = fFullPVPath.begin();
469 for (; iVAMNameCopyNo != vamPath.end(); ++iVAMNameCopyNo, ++iPVNodeId) {
471 iVAMNameCopyNo->GetName() ==
472 iPVNodeId->GetPhysicalVolume()->GetName() &&
473 iVAMNameCopyNo->GetCopyNo() ==
474 iPVNodeId->GetPhysicalVolume()->GetCopyNo()
480 if (iVAMNameCopyNo == vamPath.end()) {
486 modifiedVisAtts = *pVisAttribs;
487 pVisAttribs = &modifiedVisAtts;
489 switch (vam.GetVisAttributesSignifier()) {
552 G4bool culling = fpMP->IsCulling();
553 G4bool cullingInvisible = fpMP->IsCullingInvisible();
555 G4bool cullingLowDensity = fpMP->IsDensityCulling();
557 G4double densityCut = fpMP -> GetVisibleDensity ();
562 if (cullingInvisible) {
564 if (!markedVisible) thisToBeDrawn =
false;
567 if (cullingLowDensity) {
569 if (density < densityCut) thisToBeDrawn =
false;
573 if (fAbort) thisToBeDrawn =
false;
576 fFullPVPath.back().SetDrawn(thisToBeDrawn);
581 fDrawnPVPath.push_back
583 (fpCurrentPV,copyNo,fCurrentDepth,*fpCurrentTransform,thisToBeDrawn));
585 if (fpMP->IsExplode() && fDrawnPVPath.size() == 1) {
593 G4double explodeFactor = fpMP->GetExplodeFactor();
596 explodeFactor * oldTranslation.
dy(),
597 explodeFactor * oldTranslation.
dz());
598 theNewAT = centering * newTranslation * oldRotation * oldScale;
602 DescribeSolid (theNewAT, pSol, pVisAttribs, sceneHandler);
611 G4bool daughtersToBeDrawn =
true;
613 if (!nDaughters) daughtersToBeDrawn =
false;
615 else if (requestedDepth == 0) daughtersToBeDrawn =
false;
617 else if (fAbort) daughtersToBeDrawn =
false;
619 else if (fCurtailDescent) daughtersToBeDrawn =
false;
627 G4bool cullingCovered = fpMP->IsCullingCovered();
642 if (cullingInvisible) {
644 if (daughtersInvisible) daughtersToBeDrawn =
false;
647 if (cullingCovered) {
649 if (surfaceDrawing) {
653 if (opaque) daughtersToBeDrawn =
false;
660 if (daughtersToBeDrawn) {
661 for (
G4int iDaughter = 0; iDaughter < nDaughters; iDaughter++) {
666 VisitGeometryAndGetVisReps
667 (pDaughterVPV, requestedDepth - 1, theNewAT, sceneHandler);
675 fCurtailDescent =
false;
678 fFullPVPath.pop_back();
680 fDrawnPVPath.pop_back();
693 if (!fpClippingSolid && !pSectionSolid && !pCutawaySolid) {
696 pSol -> DescribeYourselfTo (sceneHandler);
712 if (!pOriginalPolyhedron) {
714 if (fpMP->IsWarning())
716 "WARNING: G4PhysicalVolumeModel::DescribeSolid: solid\n \""
718 "\" has no polyhedron. Cannot by clipped."
720 pSol -> DescribeYourselfTo (sceneHandler);
726 if (fpClippingSolid) {
727 switch (fClippingMode) {
731 (
"subtracted_clipped_solid", pSol, fpClippingSolid, theAT.
inverse());
735 (
"intersected_clipped_solid", pSol, fpClippingSolid, theAT.
inverse());
742 (
"sectioned_solid", pSol, pSectionSolid, theAT.
inverse());
748 (
"cutaway_solid", pSol, pCutawaySolid, theAT.
inverse());
752 if (!pResultantPolyhedron) {
753 if (fpMP->IsWarning())
755 "WARNING: G4PhysicalVolumeModel::DescribeSolid: resultant polyhedron for"
756 "\n solid \"" << pSol->
GetName() <<
757 "\" not defined due to error during Boolean processing."
766 if (pResultantPolyhedron->
GetNoFacets() == pOriginalPolyhedron->GetNoFacets())
770 pResultantPolyhedron =
nullptr;
774 if (pResultantPolyhedron) {
781 delete pResultantSolid;
791 size_t nWorlds = transportationManager->
GetNoWorlds();
795 std::vector<G4VPhysicalVolume*>::iterator iterWorld =
797 for (
size_t i = 0; i < nWorlds; ++i, ++iterWorld) {
812 if (foundVolume !=
fpTopPV && warn) {
814 "G4PhysicalVolumeModel::Validate(): A volume of the same name and"
817 <<
") still exists and is being used."
818 "\n But it is not the same volume you originally specified"
819 "\n in /vis/scene/add/."
827 if (found)
return true;
831 "G4PhysicalVolumeModel::Validate(): No volume of name and"
844 std::map<G4String,G4AttDef>* store
848 G4AttDef(
"PVPath",
"Physical Volume Path",
"Physics",
"",
"G4String");
849 (*store)[
"BasePVPath"] =
850 G4AttDef(
"BasePVPath",
"Base Physical Volume Path",
"Physics",
"",
"G4String");
852 G4AttDef(
"LVol",
"Logical Volume",
"Physics",
"",
"G4String");
854 G4AttDef(
"Solid",
"Solid Name",
"Physics",
"",
"G4String");
856 G4AttDef(
"EType",
"Entity Type",
"Physics",
"",
"G4String");
858 G4AttDef(
"DmpSol",
"Dump of Solid properties",
"Physics",
"",
"G4String");
859 (*store)[
"LocalTrans"] =
860 G4AttDef(
"LocalTrans",
"Local transformation of volume",
"Physics",
"",
"G4String");
861 (*store)[
"GlobalTrans"] =
862 G4AttDef(
"GlobalTrans",
"Global transformation of volume",
"Physics",
"",
"G4String");
863 (*store)[
"Material"] =
864 G4AttDef(
"Material",
"Material Name",
"Physics",
"",
"G4String");
865 (*store)[
"Density"] =
866 G4AttDef(
"Density",
"Material Density",
"Physics",
"G4BestUnit",
"G4double");
868 G4AttDef(
"State",
"Material State (enum undefined,solid,liquid,gas)",
"Physics",
"",
"G4String");
870 G4AttDef(
"Radlen",
"Material Radiation Length",
"Physics",
"G4BestUnit",
"G4double");
872 G4AttDef(
"Region",
"Cuts Region",
"Physics",
"",
"G4String");
873 (*store)[
"RootRegion"] =
874 G4AttDef(
"RootRegion",
"Root Region (0/1 = false/true)",
"Physics",
"",
"G4bool");
891 o << setw(
w) << t.
xx() << setw(
w) << t.
xy() << setw(
w) << t.
xz() << setw(
w) << t.
dx() << endl;
892 o << setw(
w) << t.
yx() << setw(
w) << t.
yy() << setw(
w) << t.
yz() << setw(
w) << t.
dy() << endl;
893 o << setw(
w) << t.
zx() << setw(
w) << t.
zy() << setw(
w) << t.
zz() << setw(
w) << t.
dz() << endl;
896 o <<
"= translation:" << endl;
897 o << setw(
w) << tl.dx() << setw(
w) << tl.dy() << setw(
w) << tl.dz() << endl;
900 o <<
"* rotation:" << endl;
901 o << setw(
w) <<
r.xx() << setw(
w) <<
r.xy() << setw(
w) <<
r.xz() << endl;
902 o << setw(
w) <<
r.yx() << setw(
w) <<
r.yy() << setw(
w) <<
r.yz() << endl;
903 o << setw(
w) <<
r.zx() << setw(
w) <<
r.zy() << setw(
w) <<
r.zz() << endl;
906 o <<
"* scale:" << endl;
907 o << setw(
w) <<
sc.xx() << setw(
w) <<
sc.yy() << setw(
w) <<
sc.zz() << endl;
910 o <<
"Transformed axes:" << endl;
920 std::vector<G4AttValue>*
values =
new std::vector<G4AttValue>;
924 (
"G4PhysicalVolumeModel::CreateCurrentAttValues",
927 "Current logical volume not defined.");
932 values->push_back(
G4AttValue(
"PVPath", oss.str(),
""));
934 values->push_back(
G4AttValue(
"BasePVPath", oss.str(),
""));
939 oss.str(
""); oss <<
'\n' << *pSol;
940 values->push_back(
G4AttValue(
"DmpSol", oss.str(),
""));
943 oss.str(
""); oss <<
'\n' <<
G4Transform3D(localRotation,localTranslation);
944 values->push_back(
G4AttValue(
"LocalTrans", oss.str(),
""));
946 values->push_back(
G4AttValue(
"GlobalTrans", oss.str(),
""));
948 values->push_back(
G4AttValue(
"Material", matName,
""));
952 oss.str(
""); oss << matState;
953 values->push_back(
G4AttValue(
"State", oss.str(),
""));
958 values->push_back(
G4AttValue(
"Region", regionName,
""));
960 values->push_back(
G4AttValue(
"RootRegion", oss.str(),
""));
964 G4bool G4PhysicalVolumeModel::G4PhysicalVolumeNodeID::operator<
967 if (fpPV <
right.fpPV)
return true;
968 if (fpPV ==
right.fpPV) {
969 if (fCopyNo <
right.fCopyNo)
return true;
970 if (fCopyNo ==
right.fCopyNo)
971 return fNonCulledDepth <
right.fNonCulledDepth;
976 std::ostream&
operator<<
982 <<
' ' << node.GetCopyNo()
990 os <<
" (Null node)";
995 std::ostream&
operator<<
996 (std::ostream& os,
const std::vector<G4PhysicalVolumeModel::G4PhysicalVolumeNodeID>& path)
1001 for (
const auto& nodeID: path) {
1002 os <<
' ' << nodeID;
1009 (
const std::vector<G4PhysicalVolumeNodeID>& fullPVPath):
1010 fFullPVPath(fullPVPath) {}
1016 G4Exception(
"G4PhysicalVolumeModelTouchable::GetTranslation",
1019 "Index out of range. Asking for non-existent depth");
1022 tempTranslation =
fFullPVPath[i].GetTransform().getTranslation();
1023 return tempTranslation;
1030 G4Exception(
"G4PhysicalVolumeModelTouchable::GetRotation",
1033 "Index out of range. Asking for non-existent depth");
1036 tempRotation =
fFullPVPath[i].GetTransform().getRotation();
1037 return &tempRotation;
1044 G4Exception(
"G4PhysicalVolumeModelTouchable::GetVolume",
1047 "Index out of range. Asking for non-existent depth");
1056 G4Exception(
"G4PhysicalVolumeModelTouchable::GetSolid",
1059 "Index out of range. Asking for non-existent depth");
1061 return fFullPVPath[i].GetPhysicalVolume()->GetLogicalVolume()->GetSolid();
1068 G4Exception(
"G4PhysicalVolumeModelTouchable::GetReplicaNumber",
1071 "Index out of range. Asking for non-existent depth");