From 7672e15e77ce6b71fa0c532a56e1699050833e04 Mon Sep 17 00:00:00 2001 From: Rene Brun <Rene.Brun@cern.ch> Date: Tue, 20 Jan 2004 15:44:33 +0000 Subject: [PATCH] Several improvements from Andrei GHeata. additional option "i" (reset by default) to CloseGeometry() to have the node id array built or not. git-svn-id: http://root.cern.ch/svn/root/trunk@7952 27541ba8-7e3a-0410-8455-c3a389f83636 --- geom/Module.mk | 3 +- geom/inc/LinkDef1.h | 4 +- geom/inc/TGeoCache.h | 19 ++- geom/inc/TGeoManager.h | 9 +- geom/inc/TGeoMatrix.h | 11 +- geom/inc/TGeoVoxelFinder.h | 43 +++++- geom/src/TGeoCache.cxx | 126 +++++++++++----- geom/src/TGeoManager.cxx | 48 ++++-- geom/src/TGeoTube.cxx | 4 +- geom/src/TGeoVolume.cxx | 21 ++- geom/src/TGeoVoxelFinder.cxx | 282 +++++++++++++++++++++++++++++++++-- 11 files changed, 475 insertions(+), 95 deletions(-) diff --git a/geom/Module.mk b/geom/Module.mk index 13d7be574d6..e7c47348ae5 100644 --- a/geom/Module.mk +++ b/geom/Module.mk @@ -30,7 +30,8 @@ GEOMH1 := TGeoAtt.h TGeoBoolNode.h \ TGeoEltu.h TGeoCone.h TGeoPcon.h \ TGeoPgon.h TGeoArb8.h TGeoTrd1.h TGeoTrd2.h \ TGeoManager.h TGeoCompositeShape.h \ - TVirtualGeoPainter.h TVirtualGeoTrack.h + TVirtualGeoPainter.h TVirtualGeoTrack.h \ + TGeoPolygon.h GEOMH2 := TGeoPatternFinder.h TGeoCache.h GEOMH1 := $(patsubst %,$(MODDIRI)/%,$(GEOMH1)) GEOMH2 := $(patsubst %,$(MODDIRI)/%,$(GEOMH2)) diff --git a/geom/inc/LinkDef1.h b/geom/inc/LinkDef1.h index cace0039ca8..e866a1cfe85 100644 --- a/geom/inc/LinkDef1.h +++ b/geom/inc/LinkDef1.h @@ -1,4 +1,4 @@ -// @(#)root/geom:$Name: $:$Id: LinkDef1.h,v 1.1 2003/09/09 16:56:48 brun Exp $ +// @(#)root/geom:$Name: $:$Id: LinkDef1.h,v 1.2 2003/10/20 08:46:33 brun Exp $ // Author : Andrei Gheata 10/06/02 /************************************************************************* * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. * @@ -35,6 +35,7 @@ #pragma link C++ class TGeoIdentity+; #pragma link C++ class TGeoVoxelFinder+; #pragma link C++ class TGeoCylVoxels+; +#pragma link C++ class TGeoFullVoxels+; #pragma link C++ class TGeoShape+; #pragma link C++ class TGeoBBox+; #pragma link C++ class TGeoPara+; @@ -54,6 +55,7 @@ #pragma link C++ class TGeoTrd1+; #pragma link C++ class TGeoTrd2+; #pragma link C++ class TGeoCompositeShape+; +#pragma link C++ class TGeoPolygon+; #pragma link C++ class TGeoVolume-; #pragma link C++ class TGeoVolumeAssembly+; #pragma link C++ class TGeoVolumeMulti+; diff --git a/geom/inc/TGeoCache.h b/geom/inc/TGeoCache.h index ab3a0294394..1eb5d6cf22a 100644 --- a/geom/inc/TGeoCache.h +++ b/geom/inc/TGeoCache.h @@ -1,4 +1,4 @@ -// @(#)root/geom:$Name: $:$Id: TGeoCache.h,v 1.17 2003/10/01 17:53:11 brun Exp $ +// @(#)root/geom:$Name: $:$Id: TGeoCache.h,v 1.18 2003/11/11 15:44:28 brun Exp $ // Author: Andrei Gheata 18/03/02 /************************************************************************* @@ -43,6 +43,7 @@ class TGeoCacheState : public TObject { protected: Int_t fLevel; // level in the current branch + Int_t fStart; // start level Int_t fIdBranch[30]; // ID branch Double_t *fPoint; // last point in master frame Bool_t fOverlapping; // overlap flag @@ -55,7 +56,7 @@ public: TGeoCacheState(Int_t capacity); virtual ~TGeoCacheState(); - virtual void SetState(Int_t level, Bool_t ovlp, Double_t *point=0); + virtual void SetState(Int_t level, Int_t startlevel, Bool_t ovlp, Double_t *point=0); virtual Bool_t GetState(Int_t &level, Double_t *point) const; ClassDef(TGeoCacheState, 1) // class storing the cache state @@ -78,7 +79,7 @@ public: TGeoCacheStateDummy(Int_t capacity); virtual ~TGeoCacheStateDummy(); - virtual void SetState(Int_t level, Bool_t ovlp, Double_t *point=0); + virtual void SetState(Int_t level, Int_t startlevel, Bool_t ovlp, Double_t *point=0); virtual Bool_t GetState(Int_t &level, Double_t *point) const; ClassDef(TGeoCacheStateDummy, 1) // class storing the cache state @@ -129,7 +130,8 @@ protected: public: TGeoNodeCache(); - TGeoNodeCache(Int_t size); + TGeoNodeCache(Bool_t nodeid); + TGeoNodeCache(Int_t size, Bool_t nodeid=kFALSE); virtual ~TGeoNodeCache(); Int_t AddNode(TGeoNode *node); @@ -146,7 +148,7 @@ public: virtual void ClearDaughter(Int_t index); virtual void ClearNode(Int_t nindex); virtual void Compact(); - void FillIdBranch(const Int_t *br) {memcpy(fIdBranch,br,(fLevel+1)*sizeof(Int_t)); fIndex=fIdBranch[fLevel];} + void FillIdBranch(const Int_t *br, Int_t startlevel=0) {memcpy(fIdBranch+startlevel,br,(fLevel+1-startlevel)*sizeof(Int_t)); fIndex=fIdBranch[fLevel];} const Int_t *GetIdBranch() const {return fIdBranch;} virtual void DeleteCaches(); virtual Bool_t DumpNodes(); @@ -157,7 +159,7 @@ public: virtual void *GetMatrices() const {return fMatrices;} virtual TGeoHMatrix *GetCurrentMatrix() const; Int_t GetCurrentNode() const {return fCurrentNode;} - Int_t GetCurrentNodeId() const {return (fNodeIdArray)?fNodeIdArray[fIndex]:-1;} + Int_t GetCurrentNodeId() const; virtual TGeoNode *GetMother(Int_t up=1) const; virtual TGeoNode *GetNode() const; Int_t GetStackLevel() const {return fStackLevel;} @@ -183,7 +185,7 @@ public: virtual void LocalToMasterBomb(const Double_t *local, Double_t *master) const; virtual void MasterToLocalBomb(const Double_t *master, Double_t *local) const; virtual void PrintNode() const; - virtual Int_t PushState(Bool_t ovlp, Double_t *point=0); + virtual Int_t PushState(Bool_t ovlp, Int_t startlevel=0, Double_t *point=0); virtual Bool_t PopState(Double_t *point=0); virtual Bool_t PopState(Int_t level, Double_t *point=0); virtual void PopDummy(Int_t ipop=9999) {fStackLevel=(ipop>fStackLevel)?(fStackLevel-1):(ipop-1);} @@ -209,10 +211,11 @@ private: TGeoNode *fNode; // current node TGeoHMatrix *fMatrix; // current matrix TGeoHMatrix **fMatrixBranch; // current branch of global matrices + TGeoHMatrix **fMPB; // pre-built matrices TGeoNode **fNodeBranch; // current branch of nodes public: TGeoCacheDummy(); - TGeoCacheDummy(TGeoNode *top); + TGeoCacheDummy(TGeoNode *top, Bool_t nodeid=kFALSE); virtual ~TGeoCacheDummy(); virtual Bool_t CdDown(Int_t index, Bool_t make=kTRUE); diff --git a/geom/inc/TGeoManager.h b/geom/inc/TGeoManager.h index 04fe567258c..2718b850f1b 100644 --- a/geom/inc/TGeoManager.h +++ b/geom/inc/TGeoManager.h @@ -1,4 +1,4 @@ -// @(#)root/geom:$Name: $:$Id: TGeoManager.h,v 1.41 2003/12/10 15:31:23 brun Exp $ +// @(#)root/geom:$Name: $:$Id: TGeoManager.h,v 1.42 2004/01/19 13:40:50 brun Exp $ // Author: Andrei Gheata 25/10/01 /************************************************************************* @@ -117,7 +117,7 @@ private : Double_t *fDblBuffer; //! transient dbl buffer //--- private methods - void BuildCache(Bool_t dummy=kFALSE); + void BuildCache(Bool_t dummy=kFALSE, Bool_t nodeid=kFALSE); void BuildIdArray(); TGeoNode *FindInCluster(Int_t *cluster, Int_t nc); Int_t GetTouchedCluster(Int_t start, Double_t *point, Int_t *check_list, @@ -310,6 +310,7 @@ public: TVirtualGeoTrack *GetParentTrackOfId(Int_t id) const; Int_t GetVirtualLevel(); Bool_t GotoSafeLevel(); + Int_t GetSafeLevel() const; Double_t GetSafeDistance() const {return fSafety;} Double_t GetStep() const {return fStep;} Bool_t IsAnimatingTracks() const {return fIsGeomReading;} @@ -430,12 +431,12 @@ public: void SelectTrackingMedia(); //--- stack manipulation - Int_t PushPath() {return fCache->PushState(fCurrentOverlapping);} + Int_t PushPath(Int_t startlevel=0) {return fCache->PushState(fCurrentOverlapping, startlevel);} Bool_t PopPath() {fCurrentOverlapping=fCache->PopState(); fCurrentNode=fCache->GetNode(); fLevel=fCache->GetLevel();return fCurrentOverlapping;} Bool_t PopPath(Int_t index) {fCurrentOverlapping=fCache->PopState(index); fCurrentNode=fCache->GetNode(); fLevel=fCache->GetLevel();return fCurrentOverlapping;} - Int_t PushPoint() {return fCache->PushState(fCurrentOverlapping, fPoint);} + Int_t PushPoint(Int_t startlevel=0) {return fCache->PushState(fCurrentOverlapping, startlevel,fPoint);} Bool_t PopPoint() {fCurrentOverlapping=fCache->PopState(fPoint); fCurrentNode=fCache->GetNode(); fLevel=fCache->GetLevel(); return fCurrentOverlapping;} Bool_t PopPoint(Int_t index) {fCurrentOverlapping=fCache->PopState(index, fPoint); fCurrentNode=fCache->GetNode(); diff --git a/geom/inc/TGeoMatrix.h b/geom/inc/TGeoMatrix.h index d782fd12c12..5f48f419d07 100644 --- a/geom/inc/TGeoMatrix.h +++ b/geom/inc/TGeoMatrix.h @@ -1,4 +1,4 @@ -// @(#)root/geom:$Name: $:$Id: TGeoMatrix.h,v 1.10 2003/09/25 14:50:40 brun Exp $ +// @(#)root/geom:$Name: $:$Id: TGeoMatrix.h,v 1.11 2004/01/18 12:31:54 brun Exp $ // Author: Andrei Gheata 25/10/01 /************************************************************************* @@ -301,13 +301,14 @@ public : TGeoIdentity(const char *name); virtual ~TGeoIdentity() {} - virtual void LocalToMaster(const Double_t *local, Double_t *master) const {memcpy(master, local, 3*sizeof(Double_t));} + virtual void LocalToMaster(const Double_t *local, Double_t *master) const + {memcpy(master, local, 3*sizeof(Double_t));} virtual void LocalToMasterVect(const Double_t *local, Double_t *master) const -{memcpy(master, local, 3*sizeof(Double_t));} + {memcpy(master, local, 3*sizeof(Double_t));} virtual void MasterToLocal(const Double_t *master, Double_t *local) const - {memcpy(local, master, 3*sizeof(Double_t));} + {memcpy(local, master, 3*sizeof(Double_t));} virtual void MasterToLocalVect(const Double_t *master, Double_t *local) const - {memcpy(local, master, 3*sizeof(Double_t));} + {memcpy(local, master, 3*sizeof(Double_t));} virtual void LocalToMasterBomb(const Double_t *local, Double_t *master) const {TGeoIdentity::LocalToMaster(local, master);} virtual void MasterToLocalBomb(const Double_t *master, Double_t *local) const diff --git a/geom/inc/TGeoVoxelFinder.h b/geom/inc/TGeoVoxelFinder.h index 68c71f22e89..de4197edf79 100644 --- a/geom/inc/TGeoVoxelFinder.h +++ b/geom/inc/TGeoVoxelFinder.h @@ -1,4 +1,4 @@ -// @(#)root/geom:$Name: $:$Id: TGeoVoxelFinder.h,v 1.7 2003/02/18 15:37:36 brun Exp $ +// @(#)root/geom:$Name: $:$Id: TGeoVoxelFinder.h,v 1.8 2004/01/18 12:31:54 brun Exp $ // Author: Andrei Gheata 04/02/02 /************************************************************************* @@ -23,6 +23,10 @@ class TGeoVoxelFinder : public TObject { +public: +enum EVoxelsType { + kGeoInvalidVoxels = BIT(15) +}; protected: TGeoVolume *fVolume; // volume to which applies @@ -72,6 +76,7 @@ public : void DaughterToMother(Int_t id, Double_t *local, Double_t *master) const; virtual Double_t Efficiency(); virtual Int_t *GetCheckList(Double_t *point, Int_t &nelem); + Int_t *GetCheckList(Int_t &nelem) const {nelem=fNcandidates; return fCheckList;} Int_t *GetExtraX(Int_t islice, Bool_t left, Int_t &nextra) const; Int_t *GetExtraY(Int_t islice, Bool_t left, Int_t &nextra) const; Int_t *GetExtraZ(Int_t islice, Bool_t left, Int_t &nextra) const; @@ -84,7 +89,9 @@ public : Int_t *GetValidExtra(Int_t *list, Int_t &ncheck); Int_t *GetValidExtra(Int_t n1, UChar_t *array1, Int_t *list, Int_t &ncheck); Int_t *GetValidExtra(Int_t n1, UChar_t *array1, Int_t n2, UChar_t *array2, Int_t *list, Int_t &ncheck); + virtual Int_t *GetVoxelCandidates(Int_t i, Int_t j, Int_t k, Int_t &ncheck); virtual void FindOverlaps(Int_t inode) const; + Bool_t IsInvalid() const {return TObject::TestBit(kGeoInvalidVoxels);} Double_t *GetBoxes() const {return fBoxes;} Bool_t IsSafeVoxel(Double_t *point, Int_t inode, Double_t minsafe) const; virtual void Print(Option_t *option="") const; @@ -102,6 +109,7 @@ public : Bool_t IntersectAndStore(Int_t n1, UChar_t *array1, Int_t n2, UChar_t *array2); Bool_t IntersectAndStore(Int_t n1, UChar_t *array1, Int_t n2, UChar_t *array2, Int_t n3, UChar_t *array3); + void SetInvalid(Bool_t flag=kTRUE) {TObject::SetBit(kGeoInvalidVoxels, flag);} virtual void SortAll(Option_t *option=""); void SortCrossedVoxels(Double_t *point, Double_t *dir); // Bool_t Union(Int_t n1, Int_t *array1, Int_t n2, Int_t *array2, @@ -143,4 +151,37 @@ public: ClassDef(TGeoCylVoxels, 2) // cylindrical voxel class }; +/************************************************************************* + * TGeoFullVoxels - Full voxeliztion applies to volumes with limited + * number of daughters and stores node information in each cell. + * + *************************************************************************/ + +class TGeoFullVoxels : public TGeoVoxelFinder +{ +private: + Int_t fNvoxels; + Int_t fNvx; // number of slices on X + Int_t fNvy; // number of slices on Y + Int_t fNvz; // number of slices on Z + UChar_t *fVox; //[fNvoxels] voxels storage array +public: + TGeoFullVoxels(); + TGeoFullVoxels(TGeoVolume *vol); + virtual ~TGeoFullVoxels(); + +// virtual void BuildVoxelLimits(); +// virtual Double_t Efficiency(); +// virtual void FindOverlaps(Int_t inode) const; + virtual Int_t *GetCheckList(Double_t *point, Int_t &nelem); +// virtual Bool_t GetNextIndices(Double_t *point, Double_t *dir); + UChar_t *GetVoxel(Int_t i, Int_t j, Int_t k) const {return &fVox[(i*fNvy+j)*fNvz+k];} + virtual Int_t *GetVoxelCandidates(Int_t i, Int_t j, Int_t k, Int_t &ncheck); +// virtual Int_t *GetNextVoxel(Double_t *point, Double_t *dir, Int_t &ncheck); + virtual void Print(Option_t *option="") const; + virtual void Voxelize(Option_t *option); + + ClassDef(TGeoFullVoxels, 1) // full voxels class +}; + #endif diff --git a/geom/src/TGeoCache.cxx b/geom/src/TGeoCache.cxx index 94c10bb1349..a99521ef6fa 100644 --- a/geom/src/TGeoCache.cxx +++ b/geom/src/TGeoCache.cxx @@ -1,4 +1,4 @@ -// @(#)root/geom:$Name: $:$Id: TGeoCache.cxx,v 1.23 2004/01/19 13:43:15 brun Exp $ +// @(#)root/geom:$Name: $:$Id: TGeoCache.cxx,v 1.24 2004/01/19 13:44:14 brun Exp $ // Author: Andrei Gheata 18/03/02 /************************************************************************* @@ -68,11 +68,45 @@ TGeoNodeCache::TGeoNodeCache() fMatrixPool = 0; fNodeIdArray = 0; fIndex = 0; - BuildIdArray(); +// BuildIdArray(); } //_____________________________________________________________________________ -TGeoNodeCache::TGeoNodeCache(Int_t /*size*/) +TGeoNodeCache::TGeoNodeCache(Bool_t nodeid) +{ +// dummy constructor + fGeoCacheMaxDaughters = 128; + fGeoCacheMaxSize = 1000000; + fGeoCacheStackSize = 1000; + fGeoCacheDefaultLevel = 4; + fGeoCacheMaxLevels = 30; + fGeoCacheObjArrayInd = 0xFF; + fGeoCacheUsageRatio = 0.01; + fSize = 0; + fNused = 0; + fLevel = 0; + fStackLevel = 0; + fStack = 0; + fDefaultLevel= 0; + fCache = 0; + fPath = ""; + fTopNode = 0; + fCurrentNode = 0; + fCurrentCache = 0; + fCurrentIndex = 0; + fCurrentID = 0; + fBranch = 0; + fMatrices = 0; + fGlobalMatrix= 0; + fMatrixPool = 0; + fNodeIdArray = 0; + fIndex = 0; + if (nodeid) BuildIdArray(); + else printf("--- node ID tracking disabled\n"); +} + +//_____________________________________________________________________________ +TGeoNodeCache::TGeoNodeCache(Int_t /*size*/, Bool_t nodeid) { // constructor fGeoCacheMaxDaughters = 128; @@ -120,7 +154,8 @@ TGeoNodeCache::TGeoNodeCache(Int_t /*size*/) fCurrentID = 0; fNodeIdArray = 0; fIndex = 0; - BuildIdArray(); + if (nodeid) BuildIdArray(); + else printf("--- node ID tracking disabled\n"); CdTop(); } @@ -148,8 +183,8 @@ void TGeoNodeCache::BuildIdArray() // Builds node id array. Int_t nnodes = gGeoManager->GetNNodes(); //if (nnodes>3E7) return; - if (nnodes>0) return; //do not use the node cache by default if (fNodeIdArray) delete [] fNodeIdArray; + printf("--- node ID tracking enabled, size=%i Bytes\n", (2*nnodes+1)*sizeof(Int_t)); fNodeIdArray = new Int_t[2*nnodes+1]; fNodeIdArray[0] = 0; Int_t ifree = 1; @@ -158,6 +193,14 @@ void TGeoNodeCache::BuildIdArray() fIdBranch[0] = 0; } +//_____________________________________________________________________________ +Int_t TGeoNodeCache::GetCurrentNodeId() const +{ +// Returns a fixed ID for current physical node + if (fNodeIdArray) return fNodeIdArray[fIndex]; + return GetNodeId(); +} + //_____________________________________________________________________________ void TGeoNodeCache::Compact() { @@ -469,13 +512,13 @@ void TGeoNodeCache::PrintNode() const } //_____________________________________________________________________________ -Int_t TGeoNodeCache::PushState(Bool_t ovlp, Double_t *point) +Int_t TGeoNodeCache::PushState(Bool_t ovlp, Int_t startlevel, Double_t *point) { if (fStackLevel>=fGeoCacheStackSize) { printf("ERROR TGeoNodeCach::PushSate() : stack of states full\n"); return 0; } - ((TGeoCacheState*)fStack->At(fStackLevel))->SetState(fLevel,ovlp,point); + ((TGeoCacheState*)fStack->At(fStackLevel))->SetState(fLevel,startlevel,ovlp,point); return ++fStackLevel; } @@ -549,19 +592,24 @@ TGeoCacheDummy::TGeoCacheDummy() fNode = 0; fNodeBranch = 0; fMatrixBranch = 0; + fMPB = 0; } //_____________________________________________________________________________ -TGeoCacheDummy::TGeoCacheDummy(TGeoNode *top) +TGeoCacheDummy::TGeoCacheDummy(TGeoNode *top, Bool_t nodeid) + :TGeoNodeCache(nodeid) { fTop = top; fNode = top; fNodeBranch = new TGeoNode *[fGeoCacheMaxLevels]; fNodeBranch[0] = top; fMatrixBranch = new TGeoHMatrix *[fGeoCacheMaxLevels]; - for (Int_t i=0; i<fGeoCacheMaxLevels; i++) - fMatrixBranch[i] = new TGeoHMatrix("global"); - fMatrix = fMatrixBranch[0]; + fMPB = new TGeoHMatrix *[fGeoCacheMaxLevels]; + for (Int_t i=0; i<fGeoCacheMaxLevels; i++) { + fMPB[i] = new TGeoHMatrix("global"); + fMatrixBranch[i] = 0; + } + fMatrix = fMatrixBranch[0] = fMPB[0]; fStack = new TObjArray(fGeoCacheStackSize); for (Int_t ist=0; ist<fGeoCacheStackSize; ist++) fStack->Add(new TGeoCacheStateDummy(100)); // !obsolete 100 @@ -572,10 +620,10 @@ TGeoCacheDummy::TGeoCacheDummy(TGeoNode *top) TGeoCacheDummy::~TGeoCacheDummy() { if (fNodeBranch) delete [] fNodeBranch; - if (fMatrixBranch) { + if (fMPB) { for (Int_t i=0; i<fGeoCacheMaxLevels; i++) - delete fMatrixBranch[i]; - delete [] fMatrixBranch; + delete fMPB[i]; + delete [] fMPB; } } @@ -584,18 +632,20 @@ Bool_t TGeoCacheDummy::CdDown(Int_t index, Bool_t /*make*/) { TGeoNode *newnode = fNode->GetDaughter(index); if (!newnode) return kFALSE; - TGeoHMatrix *newmat = fMatrixBranch[fLevel+1]; - TGeoMatrix *local = newnode->GetMatrix(); - *newmat = fMatrix; - newmat->Multiply(local); fLevel++; if (fNodeIdArray) { fIndex = fNodeIdArray[fIndex+index+1]; fIdBranch[fLevel] = fIndex; } - fMatrix = newmat; fNode = newnode; fNodeBranch[fLevel] = fNode; + TGeoMatrix *local = newnode->GetMatrix(); + TGeoHMatrix *newmat = fMPB[fLevel+1]; + if (!local->IsIdentity()) { + *newmat = fMatrix; + newmat->Multiply(local); + fMatrix = newmat; + } fMatrixBranch[fLevel] = fMatrix; return kTRUE; } @@ -1457,17 +1507,20 @@ TGeoCacheState::~TGeoCacheState() } //_____________________________________________________________________________ -void TGeoCacheState::SetState(Int_t level, Bool_t ovlp, Double_t *point) +void TGeoCacheState::SetState(Int_t level, Int_t startlevel, Bool_t ovlp, Double_t *point) { fLevel = level; + fStart = startlevel; if (gGeoManager->IsOutside()) { fLevel = -1; return; } TGeoNodeCache *cache = gGeoManager->GetCache(); - if (cache->HasIdArray()) memcpy(fIdBranch, cache->GetIdBranch(), (level+1)*sizeof(Int_t)); - memcpy(fBranch, (Int_t*)cache->GetBranch(), (level+1)*sizeof(Int_t)); - memcpy(fMatrices, (Int_t*)cache->GetMatrices(), (level+1)*sizeof(Int_t)); + Int_t *branch = (Int_t*)cache->GetBranch(); + Int_t *matrices = (Int_t*)cache->GetMatrices(); + if (cache->HasIdArray()) memcpy(fIdBranch, cache->GetIdBranch()+fStart, (level+1-fStart)*sizeof(Int_t)); + memcpy(fBranch, branch+fStart, (level+1-fStart)*sizeof(Int_t)); + memcpy(fMatrices, matrices+fStart, (level+1-fStart)*sizeof(Int_t)); fOverlapping = ovlp; if (point) memcpy(fPoint, point, 3*sizeof(Double_t)); } @@ -1481,9 +1534,11 @@ Bool_t TGeoCacheState::GetState(Int_t &level, Double_t *point) const return kFALSE; } TGeoNodeCache *cache = gGeoManager->GetCache(); - if (cache->HasIdArray()) cache->FillIdBranch(fIdBranch); - memcpy((Int_t*)cache->GetBranch(), fBranch, (level+1)*sizeof(Int_t)); - memcpy((Int_t*)cache->GetMatrices(), fMatrices, (level+1)*sizeof(Int_t)); + if (cache->HasIdArray()) cache->FillIdBranch(fIdBranch, fStart); + Int_t *branch = (Int_t*)cache->GetBranch(); + Int_t *matrices = (Int_t*)cache->GetMatrices(); + memcpy(branch+fStart, fBranch, (level+1-fStart)*sizeof(Int_t)); + memcpy(matrices+fStart, fMatrices, (level+1-fStart)*sizeof(Int_t)); if (point) memcpy(point, fPoint, 3*sizeof(Double_t)); return fOverlapping; } @@ -1531,17 +1586,18 @@ TGeoCacheStateDummy::~TGeoCacheStateDummy() } //_____________________________________________________________________________ -void TGeoCacheStateDummy::SetState(Int_t level, Bool_t ovlp, Double_t *point) +void TGeoCacheStateDummy::SetState(Int_t level, Int_t startlevel, Bool_t ovlp, Double_t *point) { fLevel = level; + fStart = startlevel; TGeoNodeCache *cache = gGeoManager->GetCache(); - if (cache->HasIdArray()) memcpy(fIdBranch, cache->GetIdBranch(), (level+1)*sizeof(Int_t)); + if (cache->HasIdArray()) memcpy(fIdBranch, cache->GetIdBranch()+fStart, (level+1-fStart)*sizeof(Int_t)); TGeoNode **node_branch = (TGeoNode **) cache->GetBranch(); TGeoHMatrix **mat_branch = (TGeoHMatrix **) cache->GetMatrices(); - memcpy(fNodeBranch, node_branch, (level+1)*sizeof(TGeoNode *)); - for (Int_t i=0; i<level+1; i++) - *fMatrixBranch[i] = mat_branch[i]; + memcpy(fNodeBranch, node_branch+fStart, (level+1-fStart)*sizeof(TGeoNode *)); + for (Int_t i=0; i<level+1-fStart; i++) + *fMatrixBranch[i] = mat_branch[i+fStart]; fOverlapping = ovlp; if (point) memcpy(fPoint, point, 3*sizeof(Double_t)); } @@ -1551,13 +1607,13 @@ Bool_t TGeoCacheStateDummy::GetState(Int_t &level, Double_t *point) const { level = fLevel; TGeoNodeCache *cache = gGeoManager->GetCache(); - if (cache->HasIdArray()) cache->FillIdBranch(fIdBranch); + if (cache->HasIdArray()) cache->FillIdBranch(fIdBranch, fStart); TGeoNode **node_branch = (TGeoNode **) cache->GetBranch(); TGeoHMatrix **mat_branch = (TGeoHMatrix **) cache->GetMatrices(); - memcpy(node_branch, fNodeBranch, (level+1)*sizeof(TGeoNode *)); - for (Int_t i=0; i<level+1; i++) - *mat_branch[i] = fMatrixBranch[i]; + memcpy(node_branch+fStart, fNodeBranch, (level+1-fStart)*sizeof(TGeoNode *)); + for (Int_t i=0; i<level+1-fStart; i++) + *mat_branch[i+fStart] = fMatrixBranch[i]; if (point) memcpy(point, fPoint, 3*sizeof(Double_t)); return fOverlapping; } diff --git a/geom/src/TGeoManager.cxx b/geom/src/TGeoManager.cxx index 03bd9cd44ab..10614e3a67a 100644 --- a/geom/src/TGeoManager.cxx +++ b/geom/src/TGeoManager.cxx @@ -1,4 +1,4 @@ -// @(#)root/geom:$Name: $:$Id: TGeoManager.cxx,v 1.69 2004/01/18 12:31:54 brun Exp $ +// @(#)root/geom:$Name: $:$Id: TGeoManager.cxx,v 1.70 2004/01/19 13:40:51 brun Exp $ // Author: Andrei Gheata 25/10/01 /************************************************************************* @@ -714,16 +714,16 @@ void TGeoManager::UnbombTranslation(const Double_t *tr, Double_t *bombtr) } //_____________________________________________________________________________ -void TGeoManager::BuildCache(Bool_t dummy) +void TGeoManager::BuildCache(Bool_t dummy, Bool_t nodeid) { // Builds the cache for physical nodes and global matrices. if (!fCache) { if (fNNodes>5000000 || dummy) // temporary - works without // build dummy cache - fCache = new TGeoCacheDummy(fTopNode); + fCache = new TGeoCacheDummy(fTopNode, nodeid); else // build real cache - fCache = new TGeoNodeCache(0); + fCache = new TGeoNodeCache(0,nodeid); } } @@ -1333,6 +1333,7 @@ void TGeoManager::CloseGeometry(Option_t *option) TString opt(option); opt.ToLower(); Bool_t dummy = opt.Contains("d"); + Bool_t nodeid = opt.Contains("i"); if (fIsGeomReading) { printf("### Geometry loaded from file...\n"); gGeoIdentity=(TGeoIdentity *)fMatrices->At(0); @@ -1344,11 +1345,11 @@ void TGeoManager::CloseGeometry(Option_t *option) SetTopVolume(fMasterVolume); if (fStreamVoxels) printf("### Voxelization retrieved from file\n"); Voxelize("ALL"); - if (!fCache) BuildCache(dummy); + if (!fCache) BuildCache(dummy,nodeid); } else { Warning("CloseGeometry", "top node was streamed!"); Voxelize("ALL"); - if (!fCache) BuildCache(dummy); + if (!fCache) BuildCache(dummy,nodeid); } // BuildIdArray(); printf("### %i nodes/ %i volume UID's in %s\n", fNNodes, fUniqueVolumes->GetEntriesFast(), GetTitle()); @@ -1364,7 +1365,7 @@ void TGeoManager::CloseGeometry(Option_t *option) // BuildIdArray(); Voxelize("ALL"); printf("Building caches for nodes and matrices...\n"); - BuildCache(dummy); + BuildCache(dummy,nodeid); printf("### %i nodes/ %i volume UID's in %s\n", fNNodes, fUniqueVolumes->GetEntriesFast(), GetTitle()); printf("----------------modeler ready----------------\n"); } @@ -1766,6 +1767,23 @@ Bool_t TGeoManager::GotoSafeLevel() while (fCurrentOverlapping && fLevel) CdUp(); return kTRUE; } + +//_____________________________________________________________________________ +Int_t TGeoManager::GetSafeLevel() const +{ +// Go upwards the tree until a non-overlaping node + Bool_t overlapping = fCurrentOverlapping; + if (!overlapping) return fLevel; + Int_t level = fLevel; + TGeoNode *node; + while (overlapping && level) { + level--; + node = GetMother(fLevel-level); + if (!node->IsOffset()) overlapping = node->IsOverlapping(); + } + return level; +} + //_____________________________________________________________________________ TGeoNode *TGeoManager::FindInCluster(Int_t *cluster, Int_t nc) { @@ -2018,7 +2036,8 @@ void TGeoManager::SafetyOverlaps() TGeoVolume *vol; Int_t novlp, io; Int_t *ovlp; - PushPath(); + Int_t safelevel = GetSafeLevel(); + PushPath(safelevel+1); while (fCurrentOverlapping) { ovlp = fCurrentNode->GetOverlaps(novlp); CdUp(); @@ -2571,9 +2590,10 @@ TGeoNode *TGeoManager::FindNextBoundary(Double_t stepmax, const char *path) Double_t mothpt[3]; Double_t vecpt[3]; Double_t dpt[3], dvec[3]; - PushPath(); Int_t novlps; - while (fCurrentOverlapping) { + Int_t safelevel = GetSafeLevel(); + PushPath(safelevel+1); + while (fCurrentOverlapping) { Int_t *ovlps = fCurrentNode->GetOverlaps(novlps); CdUp(); mother = fCurrentNode->GetVolume(); @@ -2885,13 +2905,10 @@ 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 if (fCurrentOverlapping) { - TGeoNode *current = fCurrentNode; Int_t cid = GetCurrentNodeId(); if (!change) PushPoint(); gGeoManager->FindNode(x,y,z); - Bool_t same = (cid>=0)?kTRUE:kFALSE; - if (same) same = (cid==GetCurrentNodeId())?kTRUE:kFALSE; - else same = (current==fCurrentNode)?kTRUE:kFALSE; + Bool_t same = (cid==GetCurrentNodeId())?kTRUE:kFALSE; if (!change) PopPoint(); return same; } @@ -3561,9 +3578,10 @@ void TGeoManager::SetTopVolume(TGeoVolume *vol) fLevel = 0; if (fCache) { Bool_t dummy=fCache->IsDummy(); + Bool_t nodeid = fCache->HasIdArray(); delete fCache; fCache = 0; - BuildCache(dummy); + BuildCache(dummy,nodeid); } printf("Top volume is %s. Master volume is %s\n", fTopVolume->GetName(), fMasterVolume->GetName()); diff --git a/geom/src/TGeoTube.cxx b/geom/src/TGeoTube.cxx index c99ff1c7aef..78f9520b4e7 100644 --- a/geom/src/TGeoTube.cxx +++ b/geom/src/TGeoTube.cxx @@ -1,4 +1,4 @@ -// @(#)root/geom:$Name: $:$Id: TGeoTube.cxx,v 1.29 2003/12/10 15:31:23 brun Exp $ +// @(#)root/geom:$Name: $:$Id: TGeoTube.cxx,v 1.30 2003/12/11 10:34:33 brun Exp $ // Author: Andrei Gheata 24/10/01 // TGeoTube::Contains() and DistToOut/In() implemented by Mihaela Gheata @@ -303,7 +303,7 @@ Double_t TGeoTube::DistToOut(Double_t *point, Double_t *dir, Int_t iact, Double_ Double_t b,d; Double_t sr; // inner cylinder - if (fRmin>1E-10) { + if (fRmin>1E-10 && rdotn<0) { DistToTube(rsq,nsq,rdotn,fRmin,b,d); if (d>0) { sr=-b-d; diff --git a/geom/src/TGeoVolume.cxx b/geom/src/TGeoVolume.cxx index 0e3ea82403e..ff09ed631e3 100644 --- a/geom/src/TGeoVolume.cxx +++ b/geom/src/TGeoVolume.cxx @@ -1,4 +1,4 @@ -// @(#)root/geom:$Name: $:$Id: TGeoVolume.cxx,v 1.39 2003/10/20 08:46:33 brun Exp $ +// @(#)root/geom:$Name: $:$Id: TGeoVolume.cxx,v 1.40 2003/11/11 15:44:28 brun Exp $ // Author: Andrei Gheata 30/05/02 // Divide(), CheckOverlaps() implemented by Mihaela Gheata @@ -1346,15 +1346,20 @@ void TGeoVolume::Voxelize(Option_t *option) } } // find optimal voxelization - Bool_t cyltype = GetOptimalVoxels(); - if (cyltype) { -// fVoxels = new TGeoCylVoxels(this); +// Bool_t cyltype = GetOptimalVoxels(); +// if (nd < 8) { +// fVoxels = new TGeoFullVoxels(this); +// if (fVoxels) printf("full voxels for %s\n", GetName()); +// } else fVoxels = new TGeoVoxelFinder(this); -// printf("%s cyl. voxels\n", GetName()); - } else { - fVoxels = new TGeoVoxelFinder(this); - } + fVoxels->Voxelize(option); + if (fVoxels) { + if (fVoxels->IsInvalid()) { + delete fVoxels; + fVoxels = 0; + } + } // if (fVoxels) fVoxels->Print(); } diff --git a/geom/src/TGeoVoxelFinder.cxx b/geom/src/TGeoVoxelFinder.cxx index d72836cab6e..40f5a40937f 100644 --- a/geom/src/TGeoVoxelFinder.cxx +++ b/geom/src/TGeoVoxelFinder.cxx @@ -1,4 +1,4 @@ -// @(#)root/geom:$Name: $:$Id: TGeoVoxelFinder.cxx,v 1.20 2003/12/11 10:34:33 brun Exp $ +// @(#)root/geom:$Name: $:$Id: TGeoVoxelFinder.cxx,v 1.21 2004/01/18 12:31:55 brun Exp $ // Author: Andrei Gheata 04/02/02 /************************************************************************* @@ -75,6 +75,7 @@ TGeoVoxelFinder::TGeoVoxelFinder() fCheckList = 0; fNcandidates = 0; fCurrentVoxel = 0; + SetInvalid(kFALSE); } //----------------------------------------------------------------------------- TGeoVoxelFinder::TGeoVoxelFinder(TGeoVolume *vol) @@ -1129,19 +1130,27 @@ void TGeoVoxelFinder::SortCrossedVoxels(Double_t *point, Double_t *dir) Int_t *TGeoVoxelFinder::GetCheckList(Double_t *point, Int_t &nelem) { // get the list of daughter indices for which point is inside their bbox - if (!fBoxes) return 0; - Bool_t one_daughter = kFALSE; - Int_t nslices = 0; +// if (!fBoxes) return 0; if (fVolume->GetNdaughters() == 1) { + if (fXb) { + if (point[0]<fXb[0] || point[0]>fXb[1]) return 0; + } + if (fYb) { + if (point[1]<fYb[0] || point[1]>fYb[1]) return 0; + } + + if (fZb) { + if (point[2]<fZb[0] || point[2]>fZb[1]) return 0; + } fCheckList[0] = 0; nelem = 1; - one_daughter = kTRUE; + return fCheckList; } + Int_t nslices = 0; UChar_t *slice1 = 0; UChar_t *slice2 = 0; UChar_t *slice3 = 0; - Int_t nd[3]; - memset(&nd[0], 0, 3*sizeof(Int_t)); + Int_t nd[3] = {0,0,0}; Int_t im; if (fPriority[0]) { im = TMath::BinarySearch(fIbx, fXb, point[0]); @@ -1190,7 +1199,6 @@ Int_t *TGeoVoxelFinder::GetCheckList(Double_t *point, Int_t &nelem) } } } - if (one_daughter) return fCheckList; nelem = 0; // Int_t i = 0; Bool_t intersect = kFALSE; @@ -1210,6 +1218,69 @@ Int_t *TGeoVoxelFinder::GetCheckList(Double_t *point, Int_t &nelem) if (intersect) return fCheckList; return 0; } + +//----------------------------------------------------------------------------- +Int_t *TGeoVoxelFinder::GetVoxelCandidates(Int_t i, Int_t j, Int_t k, Int_t &ncheck) +{ +// get the list of candidates in voxel (i,j,k) - no check + UChar_t *slice1 = 0; + UChar_t *slice2 = 0; + UChar_t *slice3 = 0; + Int_t nd[3] = {0,0,0}; + Int_t nslices = 0; + if (fPriority[0]==2) { + nd[0] = fIndX[fOBx[i]]; + if (!nd[0]) return 0; + nslices++; + slice1 = (UChar_t*)(&fIndX[fOBx[i]+1]); + } + + if (fPriority[1]==2) { + nd[1] = fIndY[fOBy[j]]; + if (!nd[1]) return 0; + nslices++; + if (slice1) { + slice2 = (UChar_t*)(&fIndY[fOBy[j]+1]); + } else { + slice1 = (UChar_t*)(&fIndY[fOBy[j]+1]); + nd[0] = nd[1]; + } + } + + if (fPriority[2]==2) { + nd[2] = fIndZ[fOBz[k]]; + if (!nd[2]) return 0; + nslices++; + if (slice1 && slice2) { + slice3 = (UChar_t*)(&fIndZ[fOBz[k]+1]); + } else { + if (slice1) { + slice2 = (UChar_t*)(&fIndZ[fOBz[k]+1]); + nd[1] = nd[2]; + } else { + slice1 = (UChar_t*)(&fIndZ[fOBz[k]+1]); + nd[0] = nd[2]; + } + } + } + Bool_t intersect = kFALSE; + switch (nslices) { + case 0: + Error("GetCheckList", "No slices for %s", fVolume->GetName()); + return 0; + case 1: + intersect = Intersect(nd[0], slice1, ncheck, fCheckList); + break; + case 2: + intersect = Intersect(nd[0], slice1, nd[1], slice2, ncheck, fCheckList); + break; + default: + intersect = Intersect(nd[0], slice1, nd[1], slice2, nd[2], slice3, ncheck, fCheckList); + } + if (intersect) return fCheckList; + return 0; +} + //----------------------------------------------------------------------------- Int_t *TGeoVoxelFinder::GetNextVoxel(Double_t *point, Double_t * /*dir*/, Int_t &ncheck) { @@ -1486,7 +1557,6 @@ void TGeoVoxelFinder::SortAll(Option_t *) { // order bounding boxes along x, y, z Int_t nd = fVolume->GetNdaughters(); - if (!nd) return; Int_t nperslice = 1 /*N in slice*/ + 1+(nd-1)/(8*sizeof(Int_t)); /*Nbytes per slice*/ Int_t nmaxslices = 2*nd-1; // max number of slices on each axis Double_t *boundaries = new Double_t[6*nd]; // list of different boundaries @@ -1545,13 +1615,14 @@ void TGeoVoxelFinder::SortAll(Option_t *) } // now find priority if (ib < 2) { - Error("SortAll", "less than 2 boundaries on X for %s!", fVolume->GetName()); + Error("SortAll", "Cannot voxelize %s :less than 2 boundaries on X", fVolume->GetName()); delete [] index; delete [] ind; delete [] temp; delete [] extra; delete [] extra_left; delete [] extra_right; + SetInvalid(); return; } if (ib == 2) { @@ -1663,13 +1734,14 @@ void TGeoVoxelFinder::SortAll(Option_t *) } // now find priority on Y if (ib < 2) { - Error("SortAll", "less than 2 boundaries on Y for %s!", fVolume->GetName()); + Error("SortAll", "Cannot voxelize %s :less than 2 boundaries on Y", fVolume->GetName()); delete [] index; delete [] ind; delete [] temp; delete [] extra; delete [] extra_left; delete [] extra_right; + SetInvalid(); return; } if (ib == 2) { @@ -1783,13 +1855,14 @@ void TGeoVoxelFinder::SortAll(Option_t *) } // now find priority on Z if (ib < 2) { - Error("SortAll", "less than 2 boundaries on Z for %s!", fVolume->GetName()); + Error("SortAll", "Cannot voxelize %s :less than 2 boundaries on Z", fVolume->GetName()); delete [] index; delete [] ind; delete [] temp; delete [] extra; delete [] extra_left; delete [] extra_right; + SetInvalid(); return; } if (ib == 2) { @@ -1819,7 +1892,6 @@ void TGeoVoxelFinder::SortAll(Option_t *) fZb = new Double_t[ib]; memcpy(fZb, &temp[0], ib*sizeof(Double_t)); fIbz = ib; - } @@ -2522,6 +2594,7 @@ void TGeoCylVoxels::SortAll(Option_t *) if ((rmin>=rmax) || (pmin>=pmax) || (zmin>=zmax)) { Error("SortAll", "wrong bounding cylinder"); printf("### volume was : %s\n", fVolume->GetName()); + SetInvalid(); return; } Int_t id; @@ -2572,6 +2645,7 @@ void TGeoCylVoxels::SortAll(Option_t *) if (ib < 2) { Error("SortAll", "less than 2 boundaries on R !"); printf("### volume was : %s\n", fVolume->GetName()); + SetInvalid(); return; } if (ib == 2) { @@ -2654,6 +2728,7 @@ void TGeoCylVoxels::SortAll(Option_t *) if (ib < 2) { Error("SortAll", "less than 2 boundaries on Phi !"); printf("### volume was : %s\n", fVolume->GetName()); + SetInvalid(); return; } if (ib == 2) { @@ -2726,6 +2801,7 @@ void TGeoCylVoxels::SortAll(Option_t *) if (ib < 2) { Error("SortAll", "less than 2 boundaries on Z !"); printf("### volume was : %s\n", fVolume->GetName()); + SetInvalid(); return; } if (ib == 2) { @@ -2810,8 +2886,184 @@ void TGeoCylVoxels::Voxelize(Option_t *) { //--- Voxelize fVolume. // printf("Voxelizing %s\n", fVolume->GetName()); - Int_t nd = fVolume->GetNdaughters(); - if (!nd) return; BuildVoxelLimits(); SortAll(); } + +ClassImp(TGeoFullVoxels) + + +//----------------------------------------------------------------------------- +TGeoFullVoxels::TGeoFullVoxels() +{ +// Default constructor + fNvoxels = 0; + fNvx = 0; + fNvy = 0; + fNvz = 0; + fVox = 0; +} +//----------------------------------------------------------------------------- +TGeoFullVoxels::TGeoFullVoxels(TGeoVolume *vol) + :TGeoVoxelFinder(vol) +{ +// Constructor + fNvoxels = 0; + fNvx = 0; + fNvy = 0; + fNvz = 0; + fVox = 0; +} + +//----------------------------------------------------------------------------- +TGeoFullVoxels::~TGeoFullVoxels() +{ +// Destructor + if (fVox) delete [] fVox; +} + +//----------------------------------------------------------------------------- +void TGeoFullVoxels::Voxelize(Option_t *) +{ +//--- Voxelize fVolume. +// printf("Voxelizing %s\n", fVolume->GetName()); + TGeoVoxelFinder::Voxelize(); + if (IsInvalid()) return; + fNvx = fNvy = fNvz = 1; + if (fPriority[0]) fNvx = fIbx-1; + if (fPriority[1]) fNvy = fIby-1; + if (fPriority[2]) fNvz = fIbz-1; + fNvoxels = fNvx*fNvy*fNvz; + if (fNvoxels <= 0) { + SetInvalid(); + return; + } + fVox = new UChar_t[fNvoxels]; + // Intersect slices to get candidates + Int_t ptrx=0, ptry=0, ptrz=0; // index of voxel (i,j,k) + UChar_t *slice1 = 0; + UChar_t *slice2 = 0; + UChar_t *slice3 = 0; + Int_t i,j,k; + if (fPriority[0]==2) { + for (i=0; i<fNvx; i++) { + ptrx = i*fNvy*fNvz; + slice1 = (UChar_t*)(&fIndX[fOBx[i]+1]); + if (fPriority[1]==2) { + for (j=0; j<fNvy; j++) { + ptry = ptrx + j*fNvz; + slice2 = (UChar_t*)(&fIndY[fOBy[j]+1]); + if (fPriority[2]==2) { + for (k=0; k<fNvz; k++) { + ptrz = ptry + k; + slice3 = (UChar_t*)(&fIndZ[fOBz[k]+1]); + fVox[ptrz] = slice1[0] & slice2[0] & slice3[0]; + } + } else { + fVox[ptry] = slice1[0] & slice2[0]; + } + } + } else { + if (fPriority[2]==2) { + for (k=0; k<fNvz; k++) { + ptrz = ptrx + k; + slice3 = (UChar_t*)(&fIndZ[fOBz[k]+1]); + fVox[ptrz] = slice1[0] & slice3[0]; + } + } else { + fVox[ptrx] = slice1[0]; + } + } + } + } else { + if (fPriority[1]==2) { + for (j=0; j<fNvy; j++) { + ptry = j*fNvz; + slice2 = (UChar_t*)(&fIndY[fOBy[j]+1]); + if (fPriority[2]==2) { + for (k=0; k<fNvz; k++) { + ptrz = ptry + k; + slice3 = (UChar_t*)(&fIndZ[fOBz[k]+1]); + fVox[ptrz] = slice2[0] & slice3[0]; + } + } else { + fVox[ptry] = slice2[0]; + } + } + } else { + if (fPriority[2]==2) { + for (k=0; k<fNvz; k++) { + ptrz = k; + slice3 = (UChar_t*)(&fIndZ[fOBz[k]+1]); + fVox[ptrz] = slice3[0]; + } + } + } + } +} + +//----------------------------------------------------------------------------- +Int_t *TGeoFullVoxels::GetVoxelCandidates(Int_t i, Int_t j, Int_t k, Int_t &ncheck) +{ +// get the list of candidates in voxel (i,j,k) - no check + ncheck = 0; + Int_t nd = fVolume->GetNdaughters(); + UChar_t *vox = GetVoxel(i,j,k); + UChar_t byte = vox[0]; + if (!vox[0]) return 0; + for (Int_t bit=0; bit<nd; bit++) { + if (byte & (1<<bit)) fCheckList[ncheck++] = bit; + } + return fCheckList; +} + +//----------------------------------------------------------------------------- +Int_t *TGeoFullVoxels::GetCheckList(Double_t *point, Int_t &nelem) +{ +// get the list of daughter indices for which point is inside their bbox + nelem = fNcandidates = 0; + Int_t im; + UChar_t *slice; + UChar_t byte = 0xFF; + if (fPriority[2]) { + im = TMath::BinarySearch(fIbz, fZb, point[2]); + if ((im==-1) || (im==fIbz-1)) return 0; + if (fPriority[2]==2) { + slice = (UChar_t*)(&fIndZ[fOBz[im]+1]); + byte &= slice[0]; + if (!byte) return 0; + } + } + + if (fPriority[0]) { + im = TMath::BinarySearch(fIbx, fXb, point[0]); + if ((im==-1) || (im==fIbx-1)) return 0; + if (fPriority[0]==2) { + slice = (UChar_t*)(&fIndX[fOBx[im]+1]); + byte &= slice[0]; + if (!byte) return 0; + } + } + + if (fPriority[1]) { + im = TMath::BinarySearch(fIby, fYb, point[1]); + if ((im==-1) || (im==fIby-1)) return 0; + if (fPriority[1]==2) { + slice = (UChar_t*)(&fIndY[fOBy[im]+1]); + byte &= slice[0]; + if (!byte) return 0; + } + } + Int_t nd = fVolume->GetNdaughters(); + for (Int_t i=0; i<nd; i++) { + if (byte & (1<<i)) fCheckList[fNcandidates++] = i; + } + nelem = fNcandidates; + return fCheckList; +} + +//----------------------------------------------------------------------------- +void TGeoFullVoxels::Print(Option_t *) const +{ +} + -- GitLab