From c1d8afc2da90fd3364f4c6f92f59c007cf55e800 Mon Sep 17 00:00:00 2001 From: Rene Brun <Rene.Brun@cern.ch> Date: Sun, 11 Jun 2006 12:56:48 +0000 Subject: [PATCH] From Andrei: 1. Mixtures components can now also be other materials/mixtures: TGeoMixture::AddElement(TGeoMaterial *mat, Double_t weight); 2. When elements are added via TGeoMixture::AddElement(TGeoElement *elem,...), the list of elements is kept. 3. Some fixes related to visualization within TGeoPainter git-svn-id: http://root.cern.ch/svn/root/trunk@15395 27541ba8-7e3a-0410-8455-c3a389f83636 --- geom/inc/TGeoMaterial.h | 30 +++- geom/inc/TVirtualGeoPainter.h | 5 +- geom/src/TGeoManager.cxx | 3 +- geom/src/TGeoMaterial.cxx | 267 +++++++++++++++++++++++++------- geom/src/TGeoVolume.cxx | 6 +- geompainter/inc/TGeoPainter.h | 1 + geompainter/src/TGeoPainter.cxx | 110 ++++++------- 7 files changed, 292 insertions(+), 130 deletions(-) diff --git a/geom/inc/TGeoMaterial.h b/geom/inc/TGeoMaterial.h index b695d98478b..d38e9c59874 100644 --- a/geom/inc/TGeoMaterial.h +++ b/geom/inc/TGeoMaterial.h @@ -1,4 +1,4 @@ -// @(#)root/geom:$Name: $:$Id: TGeoMaterial.h,v 1.19 2005/11/18 16:07:58 brun Exp $ +// @(#)root/geom:$Name: $:$Id: TGeoMaterial.h,v 1.20 2006/05/23 04:47:37 brun Exp $ // Author: Andrei Gheata 25/10/01 /************************************************************************* @@ -58,6 +58,7 @@ protected: Double_t fIntLen; // interaction length TObject *fShader; // shader with optical properties TObject *fCerenkov; // pointer to class with Cerenkov properties + TGeoElement *fElement; // pointer to element composing the material // methods TGeoMaterial(const TGeoMaterial&); @@ -82,6 +83,7 @@ public: virtual Int_t GetDefaultColor() const; virtual Double_t GetDensity() const {return fDensity;} virtual TGeoElement *GetElement(Int_t i=0) const; + TGeoElement *GetBaseElement() const {return fElement;} char *GetPointerName() const; virtual Double_t GetRadLen() const {return fRadLen;} virtual Double_t GetIntLen() const {return fIntLen;} @@ -102,7 +104,7 @@ public: - ClassDef(TGeoMaterial, 3) // base material class + ClassDef(TGeoMaterial, 4) // base material class //***** Need to add classes and globals to LinkDef.h ***** }; @@ -120,10 +122,12 @@ protected : Double_t *fZmixture; // [fNelements] array of Z of the elements Double_t *fAmixture; // [fNelements] array of A of the elements Double_t *fWeights; // [fNelements] array of relative proportions by mass - + Int_t *fNatoms; // [fNelements] array of numbers of atoms + TObjArray *fElements; // array of elements composing the mixture // methods TGeoMixture(const TGeoMixture&); // Not implemented TGeoMixture& operator=(const TGeoMixture&); // Not implemented + void AverageProperties(); public: // constructors @@ -131,16 +135,24 @@ public: TGeoMixture(const char *name, Int_t nel, Double_t rho=-1); // destructor virtual ~TGeoMixture(); - // methods + // methods for adding elements + void AddElement(Double_t a, Double_t z, Double_t weight); + void AddElement(TGeoMaterial *mat, Double_t weight); + void AddElement(TGeoElement *elem, Double_t weight); + void AddElement(TGeoElement *elem, Int_t natoms); + // backward compatibility for defining elements void DefineElement(Int_t iel, Double_t a, Double_t z, Double_t weight); void DefineElement(Int_t iel, TGeoElement *elem, Double_t weight); void DefineElement(Int_t iel, Int_t z, Int_t natoms); + // getters virtual Int_t GetByteCount() const {return 48+12*fNelements;} virtual TGeoElement *GetElement(Int_t i=0) const; Int_t GetNelements() const {return fNelements;} Double_t *GetZmixt() const {return fZmixture;} Double_t *GetAmixt() const {return fAmixture;} Double_t *GetWmixt() const {return fWeights;} + Int_t *GetNmixt() const {return fNatoms;} + // utilities virtual Bool_t IsEq(const TGeoMaterial *other) const; virtual Bool_t IsMixture() const {return kTRUE;} virtual void Print(const Option_t *option="") const; @@ -148,10 +160,14 @@ public: void SetA(Double_t a) {fA = a;} void SetZ(Double_t z) {fZ = z;} - ClassDef(TGeoMixture, 1) // material mixtures - -//***** Need to add classes and globals to LinkDef.h ***** + ClassDef(TGeoMixture, 2) // material mixtures }; +inline void TGeoMixture::DefineElement(Int_t, Double_t a, Double_t z, Double_t weight) + {return AddElement(a,z,weight);} +inline void TGeoMixture::DefineElement(Int_t, TGeoElement *elem, Double_t weight) + {return AddElement(elem,weight);} + + #endif diff --git a/geom/inc/TVirtualGeoPainter.h b/geom/inc/TVirtualGeoPainter.h index 8b62edb5a10..6a7e3c81f2e 100644 --- a/geom/inc/TVirtualGeoPainter.h +++ b/geom/inc/TVirtualGeoPainter.h @@ -1,4 +1,4 @@ -// @(#)root/geom:$Name: $:$Id: TVirtualGeoPainter.h,v 1.33 2006/04/11 11:21:44 brun Exp $ +// @(#)root/geom:$Name: $:$Id: TVirtualGeoPainter.h,v 1.34 2006/04/25 09:38:27 brun Exp $ // Author: Andrei Gheata 11/01/02 /************************************************************************* @@ -49,7 +49,8 @@ enum EGeoVisOption { kGeoVisDefault = 0, // default visualization - everything visible 3 levels down kGeoVisLeaves = 1, // only last leaves are visible kGeoVisOnly = 2, // only current volume is drawn - kGeoVisBranch = 3 // only a given branch is drawn + kGeoVisBranch = 3, // only a given branch is drawn + kGeoVisChanged = 4 // visibility changed }; enum EGeoBombOption { kGeoNoBomb = 0, // default - no bomb diff --git a/geom/src/TGeoManager.cxx b/geom/src/TGeoManager.cxx index ffeff52130f..de4b9a7e382 100644 --- a/geom/src/TGeoManager.cxx +++ b/geom/src/TGeoManager.cxx @@ -1,4 +1,4 @@ -// @(#)root/geom:$Name: $:$Id: TGeoManager.cxx,v 1.156 2006/06/07 12:22:23 brun Exp $ +// @(#)root/geom:$Name: $:$Id: TGeoManager.cxx,v 1.157 2006/06/08 15:11:47 brun Exp $ // Author: Andrei Gheata 25/10/01 /************************************************************************* @@ -2828,6 +2828,7 @@ void TGeoManager::SetVisOption(Int_t option) { // option=0 (default) all nodes drawn down to vislevel // option=1 leaves and nodes at vislevel drawn // option=2 path is drawn +// option=4 visibility changed if ((option>=0) && (option<3)) fVisOption=option; if (fPainter) fPainter->SetVisOption(option); } diff --git a/geom/src/TGeoMaterial.cxx b/geom/src/TGeoMaterial.cxx index 4f1c3eeb8c7..8ebd5e58997 100644 --- a/geom/src/TGeoMaterial.cxx +++ b/geom/src/TGeoMaterial.cxx @@ -1,4 +1,4 @@ -// @(#)root/geom:$Name: $:$Id: TGeoMaterial.cxx,v 1.29 2006/05/24 17:11:54 brun Exp $ +// @(#)root/geom:$Name: $:$Id: TGeoMaterial.cxx,v 1.30 2006/05/26 09:09:59 brun Exp $ // Author: Andrei Gheata 25/10/01 /************************************************************************* @@ -44,6 +44,7 @@ TGeoMaterial::TGeoMaterial() fRadLen = 0; fIntLen = 0; fCerenkov = 0; + fElement = 0; } //----------------------------------------------------------------------------- TGeoMaterial::TGeoMaterial(const char *name) @@ -60,6 +61,7 @@ TGeoMaterial::TGeoMaterial(const char *name) fRadLen = 0; fIntLen = 0; fCerenkov = 0; + fElement = 0; if (!gGeoManager) { gGeoManager = new TGeoManager("Geometry", "default geometry"); @@ -80,6 +82,7 @@ TGeoMaterial::TGeoMaterial(const char *name, Double_t a, Double_t z, fZ = z; fDensity = rho; fCerenkov = 0; + fElement = 0; SetRadLen(radlen, intlen); if (!gGeoManager) { gGeoManager = new TGeoManager("Geometry", "default geometry"); @@ -103,6 +106,7 @@ TGeoMaterial::TGeoMaterial(const char *name, TGeoElement *elem, fZ = elem->Z(); fDensity = rho; fCerenkov = 0; + fElement = elem; SetRadLen(0,0); if (!gGeoManager) { @@ -124,7 +128,8 @@ TGeoMaterial::TGeoMaterial(const TGeoMaterial& gm) : fRadLen(gm.fRadLen), fIntLen(gm.fIntLen), fShader(gm.fShader), - fCerenkov(gm.fCerenkov) + fCerenkov(gm.fCerenkov), + fElement(gm.fElement) { //copy constructor } @@ -143,6 +148,7 @@ TGeoMaterial& TGeoMaterial::operator=(const TGeoMaterial& gm) fIntLen=gm.fIntLen; fShader=gm.fShader; fCerenkov=gm.fCerenkov; + fElement=gm.fElement; } return *this; } @@ -250,6 +256,7 @@ Int_t TGeoMaterial::GetDefaultColor() const TGeoElement *TGeoMaterial::GetElement(Int_t) const { // Get a pointer to the element this material is made of. + if (fElement) return fElement; TGeoElementTable *table = gGeoManager->GetElementTable(); return table->GetElement(Int_t(fZ)); } @@ -277,28 +284,21 @@ TGeoMixture::TGeoMixture() fZmixture = 0; fAmixture = 0; fWeights = 0; + fNatoms = 0; + fElements = 0; } //----------------------------------------------------------------------------- -TGeoMixture::TGeoMixture(const char *name, Int_t nel, Double_t rho) +TGeoMixture::TGeoMixture(const char *name, Int_t /*nel*/, Double_t rho) :TGeoMaterial(name) { // constructor - if (nel == 0) { - fZmixture = 0; - fAmixture = 0; - fWeights = 0; - } else { - fZmixture = new Double_t[nel]; - fAmixture = new Double_t[nel]; - fWeights = new Double_t[nel]; - } - fNelements = nel; - for (Int_t j=0;j<fNelements;j++) { - fZmixture[j] = 0; - fAmixture[j] = 0; - fWeights[j] = 0; - } - fDensity = rho; //TO BE CORRECTED + fZmixture = 0; + fAmixture = 0; + fWeights = 0; + fNelements = 0; + fNatoms = 0; + fDensity = rho; + fElements = 0; if (fDensity < 0) fDensity = 0.001; } //----------------------------------------------------------------------------- @@ -307,7 +307,9 @@ TGeoMixture::TGeoMixture(const TGeoMixture& gm) : fNelements(gm.fNelements), fZmixture(gm.fZmixture), fAmixture(gm.fAmixture), - fWeights(gm.fWeights) + fWeights(gm.fWeights), + fNatoms(gm.fNatoms), + fElements(gm.fElements) { //copy constructor } @@ -321,6 +323,8 @@ TGeoMixture& TGeoMixture::operator=(const TGeoMixture& gm) fZmixture=gm.fZmixture; fAmixture=gm.fAmixture; fWeights=gm.fWeights; + fNatoms = gm.fNatoms; + fElements = gm.fElements; } return *this; } @@ -331,23 +335,13 @@ TGeoMixture::~TGeoMixture() if (fZmixture) delete[] fZmixture; if (fAmixture) delete[] fAmixture; if (fWeights) delete[] fWeights; + if (fNatoms) delete[] fNatoms; + if (fElements) delete fElements; } //----------------------------------------------------------------------------- -void TGeoMixture:: DefineElement(Int_t i, Double_t a, Double_t z, Double_t weight) +void TGeoMixture::AverageProperties() { -// add an element to the mixture - if ((i<0) || (i>fNelements)) { - Error("DefineElement", "wrong index iel=%i in mixture %s, max is %d", i, GetName(), fNelements); - return; - } - fZmixture[i] = z; - fAmixture[i] = a; - fWeights[i] = weight; - if (z - Int_t(z) > 1E-3) - Warning("DefineElement", "Mixture %s has element defined with fractional Z=%f", GetName(), z); - GetElement(i)->SetDefined(); - - //compute equivalent radiation length (taken from Geant3/GSMIXT) +// Compute effective A/Z and radiation length const Double_t alr2av = 1.39621E-03 , al183 =5.20948; Double_t radinv = 0; fA = 0; @@ -367,38 +361,198 @@ void TGeoMixture:: DefineElement(Int_t i, Double_t a, Double_t z, Double_t weigh } //----------------------------------------------------------------------------- -void TGeoMixture:: DefineElement(Int_t i, TGeoElement *elem, Double_t weight) +void TGeoMixture:: AddElement(Double_t a, Double_t z, Double_t weight) { -// Define one component as being a given element with a specified proportion by weight. - DefineElement(i, elem->A(), elem->Z(), weight); -} +// add an element to the mixture using fraction by weight + // Check if the element is already defined + Int_t i; + for (i=0; i<fNelements; i++) { + if (TMath::Abs(z-fZmixture[i])<1.e-6 && TMath::Abs(a-fAmixture[i])<1.e-6) { + fWeights[i] += weight; + AverageProperties(); + return; + } + } + if (!fNelements) { + fZmixture = new Double_t[1]; + fAmixture = new Double_t[1]; + fWeights = new Double_t[1]; + } else { + Int_t nelements = fNelements+1; + Double_t *zmixture = new Double_t[nelements]; + Double_t *amixture = new Double_t[nelements]; + Double_t *weights = new Double_t[nelements]; + for (Int_t j=0; j<fNelements; j++) { + zmixture[j] = fZmixture[j]; + amixture[j] = fAmixture[j]; + weights[j] = fWeights[j]; + } + delete [] fZmixture; + delete [] fAmixture; + delete [] fWeights; + fZmixture = zmixture; + fAmixture = amixture; + fWeights = weights; + } + + fNelements++; + i = fNelements - 1; + fZmixture[i] = z; + fAmixture[i] = a; + fWeights[i] = weight; + if (z - Int_t(z) > 1E-3) + Warning("DefineElement", "Mixture %s has element defined with fractional Z=%f", GetName(), z); + GetElement(i)->SetDefined(); + + //compute equivalent radiation length (taken from Geant3/GSMIXT) + AverageProperties(); +} //----------------------------------------------------------------------------- -void TGeoMixture:: DefineElement(Int_t iel, Int_t z, Int_t natoms) +void TGeoMixture::AddElement(TGeoMaterial *mat, Double_t weight) { -// Define the mixture element at index iel by number of atoms in the chemical formula. - Int_t i; - if ((iel<0) || (iel>fNelements)) { - Error("DefineElement", "wrong index iel=%i in mixture %s, max is %d", iel, GetName(), fNelements); +// Define one component of the mixture as an existing material/mixture. + TGeoElement *elnew, *elem; + Double_t a,z; + if (!mat->IsMixture()) { + elem = mat->GetBaseElement(); + if (elem) { + AddElement(elem, weight); + } else { + a = mat->GetA(); + z = mat->GetZ(); + AddElement(a, z, weight); + } return; } + // The material is a mixture. + TGeoMixture *mix = (TGeoMixture*)mat; + Double_t wnew; + Int_t nelem = mix->GetNelements(); + Bool_t elfound; + Int_t i,j; + // loop the elements of the daughter mixture + for (i=0; i<nelem; i++) { + elfound = kFALSE; + elnew = mix->GetElement(i); + if (!elnew) continue; + // check if we have the element already defined in the parent mixture + for (j=0; j<fNelements; j++) { + if (fWeights[j]<=0) continue; + elem = GetElement(j); + if (elem == elnew) { + // element found, compute new weight + fWeights[j] += weight * (mix->GetWmixt())[i]; + elfound = kTRUE; + break; + } + } + if (elfound) continue; + // element not found, define it + wnew = weight * (mix->GetWmixt())[i]; + AddElement(elnew, wnew); + } +} + +//----------------------------------------------------------------------------- +void TGeoMixture::AddElement(TGeoElement *elem, Double_t weight) +{ +// add an element to the mixture using fraction by weight + TGeoElement *elemold; TGeoElementTable *table = gGeoManager->GetElementTable(); - TGeoElement *elem = table->GetElement(z); - if (!elem) Fatal("DefineElement", "In mixture %s, element with Z=%i not found",GetName(),z); + if (!fElements) fElements = new TObjArray(10); + Bool_t exist = kFALSE; + // If previous elements were defined by A/Z, add corresponding TGeoElements + for (Int_t i=0; i<fNelements; i++) { + elemold = (TGeoElement*)fElements->At(i); + if (!elemold) fElements->AddAt(elemold = table->GetElement((Int_t)fZmixture[i]), i); + if (elemold == elem) exist = kTRUE; + } + if (!exist) fElements->AddAt(elem, fNelements); + AddElement(elem->A(), elem->Z(), weight); +} + +//----------------------------------------------------------------------------- +void TGeoMixture::AddElement(TGeoElement *elem, Int_t natoms) +{ +// Add a mixture element by number of atoms in the chemical formula. + Int_t i,j; + Double_t amol; + TGeoElement *elemold; + TGeoElementTable *table = gGeoManager->GetElementTable(); + if (!fElements) fElements = new TObjArray(10); + // Check if the element is already defined + for (i=0; i<fNelements; i++) { + elemold = (TGeoElement*)fElements->At(i); + if (!elemold) fElements->AddAt(table->GetElement((Int_t)fZmixture[i]), i); + else if (elemold != elem) continue; + if ((elem==elemold) || + (TMath::Abs(elem->Z()-fZmixture[i])<1.e-6 && TMath::Abs(elem->A()-fAmixture[i])<1.e-6)) { + fNatoms[i] += natoms; + amol = 0.; + for (j=0; j<fNelements; j++) amol += fAmixture[j]*fNatoms[j]; + for (j=0; j<fNelements; j++) fWeights[j] = fNatoms[j]*fAmixture[j]/amol; + AverageProperties(); + return; + } + } + // New element + if (!fNelements) { + fZmixture = new Double_t[1]; + fAmixture = new Double_t[1]; + fWeights = new Double_t[1]; + fNatoms = new Int_t[1]; + } else { + if (!fNatoms) { + Error("AddElement", "Cannot add element by natoms in mixture %s after defining elements by weight", + GetName()); + return; + } + Int_t nelements = fNelements+1; + Double_t *zmixture = new Double_t[nelements]; + Double_t *amixture = new Double_t[nelements]; + Double_t *weights = new Double_t[nelements]; + Int_t *nnatoms = new Int_t[nelements]; + for (Int_t j=0; j<fNelements; j++) { + zmixture[j] = fZmixture[j]; + amixture[j] = fAmixture[j]; + weights[j] = fWeights[j]; + nnatoms[j] = fNatoms[j]; + } + delete [] fZmixture; + delete [] fAmixture; + delete [] fWeights; + delete [] fNatoms; + fZmixture = zmixture; + fAmixture = amixture; + fWeights = weights; + fNatoms = nnatoms; + } + fNelements++; + Int_t iel = fNelements-1; fZmixture[iel] = elem->Z(); fAmixture[iel] = elem->A(); - fWeights[iel] = natoms; - Double_t amol = 0.; + fNatoms[iel] = natoms; + fElements->AddAt(elem, iel); + amol = 0.; for (i=0; i<fNelements; i++) { - if (fWeights[i]<=0) return; - amol += fAmixture[i]*fWeights[i]; + if (fNatoms[i]<=0) return; + amol += fAmixture[i]*fNatoms[i]; } - for (i=0; i<fNelements; i++) { - fWeights[i] *= fAmixture[i]/amol; - DefineElement(i, fAmixture[i], fZmixture[i], fWeights[i]); - } + for (i=0; i<fNelements; i++) fWeights[i] = fNatoms[i]*fAmixture[i]/amol; + AverageProperties(); } +//----------------------------------------------------------------------------- +void TGeoMixture::DefineElement(Int_t /*iel*/, Int_t z, Int_t natoms) +{ +// Define the mixture element at index iel by number of atoms in the chemical formula. + TGeoElementTable *table = gGeoManager->GetElementTable(); + TGeoElement *elem = table->GetElement(z); + if (!elem) Fatal("DefineElement", "In mixture %s, element with Z=%i not found",GetName(),z); + AddElement(elem, natoms); +} + //----------------------------------------------------------------------------- TGeoElement *TGeoMixture::GetElement(Int_t i) const { @@ -407,6 +561,9 @@ TGeoElement *TGeoMixture::GetElement(Int_t i) const Error("GetElement", "Mixture %s has only %d elements", GetName(), fNelements); return 0; } + TGeoElement *elem = 0; + if (fElements) elem = (TGeoElement*)fElements->At(i); + if (elem) return elem; TGeoElementTable *table = gGeoManager->GetElementTable(); return table->GetElement(Int_t(fZmixture[i])); } @@ -440,7 +597,9 @@ void TGeoMixture::Print(const Option_t * /*option*/) const printf("Mixture %s %s Aeff=%g Zeff=%g rho=%g radlen=%g index=%i\n", GetName(), GetTitle(), fA,fZ,fDensity, fRadLen, fIndex); for (Int_t i=0; i<fNelements; i++) { - printf(" Element #%i : Z=%6.2f A=%6.2f w=%6.2f\n", i, fZmixture[i], + if (fNatoms) printf(" Element #%i : Z=%6.2f A=%6.2f w=%6.2f natoms=%i\n", i, fZmixture[i], + fAmixture[i], fWeights[i], fNatoms[i]); + else printf(" Element #%i : Z=%6.2f A=%6.2f w=%6.2f\n", i, fZmixture[i], fAmixture[i], fWeights[i]); } } diff --git a/geom/src/TGeoVolume.cxx b/geom/src/TGeoVolume.cxx index 938a49dcc70..66af45016f4 100644 --- a/geom/src/TGeoVolume.cxx +++ b/geom/src/TGeoVolume.cxx @@ -1,4 +1,4 @@ -// @(#)root/geom:$Name: $:$Id: TGeoVolume.cxx,v 1.83 2006/05/24 17:11:54 brun Exp $ +// @(#)root/geom:$Name: $:$Id: TGeoVolume.cxx,v 1.84 2006/05/26 16:26:25 brun Exp $ // Author: Andrei Gheata 30/05/02 // Divide(), CheckOverlaps() implemented by Mihaela Gheata @@ -1650,7 +1650,7 @@ void TGeoVolume::SetVisibility(Bool_t vis) } TGeoAtt::SetVisibility(vis); if (fGeoManager->IsClosed()) SetVisTouched(kTRUE); - fGeoManager->ModifiedPad(); + fGeoManager->SetVisOption(4); TSeqCollection *brlist = gROOT->GetListOfBrowsers(); TIter next(brlist); TBrowser *browser = 0; @@ -1737,7 +1737,7 @@ void TGeoVolume::VisibleDaughters(Bool_t vis) // set visibility for daughters SetVisDaughters(vis); if (fGeoManager->IsClosed()) SetVisTouched(kTRUE); - fGeoManager->ModifiedPad(); + fGeoManager->SetVisOption(4); } //_____________________________________________________________________________ diff --git a/geompainter/inc/TGeoPainter.h b/geompainter/inc/TGeoPainter.h index 62e24cb2962..6f2198b0935 100644 --- a/geompainter/inc/TGeoPainter.h +++ b/geompainter/inc/TGeoPainter.h @@ -125,6 +125,7 @@ public: TH2F *LegoPlot(Int_t ntheta=60, Double_t themin=0., Double_t themax=180., Int_t nphi=90, Double_t phimin=0., Double_t phimax=360., Double_t rmin=0., Double_t rmax=9999999, Option_t *option=""); + void Lock(Bool_t flag = kTRUE) {fVisLock = flag;} virtual void ModifiedPad() const; virtual void Paint(Option_t *option=""); virtual void PaintNode(TGeoNode *node, Option_t *option=""); diff --git a/geompainter/src/TGeoPainter.cxx b/geompainter/src/TGeoPainter.cxx index 33ee73d6961..e2533fb4b92 100644 --- a/geompainter/src/TGeoPainter.cxx +++ b/geompainter/src/TGeoPainter.cxx @@ -1,4 +1,4 @@ -// @(#)root/geompainter:$Name: $:$Id: TGeoPainter.cxx,v 1.87 2006/05/26 16:26:25 brun Exp $ +// @(#)root/geompainter:$Name: $:$Id: TGeoPainter.cxx,v 1.88 2006/06/04 09:35:24 brun Exp $ // Author: Andrei Gheata 05/03/02 /************************************************************************* * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. * @@ -344,38 +344,6 @@ Int_t TGeoPainter::DistanceToPrimitiveVol(TGeoVolume *volume, Int_t px, Int_t py TGeoVolume *vol = volume; Bool_t vis = vol->IsVisible(); // Bool_t drawDaughters = kTRUE; - // Do I need to look for the top volume ? - if (fTopVisible && vis) { - dist = vol->GetShape()->DistancetoPrimitive(px,py); - if (dist<maxdist) { - fVolInfo = vol->GetName(); - gPad->SetSelected(vol); - box = (TGeoBBox*)vol->GetShape(); - memcpy(fCheckedBox, box->GetOrigin(), 3*sizeof(Double_t)); - fCheckedBox[3] = box->GetDX(); - fCheckedBox[4] = box->GetDY(); - fCheckedBox[5] = box->GetDZ(); - return 0; - } - return dist; - } - // Is this the only volume? - if (volume->IsVisOnly()) { - if (!fTopVisible) { - dist = vol->GetShape()->DistancetoPrimitive(px,py); - if (dist<maxdist) { - fVolInfo = vol->GetName(); - gPad->SetSelected(vol); - box = (TGeoBBox*)vol->GetShape(); - memcpy(fCheckedBox, box->GetOrigin(), 3*sizeof(Double_t)); - fCheckedBox[3] = box->GetDX(); - fCheckedBox[4] = box->GetDY(); - fCheckedBox[5] = box->GetDZ(); - return 0; - } - } - return dist; - } // Do we need to check a branch only? if (volume->IsVisBranch()) { if (!fGeoManager->IsClosed()) return big; @@ -404,6 +372,23 @@ Int_t TGeoPainter::DistanceToPrimitiveVol(TGeoVolume *volume, Int_t px, Int_t py return dist; } + // Do I need to look for the top volume ? + if ((fTopVisible && vis) || !vol->GetNdaughters() || !vol->IsVisDaughters() || vol->IsVisOnly()) { + dist = vol->GetShape()->DistancetoPrimitive(px,py); + if (dist<maxdist) { + fVolInfo = vol->GetName(); + gPad->SetSelected(vol); + box = (TGeoBBox*)vol->GetShape(); + memcpy(fCheckedBox, box->GetOrigin(), 3*sizeof(Double_t)); + fCheckedBox[3] = box->GetDX(); + fCheckedBox[4] = box->GetDY(); + fCheckedBox[5] = box->GetDZ(); + return 0; + } + if (vol->IsVisOnly() || !vol->GetNdaughters() || !vol->IsVisDaughters()) + return dist; + } + // Iterate the volume content TGeoIterator next(vol); next.SetTopName(Form("%s_1",vol->GetName())); @@ -460,7 +445,7 @@ Int_t TGeoPainter::DistanceToPrimitiveVol(TGeoVolume *volume, Int_t px, Int_t py } } // Check if we have to skip the branch - if (last) next.Skip(); + if (last || !daughter->IsVisDaughters()) next.Skip(); } } return dist; @@ -1102,37 +1087,11 @@ void TGeoPainter::PaintVolume(TGeoVolume *top, Option_t *option) fGlobal->Clear(); TGeoShape::SetTransform(fGlobal); Bool_t drawDaughters = kTRUE; - Bool_t vis = top->IsVisible(); + Bool_t vis = (top->IsVisible() && !top->IsAssembly()); // Update pad attributes in case we need to paint VOL if (!strstr(option,"range")) ((TAttLine*)vol)->Modify(); - // Do I need to draw the top volume ? - if (fTopVisible && vis) { - fGeoManager->SetPaintVolume(vol); - fGeoManager->SetMatrixReflection(kFALSE); - drawDaughters = PaintShape(*(vol->GetShape()),option); - if (!fVisLock && !vol->TestAttBit(TGeoAtt::kVisOnScreen)) { - fVisVolumes->Add(vol); - vol->SetAttBit(TGeoAtt::kVisOnScreen); - } - } - - // Do we need to draw only this volume ? - if (top->IsVisOnly()) { - if (!fTopVisible) { - fGeoManager->SetPaintVolume(vol); - fGeoManager->SetMatrixReflection(kFALSE); - drawDaughters = PaintShape(*(vol->GetShape()),option); - } - if (!fVisLock && !vol->TestAttBit(TGeoAtt::kVisOnScreen)) { - fVisVolumes->Add(vol); - vol->SetAttBit(TGeoAtt::kVisOnScreen); - } - fVisLock = kTRUE; - return; - } - // Do we need to draw a branch ? if (top->IsVisBranch()) { fGeoManager->PushPath(); @@ -1160,6 +1119,21 @@ void TGeoPainter::PaintVolume(TGeoVolume *top, Option_t *option) return; } + // Do I need to draw the top volume ? + if ((fTopVisible && vis) || !top->GetNdaughters() || !top->IsVisDaughters() || top->IsVisOnly()) { + fGeoManager->SetPaintVolume(vol); + fGeoManager->SetMatrixReflection(kFALSE); + drawDaughters = PaintShape(*(vol->GetShape()),option); + if (!fVisLock && !vol->TestAttBit(TGeoAtt::kVisOnScreen)) { + fVisVolumes->Add(vol); + vol->SetAttBit(TGeoAtt::kVisOnScreen); + } + if (top->IsVisOnly() || !top->GetNdaughters() || !top->IsVisDaughters()) { + fVisLock = kTRUE; + return; + } + } + // Iterate the volume content TGeoIterator next(vol); TGeoNode *daughter; @@ -1203,7 +1177,7 @@ void TGeoPainter::PaintVolume(TGeoVolume *top, Option_t *option) } } // Check if we have to skip the branch - if (!drawDaughters || last) next.Skip(); + if (!drawDaughters || last || !daughter->IsVisDaughters()) next.Skip(); } } fGeoManager->SetMatrixReflection(kFALSE); @@ -1633,10 +1607,20 @@ void TGeoPainter::SetVisOption(Int_t option) { // option=0 (default) all nodes drawn down to vislevel // option=1 leaves and nodes at vislevel drawn // option=2 path is drawn - if ((fVisOption<0) || (fVisOption>3)) { + if ((fVisOption<0) || (fVisOption>4)) { Warning("SetVisOption", "wrong visualization option"); return; } + + if (option == kGeoVisChanged) { + if (fVisLock) { + ClearVisibleVolumes(); + fVisLock = kFALSE; + } + ModifiedPad(); + return; + } + if (fTopVolume) { TGeoAtt *att = (TGeoAtt*)fTopVolume; att->SetAttBit(TGeoAtt::kVisBranch,kFALSE); -- GitLab