746{
747 G4double motherMinExtent= kInfinity, motherMaxExtent= -kInfinity,
748 targetMinExtent= kInfinity, targetMaxExtent= -kInfinity;
754 size_t nCandidates = pCandidates->size();
755 size_t nVol, nNode, targetVolNo;
757
758#ifdef G4GEOMETRY_VOXELDEBUG
759 G4cout <<
"**** G4SmartVoxelHeader::BuildNodes" <<
G4endl
760 <<
" Limits = " << pLimits <<
G4endl
761 <<
" Axis = " << pAxis <<
G4endl
762 <<
" Candidates = " << nCandidates <<
G4endl;
763#endif
764
765
766
767
771 motherMinExtent, motherMaxExtent) )
772 {
774 motherMinExtent, motherMaxExtent);
775 }
778
781 {
782
783
784
787 if (pParam == nullptr)
788 {
789 std::ostringstream message;
790 message <<
"PANIC! - Missing parameterisation." <<
G4endl
791 << " Replicated volume with no parameterisation object !";
792 G4Exception(
"G4SmartVoxelHeader::BuildNodes()",
"GeomMgt0003",
794 return nullptr;
795 }
796
797
798
801 replicated = true;
802 }
803 else
804 {
805 replicated = false;
806 }
807
808
809
810 for (nVol=0; nVol<nCandidates; ++nVol)
811 {
812 targetVolNo = (*pCandidates)[nVol];
813 if (replicated == false)
814 {
816
817
818
821
822
824 }
825 else
826 {
827
828
829 targetSolid = pParam->
ComputeSolid(targetVolNo,pDaughter);
830
831
832
834
835
836
840 }
841
842
844 targetMinExtent, targetMaxExtent))
845 {
847 targetMinExtent,targetMaxExtent);
848 }
849 minExtents[nVol] = targetMinExtent;
850 maxExtents[nVol] = targetMaxExtent;
851
852#ifdef G4GEOMETRY_VOXELDEBUG
853 G4cout <<
"---------------------------------------------------" <<
G4endl
855 <<
" Min Extent = " << targetMinExtent <<
G4endl
856 <<
" Max Extent = " << targetMaxExtent <<
G4endl
857 <<
"---------------------------------------------------" <<
G4endl;
858#endif
859
860
861
862 if ( (!pLimits.
IsLimited()) && ((targetMaxExtent<=motherMinExtent)
863 ||(targetMinExtent>=motherMaxExtent)) )
864 {
865 std::ostringstream message;
866 message <<
"PANIC! - Overlapping daughter with mother volume." <<
G4endl
867 << " Daughter physical volume "
869 << " is entirely outside mother logical volume "
870 << pVolume->
GetName() <<
" !!";
871 G4Exception(
"G4SmartVoxelHeader::BuildNodes()",
"GeomMgt0002",
873 }
874
875#ifdef G4GEOMETRY_VOXELDEBUG
876
877
878
879
881 {
883 G4int kStraddlePercent = 5;
884 width = maxExtents[nVol]-minExtents[nVol];
885 if ( (((motherMinExtent-minExtents[nVol])*100/width) > kStraddlePercent)
886 ||(((maxExtents[nVol]-motherMaxExtent)*100/width) > kStraddlePercent) )
887 {
888 G4cout <<
"**** G4SmartVoxelHeader::BuildNodes" <<
G4endl
889 << " WARNING : Daughter # " << nVol
891 << " Crosses mother boundary of logical volume, name = "
893 << " by more than " << kStraddlePercent
895 }
896 }
897#endif
898 }
899
900
901
902
903
906 for (nVol=0; nVol<nCandidates; ++nVol)
907 {
908
909
910
911
912 currentWidth = std::abs(maxExtents[nVol]-minExtents[nVol]);
913 if ( (currentWidth<minWidth)
916 {
917 minWidth = currentWidth;
918 }
919 }
920
921
922
923
924 G4double noNodesExactD = ((motherMaxExtent-motherMinExtent)*2.0/minWidth)+1.0;
925
926
927
928
929 G4double smartlessComputed = noNodesExactD / nCandidates;
931 G4double smartless = (smartlessComputed <= smartlessUser)
932 ? smartlessComputed : smartlessUser;
933 G4double noNodesSmart = smartless*nCandidates;
935 G4long noNodes = ((noNodesSmart-noNodesExactI)>=0.5)
936 ? noNodesExactI+1 : noNodesExactI;
937 if( noNodes == 0 ) { noNodes=1; }
938
939#ifdef G4GEOMETRY_VOXELDEBUG
940 G4cout <<
" Smartless computed = " << smartlessComputed <<
G4endl
941 << " Smartless volume = " << smartlessUser
942 <<
" => # Smartless = " << smartless <<
G4endl;
943 G4cout <<
" Min width = " << minWidth
944 <<
" => # Nodes = " << noNodes <<
G4endl;
945#endif
946
948 {
950#ifdef G4GEOMETRY_VOXELDEBUG
952#endif
953 }
954 G4double nodeWidth = (motherMaxExtent-motherMinExtent)/noNodes;
955
956
957
959 if (nodeList == nullptr)
960 {
961 G4Exception(
"G4SmartVoxelHeader::BuildNodes()",
"GeomMgt0003",
963 return nullptr;
964 }
965 nodeList->reserve(noNodes);
966
967 for (nNode=0;
G4long(nNode)<noNodes; ++nNode)
968 {
971 if (pNode == nullptr)
972 {
973 G4Exception(
"G4SmartVoxelHeader::BuildNodes()",
"GeomMgt0003",
975 return nullptr;
976 }
977 nodeList->push_back(pNode);
978 }
979
980
981
982
983
984 for (nVol=0; nVol<nCandidates; ++nVol)
985 {
986 G4long nodeNo, minContainingNode, maxContainingNode;
987 minContainingNode = (minExtents[nVol]-motherMinExtent)/nodeWidth;
988 maxContainingNode = (maxExtents[nVol]-motherMinExtent)/nodeWidth;
989
990
991
992 if ( (maxContainingNode>=0) && (minContainingNode<noNodes) )
993 {
994
995
996
997 if (maxContainingNode>=noNodes)
998 {
999 maxContainingNode = noNodes-1;
1000 }
1001
1002
1003
1004 if (minContainingNode<0)
1005 {
1006 minContainingNode = 0;
1007 }
1008 for (nodeNo=minContainingNode; nodeNo<=maxContainingNode; ++nodeNo)
1009 {
1010 (*nodeList)[nodeNo]->Insert((*pCandidates)[nVol]);
1011 }
1012 }
1013 }
1014
1015
1016
1017
1018
1019
1021 if (proxyList == nullptr)
1022 {
1023 G4Exception(
"G4SmartVoxelHeader::BuildNodes()",
"GeomMgt0003",
1025 return nullptr;
1026 }
1027 proxyList->reserve(noNodes);
1028
1029
1030
1031
1032 for (nNode=0;
G4long(nNode)<noNodes; ++nNode)
1033 {
1034
1035
1036 ((*nodeList)[nNode])->Shrink();
1038 if (pProxyNode == nullptr)
1039 {
1040 G4Exception(
"G4SmartVoxelHeader::BuildNodes()",
"GeomMgt0003",
1042 return nullptr;
1043 }
1044 proxyList->push_back(pProxyNode);
1045 }
1046 delete nodeList;
1047 return proxyList;
1048}
G4VSolid * GetSolid() const
G4double GetSmartless() const
const G4String & GetName() const
virtual G4VSolid * ComputeSolid(const G4int, G4VPhysicalVolume *)
virtual void ComputeTransformation(const G4int, G4VPhysicalVolume *) const =0
const G4RotationMatrix * GetRotation() const
const G4ThreeVector GetTranslation() const
G4LogicalVolume * GetLogicalVolume() const
const G4String & GetName() const
virtual G4VPVParameterisation * GetParameterisation() const =0
virtual G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const =0
virtual void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
G4double GetMinExtent(const EAxis pAxis) const
G4double GetMaxExtent(const EAxis pAxis) const
const G4int kMaxVoxelNodes