From aeb8399510a5238c44ceeecb7ec1290f52ed9ebe Mon Sep 17 00:00:00 2001 From: Rene Brun <Rene.Brun@cern.ch> Date: Tue, 3 Feb 2004 12:43:45 +0000 Subject: [PATCH] From Andrei Gheata: TGeoManager: - fixed a bug in Safety() introduced when inlining the method TGeoVoxelFinder::IsSameVoxel() - I observed it just now when debugging IsSameLocation - several daughters of a voxelized volume were not checked resulting in an overestimated safety and in some cases wrong snext computation (only with TGeant3) - fixed IsSameLocation which was resetting some parameters due to direct calls to FindNode in case of MANY (you know, the geometry of Alain has MANY's) - IsSameLocation called now only for new points x,y,z are not within previous safety distance. - eliminated the useless call to FindMatrixOfDaughterVolume() inside TGeoManager::SetTopVolume() that made the visualization slower and even produced a crash in case of very large geometries (see my today post in the forum http://root.cern.ch/phpBB2/viewtopic.php?t=371) git-svn-id: http://root.cern.ch/svn/root/trunk@8109 27541ba8-7e3a-0410-8455-c3a389f83636 --- geom/inc/TGeoManager.h | 7 +++- geom/src/TGeoManager.cxx | 71 +++++++++++++++++++++++++++++----------- 2 files changed, 57 insertions(+), 21 deletions(-) diff --git a/geom/inc/TGeoManager.h b/geom/inc/TGeoManager.h index 2718b850f1b..b584d27c544 100644 --- a/geom/inc/TGeoManager.h +++ b/geom/inc/TGeoManager.h @@ -1,4 +1,4 @@ -// @(#)root/geom:$Name: $:$Id: TGeoManager.h,v 1.42 2004/01/19 13:40:50 brun Exp $ +// @(#)root/geom:$Name: $:$Id: TGeoManager.h,v 1.43 2004/01/20 15:44:32 brun Exp $ // Author: Andrei Gheata 25/10/01 /************************************************************************* @@ -115,6 +115,7 @@ private : Int_t *fIntBuffer; //! transient int buffer Int_t *fOverlapClusters; //! internal array for overlaps Double_t *fDblBuffer; //! transient dbl buffer + Double_t fLastPoint[3]; //! last located point //--- private methods void BuildCache(Bool_t dummy=kFALSE, Bool_t nodeid=kFALSE); @@ -304,6 +305,7 @@ public: Int_t GetNtracks() const {return fNtracks;} TVirtualGeoTrack *GetCurrentTrack() {return fCurrentTrack;} TVirtualGeoTrack *GetLastTrack() {return (TVirtualGeoTrack *)fTracks->At(fNtracks-1);} + const Double_t *GetLastPoint() const {return fLastPoint;} TVirtualGeoTrack *GetTrack(Int_t index) {return (index<fNtracks)?(TVirtualGeoTrack*)fTracks->At(index):0;} Int_t GetTrackIndex(Int_t id) const; TVirtualGeoTrack *GetTrackOfId(Int_t id) const; @@ -317,6 +319,7 @@ public: Bool_t IsCheckingOverlaps() const {return fSearchOverlaps;} Bool_t IsSameLocation(Double_t x, Double_t y, Double_t z, Bool_t change=kFALSE); Bool_t IsSameLocation() const {return fIsSameLocation;} + Bool_t IsSamePoint(Double_t x, Double_t y, Double_t z) const; Bool_t IsStartSafe() const {return fStartSafe;} void SetStartSafe(Bool_t flag=kTRUE) {fStartSafe=flag;} void SetStep(Double_t step) {fStep=step;} @@ -390,6 +393,8 @@ public: void SetCurrentPoint(Double_t *point) {memcpy(fPoint,point,3*sizeof(Double_t));} void SetCurrentPoint(Double_t x, Double_t y, Double_t z) { fPoint[0]=x; fPoint[1]=y; fPoint[2]=z;} + void SetLastPoint(Double_t x, Double_t y, Double_t z) { + fLastPoint[0]=x; fLastPoint[1]=y; fLastPoint[2]=z;} void SetCurrentDirection(Double_t *dir) {memcpy(fDirection,dir,3*sizeof(Double_t));} void SetCurrentDirection(Double_t nx, Double_t ny, Double_t nz) { fDirection[0]=nx; fDirection[1]=ny; fDirection[2]=nz;} diff --git a/geom/src/TGeoManager.cxx b/geom/src/TGeoManager.cxx index 9dce322b223..808ee2bbb6e 100644 --- a/geom/src/TGeoManager.cxx +++ b/geom/src/TGeoManager.cxx @@ -1,4 +1,4 @@ -// @(#)root/geom:$Name: $:$Id: TGeoManager.cxx,v 1.72 2004/01/23 16:34:13 brun Exp $ +// @(#)root/geom:$Name: $:$Id: TGeoManager.cxx,v 1.73 2004/01/29 11:59:11 brun Exp $ // Author: Andrei Gheata 25/10/01 /************************************************************************* @@ -437,6 +437,7 @@ TGeoManager *gGeoManager = 0; const char *kGeoOutsidePath = " "; +const Int_t kN3 = 3*sizeof(Double_t); ClassImp(TGeoManager) @@ -493,11 +494,12 @@ void TGeoManager::Init() fOverlaps = new TObjArray(256); fNNodes = 0; fLevel = 0; + memset(fLastPoint, 0, kN3); fPoint = new Double_t[3]; fDirection = new Double_t[3]; // fNormalChecked = 0; fCldirChecked = new Double_t[3]; - memset(fNormal, 0, 3*sizeof(Double_t)); + memset(fNormal, 0, kN3); fCldir = new Double_t[3]; fVolumes = new TObjArray(256); fShapes = new TObjArray(256); @@ -2008,13 +2010,17 @@ Double_t TGeoManager::Safety(Bool_t inside) Double_t *boxes = voxels->GetBoxes(); for (id=0; id<nd; id++) { Int_t ist = 6*id; + Double_t dxyz = 0.; Double_t dxyz0 = TMath::Abs(point[0]-boxes[ist+3])-boxes[ist]; if (dxyz0 > fSafety) continue; Double_t dxyz1 = TMath::Abs(point[1]-boxes[ist+4])-boxes[ist+1]; if (dxyz1 > fSafety) continue; Double_t dxyz2 = TMath::Abs(point[2]-boxes[ist+5])-boxes[ist+2]; if (dxyz2 > fSafety) continue; - if (dxyz0*dxyz0+dxyz1*dxyz1+dxyz2*dxyz2 >= fSafety*fSafety) continue; + if (dxyz0>0) dxyz+=dxyz0*dxyz0; + if (dxyz1>0) dxyz+=dxyz1*dxyz1; + if (dxyz2>0) dxyz+=dxyz2*dxyz2; + if (dxyz >= fSafety*fSafety) continue; node = (TGeoNode*)nodes->UncheckedAt(id); safe = node->Safety(point, kFALSE); // if (safe<0) {printf("%s (%s) (%f, %f, %f) kFALSE vox of %s safe=%g\n", node->GetVolume()->GetName(),node->GetVolume()->GetShape()->ClassName(), local[0],local[1],local[2],vol->GetName(),safe); exit(1);} @@ -2738,6 +2744,8 @@ TGeoNode *TGeoManager::FindNextBoundary(Double_t stepmax, const char *path) TGeoNode *TGeoManager::FindNode(Bool_t safe_start) { // Returns deepest node containing current point. + fSafety = 0; + memcpy(fLastPoint, fPoint, kN3); fSearchOverlaps = kFALSE; fIsOutside = kFALSE; fIsEntering = fIsExiting = kFALSE; @@ -2757,6 +2765,8 @@ TGeoNode *TGeoManager::FindNode(Double_t x, Double_t y, Double_t z) fPoint[0] = x; fPoint[1] = y; fPoint[2] = z; + fSafety = 0; + memcpy(fLastPoint, fPoint, kN3); fSearchOverlaps = kFALSE; fIsOutside = kFALSE; fIsEntering = fIsExiting = kFALSE; @@ -2812,8 +2822,8 @@ Double_t *TGeoManager::FindNormal(Bool_t forward) Double_t bigstep = 1.E6; Int_t i, istep; Int_t start = PushPath(); - memcpy(saved_point, fPoint, 3*sizeof(Double_t)); - memcpy(saved_direction, fDirection, 3*sizeof(Double_t)); + memcpy(saved_point, fPoint, kN3); + memcpy(saved_direction, fDirection, kN3); // PushPath(); if (!forward) { @@ -2823,8 +2833,8 @@ Double_t *TGeoManager::FindNormal(Bool_t forward) FindNextBoundary(); // if it is nothing backwards, restore state and return NULL if (fStep>bigstep) { - memcpy(fPoint, saved_point, 3*sizeof(Double_t)); - memcpy(fDirection, saved_direction, 3*sizeof(Double_t)); + memcpy(fPoint, saved_point, kN3); + memcpy(fDirection, saved_direction, kN3); fStep = saved_step; fIsEntering = is_entering; PopPath(); @@ -2842,8 +2852,8 @@ Double_t *TGeoManager::FindNormal(Bool_t forward) Error("FindNormal", "cannot reach backward boundary"); printf(" starting point was : (%f, %f, %f)\n", saved_point[0], saved_point[1], saved_point[2]); printf(" direction was : (%f, %f, %f)\n", fDirection[0], fDirection[1], fDirection[2]); - memcpy(fPoint, saved_point, 3*sizeof(Double_t)); - memcpy(fDirection, saved_direction, 3*sizeof(Double_t)); + memcpy(fPoint, saved_point, kN3); + memcpy(fDirection, saved_direction, kN3); fStep = saved_step; fIsEntering = is_entering; PopPath(); @@ -2854,12 +2864,12 @@ Double_t *TGeoManager::FindNormal(Bool_t forward) } if (!fIsStepEntering) PopPath(start); // restore initial direction - memcpy(fDirection, saved_direction, 3*sizeof(Double_t)); + memcpy(fDirection, saved_direction, kN3); } else { FindNextBoundary(); if (fStep>bigstep) { - memcpy(fPoint, saved_point, 3*sizeof(Double_t)); - memcpy(fDirection, saved_direction, 3*sizeof(Double_t)); + memcpy(fPoint, saved_point, kN3); + memcpy(fDirection, saved_direction, kN3); fStep = saved_step; fIsEntering = is_entering; PopPath(); @@ -2877,8 +2887,8 @@ Double_t *TGeoManager::FindNormal(Bool_t forward) Error("FindNormal", "cannot reach forward boundary"); printf(" starting point was : (%f, %f, %f)\n", saved_point[0], saved_point[1], saved_point[2]); printf(" direction was : (%f, %f, %f)\n", fDirection[0], fDirection[1], fDirection[2]); - memcpy(fPoint, saved_point, 3*sizeof(Double_t)); - memcpy(fDirection, saved_direction, 3*sizeof(Double_t)); + memcpy(fPoint, saved_point, kN3); + memcpy(fDirection, saved_direction, kN3); fStep = saved_step; fIsEntering = is_entering; PopPath(); @@ -2895,8 +2905,8 @@ Double_t *TGeoManager::FindNormal(Bool_t forward) MasterToLocalVect(fDirection, ldir); fCurrentNode->GetVolume()->GetShape()->ComputeNormal(lpt,ldir,lnorm); LocalToMasterVect(lnorm, fNormal); - memcpy(fPoint, saved_point, 3*sizeof(Double_t)); - memcpy(fDirection, saved_direction, 3*sizeof(Double_t)); + memcpy(fPoint, saved_point, kN3); + memcpy(fDirection, saved_direction, kN3); fStep = saved_step; fIsEntering = is_entering; PopPath(); @@ -2908,11 +2918,22 @@ Bool_t TGeoManager::IsSameLocation(Double_t x, Double_t y, Double_t z, Bool_t ch { // Checks if point (x,y,z) is still in the current node. // check if this is an overlapping node + Double_t oldpt[3]; + if (fSafety>0) { + Double_t dx = (x-fLastPoint[0]); + Double_t dy = (y-fLastPoint[1]); + Double_t dz = (z-fLastPoint[2]); + Double_t dsq = dx*dx+dy*dy+dz*dz; + if (dsq<fSafety*fSafety) return kTRUE; + } else return kTRUE; if (fCurrentOverlapping) { // TGeoNode *current = fCurrentNode; Int_t cid = GetCurrentNodeId(); if (!change) PushPoint(); - gGeoManager->FindNode(x,y,z); + memcpy(oldpt, fPoint, kN3); + gGeoManager->SetCurrentPoint(x,y,z); + gGeoManager->SearchNode(); + memcpy(fPoint, oldpt, kN3); Bool_t same = (cid==GetCurrentNodeId())?kTRUE:kFALSE; if (!change) PopPoint(); return same; @@ -2922,7 +2943,7 @@ Bool_t TGeoManager::IsSameLocation(Double_t x, Double_t y, Double_t z, Bool_t ch point[0] = x; point[1] = y; point[2] = z; - if (change) memcpy(fPoint, point, 3*sizeof(Double_t)); + if (change) memcpy(fPoint, point, kN3); TGeoVolume *vol = fCurrentNode->GetVolume(); if (fIsOutside) { if (vol->GetShape()->Contains(point)) { @@ -3007,7 +3028,17 @@ Bool_t TGeoManager::IsSameLocation(Double_t x, Double_t y, Double_t z, Bool_t ch if (!change) PopPath(); return kTRUE; } - +//_____________________________________________________________________________ +Bool_t TGeoManager::IsSamePoint(Double_t x, Double_t y, Double_t z) const +{ + if (x==fLastPoint[0]) { + if (y==fLastPoint[1]) { + if (z==fLastPoint[2]) return kTRUE; + } + } + return kFALSE; +} + //_____________________________________________________________________________ Bool_t TGeoManager::IsInPhiRange() const { @@ -3570,7 +3601,7 @@ void TGeoManager::SetTopVolume(TGeoVolume *vol) GetHMatrix(); } *fCurrentMatrix = gGeoIdentity; - fMasterVolume->FindMatrixOfDaughterVolume(vol); +// fMasterVolume->FindMatrixOfDaughterVolume(vol); // fCurrentMatrix->Print(); fTopNode = new TGeoNodeMatrix(vol, gGeoIdentity); char *name = new char[strlen(vol->GetName())+3]; -- GitLab