754{
755 G4double motherMinExtent= kInfinity, motherMaxExtent= -kInfinity,
756 targetMinExtent= kInfinity, targetMaxExtent= -kInfinity;
762 G4int nCandidates = pCandidates->size();
763 G4int nVol, nNode, targetVolNo;
765
766#ifdef G4GEOMETRY_VOXELDEBUG
767 G4cout <<
"**** G4SmartVoxelHeader::BuildNodes" <<
G4endl
768 <<
" Limits = " << pLimits <<
G4endl
769 <<
" Axis = " << pAxis <<
G4endl
770 <<
" Candidates = " << nCandidates <<
G4endl;
771#endif
772
773
774
775
779 motherMinExtent, motherMaxExtent) )
780 {
782 motherMinExtent, motherMaxExtent);
783 }
786
789 {
790
791
792
795 if (!pParam)
796 {
797 std::ostringstream message;
798 message <<
"PANIC! - Missing parameterisation." <<
G4endl
799 << " Replicated volume with no parameterisation object !";
800 G4Exception(
"G4SmartVoxelHeader::BuildNodes()",
"GeomMgt0003",
802 return 0;
803 }
804
805
806
809 replicated = true;
810 }
811 else
812 {
813 replicated = false;
814 }
815
816
817
818 for (nVol=0; nVol<nCandidates; nVol++)
819 {
820 targetVolNo=(*pCandidates)[nVol];
821 if (replicated == false)
822 {
824
825
826
829
830
832 }
833 else
834 {
835
836
837 targetSolid = pParam->
ComputeSolid(targetVolNo,pDaughter);
838
839
840
842
843
844
848 }
849
850
852 targetMinExtent, targetMaxExtent))
853 {
855 targetMinExtent,targetMaxExtent);
856 }
857 minExtents[nVol] = targetMinExtent;
858 maxExtents[nVol] = targetMaxExtent;
859
860#ifdef G4GEOMETRY_VOXELDEBUG
861 G4cout <<
"---------------------------------------------------" <<
G4endl
863 <<
" Min Extent = " << targetMinExtent <<
G4endl
864 <<
" Max Extent = " << targetMaxExtent <<
G4endl
865 <<
"---------------------------------------------------" <<
G4endl;
866#endif
867
868
869
870 if ( (!pLimits.
IsLimited()) && ((targetMaxExtent<=motherMinExtent)
871 ||(targetMinExtent>=motherMaxExtent)) )
872 {
873 std::ostringstream message;
874 message <<
"PANIC! - Overlapping daughter with mother volume." <<
G4endl
875 << " Daughter physical volume "
877 << " is entirely outside mother logical volume "
878 << pVolume->
GetName() <<
" !!";
879 G4Exception(
"G4SmartVoxelHeader::BuildNodes()",
"GeomMgt0002",
881 }
882
883#ifdef G4GEOMETRY_VOXELDEBUG
884
885
886
887
889 {
891 G4int kStraddlePercent=5;
892 width = maxExtents[nVol]-minExtents[nVol];
893 if ( (((motherMinExtent-minExtents[nVol])*100/width) > kStraddlePercent)
894 ||(((maxExtents[nVol]-motherMaxExtent)*100/width) > kStraddlePercent) )
895 {
896 G4cout <<
"**** G4SmartVoxelHeader::BuildNodes" <<
G4endl
897 << " WARNING : Daughter # " << nVol
899 << " Crosses mother boundary of logical volume, name = "
901 << " by more than " << kStraddlePercent
903 }
904 }
905#endif
906 }
907
908
909
910
911
914 for (nVol=0; nVol<nCandidates; nVol++)
915 {
916
917
918
919
920 currentWidth = std::abs(maxExtents[nVol]-minExtents[nVol]);
921 if ( (currentWidth<minWidth)
924 {
925 minWidth = currentWidth;
926 }
927 }
928
929
930
931
932 G4double noNodesExactD = ((motherMaxExtent-motherMinExtent)*2.0/minWidth)+1.0;
933
934
935
936
937 G4double smartlessComputed = noNodesExactD / nCandidates;
939 G4double smartless = (smartlessComputed <= smartlessUser)
940 ? smartlessComputed : smartlessUser;
941 G4double noNodesSmart = smartless*nCandidates;
943 G4int noNodes = ((noNodesSmart-noNodesExactI)>=0.5)
944 ? noNodesExactI+1 : noNodesExactI;
945 if( noNodes == 0 ) { noNodes=1; }
946
947#ifdef G4GEOMETRY_VOXELDEBUG
948 G4cout <<
" Smartless computed = " << smartlessComputed <<
G4endl
949 << " Smartless volume = " << smartlessUser
950 <<
" => # Smartless = " << smartless <<
G4endl;
951 G4cout <<
" Min width = " << minWidth
952 <<
" => # Nodes = " << noNodes <<
G4endl;
953#endif
954
956 {
958#ifdef G4GEOMETRY_VOXELDEBUG
960#endif
961 }
962 G4double nodeWidth = (motherMaxExtent-motherMinExtent)/noNodes;
963
964
965
967 if (!nodeList)
968 {
969 G4Exception(
"G4SmartVoxelHeader::BuildNodes()",
"GeomMgt0003",
971 return 0;
972 }
973 nodeList->reserve(noNodes);
974
975 for (nNode=0; nNode<noNodes; nNode++)
976 {
979 if (!pNode)
980 {
981 G4Exception(
"G4SmartVoxelHeader::BuildNodes()",
"GeomMgt0003",
983 return 0;
984 }
985 nodeList->push_back(pNode);
986 }
987
988
989
990
991
992 for (nVol=0; nVol<nCandidates; nVol++)
993 {
994 G4int nodeNo, minContainingNode, maxContainingNode;
995 minContainingNode =
G4int((minExtents[nVol]-motherMinExtent)/nodeWidth);
996 maxContainingNode =
G4int((maxExtents[nVol]-motherMinExtent)/nodeWidth);
997
998
999
1000 if ( (maxContainingNode>=0) && (minContainingNode<noNodes) )
1001 {
1002
1003
1004
1005 if (maxContainingNode>=noNodes)
1006 {
1007 maxContainingNode = noNodes-1;
1008 }
1009
1010
1011
1012 if (minContainingNode<0)
1013 {
1014 minContainingNode=0;
1015 }
1016 for (nodeNo=minContainingNode; nodeNo<=maxContainingNode; nodeNo++)
1017 {
1018 (*nodeList)[nodeNo]->Insert((*pCandidates)[nVol]);
1019 }
1020 }
1021 }
1022
1023
1024
1025
1026
1027
1029 if (!proxyList)
1030 {
1031 G4Exception(
"G4SmartVoxelHeader::BuildNodes()",
"GeomMgt0003",
1033 return 0;
1034 }
1035 proxyList->reserve(noNodes);
1036
1037
1038
1039
1040 for (nNode=0; nNode<noNodes; nNode++)
1041 {
1042
1043
1044 ((*nodeList)[nNode])->Shrink();
1046 if (!pProxyNode)
1047 {
1048 G4Exception(
"G4SmartVoxelHeader::BuildNodes()",
"GeomMgt0003",
1050 return 0;
1051 }
1052 proxyList->push_back(pProxyNode);
1053 }
1054 delete nodeList;
1055 return proxyList;
1056}
G4VSolid * GetSolid() const
G4double GetSmartless() const
virtual G4VSolid * ComputeSolid(const G4int, G4VPhysicalVolume *)
virtual void ComputeTransformation(const G4int, G4VPhysicalVolume *) const =0
const G4RotationMatrix * GetRotation() const
G4LogicalVolume * GetLogicalVolume() const
const G4String & GetName() const
virtual G4VPVParameterisation * GetParameterisation() const =0
const G4ThreeVector & GetTranslation() const
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