diff --git a/geom/geom/inc/TGeoBoolNode.h b/geom/geom/inc/TGeoBoolNode.h index 6328de163355429fdd07e40451b529480df12234..e32a6084f27f5ee903a0a2071cc810237bea368a 100644 --- a/geom/geom/inc/TGeoBoolNode.h +++ b/geom/geom/inc/TGeoBoolNode.h @@ -87,8 +87,10 @@ public: TGeoMatrix *GetRightMatrix() const {return fRightMat;} TGeoShape *GetLeftShape() const {return fLeft;} TGeoShape *GetRightShape() const {return fRight;} + virtual TGeoBoolNode *MakeClone() const = 0; virtual void Paint(Option_t *option); void RegisterMatrices(); + Bool_t ReplaceMatrix(TGeoMatrix *mat, TGeoMatrix *newmat); virtual Double_t Safety(Double_t *point, Bool_t in=kTRUE) const = 0; virtual void SavePrimitive(std::ostream &out, Option_t *option = ""); virtual void SetPoints(Double_t *points) const; @@ -131,6 +133,7 @@ public: virtual void Sizeof3D() const; //CS specific + virtual TGeoBoolNode *MakeClone() const; virtual void Paint(Option_t *option); ClassDef(TGeoUnion, 1) // union node @@ -169,6 +172,7 @@ public: virtual void Sizeof3D() const; //CS specific + virtual TGeoBoolNode *MakeClone() const; virtual void Paint(Option_t *option); ClassDef(TGeoIntersection, 1) // intersection node @@ -206,6 +210,7 @@ public: virtual void Sizeof3D() const; //CS specific + virtual TGeoBoolNode *MakeClone() const; virtual void Paint(Option_t *option); ClassDef(TGeoSubtraction, 1) // subtraction node diff --git a/geom/geom/inc/TGeoManager.h b/geom/geom/inc/TGeoManager.h index 6aa0a2f363f0e9a9d33f0f33c1555a45c015449f..58b5080c07b8c6c0496c3a1633f17ec3282e2923 100644 --- a/geom/geom/inc/TGeoManager.h +++ b/geom/geom/inc/TGeoManager.h @@ -240,7 +240,7 @@ public: void DrawPath(const char *path); void PrintOverlaps() const; // *MENU* void RandomPoints(const TGeoVolume *vol, Int_t npoints=10000, Option_t *option=""); - void RandomRays(Int_t nrays=1000, Double_t startx=0, Double_t starty=0, Double_t startz=0); + void RandomRays(Int_t nrays=1000, Double_t startx=0, Double_t starty=0, Double_t startz=0, const char *target_vol=0, Bool_t check_norm=kFALSE); TGeoNode *SamplePoints(Int_t npoints, Double_t &dist, Double_t epsil=1E-5, const char *g3path=""); void SetNmeshPoints(Int_t npoints=1000); diff --git a/geom/geom/inc/TGeoMatrix.h b/geom/geom/inc/TGeoMatrix.h index 8ac36b633e9062738d58b889a65c1af3a67b163a..db34dfa08c5c4b7fa9473e7ec7e4f241410115fa 100644 --- a/geom/geom/inc/TGeoMatrix.h +++ b/geom/geom/inc/TGeoMatrix.h @@ -42,6 +42,7 @@ class TGeoMatrix : public TNamed public: enum EGeoTransfTypes { kGeoIdentity = 0, + kGeoShared = BIT(14), kGeoTranslation = BIT(17), kGeoRotation = BIT(18), kGeoScale = BIT(19), @@ -78,6 +79,7 @@ public : Bool_t IsRotation() const {return TestBit(kGeoRotation);} Bool_t IsReflection() const {return TestBit(kGeoReflection);} Bool_t IsScale() const {return TestBit(kGeoScale);} + Bool_t IsShared() const {return TestBit(kGeoShared);} Bool_t IsCombi() const {return (TestBit(kGeoTranslation) && TestBit(kGeoRotation));} Bool_t IsGeneral() const {return (TestBit(kGeoTranslation) @@ -112,6 +114,7 @@ public : virtual void SetDx(Double_t) {} virtual void SetDy(Double_t) {} virtual void SetDz(Double_t) {} + void SetShared(Bool_t flag=kTRUE) {SetBit(kGeoShared, flag);} ClassDef(TGeoMatrix, 1) // base geometrical transformation class }; diff --git a/geom/geom/inc/TGeoPhysicalNode.h b/geom/geom/inc/TGeoPhysicalNode.h index 5b5dcf6d0bd999af0cf014020a55cd8655cd198b..5a3bb2794e5826d8d7933f86655c00e77cb2f9a1 100644 --- a/geom/geom/inc/TGeoPhysicalNode.h +++ b/geom/geom/inc/TGeoPhysicalNode.h @@ -68,7 +68,7 @@ public: // destructor virtual ~TGeoPhysicalNode(); - void Align(TGeoMatrix *newmat=0, TGeoShape *newshape=0, Bool_t check=kFALSE, Double_t ovlp=0.001); + Bool_t Align(TGeoMatrix *newmat=0, TGeoShape *newshape=0, Bool_t check=kFALSE, Double_t ovlp=0.001); void cd() const; void Draw(Option_t *option=""); Int_t GetLevel() const {return fLevel;} diff --git a/geom/geom/inc/TGeoVolume.h b/geom/geom/inc/TGeoVolume.h index 8d144679b87bab7a4d1220d6cf8afa9a570453c6..478b86f616e7e99c554db832430891d4223ec1e2 100644 --- a/geom/geom/inc/TGeoVolume.h +++ b/geom/geom/inc/TGeoVolume.h @@ -193,7 +193,7 @@ public: TGeoVolume *MakeReflectedVolume(const char *newname="") const; Bool_t OptimizeVoxels(); // *MENU* void RandomPoints(Int_t npoints=1000000, Option_t *option=""); // *MENU* - void RandomRays(Int_t nrays=10000, Double_t startx=0, Double_t starty=0, Double_t startz=0); // *MENU* + void RandomRays(Int_t nrays=10000, Double_t startx=0, Double_t starty=0, Double_t startz=0, const char *target_vol=0, Bool_t check_norm=kFALSE); // *MENU* void Raytrace(Bool_t flag=kTRUE); // *TOGGLE* *GETTER=IsRaytracing void RegisterYourself(Option_t *option=""); void RemoveNode(TGeoNode *node); diff --git a/geom/geom/inc/TVirtualGeoPainter.h b/geom/geom/inc/TVirtualGeoPainter.h index 8ccbfb5f6e3de2d6f4a38612fd1922e670321f03..079aafacae308e95eea754b12088c14c0750616d 100644 --- a/geom/geom/inc/TVirtualGeoPainter.h +++ b/geom/geom/inc/TVirtualGeoPainter.h @@ -123,7 +123,7 @@ public: virtual void PrintOverlaps() const = 0; virtual void PaintVolume(TGeoVolume *vol, Option_t *option="", TGeoMatrix* global=0) = 0; virtual void RandomPoints(const TGeoVolume *vol, Int_t npoints, Option_t *option="") = 0; - virtual void RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz) = 0; + virtual void RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz, const char *target_vol, Bool_t check_norm) = 0; virtual void Raytrace(Option_t *option="") = 0; virtual TGeoNode *SamplePoints(Int_t npoints, Double_t &dist, Double_t epsil, const char* g3path) = 0; virtual void SetBombFactors(Double_t bombx=1.3, Double_t bomby=1.3, Double_t bombz=1.3, diff --git a/geom/geom/src/TGeoBoolNode.cxx b/geom/geom/src/TGeoBoolNode.cxx index 9f15ab5e81ab9e420df0b4b5088b3fad7d934d4c..3bdf235f40cd050b979700720c5ab10d1f8a1bc5 100644 --- a/geom/geom/src/TGeoBoolNode.cxx +++ b/geom/geom/src/TGeoBoolNode.cxx @@ -316,6 +316,31 @@ void TGeoBoolNode::RegisterMatrices() if (fRight->IsComposite()) ((TGeoCompositeShape*)fRight)->GetBoolNode()->RegisterMatrices(); } +//_____________________________________________________________________________ +Bool_t TGeoBoolNode::ReplaceMatrix(TGeoMatrix *mat, TGeoMatrix *newmat) +{ +// Replace one of the matrices. Does not work with TGeoIdentity. Returns true +// if replacement was successful. + if (mat==gGeoIdentity || newmat==gGeoIdentity) { + Error("ReplaceMatrix", "Matrices should not be gGeoIdentity. Use default matrix constructor to repersent identities."); + return kFALSE; + } + if (!mat || !newmat) { + Error("ReplaceMatrix", "Matrices should not be null pointers."); + return kFALSE; + } + Bool_t replaced = kFALSE; + if (fLeftMat == mat) { + fLeftMat = newmat; + replaced = kTRUE; + } + if (fRightMat == mat) { + fRightMat = newmat; + replaced = kTRUE; + } + return replaced; +} + //_____________________________________________________________________________ void TGeoBoolNode::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/) { @@ -357,8 +382,16 @@ void TGeoBoolNode::Sizeof3D() const fLeft->Sizeof3D(); fRight->Sizeof3D(); } + ClassImp(TGeoUnion) +//______________________________________________________________________________ +TGeoBoolNode *TGeoUnion::MakeClone() const +{ +// Make a clone of this. Pointers are preserved. + return new TGeoUnion(fLeft, fRight, fLeftMat, fRightMat); +} + //______________________________________________________________________________ void TGeoUnion::Paint(Option_t *option) { @@ -739,6 +772,13 @@ void TGeoUnion::Sizeof3D() const ClassImp(TGeoSubtraction) +//______________________________________________________________________________ +TGeoBoolNode *TGeoSubtraction::MakeClone() const +{ +// Make a clone of this. Pointers are preserved. + return new TGeoSubtraction(fLeft, fRight, fLeftMat, fRightMat); +} + //______________________________________________________________________________ void TGeoSubtraction::Paint(Option_t *option) { @@ -1048,6 +1088,13 @@ void TGeoSubtraction::Sizeof3D() const ClassImp(TGeoIntersection) +//______________________________________________________________________________ +TGeoBoolNode *TGeoIntersection::MakeClone() const +{ +// Make a clone of this. Pointers are preserved. + return new TGeoIntersection(fLeft, fRight, fLeftMat, fRightMat); +} + //______________________________________________________________________________ void TGeoIntersection::Paint(Option_t *option) { diff --git a/geom/geom/src/TGeoManager.cxx b/geom/geom/src/TGeoManager.cxx index c31aaa3251e12c09ecc29b7e8281a11c751afa66..4888cea42e7a099511f0dd3c90ef60cd59c0e961 100644 --- a/geom/geom/src/TGeoManager.cxx +++ b/geom/geom/src/TGeoManager.cxx @@ -2691,11 +2691,11 @@ Int_t TGeoManager::GetMaterialIndex(const char *matname) const return -1; // fail } //_____________________________________________________________________________ -void TGeoManager::RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz) +void TGeoManager::RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz, const char *target_vol, Bool_t check_norm) { // Randomly shoot nrays and plot intersections with surfaces for current // top node. - GetGeomPainter()->RandomRays(nrays, startx, starty, startz); + GetGeomPainter()->RandomRays(nrays, startx, starty, startz, target_vol, check_norm); } //_____________________________________________________________________________ diff --git a/geom/geom/src/TGeoNode.cxx b/geom/geom/src/TGeoNode.cxx index 8cba09011adb89e585d0d6a027379c8de816317e..bf5b7b845f3bbcc6330f20f100776a41f5d3d6ed 100644 --- a/geom/geom/src/TGeoNode.cxx +++ b/geom/geom/src/TGeoNode.cxx @@ -704,6 +704,7 @@ TGeoNode *TGeoNodeMatrix::MakeCopyNode() const } // copy VC if (IsVirtual()) node->SetVirtual(); + if (IsOverlapping()) node->SetOverlapping(); // <--- ADDED return node; } diff --git a/geom/geom/src/TGeoPhysicalNode.cxx b/geom/geom/src/TGeoPhysicalNode.cxx index 0e07ca0460beaf0a033ff3afd5145e9107998335..899aa33cbb003a4fb9e0ae770afe43a0623c14e1 100644 --- a/geom/geom/src/TGeoPhysicalNode.cxx +++ b/geom/geom/src/TGeoPhysicalNode.cxx @@ -51,6 +51,8 @@ #include "TGeoCache.h" #include "TGeoMatrix.h" #include "TGeoShapeAssembly.h" +#include "TGeoCompositeShape.h" +#include "TGeoBoolNode.h" #include "TGeoVolume.h" #include "TVirtualGeoPainter.h" @@ -133,7 +135,7 @@ TGeoPhysicalNode::~TGeoPhysicalNode() } //_____________________________________________________________________________ -void TGeoPhysicalNode::Align(TGeoMatrix *newmat, TGeoShape *newshape, Bool_t check, Double_t ovlp) +Bool_t TGeoPhysicalNode::Align(TGeoMatrix *newmat, TGeoShape *newshape, Bool_t check, Double_t ovlp) { // Align a physical node with a new relative matrix/shape. // Example: /TOP_1/A_1/B_1/C_1 @@ -144,15 +146,19 @@ void TGeoPhysicalNode::Align(TGeoMatrix *newmat, TGeoShape *newshape, Bool_t che // *NOTE* The operations will affect ONLY the LAST node in the branch. All // volumes/nodes in the branch represented by this physical node are // CLONED so the operation does not affect other possible replicas. - if (!newmat && !newshape) return; + if (!newmat && !newshape) return kFALSE; if (TGeoManager::IsLocked()) { Error("Align", "Not performed. Geometry in LOCKED mode !"); - return; + return kFALSE; } + if (newmat == gGeoIdentity) { + Error("Align", "Cannot align using gGeoIdentity. Use some default matrix constructor to represent identities."); + return kFALSE; + } TGeoNode *node = GetNode(); if (node->IsOffset()) { Error("Align", "Cannot align division nodes: %s\n",node->GetName()); - return; + return kFALSE; } TGeoNode *nnode = 0; TGeoVolume *vm = GetVolume(0); @@ -168,7 +174,7 @@ void TGeoPhysicalNode::Align(TGeoMatrix *newmat, TGeoShape *newshape, Bool_t che if (id[i]<0) { Error("Align","%s cannot align node %s",GetName(), node->GetName()); delete [] id; - return; + return kFALSE; } } for (i=0; i<fLevel; i++) { @@ -179,13 +185,13 @@ void TGeoPhysicalNode::Align(TGeoMatrix *newmat, TGeoShape *newshape, Bool_t che if (!vd) { delete [] id; Fatal("Align", "Cannot clone volume %s", node->GetVolume()->GetName()); - return; + return kFALSE; } nnode = node->MakeCopyNode(); if (!nnode) { delete [] id; Fatal("Align", "Cannot make copy node for %s", node->GetName()); - return; + return kFALSE; } // Correct pointers to mother and volume nnode->SetVolume(vd); @@ -210,14 +216,77 @@ void TGeoPhysicalNode::Align(TGeoMatrix *newmat, TGeoShape *newshape, Bool_t che vm = nnode->GetMotherVolume(); vd = nnode->GetVolume(); if (newmat) { + // Check if the old matrix for this node was shared + Bool_t shared = kFALSE; + Int_t nd = vm->GetNdaughters(); + TGeoCompositeShape *cs; + if (nnode->GetMatrix()->IsShared()) { + // Now find the node having a composite shape using this shared matrix + for (i=0; i<nd; i++) { + node = vm->GetNode(i); + if (node==nnode) continue; + if (node->IsOffset()) continue; + if (!node->GetVolume()->GetShape()->IsComposite()) continue; + // We found a node having a composite shape, scan for the shared matrix + cs = (TGeoCompositeShape*)node->GetVolume()->GetShape(); + if (cs->GetBoolNode()->GetRightMatrix() != nnode->GetMatrix()) continue; + // The composite uses the matrix -> replace it + TGeoCompositeShape *ncs = new TGeoCompositeShape(cs->GetName(), cs->GetBoolNode()->MakeClone()); + ncs->GetBoolNode()->ReplaceMatrix(nnode->GetMatrix(), newmat); + // We have to clone the node/volume having the composite shape + TGeoVolume *newvol = node->GetVolume()->CloneVolume(); + if (!newvol) { + Error("Align", "Cannot clone volume %s", node->GetVolume()->GetName()); + return kFALSE; + } + newvol->SetShape(ncs); + TGeoNode *newnode = node->MakeCopyNode(); + if (!newnode) { + Error("Align", "Cannot clone node %s", node->GetName()); + return kFALSE; + } + newnode->SetVolume(newvol); + newnode->SetMotherVolume(vm); + if (vm->TestBit(TGeoVolume::kVolumeImportNodes)) { + gGeoManager->GetListOfGShapes()->Add(newnode); + } + vm->GetNodes()->RemoveAt(i); + vm->GetNodes()->AddAt(newnode,i); + shared = kTRUE; + } + if (!shared) Error("Align", "The matrix replaced for %s is not actually shared", GetName()); + } else { + // The aligned node may have a composite shape containing a shared matrix + if (vd->GetShape()->IsComposite()) { + cs = (TGeoCompositeShape*)vd->GetShape(); + if (cs->GetBoolNode()->GetRightMatrix()->IsShared()) { + if (!nnode->GetMatrix()->IsIdentity()) { + Error("Align", "The composite shape having a shared matrix on the subtracted branch must be positioned using identity matrix."); + return kFALSE; + } + // We have to put the alignment matrix on top of the left branch + // of the composite shape. The node is already decoupled from logical tree. + TGeoCompositeShape *ncs = new TGeoCompositeShape(cs->GetName(), cs->GetBoolNode()->MakeClone()); + TGeoMatrix *oldmat = ncs->GetBoolNode()->GetLeftMatrix(); + TGeoHMatrix *newmat1 = new TGeoHMatrix(*newmat); + newmat1->Multiply(oldmat); + ncs->GetBoolNode()->ReplaceMatrix(oldmat, newmat1); + vd->SetShape(ncs); + // The right-side matrix pointer is preserved, so no need to update nodes. + aligned = 0; // to prevent updating its matrix + } + } + } // Register matrix and make it the active one if (!newmat->IsRegistered()) newmat->RegisterYourself(); - aligned->SetMatrix(newmat); - // Update the global matrix for the aligned node - TGeoHMatrix *global = GetMatrix(); - TGeoHMatrix *up = GetMatrix(fLevel-1); - *global = up; - global->Multiply(newmat); + if (aligned) { + aligned->SetMatrix(newmat); + // Update the global matrix for the aligned node + TGeoHMatrix *global = GetMatrix(); + TGeoHMatrix *up = GetMatrix(fLevel-1); + *global = up; + global->Multiply(newmat); + } } // Change the shape for the aligned node if (newshape) vd->SetShape(newshape); @@ -245,7 +314,7 @@ void TGeoPhysicalNode::Align(TGeoMatrix *newmat, TGeoShape *newshape, Bool_t che // Set aligned node to be checked i = fLevel; node = GetNode(i); - if (!node) return; + if (!node) return kTRUE; if (node->IsOverlapping()) { Info("Align", "The check for overlaps for node: \n%s\n cannot be performed since the node is declared possibly overlapping", GetName()); @@ -267,6 +336,7 @@ void TGeoPhysicalNode::Align(TGeoMatrix *newmat, TGeoShape *newshape, Bool_t che // Clean current matrices from cache gGeoManager->CdTop(); SetAligned(kTRUE); + return kTRUE; } //_____________________________________________________________________________ diff --git a/geom/geom/src/TGeoVolume.cxx b/geom/geom/src/TGeoVolume.cxx index ae2c217741bdbdabdce1ebbb4d7fa15ccaea21c1..5fca75b1c2965d90b74ab0146cc4e4e9772710c9 100644 --- a/geom/geom/src/TGeoVolume.cxx +++ b/geom/geom/src/TGeoVolume.cxx @@ -1247,14 +1247,14 @@ void TGeoVolume::RandomPoints(Int_t npoints, Option_t *option) } //_____________________________________________________________________________ -void TGeoVolume::RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz) +void TGeoVolume::RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz, const char *target_vol, Bool_t check_norm) { // Random raytracing method. if (gGeoManager != fGeoManager) gGeoManager = fGeoManager; TGeoVolume *old_vol = fGeoManager->GetTopVolume(); if (old_vol!=this) fGeoManager->SetTopVolume(this); else old_vol=0; - fGeoManager->RandomRays(nrays, startx, starty, startz); + fGeoManager->RandomRays(nrays, startx, starty, startz, target_vol, check_norm); if (old_vol) fGeoManager->SetTopVolume(old_vol); } diff --git a/geom/geompainter/inc/TGeoChecker.h b/geom/geompainter/inc/TGeoChecker.h index 5a2e5acaf30f307d86c4e094d73eb1318fb84752..a293ac946560eb3c05c3f20cbb58fe7d94a88b0f 100644 --- a/geom/geompainter/inc/TGeoChecker.h +++ b/geom/geompainter/inc/TGeoChecker.h @@ -79,7 +79,7 @@ public: Double_t rmin=0., Double_t rmax=9999999, Option_t *option=""); void PrintOverlaps() const; void RandomPoints(TGeoVolume *vol, Int_t npoints, Option_t *option); - void RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz); + void RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz, const char *target_vol=0, Bool_t check_norm=kFALSE); TGeoOverlap *MakeCheckOverlap(const char *name, TGeoVolume *vol1, TGeoVolume *vol2, TGeoMatrix *mat1, TGeoMatrix *mat2, Bool_t isovlp, Double_t ovlp); void OpProgress(const char *opname, Long64_t current, Long64_t size, TStopwatch *watch=0, Bool_t last=kFALSE, Bool_t refresh=kFALSE); TGeoNode *SamplePoints(Int_t npoints, Double_t &dist, Double_t epsil, const char* g3path); diff --git a/geom/geompainter/inc/TGeoPainter.h b/geom/geompainter/inc/TGeoPainter.h index fc14161d72f74ec20efd3a78162a7412f7e85ad2..3e1c3bd60c334cb970266075c749468e44b01c11 100644 --- a/geom/geompainter/inc/TGeoPainter.h +++ b/geom/geompainter/inc/TGeoPainter.h @@ -148,7 +148,7 @@ public: virtual void PrintOverlaps() const; void PaintPhysicalNode(TGeoPhysicalNode *node, Option_t *option=""); virtual void RandomPoints(const TGeoVolume *vol, Int_t npoints, Option_t *option=""); - virtual void RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz); + virtual void RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz, const char *target_vol=0, Bool_t check_norm=kFALSE); virtual void Raytrace(Option_t *option=""); virtual TGeoNode *SamplePoints(Int_t npoints, Double_t &dist, Double_t epsil, const char* g3path); virtual void SetBombFactors(Double_t bombx=1.3, Double_t bomby=1.3, Double_t bombz=1.3, Double_t bombr=1.3); diff --git a/geom/geompainter/src/TGeoChecker.cxx b/geom/geompainter/src/TGeoChecker.cxx index b16914434db75cd4ce3485f137c622027602cdca..ed13c2cae4096329927fd7e3dbecf3f05d6fd26c 100644 --- a/geom/geompainter/src/TGeoChecker.cxx +++ b/geom/geompainter/src/TGeoChecker.cxx @@ -2104,16 +2104,22 @@ void TGeoChecker::RandomPoints(TGeoVolume *vol, Int_t npoints, Option_t *option) } //______________________________________________________________________________ -void TGeoChecker::RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz) +void TGeoChecker::RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz, const char *target_vol, Bool_t check_norm) { // Randomly shoot nrays from point (startx,starty,startz) and plot intersections // with surfaces for current top node. TObjArray *pm = new TObjArray(128); + TString starget = target_vol; TPolyLine3D *line = 0; TPolyLine3D *normline = 0; TGeoVolume *vol=fGeoManager->GetTopVolume(); // vol->VisibleDaughters(kTRUE); + Bool_t random = kFALSE; + if (nrays<=0) { + nrays = 100000; + random = kTRUE; + } Double_t start[3]; Double_t dir[3]; const Double_t *point = fGeoManager->GetCurrentPoint(); @@ -2127,6 +2133,9 @@ void TGeoChecker::RandomRays(Int_t nrays, Double_t startx, Double_t starty, Doub Int_t n10=nrays/10; Double_t theta,phi, step, normlen; const Double_t *normal; + Double_t ox = ((TGeoBBox*)vol->GetShape())->GetOrigin()[0]; + Double_t oy = ((TGeoBBox*)vol->GetShape())->GetOrigin()[1]; + Double_t oz = ((TGeoBBox*)vol->GetShape())->GetOrigin()[2]; Double_t dx = ((TGeoBBox*)vol->GetShape())->GetDX(); Double_t dy = ((TGeoBBox*)vol->GetShape())->GetDY(); Double_t dz = ((TGeoBBox*)vol->GetShape())->GetDZ(); @@ -2140,9 +2149,15 @@ void TGeoChecker::RandomRays(Int_t nrays, Double_t startx, Double_t starty, Doub if (n10) { if ((itot%n10) == 0) printf("%i percent\n", Int_t(100*itot/nrays)); } - start[0] = startx; - start[1] = starty; - start[2] = startz; + if (random) { + start[0] = ox-dx+2*dx*gRandom->Rndm(); + start[1] = oy-dy+2*dy*gRandom->Rndm(); + start[2] = oz-dz+2*dz*gRandom->Rndm(); + } else { + start[0] = startx; + start[1] = starty; + start[2] = startz; + } phi = 2*TMath::Pi()*gRandom->Rndm(); theta= TMath::ACos(1.-2.*gRandom->Rndm()); dir[0]=TMath::Sin(theta)*TMath::Cos(phi); @@ -2151,11 +2166,16 @@ void TGeoChecker::RandomRays(Int_t nrays, Double_t startx, Double_t starty, Doub startnode = fGeoManager->InitTrack(start[0],start[1],start[2], dir[0],dir[1],dir[2]); line = 0; if (fGeoManager->IsOutside()) startnode=0; - vis1 = (startnode)?(startnode->IsOnScreen()):kFALSE; + vis1 = kFALSE; + if (target_vol) { + if (startnode && starget==startnode->GetVolume()->GetName()) vis1 = kTRUE; + } else { + if (startnode && startnode->IsOnScreen()) vis1 = kTRUE; + } if (vis1) { line = new TPolyLine3D(2); line->SetLineColor(startnode->GetVolume()->GetLineColor()); - line->SetPoint(ipoint++, startx, starty, startz); + line->SetPoint(ipoint++, start[0], start[1], start[2]); i++; pm->Add(line); } @@ -2164,13 +2184,18 @@ void TGeoChecker::RandomRays(Int_t nrays, Double_t startx, Double_t starty, Doub if (step<TGeoShape::Tolerance()) inull++; else inull = 0; if (inull>5) break; - normal = fGeoManager->FindNormalFast(); - if (!normal) break; - vis2 = endnode->IsOnScreen(); + if (check_norm) { + normal = fGeoManager->FindNormalFast(); + if (!normal) break; + } + vis2 = kFALSE; + if (target_vol) { + if (starget==endnode->GetVolume()->GetName()) vis2 = kTRUE; + } else if (endnode->IsOnScreen()) vis2 = kTRUE; if (ipoint>0) { // old visible node had an entry point -> finish segment line->SetPoint(ipoint, point[0], point[1], point[2]); - if (!vis2) { + if (!vis2 && check_norm) { normline = new TPolyLine3D(2); normline->SetLineColor(kBlue); normline->SetLineWidth(1); @@ -2189,15 +2214,17 @@ void TGeoChecker::RandomRays(Int_t nrays, Double_t startx, Double_t starty, Doub line->SetLineColor(endnode->GetVolume()->GetLineColor()); line->SetPoint(ipoint++, point[0], point[1], point[2]); i++; - normline = new TPolyLine3D(2); - normline->SetLineColor(kBlue); - normline->SetLineWidth(2); - normline->SetPoint(0, point[0], point[1], point[2]); - normline->SetPoint(1, point[0]+normal[0]*normlen, - point[1]+normal[1]*normlen, - point[2]+normal[2]*normlen); + if (check_norm) { + normline = new TPolyLine3D(2); + normline->SetLineColor(kBlue); + normline->SetLineWidth(2); + normline->SetPoint(0, point[0], point[1], point[2]); + normline->SetPoint(1, point[0]+normal[0]*normlen, + point[1]+normal[1]*normlen, + point[2]+normal[2]*normlen); + } pm->Add(line); - pm->Add(normline); + if (!random) pm->Add(normline); } } } diff --git a/geom/geompainter/src/TGeoPainter.cxx b/geom/geompainter/src/TGeoPainter.cxx index 82075bb413991197357266035a91c971b810ec41..58726ead32989b65bb2cbff2af4235fe9c6b12ae 100644 --- a/geom/geompainter/src/TGeoPainter.cxx +++ b/geom/geompainter/src/TGeoPainter.cxx @@ -1485,10 +1485,10 @@ void TGeoPainter::RandomPoints(const TGeoVolume *vol, Int_t npoints, Option_t *o } //______________________________________________________________________________ -void TGeoPainter::RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz) +void TGeoPainter::RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz, const char *target_vol, Bool_t check_norm) { // Shoot nrays in the current drawn geometry - fChecker->RandomRays(nrays, startx, starty, startz); + fChecker->RandomRays(nrays, startx, starty, startz, target_vol, check_norm); } //______________________________________________________________________________