762{
768 G4double ourStep=currentProposedStepLength;
770 G4double sampleStep, sampleSafety, motherStep, motherSafety;
771 G4long localNoDaughters, sampleNo;
774
775
776 calculatedExitNormal= false;
777
778
779
780 if ( exiting&&validExitNormal )
781 {
782 if ( localDirection.
dot(exitNormalVector)>=kMinExitingNormalCosine )
783 {
784
785
786 blockedExitedVol = *pBlockedPhysical;
787 ourSafety = 0;
788 }
789 }
790 exiting = false;
791 entering = false;
792
795
796
797
798
799
802 localPoint);
805
806 ourSafety = std::min( ourSafety, sampleSafety);
807
808 if ( sampleSafety<ourStep )
809 {
810
813 localPoint,
814 localDirection,
815 normalOutStc);
816 if ( sampleStep<ourStep )
817 {
818 ourStep = sampleStep;
819 exiting = true;
821
822 exitNormalStc = normalOutStc;
825 calculatedExitNormal = true;
826 }
827 }
828 const G4int secondDepth = topDepth;
829 depth = secondDepth;
830
831
833 {
836
837
840 repPoint);
841 if ( sampleSafety < ourSafety )
842 {
843 ourSafety = sampleSafety;
844 }
845 if ( sampleSafety < ourStep )
846 {
851 repPoint,
852 newLocalDirection,
853 normalOutStc);
854 if ( sampleStep < ourStep )
855 {
856 ourStep = sampleStep;
857 exiting = true;
858
859
860
864
865 exitNormalStc = normalOutStc;
867 calculatedExitNormal = true;
868 }
869 }
870 depth--;
871 }
872
873
874
876 G4bool exitConvex =
false;
878
880 motherPhysical = history.
GetVolume(depth);
884
885 motherStep = motherSolid->
DistanceToOut(repPoint,repDirection,
true,
886 &exitConvex,&exitVectorMother);
887 if( exitConvex )
888 {
889 motherNormalStc =
G4ExitNormal( exitVectorMother,
true,
false,
891 calculatedExitNormal = true;
892 }
894
895 G4bool motherDeterminedStep = (motherStep<ourStep);
896
897 if( (!exitConvex) && motherDeterminedStep )
898 {
900 motherNormalStc =
G4ExitNormal( exitVectorMother,
true,
false,
902
903
904
905
906 calculatedExitNormal = true;
907 }
908 if( motherDeterminedStep )
909 {
912
913 exitNormalStc = motherNormalStc;
914 exitNormalStc.
exitNormal = globalExitNormalTop;
915 }
916
917
918
919
920
921
922
923
924 if( ourStep<fMinStep )
925 {
926 ourStep = 2*kCarTolerance;
927 }
928
929 if ( motherSafety<ourSafety )
930 {
931 ourSafety = motherSafety;
932 }
933
934#ifdef G4VERBOSE
935 if ( fCheck )
936 {
938 {
939 std::ostringstream message;
940 message <<
"Point outside volume !" <<
G4endl
941 << " Point " << localPoint
942 <<
" is outside current volume " << motherPhysical->
GetName()
945 message << " Estimated isotropic distance to solid (distToIn)= "
946 << estDistToSolid <<
G4endl;
947 if( estDistToSolid > 100.0 * kCarTolerance )
948 {
952 "Point is far outside Current Volume !" );
953 }
954 else
955 {
958 "Point is a little outside Current Volume.");
959 }
960 }
961 }
962#endif
963
964
965
966#if 1
967 if( motherDeterminedStep )
968 {
969 ourStep = motherStep;
970 exiting = true;
971 }
972
973
974
975 if ( calculatedExitNormal )
976 {
977 if ( motherDeterminedStep )
978 {
979 exitNormalVector = motherNormalStc.
exitNormal;
980 }
981 else
982 {
984 exitNormalVector = globalToLocalTop.
TransformAxis(exitNormalGlobal);
985
986
987 }
988
990 if ( rot != nullptr )
991 {
992 exitNormalVector *= rot->
inverse();
993 }
994
995 }
996 else
997 {
998 validExitNormal = false;
999 }
1000
1001#else
1002 if ( motherSafety<=ourStep )
1003 {
1004 if ( motherStep<=ourStep )
1005 {
1006 ourStep = motherStep;
1007 exiting = true;
1008 if ( validExitNormal )
1009 {
1011 if ( rot )
1012 {
1014 }
1015 }
1016 }
1017 else
1018 {
1019 validExitNormal = false;
1020
1021 }
1022 }
1023#endif
1024
1025
1026 G4bool daughterDeterminedStep =
false;
1028
1029
1030
1031
1032
1033
1035 for ( sampleNo=localNoDaughters-1; sampleNo>=0; sampleNo-- )
1036 {
1038 if ( samplePhysical!=blockedExitedVol )
1039 {
1042
1045 sampleTf.Invert();
1047 sampleTf.TransformPoint(localPoint);
1050 const G4double sampleSafetyDistance =
1052 if ( sampleSafetyDistance<ourSafety )
1053 {
1054 ourSafety = sampleSafetyDistance;
1055 }
1056 if ( sampleSafetyDistance<=ourStep )
1057 {
1058 sampleDirection = sampleTf.TransformAxis(localDirection);
1059 const G4double sampleStepDistance =
1060 sampleSolid->
DistanceToIn(samplePoint,sampleDirection);
1061 if ( sampleStepDistance<=ourStep )
1062 {
1063 daughterDeterminedStep = true;
1064
1065 ourStep = sampleStepDistance;
1066 entering = true;
1067 exiting = false;
1068 *pBlockedPhysical = samplePhysical;
1069 blockedReplicaNo = (
G4int)sampleNo;
1070
1071#ifdef DAUGHTER_NORMAL_ALSO
1072
1074 daughtNormRepCrd = sampleTf.InverseTransformAxis(localExitNorm);
1075#endif
1076
1077#ifdef G4VERBOSE
1078
1079
1080
1081 if ( ( fCheck ) && ( sampleStepDistance < kInfinity ) )
1082 {
1084 intersectionPoint = samplePoint
1085 + sampleStepDistance * sampleDirection;
1086 EInside insideIntPt = sampleSolid->
Inside(intersectionPoint);
1088 {
1090 std::ostringstream message;
1091 message << "Navigator gets conflicting response from Solid."
1093 << " Inaccurate DistanceToIn for solid "
1095 << " Solid gave DistanceToIn = "
1096 << sampleStepDistance << " yet returns " ;
1097 if ( insideIntPt ==
kInside ) {
1098 message << "-kInside-";
1099 }
else if ( insideIntPt ==
kOutside ) {
1100 message << "-kOutside-";
1101 } else {
1102 message << "-kSurface-";
1103 }
1104 message <<
" for this point !" <<
G4endl
1105 <<
" Point = " << intersectionPoint <<
G4endl;
1106 if ( insideIntPt !=
kInside ) {
1107 message << " DistanceToIn(p) = "
1110}
1112 message << " DistanceToOut(p) = "
1114}
1117 G4cout.precision(oldcoutPrec);
1118 }
1119 }
1120#endif
1121 }
1122 }
1123 }
1124 }
1125
1126 calculatedExitNormal &= (!daughterDeterminedStep);
1127
1128#ifdef DAUGHTER_NORMAL_ALSO
1129 if( daughterDeterminedStep )
1130 {
1131
1132
1133
1134
1136 validExitNormal = false;
1137
1138 calculatedExitNormal = true;
1139 }
1140
1141#endif
1142
1143 newSafety = ourSafety;
1144 return ourStep;
1145}
G4GLOB_DLL std::ostream G4cout
double dot(const Hep3Vector &) const
HepRotation inverse() const
const G4AffineTransform & GetTopTransform() const
const G4String & GetName() const
virtual G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const =0