From d6bdbe6e3c441fdf065ff5ccf044260dbc73f881 Mon Sep 17 00:00:00 2001
From: Rene Brun <Rene.Brun@cern.ch>
Date: Tue, 11 Mar 2008 10:21:53 +0000
Subject: [PATCH] From Andrei Gheata and Pter Hristov: some protections in
 voxels in case of propagation in wrong geometries.

git-svn-id: http://root.cern.ch/svn/root/trunk@22587 27541ba8-7e3a-0410-8455-c3a389f83636
---
 geom/src/TGeoVoxelFinder.cxx | 54 ++++++++++++++++++++++++++++++++----
 1 file changed, 48 insertions(+), 6 deletions(-)

diff --git a/geom/src/TGeoVoxelFinder.cxx b/geom/src/TGeoVoxelFinder.cxx
index 68903e191f7..485e25c8fa1 100644
--- a/geom/src/TGeoVoxelFinder.cxx
+++ b/geom/src/TGeoVoxelFinder.cxx
@@ -641,11 +641,11 @@ Int_t *TGeoVoxelFinder::GetNextCandidates(Double_t *point, Int_t &ncheck)
    if (fPriority[0] && fInc[0]) {
       //---> increment/decrement slice
       dind[0] += fInc[0];
-      if (dind[0]<-1) return 0; // outside range
-      if (dind[0]>fIbx-1) return 0; // outside range
       if (fInc[0]==1) {
+	 if (dind[0]<0 || dind[0]>fIbx-1) return 0; // outside range
          dmin[0] = (fXb[dind[0]]-point[0])*fInvdir[0];
       } else {
+	 if (fSlices[0]<0 || fSlices[0]>fIbx-1) return 0; // outside range
          dmin[0] = (fXb[fSlices[0]]-point[0])*fInvdir[0];
       }
       isXlimit = (dmin[0]>maxstep)?kTRUE:kFALSE;
@@ -681,11 +681,11 @@ Int_t *TGeoVoxelFinder::GetNextCandidates(Double_t *point, Int_t &ncheck)
    if (fPriority[1] && fInc[1]) {
       //---> increment/decrement slice
       dind[1] += fInc[1];
-      if (dind[1]<-1) return 0; // outside range
-      if (dind[1]>fIby-1) return 0; // outside range
       if (fInc[1]==1) {
+	 if (dind[1]<0 || dind[1]>fIby-1) return 0; // outside range
          dmin[1] = (fYb[dind[1]]-point[1])*fInvdir[1];
       } else {
+	 if (fSlices[1]<0 || fSlices[1]>fIby-1) return 0; // outside range
          dmin[1] = (fYb[fSlices[1]]-point[1])*fInvdir[1];
       }
       isYlimit = (dmin[1]>maxstep)?kTRUE:kFALSE;
@@ -722,11 +722,11 @@ Int_t *TGeoVoxelFinder::GetNextCandidates(Double_t *point, Int_t &ncheck)
    if (fPriority[2] && fInc[2]) {
       //---> increment/decrement slice
       dind[2] += fInc[2];
-      if (dind[2]<-1) return 0; // outside range
-      if (dind[2]>fIbz-1) return 0; // outside range
       if (fInc[2]==1) {
+	 if (dind[2]<0 || dind[2]>fIbz-1) return 0; // outside range
          dmin[2] = (fZb[dind[2]]-point[2])*fInvdir[2];
       } else {
+	 if (fSlices[2]<0 || fSlices[2]>fIbz-1) return 0; // outside range
          dmin[2] = (fZb[fSlices[2]]-point[2])*fInvdir[2];
       }
       isZlimit = (dmin[2]>maxstep)?kTRUE:kFALSE;
@@ -843,8 +843,10 @@ Int_t *TGeoVoxelFinder::GetNextCandidates(Double_t *point, Int_t &ncheck)
                while (1) {
                   fSlices[1] += fInc[1];
                   if (fInc[1]==1) {
+  		     if (fSlices[1]<-1 || fSlices[1]>fIby-2) break; // outside range
                      if (fYb[fSlices[1]+1]>=xptnew) break;
                   } else {
+		     if (fSlices[1]<0 || fSlices[1]>fIby-1) break; // outside range
                      if (fYb[fSlices[1]]<= xptnew) break;
                   }
                }
@@ -856,8 +858,10 @@ Int_t *TGeoVoxelFinder::GetNextCandidates(Double_t *point, Int_t &ncheck)
                while (1) {
                   fSlices[2] += fInc[2];
                   if (fInc[2]==1) {
+  		     if (fSlices[2]<-1 || fSlices[2]>fIbz-2) break; // outside range
                      if (fZb[fSlices[2]+1]>=xptnew) break;
                   } else {
+  		     if (fSlices[2]<0 || fSlices[2]>fIbz-1) break; // outside range
                      if (fZb[fSlices[2]]<= xptnew) break;
                   }
                }          
@@ -869,12 +873,14 @@ Int_t *TGeoVoxelFinder::GetNextCandidates(Double_t *point, Int_t &ncheck)
          // we are entering the unique slice on this axis
          //---> intersect and store Y and Z
             if (fPriority[1]==2) {
+	      if (fSlices[1]<0 || fSlices[1]>fIby-1) return fCheckList; // outside range
                ndd[0] = fNsliceY[fSlices[1]];
                if (!ndd[0]) return fCheckList;
                slice1 = &fIndcY[fOBy[fSlices[1]]];
                islices++;
             }
             if (fPriority[2]==2) {
+	      if (fSlices[2]<0 || fSlices[2]>fIbz-1) return fCheckList; // outside range
                ndd[1] = fNsliceZ[fSlices[2]];
                if (!ndd[1]) return fCheckList;
                islices++;
@@ -899,6 +905,10 @@ Int_t *TGeoVoxelFinder::GetNextCandidates(Double_t *point, Int_t &ncheck)
 //         printf("   New list on X : %i new candidates\n", ncheck);
          if (!ncheck) return fCheckList;
          if (fPriority[1]==2) {
+	    if (fSlices[1]<0 || fSlices[1]>fIby-1) {
+	       ncheck = 0;
+	       return fCheckList; // outside range
+	    }
             ndd[0] = fNsliceY[fSlices[1]];
             if (!ndd[0]) {
                ncheck = 0;
@@ -908,6 +918,10 @@ Int_t *TGeoVoxelFinder::GetNextCandidates(Double_t *point, Int_t &ncheck)
             islices++;
          }
          if (fPriority[2]==2) {
+	    if (fSlices[2]<0 || fSlices[2]>fIbz-1) {
+	       ncheck = 0;
+	       return fCheckList; // outside range
+	    }
             ndd[1] = fNsliceZ[fSlices[2]];
             if (!ndd[1]) {
                ncheck = 0;
@@ -941,8 +955,10 @@ Int_t *TGeoVoxelFinder::GetNextCandidates(Double_t *point, Int_t &ncheck)
                while (1) {
                   fSlices[0] += fInc[0];
                   if (fInc[0]==1) {
+		     if (fSlices[0]<-1 || fSlices[0]>fIbx-2) break; // outside range
                      if (fXb[fSlices[0]+1]>=xptnew) break;
                   } else {
+		     if (fSlices[0]<0 || fSlices[0]>fIbx-1) break; // outside range
                      if (fXb[fSlices[0]]<= xptnew) break;
                   }
                }
@@ -954,8 +970,10 @@ Int_t *TGeoVoxelFinder::GetNextCandidates(Double_t *point, Int_t &ncheck)
                while (1) {
                   fSlices[2] += fInc[2];
                   if (fInc[2]==1) {
+		     if (fSlices[2]<-1 || fSlices[2]>fIbz-2) break; // outside range
                      if (fZb[fSlices[2]+1]>=xptnew) break;
                   } else {
+		     if (fSlices[2]<0 || fSlices[2]>fIbz-1) break; // outside range
                      if (fZb[fSlices[2]]<= xptnew) break;
                   }
                }          
@@ -967,12 +985,14 @@ Int_t *TGeoVoxelFinder::GetNextCandidates(Double_t *point, Int_t &ncheck)
          // we are entering the unique slice on this axis
          //---> intersect and store X and Z
             if (fPriority[0]==2) {
+	       if (fSlices[0]<0 || fSlices[0]>fIbx-1) return fCheckList; // outside range
                ndd[0] = fNsliceX[fSlices[0]];
                if (!ndd[0]) return fCheckList;
                slice1 = &fIndcX[fOBx[fSlices[0]]];
                islices++;
             }
             if (fPriority[2]==2) {
+	       if (fSlices[2]<0 || fSlices[2]>fIbz-1) return fCheckList; // outside range
                ndd[1] = fNsliceZ[fSlices[2]];
                if (!ndd[1]) return fCheckList;
                islices++;
@@ -997,6 +1017,10 @@ Int_t *TGeoVoxelFinder::GetNextCandidates(Double_t *point, Int_t &ncheck)
 //         printf("   New list on Y : %i new candidates\n", ncheck);
          if (!ncheck) return fCheckList;
          if (fPriority[0]==2) {
+	    if (fSlices[0]<0 || fSlices[0]>fIbx-1) {
+	       ncheck = 0;
+	       return fCheckList; // outside range
+	    }
             ndd[0] = fNsliceX[fSlices[0]];
             if (!ndd[0]) {
                ncheck = 0;
@@ -1006,6 +1030,10 @@ Int_t *TGeoVoxelFinder::GetNextCandidates(Double_t *point, Int_t &ncheck)
             islices++;
          }
          if (fPriority[2]==2) {
+	    if (fSlices[2]<0 || fSlices[2]>fIbz-1) {
+	       ncheck = 0;
+	       return fCheckList; // outside range
+	    }
             ndd[1] = fNsliceZ[fSlices[2]];
             if (!ndd[1]) {
                ncheck = 0;
@@ -1039,8 +1067,10 @@ Int_t *TGeoVoxelFinder::GetNextCandidates(Double_t *point, Int_t &ncheck)
                while (1) {
                   fSlices[1] += fInc[1];
                   if (fInc[1]==1) {
+  		     if (fSlices[1]<-1 || fSlices[1]>fIby-2) break; // outside range
                      if (fYb[fSlices[1]+1]>=xptnew) break;
                   } else {
+		     if (fSlices[1]<0 || fSlices[1]>fIby-1) break; // outside range
                      if (fYb[fSlices[1]]<= xptnew) break;
                   }
                }
@@ -1052,8 +1082,10 @@ Int_t *TGeoVoxelFinder::GetNextCandidates(Double_t *point, Int_t &ncheck)
                while (1) {
                   fSlices[0] += fInc[0];
                   if (fInc[0]==1) {
+		     if (fSlices[0]<-1 || fSlices[0]>fIbx-2) break; // outside range
                      if (fXb[fSlices[0]+1]>=xptnew) break;
                   } else {
+		     if (fSlices[0]<0 || fSlices[0]>fIbx-1) break; // outside range
                      if (fXb[fSlices[0]]<= xptnew) break;
                   }
                }          
@@ -1065,12 +1097,14 @@ Int_t *TGeoVoxelFinder::GetNextCandidates(Double_t *point, Int_t &ncheck)
          // we are entering the unique slice on this axis
          //---> intersect and store Y and X
             if (fPriority[1]==2) {
+	      if (fSlices[1]<0 || fSlices[1]>fIby-1) return fCheckList; // outside range
                ndd[0] = fNsliceY[fSlices[1]];
                if (!ndd[0]) return fCheckList;
                slice1 = &fIndcY[fOBy[fSlices[1]]];
                islices++;
             }
             if (fPriority[0]==2) {
+	      if (fSlices[0]<0 || fSlices[0]>fIbx-1) return fCheckList; // outside range
                ndd[1] = fNsliceX[fSlices[0]];
                if (!ndd[1]) return fCheckList;
                islices++;
@@ -1095,6 +1129,10 @@ Int_t *TGeoVoxelFinder::GetNextCandidates(Double_t *point, Int_t &ncheck)
 //         printf("   New list on Z : %i new candidates\n", ncheck);
          if (!ncheck) return fCheckList;
          if (fPriority[1]==2) {
+	    if (fSlices[1]<0 || fSlices[1]>fIby-1) {
+	       ncheck = 0;
+	       return fCheckList; // outside range
+	    }
             ndd[0] = fNsliceY[fSlices[1]];
             if (!ndd[0]) {
                ncheck = 0;
@@ -1104,6 +1142,10 @@ Int_t *TGeoVoxelFinder::GetNextCandidates(Double_t *point, Int_t &ncheck)
             islices++;
          }
          if (fPriority[0]==2) {
+	    if (fSlices[0]<0 || fSlices[0]>fIbx-1) {
+	       ncheck = 0;
+	       return fCheckList; // outside range
+	    }
             ndd[1] = fNsliceX[fSlices[0]];
             if (!ndd[1]) {
                ncheck = 0;
-- 
GitLab