Logo ROOT  
Reference Guide
TGeoNavigator.cxx
Go to the documentation of this file.
1 // @(#)root/geom:$Id$
2 // Author: Mihaela Gheata 30/05/07
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 /** \class TGeoNavigator
13 \ingroup Geometry_classes
14 
15  Class providing navigation API for TGeo geometries. Several instances are
16 allowed for a single geometry.
17 A default navigator is provided for any geometry but one may add several
18 others for parallel navigation:
19 
20 ~~~ {.cpp}
21 TGeoNavigator *navig = new TGeoNavigator(gGeoManager);
22 Int_t inav = gGeoManager->AddNavigator(navig);
23 gGeoManager->SetCurrentNavigator(inav);
24 ~~~
25 
26 .... and then switch back to the default navigator:
27 
28 ~~~ {.cpp}
29 gGeoManager->SetCurrentNavigator(0);
30 ~~~
31 
32 */
33 
34 #include "TGeoNavigator.h"
35 
36 #include "TGeoManager.h"
37 #include "TGeoMatrix.h"
38 #include "TGeoNode.h"
39 #include "TGeoVolume.h"
40 #include "TGeoPatternFinder.h"
41 #include "TGeoVoxelFinder.h"
42 #include "TMath.h"
43 #include "TGeoParallelWorld.h"
44 #include "TGeoPhysicalNode.h"
45 
47 const char *kGeoOutsidePath = " ";
48 const Int_t kN3 = 3*sizeof(Double_t);
49 
51 
52 ////////////////////////////////////////////////////////////////////////////////
53 /// Constructor
54 
56  :fStep(0.),
57  fSafety(0.),
58  fLastSafety(0.),
59  fThreadId(0),
60  fLevel(0),
61  fNmany(0),
62  fNextDaughterIndex(0),
63  fOverlapSize(0),
64  fOverlapMark(0),
65  fOverlapClusters(0),
66  fSearchOverlaps(kFALSE),
67  fCurrentOverlapping(kFALSE),
68  fStartSafe(kFALSE),
69  fIsEntering(kFALSE),
70  fIsExiting(kFALSE),
71  fIsStepEntering(kFALSE),
72  fIsStepExiting(kFALSE),
73  fIsOutside(kFALSE),
74  fIsOnBoundary(kFALSE),
75  fIsSameLocation(kFALSE),
76  fIsNullStep(kFALSE),
77  fGeometry(0),
78  fCache(0),
79  fCurrentVolume(0),
80  fCurrentNode(0),
81  fTopNode(0),
82  fLastNode(0),
83  fNextNode(0),
84  fForcedNode(0),
85  fBackupState(0),
86  fCurrentMatrix(0),
87  fGlobalMatrix(0),
88  fDivMatrix(0),
89  fPath()
90 
91 {
92 // dummy constructor
93  for (Int_t i=0; i<3; i++) {
94  fNormal[i] = 0.;
95  fCldir[i] = 0.;
96  fCldirChecked[i] = 0.;
97  fPoint[i] = 0.;
98  fDirection[i] = 0.;
99  fLastPoint[i] = 0.;
100  }
101 }
102 
103 ////////////////////////////////////////////////////////////////////////////////
104 /// Constructor
105 
107  :fStep(0.),
108  fSafety(0.),
109  fLastSafety(0.),
110  fThreadId(0),
111  fLevel(0),
112  fNmany(0),
113  fNextDaughterIndex(-2),
114  fOverlapSize(1000),
115  fOverlapMark(0),
116  fOverlapClusters(0),
117  fSearchOverlaps(kFALSE),
118  fCurrentOverlapping(kFALSE),
119  fStartSafe(kTRUE),
120  fIsEntering(kFALSE),
121  fIsExiting(kFALSE),
122  fIsStepEntering(kFALSE),
123  fIsStepExiting(kFALSE),
124  fIsOutside(kFALSE),
125  fIsOnBoundary(kFALSE),
126  fIsSameLocation(kTRUE),
127  fIsNullStep(kFALSE),
128  fGeometry(geom),
129  fCache(0),
130  fCurrentVolume(0),
131  fCurrentNode(0),
132  fTopNode(0),
133  fLastNode(0),
134  fNextNode(0),
135  fForcedNode(0),
136  fBackupState(0),
137  fCurrentMatrix(0),
138  fGlobalMatrix(0),
139  fDivMatrix(0),
140  fPath()
141 
142 {
143 // Default constructor.
145  // printf("Navigator: threadId=%d\n", fThreadId);
146  for (Int_t i=0; i<3; i++) {
147  fNormal[i] = 0.;
148  fCldir[i] = 0.;
149  fCldirChecked[i] = 0;
150  fPoint[i] = 0.;
151  fDirection[i] = 0.;
152  fLastPoint[i] = 0.;
153  }
154  fCurrentMatrix = new TGeoHMatrix();
156  fDivMatrix = new TGeoHMatrix();
159  ResetAll();
160 }
161 
162 ////////////////////////////////////////////////////////////////////////////////
163 /// Destructor.
164 
166 {
167  if (fCache) delete fCache;
168  if (fBackupState) delete fBackupState;
169  if (fOverlapClusters) delete [] fOverlapClusters;
170 }
171 
172 ////////////////////////////////////////////////////////////////////////////////
173 /// Builds the cache for physical nodes and global matrices.
174 
175 void TGeoNavigator::BuildCache(Bool_t /*dummy*/, Bool_t nodeid)
176 {
177  static Bool_t first = kTRUE;
179  Int_t nlevel = fGeometry->GetMaxLevel();
180  if (nlevel<=0) nlevel = 100;
181  if (!fCache) {
182  if (nlevel==100) {
183  if (first && verbose>0) Info("BuildCache","--- Maximum geometry depth set to 100");
184  } else {
185  if (first && verbose>0) Info("BuildCache","--- Maximum geometry depth is %i", nlevel);
186  }
187  // build cache
188  fCache = new TGeoNodeCache(fGeometry->GetTopNode(), nodeid, nlevel+1);
190  fBackupState = new TGeoCacheState(nlevel+1);
191  }
192  first = kFALSE;
193 }
194 
195 ////////////////////////////////////////////////////////////////////////////////
196 /// Browse the tree of nodes starting from top node according to pathname.
197 /// Changes the path accordingly. The path is changed to point to the top node
198 /// in case of failure.
199 
200 Bool_t TGeoNavigator::cd(const char *path)
201 {
202  CdTop();
203  if (!path[0]) return kTRUE;
204  TString spath = path;
205  TGeoVolume *vol;
206  Int_t length = spath.Length();
207  Int_t ind1 = spath.Index("/");
208  if (ind1 == length-1) ind1 = -1;
209  Int_t ind2 = 0;
210  Bool_t end = kFALSE;
211  Bool_t first = kTRUE;
212  TString name;
213  TGeoNode *node;
214  while (!end) {
215  ind2 = spath.Index("/", ind1+1);
216  if (ind2<0 || ind2==length-1) {
217  if (ind2<0) ind2 = length;
218  end = kTRUE;
219  }
220  name = spath(ind1+1, ind2-ind1-1);
221  vol = fCurrentNode->GetVolume();
222  if (first) {
223  first = kFALSE;
224  if (name.BeginsWith(vol->GetName())) {
225  ind1 = ind2;
226  continue;
227  }
228  }
229  node = vol->GetNode(name.Data());
230  if (!node) {
231  Error("cd", "Path %s not valid", path);
232  return kFALSE;
233  }
234  CdDown(vol->GetIndex(node));
235  ind1 = ind2;
236  }
237  return kTRUE;
238 }
239 
240 ////////////////////////////////////////////////////////////////////////////////
241 /// Check if a geometry path is valid without changing the state of the navigator.
242 
243 Bool_t TGeoNavigator::CheckPath(const char *path) const
244 {
245  if (!path[0]) return kTRUE;
246  TGeoNode *crtnode = fGeometry->GetTopNode();
247  TString spath = path;
248  TGeoVolume *vol;
249  Int_t length = spath.Length();
250  Int_t ind1 = spath.Index("/");
251  if (ind1 == length-1) ind1 = -1;
252  Int_t ind2 = 0;
253  Bool_t end = kFALSE;
254  Bool_t first = kTRUE;
255  TString name;
256  TGeoNode *node;
257  while (!end) {
258  ind2 = spath.Index("/", ind1+1);
259  if (ind2<0 || ind2==length-1) {
260  if (ind2<0) ind2 = length;
261  end = kTRUE;
262  }
263  name = spath(ind1+1, ind2-ind1-1);
264  vol = crtnode->GetVolume();
265  if (first) {
266  first = kFALSE;
267  if (name.BeginsWith(vol->GetName())) {
268  ind1 = ind2;
269  continue;
270  }
271  }
272  node = vol->GetNode(name.Data());
273  if (!node) return kFALSE;
274  crtnode = node;
275  ind1 = ind2;
276  }
277  return kTRUE;
278 }
279 
280 ////////////////////////////////////////////////////////////////////////////////
281 /// Change current path to point to the node having this id.
282 /// Node id has to be in range : 0 to fNNodes-1 (no check for performance reasons)
283 
285 {
286  if (fCache) {
287  fCache->CdNode(nodeid);
289  }
290 }
291 
292 ////////////////////////////////////////////////////////////////////////////////
293 /// Make a daughter of current node current. Can be called only with a valid
294 /// daughter index (no check). Updates cache accordingly.
295 
297 {
298  TGeoNode *node = fCurrentNode->GetDaughter(index);
299  Bool_t is_offset = node->IsOffset();
300  if (is_offset)
301  node->cd();
302  else
304  fCache->CdDown(index);
305  fCurrentNode = node;
308  fLevel++;
309 }
310 
311 ////////////////////////////////////////////////////////////////////////////////
312 /// Make a daughter of current node current. Can be called only with a valid
313 /// daughter node (no check). Updates cache accordingly.
314 
316 {
317  Bool_t is_offset = node->IsOffset();
318  if (is_offset)
319  node->cd();
320  else
322  fCache->CdDown(node);
323  fCurrentNode = node;
326  fLevel++;
327 }
328 
329 ////////////////////////////////////////////////////////////////////////////////
330 /// Go one level up in geometry. Updates cache accordingly.
331 /// Determine the overlapping state of current node.
332 
334 {
335  if (!fLevel || !fCache) return;
336  fLevel--;
337  if (!fLevel) {
338  CdTop();
339  return;
340  }
341  fCache->CdUp();
342  if (fCurrentOverlapping) {
344  fNmany--;
345  }
348  if (!fCurrentNode->IsOffset()) {
350  } else {
351  Int_t up = 1;
352  Bool_t offset = kTRUE;
353  TGeoNode *mother = 0;
354  while (offset) {
355  mother = GetMother(up++);
356  offset = mother->IsOffset();
357  }
359  }
360 }
361 
362 ////////////////////////////////////////////////////////////////////////////////
363 /// Make top level node the current node. Updates the cache accordingly.
364 /// Determine the overlapping state of current node.
365 
367 {
368  if (!fCache) return;
369  fLevel = 0;
370  fNmany = 0;
373  fCache->CdTop();
377 }
378 
379 ////////////////////////////////////////////////////////////////////////////////
380 /// Do a cd to the node found next by FindNextBoundary
381 
383 {
384  if (fNextDaughterIndex == -2 || !fCache) return;
385  if (fNextDaughterIndex == -3) {
386  // Next node is a many - restore it
387  DoRestoreState();
388  fNextDaughterIndex = -2;
389  return;
390  }
391  if (fNextDaughterIndex == -1) {
392  CdUp();
393  while (fCurrentNode->GetVolume()->IsAssembly()) CdUp();
395  return;
396  }
397  if (fCurrentNode && fNextDaughterIndex<fCurrentNode->GetNdaughters()) {
399  Int_t nextindex = fCurrentNode->GetVolume()->GetNextNodeIndex();
400  while (nextindex>=0) {
401  CdDown(nextindex);
402  nextindex = fCurrentNode->GetVolume()->GetNextNodeIndex();
403  }
404  }
405  fNextDaughterIndex = -2;
406 }
407 
408 ////////////////////////////////////////////////////////////////////////////////
409 /// Fill volume names of current branch into an array.
410 
412 {
413  fCache->GetBranchNames(names);
414 }
415 
416 ////////////////////////////////////////////////////////////////////////////////
417 /// Fill node copy numbers of current branch into an array.
418 
419 void TGeoNavigator::GetBranchNumbers(Int_t *copyNumbers, Int_t *volumeNumbers) const
420 {
421  fCache->GetBranchNumbers(copyNumbers, volumeNumbers);
422 }
423 
424 ////////////////////////////////////////////////////////////////////////////////
425 /// Fill node copy numbers of current branch into an array.
426 
428 {
429  fCache->GetBranchOnlys(isonly);
430 }
431 
432 ////////////////////////////////////////////////////////////////////////////////
433 /// Cross a division cell. Distance to exit contained in fStep, current node
434 /// points to the cell node.
435 
437 {
439  if (!finder) {
440  Fatal("CrossDivisionCell", "Volume has no pattern finder");
441  return 0;
442  }
443  // Mark current node and go up to the level of the divided volume
444  TGeoNode *skip = fCurrentNode;
445  CdUp();
446  Double_t point[3], newpoint[3], dir[3];
447  fGlobalMatrix->MasterToLocal(fPoint, newpoint);
449  // Does step cross a boundary along division axis ?
450  Bool_t onbound = finder->IsOnBoundary(newpoint);
451  if (onbound) {
452  // Work along division axis
453  // Get the starting point
454  point[0] = newpoint[0] - dir[0]*fStep*(1.-gTolerance);
455  point[1] = newpoint[1] - dir[1]*fStep*(1.-gTolerance);
456  point[2] = newpoint[2] - dir[2]*fStep*(1.-gTolerance);
457  // Find which is the next crossed cell.
458  finder->FindNode(point, dir);
459  Int_t inext = finder->GetNext();
460  if (inext<0) {
461  // step fully exits the division along the division axis
462  // Do step exits in a mother cell ?
463  if (fCurrentNode->IsOffset()) {
465  // Do step exit also from mother cell ?
466  if (dist < fStep+2.*gTolerance) {
467  // Step exits mother on its own division axis
468  return CrossDivisionCell();
469  }
470  // We end up here
471  return fCurrentNode;
472  }
473  // Exiting in a non-divided volume
474  while (fCurrentNode->GetVolume()->IsAssembly()) {
475  // Move always to mother for assemblies
476  skip = fCurrentNode;
477  if (!fLevel) break;
478  CdUp();
479  }
480  return CrossBoundaryAndLocate(kFALSE, skip);
481  }
482  // step enters a new cell
483  CdDown(inext+finder->GetDivIndex());
484  skip = fCurrentNode;
485  return CrossBoundaryAndLocate(kTRUE, skip);
486  }
487  // step exits on an axis other than the division axis -> get next slice
488  if (fCurrentNode->IsOffset()) return CrossDivisionCell();
489  return CrossBoundaryAndLocate(kFALSE, skip);
490 }
491 
492 ////////////////////////////////////////////////////////////////////////////////
493 /// Cross next boundary and locate within current node
494 /// The current point must be on the boundary of fCurrentNode.
495 
497 {
498 // Extrapolate current point with estimated error.
500  Double_t trmax = 1.+TMath::Abs(tr[0])+TMath::Abs(tr[1])+TMath::Abs(tr[2]);
501  Double_t extra = 100.*(trmax+fStep)*gTolerance;
502  const Int_t idebug = TGeoManager::GetVerboseLevel();
503  TGeoNode *crtstate[10];
504  Int_t level = fLevel+1;
505  Bool_t samepath = kFALSE;
506  for (Int_t i=0; i<10; ++i)
507  crtstate[i] = nullptr;
508 
509  if (!downwards) {
510  for (Int_t i=0; i<fLevel; ++i) {
511  crtstate[i] = GetMother(i);
512  if (i==9) break;
513  }
514  }
515  fPoint[0] += extra*fDirection[0];
516  fPoint[1] += extra*fDirection[1];
517  fPoint[2] += extra*fDirection[2];
518  TGeoNode *current = SearchNode(downwards, skipnode);
519  fForcedNode = 0;
520  fPoint[0] -= extra*fDirection[0];
521  fPoint[1] -= extra*fDirection[1];
522  fPoint[2] -= extra*fDirection[2];
523  if (!current) return 0;
524  if (downwards) {
525  Int_t nextindex = current->GetVolume()->GetNextNodeIndex();
526  while (nextindex>=0) {
527  CdDown(nextindex);
528  current = fCurrentNode;
529  nextindex = fCurrentNode->GetVolume()->GetNextNodeIndex();
530  }
531  if (idebug>4) {
532  printf("CrossBoundaryAndLocate: entered %s\n", GetPath());
533  }
534  return current;
535  }
536 
537  if (skipnode) {
538  if (current == skipnode) {
539  samepath = kTRUE;
540  if (!downwards) {
541  level = TMath::Min(level, 10);
542  for (Int_t i=1; i<level; i++) {
543  if (crtstate[i-1] != GetMother(i)) {
544  samepath = kFALSE;
545  break;
546  }
547  }
548  }
549  }
550  }
551 
552  if (samepath || current->GetVolume()->IsAssembly()) {
553  if (!fLevel) {
554  fIsOutside = kTRUE;
555  if (idebug>4) {
556  printf("CrossBoundaryAndLocate: Exited geometry\n");
557  }
558  return fGeometry->GetCurrentNode();
559  }
560  CdUp();
561  while (fLevel && fCurrentNode->GetVolume()->IsAssembly()) CdUp();
562  if (!fLevel && fCurrentNode->GetVolume()->IsAssembly()) {
563  fIsOutside = kTRUE;
564  if (idebug>4) {
565  printf("CrossBoundaryAndLocate: Exited geometry\n");
566  }
567  if (idebug>4) {
568  printf("CrossBoundaryAndLocate: entered %s\n", GetPath());
569  }
570  return fCurrentNode;
571  }
572  return fCurrentNode;
573  }
574  if (idebug>4) {
575  printf("CrossBoundaryAndLocate: entered %s\n", GetPath());
576  }
577  return current;
578 }
579 
580 ////////////////////////////////////////////////////////////////////////////////
581 /// Find distance to next boundary and store it in fStep. Returns node to which this
582 /// boundary belongs. If PATH is specified, compute only distance to the node to which
583 /// PATH points. If STEPMAX is specified, compute distance only in case fSafety is smaller
584 /// than this value. STEPMAX represent the step to be made imposed by other reasons than
585 /// geometry (usually physics processes). Therefore in this case this method provides the
586 /// answer to the question : "Is STEPMAX a safe step ?" returning a NULL node and filling
587 /// fStep with a big number.
588 /// In case frombdr=kTRUE, the isotropic safety is set to zero.
589 ///
590 /// Note : safety distance for the current point is computed ONLY in case STEPMAX is
591 /// specified, otherwise users have to call explicitly TGeoManager::Safety() if
592 /// they want this computed for the current point.
593 
594 TGeoNode *TGeoNavigator::FindNextBoundary(Double_t stepmax, const char *path, Bool_t frombdr)
595 {
596  // convert current point and direction to local reference
597  Int_t iact = 3;
599  fNextDaughterIndex = -2;
600  fStep = TGeoShape::Big();
603  fForcedNode = 0;
604  Bool_t computeGlobal = kFALSE;
605  fIsOnBoundary = frombdr;
606  fSafety = 0.;
607  TGeoNode *top_node = fGeometry->GetTopNode();
608  TGeoVolume *top_volume = top_node->GetVolume();
609  // If inside an assembly, go logically up in the hierarchy
610  while (fCurrentNode->GetVolume()->IsAssembly() && fLevel) CdUp();
611  if (stepmax<1E29) {
612  if (stepmax <= 0) {
613  stepmax = - stepmax;
614  computeGlobal = kTRUE;
615  }
616 // if (fLastSafety>0 && IsSamePoint(fPoint[0], fPoint[1], fPoint[2])) fSafety = fLastSafety;
617  fSafety = Safety();
618  // Try to get out easy if proposed step within safe region
619  if (!frombdr && (fSafety>0) && IsSafeStep(stepmax+gTolerance, fSafety)) {
620  fStep = stepmax;
622  return fCurrentNode;
623  }
625  memcpy(fLastPoint, fPoint, kN3);
628  else fIsOnBoundary = kFALSE;
629  fStep = stepmax;
630  if (stepmax+gTolerance<fSafety) {
632  return fCurrentNode;
633  }
634  }
635  if (computeGlobal) fCurrentMatrix->CopyFrom(fGlobalMatrix);
637  Double_t safe;
638  Double_t point[3];
639  Double_t dir[3];
640  if (idebug>4) {
641  printf("TGeoManager::FindNextBoundary: point=(%19.16f, %19.16f, %19.16f)\n",
642  fPoint[0],fPoint[1],fPoint[2]);
643  printf(" dir= (%19.16f, %19.16f, %19.16f)\n",
644  fDirection[0], fDirection[1], fDirection[2]);
645  printf(" pstep=%9.6g path=%s\n", stepmax, GetPath());
646  }
647  if (path[0]) {
648  PushPath();
649  if (!cd(path)) {
650  PopPath();
651  return 0;
652  }
653  if (computeGlobal) fCurrentMatrix->CopyFrom(fGlobalMatrix);
656  fGlobalMatrix->MasterToLocal(fPoint, &point[0]);
658  if (idebug>4) {
659  printf("=== To path: %s\n", path);
660  printf("=== local to %s: (%19.16f, %19.16f, %19.16f, %19.16f, %19.16f, %19.16f)\n",
661  tvol->GetName(), point[0],point[1],point[2],dir[0],dir[1],dir[2]);
662  }
663  if (tvol->Contains(point)) {
664  if (idebug>4) printf("=== volume %s contains point\n", tvol->GetName());
665  fStep=tvol->GetShape()->DistFromInside(&point[0], &dir[0], iact, fStep, &safe);
666  } else {
667  fStep=tvol->GetShape()->DistFromOutside(&point[0], &dir[0], iact, fStep, &safe);
668  if (idebug>4) {
669  printf("=== volume %s does not contain point\n", tvol->GetName());
670  printf("=== distance to path: %g\n", fStep);
671  tvol->InspectShape();
672  if (fStep<1.E20) {
673  Double_t newpt[3];
674  newpt[0] = point[0] + fStep*dir[0];
675  newpt[1] = point[1] + fStep*dir[1];
676  newpt[2] = point[2] + fStep*dir[2];
677  printf("=== Propagated point: (%19.16f, %19.16f, %19.16f)", newpt[0],newpt[1],newpt[2]);
678  }
679  while (fLevel) {
680  CdUp();
681  tvol = fCurrentNode->GetVolume();
682  fGlobalMatrix->MasterToLocal(fPoint, &point[0]);
684  printf("=== local to %s: (%19.16f, %19.16f, %19.16f, %19.16f, %19.16f, %19.16f)\n",
685  tvol->GetName(), point[0],point[1],point[2],dir[0],dir[1],dir[2]);
686  if (tvol->Contains(point)) {
687  printf("=== volume %s contains point\n", tvol->GetName());
688  } else {
689  printf("=== volume %s does not contain point\n", tvol->GetName());
690  snext = tvol->GetShape()->DistFromOutside(&point[0], &dir[0], iact, 1.E30, &safe);
691  }
692  }
693  }
694  }
695  PopPath();
696  return fNextNode;
697  }
698  // compute distance to exit point from current node and the distance to its
699  // closest boundary
700  // if point is outside, just check the top node
701  if (fIsOutside) {
702  snext = top_volume->GetShape()->DistFromOutside(fPoint, fDirection, iact, fStep, &safe);
703  fNextNode = top_node;
704  if (snext < fStep-gTolerance) {
706  fStep = snext;
707  Int_t indnext = fNextNode->GetVolume()->GetNextNodeIndex();
708  fNextDaughterIndex = indnext;
709  while (indnext>=0) {
710  fNextNode = fNextNode->GetDaughter(indnext);
711  if (computeGlobal) fCurrentMatrix->Multiply(fNextNode->GetMatrix());
712  indnext = fNextNode->GetVolume()->GetNextNodeIndex();
713  }
714  return fNextNode;
715  }
716  return 0;
717  }
718  fGlobalMatrix->MasterToLocal(fPoint, &point[0]);
721  if (idebug>4) {
722  printf(" -> from local=(%19.16f, %19.16f, %19.16f)\n",
723  point[0],point[1],point[2]);
724  printf(" ldir =(%19.16f, %19.16f, %19.16f)\n",
725  dir[0],dir[1],dir[2]);
726  }
727  // find distance to exiting current node
728  snext = vol->GetShape()->DistFromInside(&point[0], &dir[0], iact, fStep, &safe);
729  if (idebug>4) {
730  printf(" exiting %s shape %s at snext=%g\n", vol->GetName(), vol->GetShape()->ClassName(),snext);
731  }
732  if (snext < fStep-gTolerance) {
734  fNextDaughterIndex = -1;
736  fStep = snext;
738  if (fStep<1E-6) return fCurrentNode;
739  }
740  fNextNode = (fStep<1E20)?fCurrentNode:0;
741  // Find next daughter boundary for the current volume
742  Int_t idaughter = -1;
743  FindNextDaughterBoundary(point,dir,idaughter,computeGlobal);
744  if (idaughter>=0) fNextDaughterIndex = idaughter;
745  TGeoNode *current = 0;
746  TGeoNode *dnode = 0;
747  TGeoVolume *mother = 0;
748  // if we are in an overlapping node, check also the mother(s)
749  if (fNmany) {
750  Double_t mothpt[3];
751  Double_t vecpt[3];
752  Double_t dpt[3], dvec[3];
753  Int_t novlps;
754  Int_t idovlp = -1;
755  Int_t safelevel = GetSafeLevel();
756  PushPath(safelevel+1);
757  while (fCurrentOverlapping) {
758  Int_t *ovlps = fCurrentNode->GetOverlaps(novlps);
759  CdUp();
760  mother = fCurrentNode->GetVolume();
761  fGlobalMatrix->MasterToLocal(fPoint, &mothpt[0]);
763  // check distance to out
764  snext = TGeoShape::Big();
765  if (!mother->IsAssembly()) snext = mother->GetShape()->DistFromInside(&mothpt[0], &vecpt[0], iact, fStep, &safe);
766  if (snext<fStep-gTolerance) {
769  fStep = snext;
770  if (computeGlobal) fCurrentMatrix->CopyFrom(fGlobalMatrix);
772  fNextDaughterIndex = -3;
773  DoBackupState();
774  }
775  // check overlapping nodes
776  for (Int_t i=0; i<novlps; i++) {
777  current = mother->GetNode(ovlps[i]);
778  if (!current->IsOverlapping()) {
779  current->cd();
780  current->MasterToLocal(&mothpt[0], &dpt[0]);
781  current->MasterToLocalVect(&vecpt[0], &dvec[0]);
782  // Current point may be inside the other node - geometry error that we ignore
783  snext = current->GetVolume()->GetShape()->DistFromOutside(&dpt[0], &dvec[0], iact, fStep, &safe);
784  if (snext<fStep-gTolerance) {
785  if (computeGlobal) {
787  fCurrentMatrix->Multiply(current->GetMatrix());
788  }
791  fStep = snext;
792  fNextNode = current;
793  fNextDaughterIndex = -3;
794  CdDown(ovlps[i]);
795  DoBackupState();
796  CdUp();
797  }
798  } else {
799  // another many - check if point is in or out
800  current->cd();
801  current->MasterToLocal(&mothpt[0], &dpt[0]);
802  current->MasterToLocalVect(&vecpt[0], &dvec[0]);
803  if (current->GetVolume()->Contains(dpt)) {
804  if (current->GetVolume()->GetNdaughters()) {
805  CdDown(ovlps[i]);
808  dnode = FindNextDaughterBoundary(dpt,dvec,idovlp,computeGlobal);
809  if (dnode) {
810  if (computeGlobal) {
812  fCurrentMatrix->Multiply(dnode->GetMatrix());
813  }
814  fNextNode = dnode;
815  fNextDaughterIndex = -3;
816  CdDown(idovlp);
818  Int_t iup=0;
819  while (indnext>=0) {
820  CdDown(indnext);
821  iup++;
822  indnext = fCurrentNode->GetVolume()->GetNextNodeIndex();
823  }
824  DoBackupState();
825  while (iup>0) {
826  CdUp();
827  iup--;
828  }
829  CdUp();
830  }
831  CdUp();
832  }
833  } else {
834  snext = current->GetVolume()->GetShape()->DistFromOutside(&dpt[0], &dvec[0], iact, fStep, &safe);
835  if (snext<fStep-gTolerance) {
836  if (computeGlobal) {
838  fCurrentMatrix->Multiply(current->GetMatrix());
839  }
842  fStep = snext;
843  fNextNode = current;
844  fNextDaughterIndex = -3;
845  CdDown(ovlps[i]);
846  DoBackupState();
847  CdUp();
848  }
849  }
850  }
851  }
852  }
853  // Now we are in a non-overlapping node
854  if (fNmany) {
855  // We have overlaps up in the branch, check distance to exit
856  Int_t up = 1;
857  Int_t imother;
858  Int_t nmany = fNmany;
859  Bool_t ovlp = kFALSE;
860  Bool_t nextovlp = kFALSE;
861  Bool_t offset = kFALSE;
862  TGeoNode *currentnode = fCurrentNode;
863  TGeoNode *mothernode, *mup;
864  TGeoHMatrix *matrix;
865  while (nmany) {
866  mothernode = GetMother(up);
867  if (!mothernode) {
868  Fatal("FindNextBoundary", "Cannot find mother node");
869  return 0;
870  }
871  mup = mothernode;
872  imother = up+1;
873  offset = kFALSE;
874  while (mup->IsOffset()) {
875  mup = GetMother(imother++);
876  offset = kTRUE;
877  }
878  nextovlp = mup->IsOverlapping();
879  if (offset) {
880  mothernode = mup;
881  if (nextovlp) nmany -= imother-up;
882  up = imother-1;
883  } else {
884  if (ovlp) nmany--;
885  }
886  if (ovlp || nextovlp) {
887  matrix = GetMotherMatrix(up);
888  if (!matrix) {
889  Fatal("FindNextBoundary", "Cannot find mother matrix");
890  return 0;
891  }
892  matrix->MasterToLocal(fPoint,dpt);
893  matrix->MasterToLocalVect(fDirection,dvec);
894  snext = TGeoShape::Big();
895  if (!mothernode->GetVolume()->IsAssembly()) snext = mothernode->GetVolume()->GetShape()->DistFromInside(dpt,dvec,iact,fStep);
896  if (snext<fStep-gTolerance) {
899  fStep = snext;
900  fNextNode = mothernode;
901  fNextDaughterIndex = -3;
902  if (computeGlobal) fCurrentMatrix->CopyFrom(matrix);
903  while (up--) CdUp();
904  DoBackupState();
905  up = 1;
906  currentnode = fCurrentNode;
907  ovlp = currentnode->IsOverlapping();
908  continue;
909  }
910  }
911  currentnode = mothernode;
912  ovlp = nextovlp;
913  up++;
914  }
915  }
916  PopPath();
917  }
918  // Compute now the distance in case we have a parallel world
919  Double_t parstep = TGeoShape::Big();
920  if (fGeometry->IsParallelWorldNav()) {
921 // printf("path: %s next node %s at %g\n", GetPath(), fNextNode->GetName(), fStep);
923  if (pnode) {
924  // A boundary is hit at less than fPStep
925  fStep = parstep;
926  fNextNode = pnode->GetNode();
927  fNextDaughterIndex = -2; // No way to store it for CdNext
930  Int_t nextindex = fNextNode->GetVolume()->GetNextNodeIndex();
931  while (nextindex>=0) {
932  fNextNode = fNextNode->GetDaughter(nextindex);
933  nextindex = fNextNode->GetVolume()->GetNextNodeIndex();
934  }
935  }
936  }
937  return fNextNode;
938 }
939 
940 ////////////////////////////////////////////////////////////////////////////////
941 /// Computes as fStep the distance to next daughter of the current volume.
942 /// The point and direction must be converted in the coordinate system of the current volume.
943 /// The proposed step limit is fStep.
944 
946 {
949  idaughter = -1; // nothing crossed
950  TGeoNode *nodefound = 0;
951  // Get number of daughters. If no daughters we are done.
952 
954  Int_t nd = vol->GetNdaughters();
955  if (!nd) return 0; // No daughter
956  if (fGeometry->IsActivityEnabled() && !vol->IsActiveDaughters()) return 0;
957  Double_t lpoint[3], ldir[3];
958  TGeoNode *current = 0;
959  Int_t i=0;
960  // if current volume is divided, we are in the non-divided region. We
961  // check first if we are inside a cell in which case compute distance to next cell
962  TGeoPatternFinder *finder = vol->GetFinder();
963  if (finder) {
964  Int_t ifirst = finder->GetDivIndex();
965  Int_t ilast = ifirst+finder->GetNdiv()-1;
966  current = finder->FindNode(point);
967  if (current) {
968  // Point inside a cell: find distance to next cell
969  Int_t index = current->GetIndex();
970  if ((index-1) >= ifirst) ifirst = index-1;
971  else ifirst = -1;
972  if ((index+1) <= ilast) ilast = index+1;
973  else ilast = -1;
974  }
975  if (ifirst>=0) {
976  current = vol->GetNode(ifirst);
977  current->cd();
978  current->MasterToLocal(&point[0], lpoint);
979  current->MasterToLocalVect(&dir[0], ldir);
980  snext = current->GetVolume()->GetShape()->DistFromOutside(lpoint, ldir, 3, fStep);
981  if (snext<fStep-gTolerance) {
982  if (compmatrix) {
984  fCurrentMatrix->Multiply(current->GetMatrix());
985  }
988  fStep=snext;
989  fNextNode = current;
990  nodefound = current;
991  idaughter = ifirst;
992  }
993  }
994  if (ilast==ifirst) return nodefound;
995  if (ilast>=0) {
996  current = vol->GetNode(ilast);
997  current->cd();
998  current->MasterToLocal(&point[0], lpoint);
999  current->MasterToLocalVect(&dir[0], ldir);
1000  snext = current->GetVolume()->GetShape()->DistFromOutside(lpoint, ldir, 3, fStep);
1001  if (snext<fStep-gTolerance) {
1002  if (compmatrix) {
1004  fCurrentMatrix->Multiply(current->GetMatrix());
1005  }
1008  fStep=snext;
1009  fNextNode = current;
1010  nodefound = current;
1011  idaughter = ilast;
1012  }
1013  }
1014  return nodefound;
1015  }
1016  // if only few daughters, check all and exit
1017  TGeoVoxelFinder *voxels = vol->GetVoxels();
1018  Int_t indnext;
1019  if (idebug>4) printf(" Checking distance to %d daughters...\n",nd);
1020  if (nd<5 || !voxels) {
1021  for (i=0; i<nd; i++) {
1022  current = vol->GetNode(i);
1023  if (fGeometry->IsActivityEnabled() && !current->GetVolume()->IsActive()) continue;
1024  current->cd();
1025  if (voxels && voxels->IsSafeVoxel(point, i, fStep)) continue;
1026  current->MasterToLocal(point, lpoint);
1027  current->MasterToLocalVect(dir, ldir);
1028  if (current->IsOverlapping() &&
1029  current->GetVolume()->Contains(lpoint) &&
1030  current->GetVolume()->GetShape()->Safety(lpoint, kTRUE) > gTolerance) continue;
1031  snext = current->GetVolume()->GetShape()->DistFromOutside(lpoint, ldir, 3, fStep);
1032  if (snext<fStep-gTolerance) {
1033  if (idebug>4) {
1034  printf(" -> from local=(%19.16f, %19.16f, %19.16f)\n",
1035  lpoint[0],lpoint[1],lpoint[2]);
1036  printf(" ldir =(%19.16f, %19.16f, %19.16f)\n",
1037  ldir[0],ldir[1],ldir[2]);
1038  printf(" -> to: %s shape %s snext=%g\n", current->GetName(),
1039  current->GetVolume()->GetShape()->ClassName(), snext);
1040  }
1041  indnext = current->GetVolume()->GetNextNodeIndex();
1042  if (compmatrix) {
1044  fCurrentMatrix->Multiply(current->GetMatrix());
1045  }
1048  fStep=snext;
1049  fNextNode = current;
1050  nodefound = fNextNode;
1051  idaughter = i;
1052  while (indnext>=0) {
1053  current = current->GetDaughter(indnext);
1054  if (compmatrix) fCurrentMatrix->Multiply(current->GetMatrix());
1055  fNextNode = current;
1056  nodefound = current;
1057  indnext = current->GetVolume()->GetNextNodeIndex();
1058  }
1059  }
1060  }
1061  if (vol->IsAssembly()) ((TGeoVolumeAssembly*)vol)->SetNextNodeIndex(idaughter);
1062  return nodefound;
1063  }
1064  // if current volume is voxelized, first get current voxel
1065  Int_t ncheck = 0;
1066  Int_t sumchecked = 0;
1067  Int_t *vlist = 0;
1068  TGeoStateInfo &info = *fCache->GetInfo();
1069  voxels->SortCrossedVoxels(point, dir, info);
1070  while ((sumchecked<nd) && (vlist=voxels->GetNextVoxel(point, dir, ncheck, info))) {
1071  for (i=0; i<ncheck; i++) {
1072  current = vol->GetNode(vlist[i]);
1073  if (fGeometry->IsActivityEnabled() && !current->GetVolume()->IsActive()) continue;
1074  current->cd();
1075  current->MasterToLocal(point, lpoint);
1076  current->MasterToLocalVect(dir, ldir);
1077  if (current->IsOverlapping() && current->GetVolume()->Contains(lpoint) &&
1078  current->GetVolume()->GetShape()->Safety(lpoint, kTRUE) > gTolerance) continue;
1079  snext = current->GetVolume()->GetShape()->DistFromOutside(lpoint, ldir, 3, fStep);
1080  sumchecked++;
1081 // printf("checked %d from %d : snext=%g\n", sumchecked, nd, snext);
1082  if (snext<fStep-gTolerance) {
1083  if (idebug>4) {
1084  printf(" -> from local=(%19.16f, %19.16f, %19.16f)\n",
1085  lpoint[0],lpoint[1],lpoint[2]);
1086  printf(" ldir =(%19.16f, %19.16f, %19.16f)\n",
1087  ldir[0],ldir[1],ldir[2]);
1088  printf(" -> to: %s shape %s snext=%g\n", current->GetName(),
1089  current->GetVolume()->GetShape()->ClassName(), snext);
1090  }
1091  indnext = current->GetVolume()->GetNextNodeIndex();
1092  if (compmatrix) {
1094  fCurrentMatrix->Multiply(current->GetMatrix());
1095  }
1098  fStep=snext;
1099  fNextNode = current;
1100  nodefound = fNextNode;
1101  idaughter = vlist[i];
1102  while (indnext>=0) {
1103  current = current->GetDaughter(indnext);
1104  if (compmatrix) fCurrentMatrix->Multiply(current->GetMatrix());
1105  fNextNode = current;
1106  nodefound = current;
1107  indnext = current->GetVolume()->GetNextNodeIndex();
1108  }
1109  }
1110  }
1111  }
1112  fCache->ReleaseInfo();
1113  if (vol->IsAssembly()) ((TGeoVolumeAssembly*)vol)->SetNextNodeIndex(idaughter);
1114  return nodefound;
1115 }
1116 
1117 ////////////////////////////////////////////////////////////////////////////////
1118 /// Compute distance to next boundary within STEPMAX. If no boundary is found,
1119 /// propagate current point along current direction with fStep=STEPMAX. Otherwise
1120 /// propagate with fStep=SNEXT (distance to boundary) and locate/return the next
1121 /// node.
1122 
1124 {
1125  static Int_t icount = 0;
1126  icount++;
1127  Int_t iact = 3;
1129  Int_t nextindex;
1130  Bool_t is_assembly;
1131  fForcedNode = 0;
1133  TGeoNode *skip;
1135  fStep = stepmax;
1137  // If inside an assembly, go logically up in the hierarchy
1138  while (fCurrentNode->GetVolume()->IsAssembly() && fLevel) CdUp();
1139  if (compsafe) {
1140  // Try to get out easy if proposed step within safe region
1142  if (IsSafeStep(stepmax+gTolerance, fSafety)) {
1143  fPoint[0] += stepmax*fDirection[0];
1144  fPoint[1] += stepmax*fDirection[1];
1145  fPoint[2] += stepmax*fDirection[2];
1146  return fCurrentNode;
1147  }
1148  Safety();
1149  fLastSafety = fSafety;
1150  memcpy(fLastPoint, fPoint, kN3);
1151  // If proposed step less than safety, nothing to check
1152  if (fSafety > stepmax+gTolerance) {
1153  fPoint[0] += stepmax*fDirection[0];
1154  fPoint[1] += stepmax*fDirection[1];
1155  fPoint[2] += stepmax*fDirection[2];
1156  return fCurrentNode;
1157  }
1158  }
1159  Double_t extra = (fIsOnBoundary)?gTolerance:0.0;
1161  fPoint[0] += extra*fDirection[0];
1162  fPoint[1] += extra*fDirection[1];
1163  fPoint[2] += extra*fDirection[2];
1165  if (idebug>4) {
1166  printf("TGeoManager::FindNextBAndStep: point=(%19.16f, %19.16f, %19.16f)\n",
1167  fPoint[0],fPoint[1],fPoint[2]);
1168  printf(" dir= (%19.16f, %19.16f, %19.16f)\n",
1169  fDirection[0], fDirection[1], fDirection[2]);
1170  printf(" pstep=%9.6g path=%s\n", stepmax, GetPath());
1171  }
1172 
1173  if (fIsOutside) {
1175  if (snext < fStep-gTolerance) {
1176  if (snext<=0) {
1177  snext = 0.0;
1178  fStep = snext;
1179  fPoint[0] -= extra*fDirection[0];
1180  fPoint[1] -= extra*fDirection[1];
1181  fPoint[2] -= extra*fDirection[2];
1182  } else {
1183  fStep = snext+extra;
1184  }
1187  nextindex = fNextNode->GetVolume()->GetNextNodeIndex();
1188  while (nextindex>=0) {
1189  CdDown(nextindex);
1191  nextindex = fNextNode->GetVolume()->GetNextNodeIndex();
1192  if (nextindex<0) fCurrentMatrix->CopyFrom(fGlobalMatrix);
1193  }
1194  // Update global point
1195  fPoint[0] += snext*fDirection[0];
1196  fPoint[1] += snext*fDirection[1];
1197  fPoint[2] += snext*fDirection[2];
1198  fIsOnBoundary = kTRUE;
1199  fIsOutside = kFALSE;
1202  }
1203  if (snext<TGeoShape::Big()) {
1204  // New point still outside, but the top node is reachable
1206  fPoint[0] += (fStep-extra)*fDirection[0];
1207  fPoint[1] += (fStep-extra)*fDirection[1];
1208  fPoint[2] += (fStep-extra)*fDirection[2];
1209  return fNextNode;
1210  }
1211  // top node not reachable from current point/direction
1212  fNextNode = 0;
1214  return 0;
1215  }
1216  Double_t point[3],dir[3];
1217  Int_t icrossed = -2;
1218  fGlobalMatrix->MasterToLocal(fPoint, &point[0]);
1220  TGeoVolume *vol = fCurrentNode->GetVolume();
1221  // find distance to exiting current node
1222  if (idebug>4) {
1223  printf(" -> from local=(%19.16f, %19.16f, %19.16f)\n",
1224  point[0],point[1],point[2]);
1225  printf(" ldir =(%19.16f, %19.16f, %19.16f)\n",
1226  dir[0],dir[1],dir[2]);
1227  }
1228  // find distance to exiting current node
1229  snext = vol->GetShape()->DistFromInside(point, dir, iact, fStep);
1230  if (idebug>4) {
1231  printf(" exiting %s shape %s at snext=%g\n", vol->GetName(), vol->GetShape()->ClassName(),snext);
1232  }
1234  if (snext <= gTolerance) {
1235  // Current point on the boundary while track exiting
1236  snext = gTolerance;
1237  fStep = snext;
1238  fIsOnBoundary = kTRUE;
1241  skip = fCurrentNode;
1242  fPoint[0] += fStep*fDirection[0];
1243  fPoint[1] += fStep*fDirection[1];
1244  fPoint[2] += fStep*fDirection[2];
1245  is_assembly = fCurrentNode->GetVolume()->IsAssembly();
1246  if (!fLevel && !is_assembly) {
1247  fIsOutside = kTRUE;
1248  return 0;
1249  }
1250  if (fCurrentNode->IsOffset()) return CrossDivisionCell();
1251  if (fLevel) CdUp();
1252  else skip = 0;
1253  return CrossBoundaryAndLocate(kFALSE, skip);
1254  }
1255 
1256  if (snext < fStep-gTolerance) {
1257  // Currently the minimum step chosen is the exiting one
1258  icrossed = -1;
1259  fStep = snext;
1262  }
1263  // Find next daughter boundary for the current volume
1264  Int_t idaughter = -1;
1265  TGeoNode *crossed = FindNextDaughterBoundary(point,dir, idaughter, kTRUE);
1266  if (crossed) {
1268  icrossed = idaughter;
1270  }
1271  TGeoNode *current = 0;
1272  TGeoNode *dnode = 0;
1273  TGeoVolume *mother = 0;
1274  // if we are in an overlapping node, check also the mother(s)
1275  if (fNmany) {
1276  Double_t mothpt[3];
1277  Double_t vecpt[3];
1278  Double_t dpt[3], dvec[3];
1279  Int_t novlps;
1280  Int_t safelevel = GetSafeLevel();
1281  PushPath(safelevel+1);
1282  while (fCurrentOverlapping) {
1283  Int_t *ovlps = fCurrentNode->GetOverlaps(novlps);
1284  CdUp();
1285  mother = fCurrentNode->GetVolume();
1286  fGlobalMatrix->MasterToLocal(fPoint, &mothpt[0]);
1288  // check distance to out
1289  snext = TGeoShape::Big();
1290  if (!mother->IsAssembly()) snext = mother->GetShape()->DistFromInside(mothpt, vecpt, iact, fStep);
1291  if (snext<fStep-gTolerance) {
1292  // exiting mother first (extrusion)
1293  icrossed = -1;
1294  PopDummy();
1295  PushPath(safelevel+1);
1298  fStep = snext;
1301  }
1302  // check overlapping nodes
1303  for (Int_t i=0; i<novlps; i++) {
1304  current = mother->GetNode(ovlps[i]);
1305  if (!current->IsOverlapping()) {
1306  current->cd();
1307  current->MasterToLocal(&mothpt[0], &dpt[0]);
1308  current->MasterToLocalVect(&vecpt[0], &dvec[0]);
1309  snext = current->GetVolume()->GetShape()->DistFromOutside(dpt, dvec, iact, fStep);
1310  if (snext<fStep-gTolerance) {
1311  PopDummy();
1312  PushPath(safelevel+1);
1314  fCurrentMatrix->Multiply(current->GetMatrix());
1317  icrossed = ovlps[i];
1318  fStep = snext;
1319  fNextNode = current;
1320  }
1321  } else {
1322  // another many - check if point is in or out
1323  current->cd();
1324  current->MasterToLocal(&mothpt[0], &dpt[0]);
1325  current->MasterToLocalVect(&vecpt[0], &dvec[0]);
1326  if (current->GetVolume()->Contains(dpt)) {
1327  if (current->GetVolume()->GetNdaughters()) {
1328  CdDown(ovlps[i]);
1329  dnode = FindNextDaughterBoundary(dpt,dvec,idaughter,kFALSE);
1330  if (dnode) {
1332  fCurrentMatrix->Multiply(dnode->GetMatrix());
1333  icrossed = idaughter;
1334  PopDummy();
1335  PushPath(safelevel+1);
1338  fNextNode = dnode;
1339  }
1340  CdUp();
1341  }
1342  } else {
1343  snext = current->GetVolume()->GetShape()->DistFromOutside(dpt, dvec, iact, fStep);
1344  if (snext<fStep-gTolerance) {
1346  fCurrentMatrix->Multiply(current->GetMatrix());
1349  fStep = snext;
1350  fNextNode = current;
1351  icrossed = ovlps[i];
1352  PopDummy();
1353  PushPath(safelevel+1);
1354  }
1355  }
1356  }
1357  }
1358  }
1359  // Now we are in a non-overlapping node
1360  if (fNmany) {
1361  // We have overlaps up in the branch, check distance to exit
1362  Int_t up = 1;
1363  Int_t imother;
1364  Int_t nmany = fNmany;
1365  Bool_t ovlp = kFALSE;
1366  Bool_t nextovlp = kFALSE;
1367  Bool_t offset = kFALSE;
1368  TGeoNode *currentnode = fCurrentNode;
1369  TGeoNode *mothernode, *mup;
1370  TGeoHMatrix *matrix;
1371  while (nmany) {
1372  mothernode = GetMother(up);
1373  mup = mothernode;
1374  imother = up+1;
1375  offset = kFALSE;
1376  while (mup->IsOffset()) {
1377  mup = GetMother(imother++);
1378  offset = kTRUE;
1379  }
1380  nextovlp = mup->IsOverlapping();
1381  if (offset) {
1382  mothernode = mup;
1383  if (nextovlp) nmany -= imother-up;
1384  up = imother-1;
1385  } else {
1386  if (ovlp) nmany--;
1387  }
1388  if (ovlp || nextovlp) {
1389  matrix = GetMotherMatrix(up);
1390  matrix->MasterToLocal(fPoint,dpt);
1391  matrix->MasterToLocalVect(fDirection,dvec);
1392  snext = TGeoShape::Big();
1393  if (!mothernode->GetVolume()->IsAssembly()) snext = mothernode->GetVolume()->GetShape()->DistFromInside(dpt,dvec,iact,fStep);
1396  if (snext<fStep-gTolerance) {
1397  fNextNode = mothernode;
1398  fCurrentMatrix->CopyFrom(matrix);
1399  fStep = snext;
1400  while (up--) CdUp();
1401  PopDummy();
1402  PushPath();
1403  icrossed = -1;
1404  up = 1;
1405  currentnode = fCurrentNode;
1406  ovlp = currentnode->IsOverlapping();
1407  continue;
1408  }
1409  }
1410  currentnode = mothernode;
1411  ovlp = nextovlp;
1412  up++;
1413  }
1414  }
1415  PopPath();
1416  }
1417  // Compute now the distance in case we have a parallel world
1418  Double_t parstep = TGeoShape::Big();
1419  TGeoPhysicalNode *pnode = 0;
1420  if (fGeometry->IsParallelWorldNav()) {
1422  if (pnode) {
1423  // A boundary is hit at less than fPStep
1424  fStep = parstep;
1425  fPoint[0] += fStep*fDirection[0];
1426  fPoint[1] += fStep*fDirection[1];
1427  fPoint[2] += fStep*fDirection[2];
1428  fNextNode = pnode->GetNode();
1429 // icrossed = -4; //
1432  cd(pnode->GetName());
1433  nextindex = fCurrentNode->GetVolume()->GetNextNodeIndex();
1434  while (nextindex>=0) {
1435  current = fCurrentNode;
1436  CdDown(nextindex);
1437  nextindex = fCurrentNode->GetVolume()->GetNextNodeIndex();
1438  }
1439  return fCurrentNode;
1440  }
1441  }
1442  fPoint[0] += fStep*fDirection[0];
1443  fPoint[1] += fStep*fDirection[1];
1444  fPoint[2] += fStep*fDirection[2];
1445  fStep += extra;
1446  if (icrossed == -2) {
1447  // Nothing crossed within stepmax -> propagate and return same location
1449  return fCurrentNode;
1450  }
1451  fIsOnBoundary = kTRUE;
1452  if (icrossed == -1) {
1453  // Exiting current node.
1454  skip = fCurrentNode;
1455  is_assembly = fCurrentNode->GetVolume()->IsAssembly();
1456  if (!fLevel && !is_assembly) {
1457  fIsOutside = kTRUE;
1458  return 0;
1459  }
1460  if (fCurrentNode->IsOffset()) return CrossDivisionCell();
1461  if (fLevel) CdUp();
1462  else skip = 0;
1463  return CrossBoundaryAndLocate(kFALSE, skip);
1464  }
1465 
1466  CdDown(icrossed);
1467  nextindex = fCurrentNode->GetVolume()->GetNextNodeIndex();
1468  while (nextindex>=0) {
1469  current = fCurrentNode;
1470  CdDown(nextindex);
1471  nextindex = fCurrentNode->GetVolume()->GetNextNodeIndex();
1472  }
1474  return CrossBoundaryAndLocate(kTRUE, current);
1475 }
1476 
1477 ////////////////////////////////////////////////////////////////////////////////
1478 /// Returns deepest node containing current point.
1479 
1481 {
1482  fSafety = 0;
1484  fIsOutside = kFALSE;
1487  fStartSafe = safe_start;
1489  TGeoNode *last = fCurrentNode;
1490  TGeoNode *found = SearchNode();
1491  if (found != last) {
1493  } else {
1494  if (last->IsOverlapping()) fIsSameLocation = kTRUE;
1495  }
1496  return found;
1497 }
1498 
1499 ////////////////////////////////////////////////////////////////////////////////
1500 /// Returns deepest node containing current point.
1501 
1503 {
1504  fPoint[0] = x;
1505  fPoint[1] = y;
1506  fPoint[2] = z;
1507  fSafety = 0;
1509  fIsOutside = kFALSE;
1512  fStartSafe = kTRUE;
1514  TGeoNode *last = fCurrentNode;
1515  TGeoNode *found = SearchNode();
1516  if (found != last) {
1518  } else {
1519  if (last->IsOverlapping()) fIsSameLocation = kTRUE;
1520  }
1521  return found;
1522 }
1523 
1524 ////////////////////////////////////////////////////////////////////////////////
1525 /// Computes fast normal to next crossed boundary, assuming that the current point
1526 /// is close enough to the boundary. Works only after calling FindNextBoundary.
1527 
1529 {
1530  if (!fNextNode) return 0;
1531  Double_t local[3];
1532  Double_t ldir[3];
1533  Double_t lnorm[3];
1536  fNextNode->GetVolume()->GetShape()->ComputeNormal(local, ldir,lnorm);
1538  return fNormal;
1539 }
1540 
1541 ////////////////////////////////////////////////////////////////////////////////
1542 /// Computes normal vector to the next surface that will be or was already
1543 /// crossed when propagating on a straight line from a given point/direction.
1544 /// Returns the normal vector cosines in the MASTER coordinate system. The dot
1545 /// product of the normal and the current direction is positive defined.
1546 
1548 {
1549  return FindNormalFast();
1550 }
1551 
1552 ////////////////////////////////////////////////////////////////////////////////
1553 /// Initialize current point and current direction vector (normalized)
1554 /// in MARS. Return corresponding node.
1555 
1557 {
1558  SetCurrentPoint(point);
1559  SetCurrentDirection(dir);
1560  return FindNode();
1561 }
1562 
1563 ////////////////////////////////////////////////////////////////////////////////
1564 /// Initialize current point and current direction vector (normalized)
1565 /// in MARS. Return corresponding node.
1566 
1568 {
1569  SetCurrentPoint(x,y,z);
1570  SetCurrentDirection(nx,ny,nz);
1571  return FindNode();
1572 }
1573 
1574 ////////////////////////////////////////////////////////////////////////////////
1575 /// Reset current state flags.
1576 
1578 {
1580  fIsOutside = kFALSE;
1584 }
1585 
1586 ////////////////////////////////////////////////////////////////////////////////
1587 /// Compute safe distance from the current point. This represent the distance
1588 /// from POINT to the closest boundary.
1589 
1591 {
1592  if (fIsOnBoundary) {
1593  fSafety = 0;
1594  return fSafety;
1595  }
1596  Double_t point[3];
1597  Double_t safpar = TGeoShape::Big();
1598  if (!inside) fSafety = TGeoShape::Big();
1599  // Check if parallel navigation is enabled
1600  if (fGeometry->IsParallelWorldNav()) {
1601  safpar = fGeometry->GetParallelWorld()->Safety(fPoint);
1602  }
1603 
1604  if (fIsOutside) {
1606  if (fSafety < gTolerance) {
1607  fSafety = 0;
1608  fIsOnBoundary = kTRUE;
1609  return fSafety;
1610  }
1611  return TMath::Min(fSafety,safpar);
1612  }
1613  //---> convert point to local reference frame of current node
1615 
1616  //---> compute safety to current node
1617  TGeoVolume *vol = fCurrentNode->GetVolume();
1618  if (!inside) {
1619  fSafety = vol->GetShape()->Safety(point, kTRUE);
1620  //---> if we were just entering, return this safety
1621  if (fSafety < gTolerance) {
1622  fSafety = 0;
1623  fIsOnBoundary = kTRUE;
1624  return fSafety;
1625  }
1626  }
1627 
1628  //---> Check against the parallel geometry safety
1629  if (safpar < fSafety) fSafety = safpar;
1630 
1631  //---> if we were just exiting, return this safety
1632  TObjArray *nodes = vol->GetNodes();
1634  if (!nd && !fCurrentOverlapping) return fSafety;
1635  TGeoNode *node;
1636  Double_t safe;
1637  Int_t id;
1638 
1639  // if current volume is divided, we are in the non-divided region. We
1640  // check only the first and the last cell
1641  TGeoPatternFinder *finder = vol->GetFinder();
1642  if (finder) {
1643  Int_t ifirst = finder->GetDivIndex();
1644  node = (TGeoNode*)nodes->UncheckedAt(ifirst);
1645  node->cd();
1646  safe = node->Safety(point, kFALSE);
1647  if (safe < gTolerance) {
1648  fSafety=0;
1649  fIsOnBoundary = kTRUE;
1650  return fSafety;
1651  }
1652  if (safe<fSafety) fSafety=safe;
1653  Int_t ilast = ifirst+finder->GetNdiv()-1;
1654  if (ilast==ifirst) return fSafety;
1655  node = (TGeoNode*)nodes->UncheckedAt(ilast);
1656  node->cd();
1657  safe = node->Safety(point, kFALSE);
1658  if (safe < gTolerance) {
1659  fSafety=0;
1660  fIsOnBoundary = kTRUE;
1661  return fSafety;
1662  }
1663  if (safe<fSafety) fSafety=safe;
1664  if (fCurrentOverlapping && !inside) SafetyOverlaps();
1665  return fSafety;
1666  }
1667 
1668  //---> If no voxels just loop daughters
1669  TGeoVoxelFinder *voxels = vol->GetVoxels();
1670  if (!voxels) {
1671  for (id=0; id<nd; id++) {
1672  node = (TGeoNode*)nodes->UncheckedAt(id);
1673  safe = node->Safety(point, kFALSE);
1674  if (safe < gTolerance) {
1675  fSafety=0;
1676  fIsOnBoundary = kTRUE;
1677  return fSafety;
1678  }
1679  if (safe<fSafety) fSafety=safe;
1680  }
1681  if (fNmany && !inside) SafetyOverlaps();
1682  return fSafety;
1683  } else {
1684  if (voxels->NeedRebuild()) {
1685  voxels->Voxelize();
1686  vol->FindOverlaps();
1687  }
1688  }
1689 
1690  //---> check fast unsafe voxels
1691  Double_t *boxes = voxels->GetBoxes();
1692  for (id=0; id<nd; id++) {
1693  Int_t ist = 6*id;
1694  Double_t dxyz = 0.;
1695  Double_t dxyz0 = TMath::Abs(point[0]-boxes[ist+3])-boxes[ist];
1696  if (dxyz0 > fSafety) continue;
1697  Double_t dxyz1 = TMath::Abs(point[1]-boxes[ist+4])-boxes[ist+1];
1698  if (dxyz1 > fSafety) continue;
1699  Double_t dxyz2 = TMath::Abs(point[2]-boxes[ist+5])-boxes[ist+2];
1700  if (dxyz2 > fSafety) continue;
1701  if (dxyz0>0) dxyz+=dxyz0*dxyz0;
1702  if (dxyz1>0) dxyz+=dxyz1*dxyz1;
1703  if (dxyz2>0) dxyz+=dxyz2*dxyz2;
1704  if (dxyz >= fSafety*fSafety) continue;
1705  node = (TGeoNode*)nodes->UncheckedAt(id);
1706  safe = node->Safety(point, kFALSE);
1707  if (safe<gTolerance) {
1708  fSafety=0;
1709  fIsOnBoundary = kTRUE;
1710  return fSafety;
1711  }
1712  if (safe<fSafety) fSafety = safe;
1713  }
1714  if (fNmany && !inside) SafetyOverlaps();
1715  return fSafety;
1716 }
1717 
1718 ////////////////////////////////////////////////////////////////////////////////
1719 /// Compute safe distance from the current point within an overlapping node
1720 
1722 {
1723  Double_t point[3], local[3];
1724  Double_t safe;
1725  Bool_t contains;
1726  TGeoNode *nodeovlp;
1727  TGeoVolume *vol;
1728  Int_t novlp, io;
1729  Int_t *ovlp;
1730  Int_t safelevel = GetSafeLevel();
1731  PushPath(safelevel+1);
1732  while (fCurrentOverlapping) {
1733  ovlp = fCurrentNode->GetOverlaps(novlp);
1734  CdUp();
1735  vol = fCurrentNode->GetVolume();
1736  fGeometry->MasterToLocal(fPoint, point);
1737  contains = fCurrentNode->GetVolume()->Contains(point);
1738  safe = fCurrentNode->GetVolume()->GetShape()->Safety(point, contains);
1739  if (safe<fSafety && safe>=0) fSafety=safe;
1740  if (!novlp || !contains) continue;
1741  // we are now in the container, check safety to all candidates
1742  for (io=0; io<novlp; io++) {
1743  nodeovlp = vol->GetNode(ovlp[io]);
1744  nodeovlp->GetMatrix()->MasterToLocal(point,local);
1745  contains = nodeovlp->GetVolume()->Contains(local);
1746  if (contains) {
1747  CdDown(ovlp[io]);
1748  safe = Safety(kTRUE);
1749  CdUp();
1750  } else {
1751  safe = nodeovlp->GetVolume()->GetShape()->Safety(local, kFALSE);
1752  }
1753  if (safe<fSafety && safe>=0) fSafety=safe;
1754  }
1755  }
1756  if (fNmany) {
1757  // We have overlaps up in the branch, check distance to exit
1758  Int_t up = 1;
1759  Int_t imother;
1760  Int_t nmany = fNmany;
1761  Bool_t crtovlp = kFALSE;
1762  Bool_t nextovlp = kFALSE;
1763  TGeoNode *mother, *mup;
1764  TGeoHMatrix *matrix;
1765  while (nmany) {
1766  mother = GetMother(up);
1767  mup = mother;
1768  imother = up+1;
1769  while (mup->IsOffset()) mup = GetMother(imother++);
1770  nextovlp = mup->IsOverlapping();
1771  if (crtovlp) nmany--;
1772  if (crtovlp || nextovlp) {
1773  matrix = GetMotherMatrix(up);
1774  matrix->MasterToLocal(fPoint,local);
1775  safe = mother->GetVolume()->GetShape()->Safety(local,kTRUE);
1776  if (safe<fSafety) fSafety = safe;
1777  crtovlp = nextovlp;
1778  }
1779  up++;
1780  }
1781  }
1782  PopPath();
1783  if (fSafety < gTolerance) {
1784  fSafety = 0.;
1785  fIsOnBoundary = kTRUE;
1786  }
1787 }
1788 
1789 ////////////////////////////////////////////////////////////////////////////////
1790 /// Returns the deepest node containing fPoint, which must be set a priori.
1791 /// Check if parallel world navigation is enabled
1792 
1794 {
1795  if (fGeometry->IsParallelWorldNav()) {
1797  if (pnode) {
1798  // A node from the parallel world contains the point -> stop the search
1799  // and synchronize with navigation state
1800  pnode->cd();
1802  while (crtindex>=0) {
1803  // Make sure we did not end up in an assembly.
1804  CdDown(crtindex);
1805  crtindex = fCurrentNode->GetVolume()->GetCurrentNodeIndex();
1806  }
1807  return fCurrentNode;
1808  }
1809  }
1810  Double_t point[3];
1811  fNextDaughterIndex = -2;
1812  TGeoVolume *vol = 0;
1814  Bool_t inside_current = (fCurrentNode==skipnode)?kTRUE:kFALSE;
1815  if (!downwards) {
1816  // we are looking upwards until inside current node or exit
1818  // We are inside an inactive volume-> go upwards
1819  CdUp();
1821  return SearchNode(kFALSE, skipnode);
1822  }
1823  // Check if the current point is still inside the current volume
1824  vol=fCurrentNode->GetVolume();
1825  if (vol->IsAssembly()) inside_current=kTRUE;
1826  // If the current node is not to be skipped
1827  if (!inside_current) {
1829  inside_current = vol->Contains(point);
1830  }
1831  // Point might be inside an overlapping node
1832  if (fNmany) {
1833  inside_current = GotoSafeLevel();
1834  }
1835  if (!inside_current) {
1836  // If not, go upwards
1838  TGeoNode *skip = fCurrentNode; // skip current node at next search
1839  // check if we can go up
1840  if (!fLevel) {
1841  fIsOutside = kTRUE;
1842  return 0;
1843  }
1844  CdUp();
1845  return SearchNode(kFALSE, skip);
1846  }
1847  }
1848  vol = fCurrentNode->GetVolume();
1850  if (!inside_current && downwards) {
1851  // we are looking downwards
1852  if (fCurrentNode == fForcedNode) inside_current = kTRUE;
1853  else inside_current = vol->Contains(point);
1854  if (!inside_current) {
1856  return 0;
1857  } else {
1858  if (fIsOutside) {
1859  fIsOutside = kFALSE;
1861  }
1862  if (idebug>4) {
1863  printf("Search node local=(%19.16f, %19.16f, %19.16f) -> %s\n",
1864  point[0],point[1],point[2], fCurrentNode->GetName());
1865  }
1866  }
1867  }
1868  // point inside current (safe) node -> search downwards
1869  TGeoNode *node;
1870  Int_t ncheck = 0;
1871  // if inside an non-overlapping node, reset overlap searches
1872  if (!fCurrentOverlapping) {
1874  }
1875 
1876  Int_t crtindex = vol->GetCurrentNodeIndex();
1877  while (crtindex>=0 && downwards) {
1878  // Make sure we did not end up in an assembly.
1879  CdDown(crtindex);
1880  vol = fCurrentNode->GetVolume();
1881  crtindex = vol->GetCurrentNodeIndex();
1882  if (crtindex<0) fGlobalMatrix->MasterToLocal(fPoint, point);
1883  }
1884 
1885  Int_t nd = vol->GetNdaughters();
1886  // in case there are no daughters
1887  if (!nd) return fCurrentNode;
1888  if (fGeometry->IsActivityEnabled() && !vol->IsActiveDaughters()) return fCurrentNode;
1889 
1890  TGeoPatternFinder *finder = vol->GetFinder();
1891  // point is inside the current node
1892  // first check if inside a division
1893  if (finder) {
1894  node=finder->FindNode(point);
1895  if (!node && fForcedNode) {
1896  // Point *HAS* to be inside a cell
1897  Double_t dir[3];
1899  finder->FindNode(point,dir);
1900  node = finder->CdNext();
1901  if (!node) return fCurrentNode; // inside divided volume but not in a cell
1902  }
1903  if (node && node!=skipnode) {
1904  // go inside the division cell and search downwards
1906  CdDown(node->GetIndex());
1907  fForcedNode = 0;
1908  return SearchNode(kTRUE, node);
1909  }
1910  // point is not inside the division, but might be in other nodes
1911  // at the same level (NOT SUPPORTED YET)
1912  while (fCurrentNode && fCurrentNode->IsOffset()) CdUp();
1913  return fCurrentNode;
1914  }
1915  // second, look if current volume is voxelized
1916  TGeoVoxelFinder *voxels = vol->GetVoxels();
1917  Int_t *check_list = 0;
1918  Int_t id;
1919  if (voxels) {
1920  // get the list of nodes passing thorough the current voxel
1921  check_list = voxels->GetCheckList(&point[0], ncheck, *fCache->GetInfo());
1922  // if none in voxel, see if this is the last one
1923  if (!check_list) {
1924  if (!fCurrentNode->GetVolume()->IsAssembly()) {
1925  fCache->ReleaseInfo();
1926  return fCurrentNode;
1927  }
1928  // Point in assembly - go up
1929  node = fCurrentNode;
1930  if (!fLevel) {
1931  fIsOutside = kTRUE;
1932  fCache->ReleaseInfo();
1933  return 0;
1934  }
1935  CdUp();
1936  fCache->ReleaseInfo();
1937  return SearchNode(kFALSE,node);
1938  }
1939  // loop all nodes in voxel
1940  for (id=0; id<ncheck; id++) {
1941  node = vol->GetNode(check_list[id]);
1942  if (node==skipnode) continue;
1943  if (fGeometry->IsActivityEnabled() && !node->GetVolume()->IsActive()) continue;
1944  if ((id<(ncheck-1)) && node->IsOverlapping()) {
1945  // make the cluster of overlaps
1946  if (ncheck+fOverlapMark > fOverlapSize) {
1947  fOverlapSize = 2*(ncheck+fOverlapMark);
1948  delete [] fOverlapClusters;
1950  }
1951  Int_t *cluster = fOverlapClusters + fOverlapMark;
1952  Int_t nc = GetTouchedCluster(id, &point[0], check_list, ncheck, cluster);
1953  if (nc>1) {
1954  fOverlapMark += nc;
1955  node = FindInCluster(cluster, nc);
1956  fOverlapMark -= nc;
1957  fCache->ReleaseInfo();
1958  return node;
1959  }
1960  }
1961  CdDown(check_list[id]);
1962  fForcedNode = 0;
1963  node = SearchNode(kTRUE);
1964  if (node) {
1966  fCache->ReleaseInfo();
1967  return node;
1968  }
1969  CdUp();
1970  }
1971  if (!fCurrentNode->GetVolume()->IsAssembly()) {
1972  fCache->ReleaseInfo();
1973  return fCurrentNode;
1974  }
1975  node = fCurrentNode;
1976  if (!fLevel) {
1977  fIsOutside = kTRUE;
1978  fCache->ReleaseInfo();
1979  return 0;
1980  }
1981  CdUp();
1982  fCache->ReleaseInfo();
1983  return SearchNode(kFALSE,node);
1984  }
1985  // if there are no voxels just loop all daughters
1986  for (id=0; id<nd; id++) {
1987  node=fCurrentNode->GetDaughter(id);
1988  if (node==skipnode) continue;
1989  if (fGeometry->IsActivityEnabled() && !node->GetVolume()->IsActive()) continue;
1990  CdDown(id);
1991  fForcedNode = 0;
1992  node = SearchNode(kTRUE);
1993  if (node) {
1995  return node;
1996  }
1997  CdUp();
1998  }
1999  // point is not inside one of the daughters, so it is in the current vol
2000  if (fCurrentNode->GetVolume()->IsAssembly()) {
2001  node = fCurrentNode;
2002  if (!fLevel) {
2003  fIsOutside = kTRUE;
2004  return 0;
2005  }
2006  CdUp();
2007  return SearchNode(kFALSE,node);
2008  }
2009  return fCurrentNode;
2010 }
2011 
2012 ////////////////////////////////////////////////////////////////////////////////
2013 /// Find a node inside a cluster of overlapping nodes. Current node must
2014 /// be on top of all the nodes in cluster. Always nc>1.
2015 
2017 {
2018  TGeoNode *clnode = 0;
2019  TGeoNode *priority = fLastNode;
2020  // save current node
2021  TGeoNode *current = fCurrentNode;
2022  TGeoNode *found = 0;
2023  // save path
2024  Int_t ipop = PushPath();
2025  // mark this search
2027  Int_t deepest = fLevel;
2028  Int_t deepest_virtual = fLevel-GetVirtualLevel();
2029  Int_t found_virtual = 0;
2030  Bool_t replace = kFALSE;
2031  Bool_t added = kFALSE;
2032  Int_t i;
2033  for (i=0; i<nc; i++) {
2034  clnode = current->GetDaughter(cluster[i]);
2035  CdDown(cluster[i]);
2036  Bool_t max_priority = (clnode==fNextNode)?kTRUE:kFALSE;
2037  found = SearchNode(kTRUE, clnode);
2038  if (!fSearchOverlaps || max_priority) {
2039  // an only was found during the search -> exiting
2040  // The node given by FindNextBoundary returned -> exiting
2041  PopDummy(ipop);
2042  return found;
2043  }
2044  found_virtual = fLevel-GetVirtualLevel();
2045  if (added) {
2046  // we have put something in stack -> check it
2047  if (found_virtual>deepest_virtual) {
2048  replace = kTRUE;
2049  } else {
2050  if (found_virtual==deepest_virtual) {
2051  if (fLevel>deepest) {
2052  replace = kTRUE;
2053  } else {
2054  if ((fLevel==deepest) && (clnode==priority)) replace=kTRUE;
2055  else replace = kFALSE;
2056  }
2057  } else replace = kFALSE;
2058  }
2059  // if this was the last checked node
2060  if (i==(nc-1)) {
2061  if (replace) {
2062  PopDummy(ipop);
2063  return found;
2064  } else {
2066  PopDummy(ipop);
2067  return fCurrentNode;
2068  }
2069  }
2070  // we still have to go on
2071  if (replace) {
2072  // reset stack
2073  PopDummy();
2074  PushPath();
2075  deepest = fLevel;
2076  deepest_virtual = found_virtual;
2077  }
2078  // restore top of cluster
2079  fCurrentOverlapping = PopPath(ipop);
2080  } else {
2081  // the stack was clean, push new one
2082  PushPath();
2083  added = kTRUE;
2084  deepest = fLevel;
2085  deepest_virtual = found_virtual;
2086  // restore original path
2087  fCurrentOverlapping = PopPath(ipop);
2088  }
2089  }
2090  PopDummy(ipop);
2091  return fCurrentNode;
2092 }
2093 
2094 ////////////////////////////////////////////////////////////////////////////////
2095 /// Make the cluster of overlapping nodes in a voxel, containing point in reference
2096 /// of the mother. Returns number of nodes containing the point. Nodes should not be
2097 /// offsets.
2098 
2100  Int_t *check_list, Int_t ncheck, Int_t *result)
2101 {
2102  // we are in the mother reference system
2103  TGeoNode *current = fCurrentNode->GetDaughter(check_list[start]);
2104  Int_t novlps = 0;
2105  Int_t *ovlps = current->GetOverlaps(novlps);
2106  if (!ovlps) return 0;
2107  Double_t local[3];
2108  // intersect check list with overlap list
2109  Int_t ntotal = 0;
2110  current->MasterToLocal(point, &local[0]);
2111  if (current->GetVolume()->Contains(&local[0])) {
2112  result[ntotal++]=check_list[start];
2113  }
2114 
2115  Int_t jst=0, i, j;
2116  while ((jst<novlps) && (ovlps[jst]<=check_list[start])) jst++;
2117  if (jst==novlps) return 0;
2118  for (i=start; i<ncheck; i++) {
2119  for (j=jst; j<novlps; j++) {
2120  if (check_list[i]==ovlps[j]) {
2121  // overlapping node in voxel -> check if touched
2122  current = fCurrentNode->GetDaughter(check_list[i]);
2123  if (fGeometry->IsActivityEnabled() && !current->GetVolume()->IsActive()) continue;
2124  current->MasterToLocal(point, &local[0]);
2125  if (current->GetVolume()->Contains(&local[0])) {
2126  result[ntotal++]=check_list[i];
2127  }
2128  }
2129  }
2130  }
2131  return ntotal;
2132 }
2133 
2134 ////////////////////////////////////////////////////////////////////////////////
2135 /// Make a rectiliniar step of length fStep from current point (fPoint) on current
2136 /// direction (fDirection). If the step is imposed by geometry, is_geom flag
2137 /// must be true (default). The cross flag specifies if the boundary should be
2138 /// crossed in case of a geometry step (default true). Returns new node after step.
2139 /// Set also on boundary condition.
2140 
2142 {
2143  Double_t epsil = 0;
2144  if (fStep<1E-6) {
2146  if (fStep<0) fStep = 0.;
2147  } else {
2149  }
2150  if (is_geom) epsil=(cross)?1E-6:-1E-6;
2151  TGeoNode *old = fCurrentNode;
2152  Int_t idold = GetNodeId();
2153  if (fIsOutside) old = 0;
2154  fStep += epsil;
2155  for (Int_t i=0; i<3; i++) fPoint[i]+=fStep*fDirection[i];
2156  TGeoNode *current = FindNode();
2157  if (is_geom) {
2158  fIsEntering = (current==old)?kFALSE:kTRUE;
2159  if (!fIsEntering) {
2160  Int_t id = GetNodeId();
2161  fIsEntering = (id==idold)?kFALSE:kTRUE;
2162  }
2165  fIsOnBoundary = kTRUE;
2166  } else {
2169  }
2170  return current;
2171 }
2172 
2173 ////////////////////////////////////////////////////////////////////////////////
2174 /// Find level of virtuality of current overlapping node (number of levels
2175 /// up having the same tracking media.
2176 
2178 {
2179  // return if the current node is ONLY
2180  if (!fCurrentOverlapping) return 0;
2181  Int_t new_media = 0;
2182  TGeoMedium *medium = fCurrentNode->GetMedium();
2183  Int_t virtual_level = 1;
2184  TGeoNode *mother = 0;
2185 
2186  while ((mother=GetMother(virtual_level))) {
2187  if (!mother->IsOverlapping() && !mother->IsOffset()) {
2188  if (!new_media) new_media=(mother->GetMedium()==medium)?0:virtual_level;
2189  break;
2190  }
2191  if (!new_media) new_media=(mother->GetMedium()==medium)?0:virtual_level;
2192  virtual_level++;
2193  }
2194  return (new_media==0)?virtual_level:(new_media-1);
2195 }
2196 
2197 ////////////////////////////////////////////////////////////////////////////////
2198 /// Go upwards the tree until a non-overlapping node
2199 
2201 {
2202  while (fCurrentOverlapping && fLevel) CdUp();
2203  Double_t point[3];
2205  if (!fCurrentNode->GetVolume()->Contains(point)) return kFALSE;
2206  if (fNmany) {
2207  // We still have overlaps on the branch
2208  Int_t up = 1;
2209  Int_t imother;
2210  Int_t nmany = fNmany;
2211  Bool_t ovlp = kFALSE;
2212  Bool_t nextovlp = kFALSE;
2213  TGeoNode *mother, *mup;
2214  TGeoHMatrix *matrix;
2215  while (nmany) {
2216  mother = GetMother(up);
2217  if (!mother) return kTRUE;
2218  mup = mother;
2219  imother = up+1;
2220  while (mup->IsOffset()) mup = GetMother(imother++);
2221  nextovlp = mup->IsOverlapping();
2222  if (ovlp) nmany--;
2223  if (ovlp || nextovlp) {
2224  // check if the point is in the next node up
2225  matrix = GetMotherMatrix(up);
2226  matrix->MasterToLocal(fPoint,point);
2227  if (!mother->GetVolume()->Contains(point)) {
2228  up++;
2229  while (up--) CdUp();
2230  return GotoSafeLevel();
2231  }
2232  }
2233  ovlp = nextovlp;
2234  up++;
2235  }
2236  }
2237  return kTRUE;
2238 }
2239 
2240 ////////////////////////////////////////////////////////////////////////////////
2241 /// Go upwards the tree until a non-overlapping node
2242 
2244 {
2245  Bool_t overlapping = fCurrentOverlapping;
2246  if (!overlapping) return fLevel;
2247  Int_t level = fLevel;
2248  TGeoNode *node;
2249  while (overlapping && level) {
2250  level--;
2251  node = GetMother(fLevel-level);
2252  if (!node->IsOffset()) overlapping = node->IsOverlapping();
2253  }
2254  return level;
2255 }
2256 
2257 ////////////////////////////////////////////////////////////////////////////////
2258 /// Inspects path and all flags for the current state.
2259 
2261 {
2262  Info("InspectState","Current path is: %s",GetPath());
2263  Int_t level;
2264  TGeoNode *node;
2265  Bool_t is_offset, is_overlapping;
2266  for (level=0; level<fLevel+1; level++) {
2267  node = GetMother(fLevel-level);
2268  if (!node) continue;
2269  is_offset = node->IsOffset();
2270  is_overlapping = node->IsOverlapping();
2271  Info("InspectState","level %i: %s div=%i many=%i",level,node->GetName(),is_offset,is_overlapping);
2272  }
2273  Info("InspectState","on_bound=%i entering=%i", fIsOnBoundary, fIsEntering);
2274 }
2275 
2276 ////////////////////////////////////////////////////////////////////////////////
2277 /// Checks if point (x,y,z) is still in the current node.
2278 /// check if this is an overlapping node
2279 
2281 {
2282  Double_t oldpt[3];
2283  if (fLastSafety>0) {
2284  Double_t dx = (x-fLastPoint[0]);
2285  Double_t dy = (y-fLastPoint[1]);
2286  Double_t dz = (z-fLastPoint[2]);
2287  Double_t dsq = dx*dx+dy*dy+dz*dz;
2288  if (dsq<fLastSafety*fLastSafety) {
2289  if (change) {
2290  fPoint[0] = x;
2291  fPoint[1] = y;
2292  fPoint[2] = z;
2293  memcpy(fLastPoint, fPoint, 3*sizeof(Double_t));
2294  fLastSafety -= TMath::Sqrt(dsq);
2295  }
2296  return kTRUE;
2297  }
2298  if (change) fLastSafety = 0;
2299  }
2300  if (fCurrentOverlapping) {
2301 // TGeoNode *current = fCurrentNode;
2302  Int_t cid = GetCurrentNodeId();
2303  if (!change) PushPoint();
2304  memcpy(oldpt, fPoint, kN3);
2305  SetCurrentPoint(x,y,z);
2306  SearchNode();
2307  memcpy(fPoint, oldpt, kN3);
2308  Bool_t same = (cid==GetCurrentNodeId())?kTRUE:kFALSE;
2309  if (!change) PopPoint();
2310  return same;
2311  }
2312 
2313  Double_t point[3];
2314  point[0] = x;
2315  point[1] = y;
2316  point[2] = z;
2317  if (change) memcpy(fPoint, point, kN3);
2318  TGeoVolume *vol = fCurrentNode->GetVolume();
2319  if (fIsOutside) {
2320  if (vol->GetShape()->Contains(point)) {
2321  if (!change) return kFALSE;
2322  FindNode(x,y,z);
2323  return kFALSE;
2324  }
2325  return kTRUE;
2326  }
2327  Double_t local[3];
2328  // convert to local frame
2329  fGlobalMatrix->MasterToLocal(point,local);
2330  // check if still in current volume.
2331  if (!vol->GetShape()->Contains(local)) {
2332  if (!change) return kFALSE;
2333  CdUp();
2334  FindNode(x,y,z);
2335  return kFALSE;
2336  }
2337 
2338  // Check if the point is in a parallel world volume
2339  if (fGeometry->IsParallelWorldNav()) {
2341  if (pnode) {
2342  if (!change) return kFALSE;
2343  pnode->cd();
2345  while (crtindex>=0) {
2346  // Make sure we did not end up in an assembly.
2347  CdDown(crtindex);
2348  crtindex = fCurrentNode->GetVolume()->GetCurrentNodeIndex();
2349  }
2350  return kFALSE;
2351  }
2352  }
2353  // check if there are daughters
2354  Int_t nd = vol->GetNdaughters();
2355  if (!nd) return kTRUE;
2356 
2357  TGeoNode *node;
2358  TGeoPatternFinder *finder = vol->GetFinder();
2359  if (finder) {
2360  node=finder->FindNode(local);
2361  if (node) {
2362  if (!change) return kFALSE;
2363  CdDown(node->GetIndex());
2364  SearchNode(kTRUE,node);
2365  return kFALSE;
2366  }
2367  return kTRUE;
2368  }
2369  // if we are not allowed to do changes, save the current path
2370  TGeoVoxelFinder *voxels = vol->GetVoxels();
2371  Int_t *check_list = 0;
2372  Int_t ncheck = 0;
2373  Double_t local1[3];
2374  if (voxels) {
2375  check_list = voxels->GetCheckList(local, ncheck, *fCache->GetInfo());
2376  if (!check_list) {
2377  fCache->ReleaseInfo();
2378  return kTRUE;
2379  }
2380  if (!change) PushPath();
2381  for (Int_t id=0; id<ncheck; id++) {
2382 // node = vol->GetNode(check_list[id]);
2383  CdDown(check_list[id]);
2384  fGlobalMatrix->MasterToLocal(point,local1);
2385  if (fCurrentNode->GetVolume()->GetShape()->Contains(local1)) {
2386  if (!change) {
2387  PopPath();
2388  fCache->ReleaseInfo();
2389  return kFALSE;
2390  }
2391  SearchNode(kTRUE);
2392  fCache->ReleaseInfo();
2393  return kFALSE;
2394  }
2395  CdUp();
2396  }
2397  if (!change) PopPath();
2398  fCache->ReleaseInfo();
2399  return kTRUE;
2400  }
2401  Int_t id = 0;
2402  if (!change) PushPath();
2403  while (fCurrentNode && fCurrentNode->GetDaughter(id++)) {
2404  CdDown(id-1);
2405  fGlobalMatrix->MasterToLocal(point,local1);
2406  if (fCurrentNode->GetVolume()->GetShape()->Contains(local1)) {
2407  if (!change) {
2408  PopPath();
2409  return kFALSE;
2410  }
2411  SearchNode(kTRUE);
2412  return kFALSE;
2413  }
2414  CdUp();
2415  if (id == nd) {
2416  if (!change) PopPath();
2417  return kTRUE;
2418  }
2419  }
2420  if (!change) PopPath();
2421  return kTRUE;
2422 }
2423 
2424 ////////////////////////////////////////////////////////////////////////////////
2425 /// In case a previous safety value was computed, check if the safety region is
2426 /// still safe for the current point and proposed step. Return value changed only
2427 /// if proposed distance is safe.
2428 
2430 {
2431  // Last safety not computed.
2432  if (fLastSafety < gTolerance) return kFALSE;
2433  // Proposed step too small
2434  if (proposed < gTolerance) {
2435  newsafety = fLastSafety - proposed;
2436  return kTRUE;
2437  }
2438  // Normal step
2439  Double_t dist = (fPoint[0]-fLastPoint[0])*(fPoint[0]-fLastPoint[0])+
2440  (fPoint[1]-fLastPoint[1])*(fPoint[1]-fLastPoint[1])+
2441  (fPoint[2]-fLastPoint[2])*(fPoint[2]-fLastPoint[2]);
2442  dist = TMath::Sqrt(dist);
2443  Double_t safe = fLastSafety - dist;
2444  if (safe < proposed) return kFALSE;
2445  newsafety = safe;
2446  return kTRUE;
2447 }
2448 
2449 ////////////////////////////////////////////////////////////////////////////////
2450 /// Check if a new point with given coordinates is the same as the last located one.
2451 
2453 {
2454  if (TMath::Abs(x-fLastPoint[0]) < 1.E-20) {
2455  if (TMath::Abs(y-fLastPoint[1]) < 1.E-20) {
2456  if (TMath::Abs(z-fLastPoint[2]) < 1.E-20) return kTRUE;
2457  }
2458  }
2459  return kFALSE;
2460 }
2461 
2462 ////////////////////////////////////////////////////////////////////////////////
2463 /// Backup the current state without affecting the cache stack.
2464 
2466 {
2468 }
2469 
2470 ////////////////////////////////////////////////////////////////////////////////
2471 /// Restore a backed-up state without affecting the cache stack.
2472 
2474 {
2475  if (fBackupState && fCache) {
2479  fLevel=fCache->GetLevel();
2480  }
2481 }
2482 
2483 ////////////////////////////////////////////////////////////////////////////////
2484 /// Return stored current matrix (global matrix of the next touched node).
2485 
2487 {
2488  if (!fCurrentMatrix) {
2489  fCurrentMatrix = new TGeoHMatrix();
2491  }
2492  return fCurrentMatrix;
2493 }
2494 
2495 ////////////////////////////////////////////////////////////////////////////////
2496 /// Get path to the current node in the form /node0/node1/...
2497 
2498 const char *TGeoNavigator::GetPath() const
2499 {
2500  if (fIsOutside) return kGeoOutsidePath;
2501  return fCache->GetPath();
2502 }
2503 
2504 ////////////////////////////////////////////////////////////////////////////////
2505 /// Convert coordinates from master volume frame to top.
2506 
2507 void TGeoNavigator::MasterToTop(const Double_t *master, Double_t *top) const
2508 {
2509  fCurrentMatrix->MasterToLocal(master, top);
2510 }
2511 
2512 ////////////////////////////////////////////////////////////////////////////////
2513 /// Convert coordinates from top volume frame to master.
2514 
2515 void TGeoNavigator::TopToMaster(const Double_t *top, Double_t *master) const
2516 {
2517  fCurrentMatrix->LocalToMaster(top, master);
2518 }
2519 
2520 ////////////////////////////////////////////////////////////////////////////////
2521 /// Reset the navigator.
2522 
2524 {
2525  GetHMatrix();
2528  ResetState();
2529  fStep = 0.;
2530  fSafety = 0.;
2531  fLastSafety = 0.;
2532  fLevel = 0;
2533  fNmany = 0;
2534  fNextDaughterIndex = -2;
2536  fStartSafe = kFALSE;
2538  fIsNullStep = kFALSE;
2541  fLastNode = 0;
2542  fNextNode = 0;
2543  fPath = "";
2544  if (fCache) {
2545  Bool_t dummy=fCache->IsDummy();
2546  Bool_t nodeid = fCache->HasIdArray();
2547  delete fCache;
2548  fCache = nullptr;
2549  delete fBackupState;
2550  fBackupState = nullptr;
2551  BuildCache(dummy,nodeid);
2552  }
2553 }
2554 
2556 
2557 ////////////////////////////////////////////////////////////////////////////////
2558 /// Add a new navigator to the array.
2559 
2561 {
2562  SetOwner(kTRUE);
2564  nav->BuildCache(kTRUE, kFALSE);
2565  Add(nav);
2567  return nav;
2568 }
TGeoNavigator::Safety
Double_t Safety(Bool_t inside=kFALSE)
Compute safe distance from the current point.
Definition: TGeoNavigator.cxx:1590
TGeoNodeCache::GetBranchOnlys
void GetBranchOnlys(Int_t *isonly) const
Fill copy numbers of current branch nodes.
Definition: TGeoCache.cxx:307
TGeoNavigatorArray::AddNavigator
TGeoNavigator * AddNavigator()
Add a new navigator to the array.
Definition: TGeoNavigator.cxx:2560
TGeoNavigator::fCurrentVolume
TGeoVolume * fCurrentVolume
cache of states
Definition: TGeoNavigator.h:75
TGeoNodeCache::CdNode
void CdNode(Int_t nodeid)
Change current path to point to the node having this id.
Definition: TGeoCache.cxx:165
TGeoPatternFinder::CdNext
virtual TGeoNode * CdNext()
Make next node (if any) current.
Definition: TGeoPatternFinder.cxx:212
TGeoMatrix::MasterToLocalVect
virtual void MasterToLocalVect(const Double_t *master, Double_t *local) const
convert a point by multiplying its column vector (x, y, z, 1) to matrix
Definition: TGeoMatrix.cxx:431
TGeoNavigator::fSafety
Double_t fSafety
step to be done from current point and direction
Definition: TGeoNavigator.h:47
first
Definition: first.py:1
TGeoNavigator::FindNormal
Double_t * FindNormal(Bool_t forward=kTRUE)
Computes normal vector to the next surface that will be or was already crossed when propagating on a ...
Definition: TGeoNavigator.cxx:1547
TGeoHMatrix::Multiply
void Multiply(const TGeoMatrix *right)
multiply to the right with an other transformation if right is identity matrix, just return
Definition: TGeoMatrix.cxx:2510
kTRUE
const Bool_t kTRUE
Definition: RtypesCore.h:100
TGeoPhysicalNode
Physical nodes are the actual 'touchable' objects in the geometry, representing a path of positioned ...
Definition: TGeoPhysicalNode.h:37
TGeoVoxelFinder::GetCheckList
virtual Int_t * GetCheckList(const Double_t *point, Int_t &nelem, TGeoStateInfo &td)
get the list of daughter indices for which point is inside their bbox
Definition: TGeoVoxelFinder.cxx:1205
TGeoManager::GetTopVolume
TGeoVolume * GetTopVolume() const
Definition: TGeoManager.h:532
gGeoIdentity
R__EXTERN TGeoIdentity * gGeoIdentity
Definition: TGeoMatrix.h:478
TGeoVolume::GetShape
TGeoShape * GetShape() const
Definition: TGeoVolume.h:188
TObjArray
An array of TObjects.
Definition: TObjArray.h:37
TGeoNodeCache::HasIdArray
Bool_t HasIdArray() const
Definition: TGeoCache.h:116
TGeoNavigator::fOverlapClusters
Int_t * fOverlapClusters
current recursive position in fOverlapClusters
Definition: TGeoNavigator.h:61
TGeoPatternFinder::GetNdiv
Int_t GetNdiv() const
Definition: TGeoPatternFinder.h:86
TGeoVolume::GetFinder
TGeoPatternFinder * GetFinder() const
Definition: TGeoVolume.h:175
TGeoManager::ThreadId
static Int_t ThreadId()
Translates the current thread id to an ordinal number.
Definition: TGeoManager.cxx:905
TGeoNavigator::IsSafeStep
Bool_t IsSafeStep(Double_t proposed, Double_t &newsafety) const
In case a previous safety value was computed, check if the safety region is still safe for the curren...
Definition: TGeoNavigator.cxx:2429
TGeoNavigator::GetBranchNames
void GetBranchNames(Int_t *names) const
Fill volume names of current branch into an array.
Definition: TGeoNavigator.cxx:411
TGeoNavigator::GetBranchOnlys
void GetBranchOnlys(Int_t *isonly) const
Fill node copy numbers of current branch into an array.
Definition: TGeoNavigator.cxx:427
TGeoNavigator::GetHMatrix
TGeoHMatrix * GetHMatrix()
Return stored current matrix (global matrix of the next touched node).
Definition: TGeoNavigator.cxx:2486
TGeoVolume::GetNdaughters
Int_t GetNdaughters() const
Definition: TGeoVolume.h:349
TGeoNavigator::fIsStepExiting
Bool_t fIsStepExiting
flag that next geometric step will enter new volume
Definition: TGeoNavigator.h:68
TGeoShape::DistFromOutside
virtual Double_t DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=0) const =0
TGeoNavigator::fIsOutside
Bool_t fIsOutside
flag that next geometric step will exit current volume
Definition: TGeoNavigator.h:69
TGeoNavigator::fDivMatrix
TGeoHMatrix * fDivMatrix
current pointer to cached global matrix
Definition: TGeoNavigator.h:84
TGeoManager::GetCurrentNode
TGeoNode * GetCurrentNode() const
Definition: TGeoManager.h:519
TGeoVolume::IsActiveDaughters
Bool_t IsActiveDaughters() const
Definition: TGeoVolume.h:144
TGeoNavigator::FindInCluster
TGeoNode * FindInCluster(Int_t *cluster, Int_t nc)
Find a node inside a cluster of overlapping nodes.
Definition: TGeoNavigator.cxx:2016
TGeoNode::GetMedium
TGeoMedium * GetMedium() const
Definition: TGeoNode.h:91
TGeoVoxelFinder::IsSafeVoxel
Bool_t IsSafeVoxel(const Double_t *point, Int_t inode, Double_t minsafe) const
Computes squared distance from POINT to the voxel(s) containing node INODE.
Definition: TGeoVoxelFinder.cxx:227
ClassImp
#define ClassImp(name)
Definition: Rtypes.h:364
TGeoNavigator::fIsExiting
Bool_t fIsExiting
flag if current step just got into a new node
Definition: TGeoNavigator.h:66
TGeoPhysicalNode::cd
void cd() const
Definition: TGeoPhysicalNode.cxx:343
TGeoManager::IsActivityEnabled
Bool_t IsActivityEnabled() const
Definition: TGeoManager.h:431
TGeoNavigatorArray
Definition: TGeoNavigator.h:217
TObject::Info
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:867
TObject::Error
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:893
TGeoHMatrix::GetTranslation
virtual const Double_t * GetTranslation() const
Definition: TGeoMatrix.h:467
TGeoNavigator::CdTop
void CdTop()
Make top level node the current node.
Definition: TGeoNavigator.cxx:366
TGeoNavigator::IsSameLocation
Bool_t IsSameLocation() const
Definition: TGeoNavigator.h:132
TMath::Sqrt
Double_t Sqrt(Double_t x)
Definition: TMath.h:691
TGeoVolume::GetIndex
Int_t GetIndex(const TGeoNode *node) const
get index number for a given daughter
Definition: TGeoVolume.cxx:1633
TCollection::SetOwner
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
Definition: TCollection.cxx:746
TGeoNode::GetVolume
TGeoVolume * GetVolume() const
Definition: TGeoNode.h:97
TGeoNavigator::CdNode
void CdNode(Int_t nodeid)
Change current path to point to the node having this id.
Definition: TGeoNavigator.cxx:284
TGeoVolume::InspectShape
void InspectShape() const
Definition: TGeoVolume.h:193
TGeoNavigator::BuildCache
void BuildCache(Bool_t dummy=kFALSE, Bool_t nodeid=kFALSE)
Builds the cache for physical nodes and global matrices.
Definition: TGeoNavigator.cxx:175
TGeoNavigator::PopPath
Bool_t PopPath()
Definition: TGeoNavigator.h:197
TObject::Fatal
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition: TObject.cxx:921
TGeoVoxelFinder::GetNextVoxel
virtual Int_t * GetNextVoxel(const Double_t *point, const Double_t *dir, Int_t &ncheck, TGeoStateInfo &td)
get the list of new candidates for the next voxel crossed by current ray printf("### GetNextVoxel\n")...
Definition: TGeoVoxelFinder.cxx:1366
TGeoNodeCache::CdDown
Bool_t CdDown(Int_t index)
Make daughter INDEX of current node the active state. Compute global matrix.
Definition: TGeoCache.cxx:202
TGeoPhysicalNode::GetNode
TGeoNode * GetNode(Int_t level=-1) const
Return node in branch at LEVEL. If not specified, return last leaf.
Definition: TGeoPhysicalNode.cxx:379
TGeoNode::GetFinder
virtual TGeoPatternFinder * GetFinder() const
Definition: TGeoNode.h:90
Int_t
int Int_t
Definition: RtypesCore.h:45
TGeoNavigator::fCurrentNode
TGeoNode * fCurrentNode
current volume
Definition: TGeoNavigator.h:76
TGeoVolume.h
TGeoManager::IsParallelWorldNav
Bool_t IsParallelWorldNav() const
Definition: TGeoManager.h:597
TGeoNavigator::GetPath
const char * GetPath() const
Get path to the current node in the form /node0/node1/...
Definition: TGeoNavigator.cxx:2498
TGeoNavigator::fBackupState
TGeoCacheState * fBackupState
current point is supposed to be inside this node
Definition: TGeoNavigator.h:81
TGeoNavigator::CrossDivisionCell
TGeoNode * CrossDivisionCell()
Cross a division cell.
Definition: TGeoNavigator.cxx:436
x
Double_t x[n]
Definition: legend1.C:17
TString::Length
Ssiz_t Length() const
Definition: TString.h:410
TGeoPhysicalNode.h
TGeoNavigator::GetVirtualLevel
Int_t GetVirtualLevel()
Find level of virtuality of current overlapping node (number of levels up having the same tracking me...
Definition: TGeoNavigator.cxx:2177
TGeoNavigator::GetTouchedCluster
Int_t GetTouchedCluster(Int_t start, Double_t *point, Int_t *check_list, Int_t ncheck, Int_t *result)
Make the cluster of overlapping nodes in a voxel, containing point in reference of the mother.
Definition: TGeoNavigator.cxx:2099
TGeoNavigatorArray::SetCurrentNavigator
TGeoNavigator * SetCurrentNavigator(Int_t inav)
Definition: TGeoNavigator.h:232
TGeoNode::IsOffset
Bool_t IsOffset() const
Definition: TGeoNode.h:103
TGeoParallelWorld::FindNode
TGeoPhysicalNode * FindNode(Double_t point[3])
Finds physical node containing the point.
Definition: TGeoParallelWorld.cxx:182
TGeoNavigator::PopDummy
void PopDummy(Int_t ipop=9999)
Definition: TGeoNavigator.h:202
TGeoCacheState
Class storing the state of the cache at a given moment.
Definition: TGeoCache.h:29
TGeoNavigator::CdDown
void CdDown(Int_t index)
Make a daughter of current node current.
Definition: TGeoNavigator.cxx:296
TMath::Abs
Short_t Abs(Short_t d)
Definition: TMathBase.h:120
TGeoNodeCache
Special pool of reusable nodes.
Definition: TGeoCache.h:58
TGeoNavigator::fIsNullStep
Bool_t fIsNullStep
flag that a new point is in the same node as previous
Definition: TGeoNavigator.h:72
TObjArray::UncheckedAt
TObject * UncheckedAt(Int_t i) const
Definition: TObjArray.h:90
TGeoVolume::Contains
Bool_t Contains(const Double_t *point) const
Definition: TGeoVolume.h:109
TGeoNodeCache::RestoreState
Bool_t RestoreState(Int_t &nmany, TGeoCacheState *state, Double_t *point=0)
Pop next state/point from a backed-up state.
Definition: TGeoCache.cxx:393
TGeoNode::MasterToLocal
virtual void MasterToLocal(const Double_t *master, Double_t *local) const
Convert the point coordinates from mother reference to local reference system.
Definition: TGeoNode.cxx:518
TString
Basic string class.
Definition: TString.h:136
TGeoNode::IsOverlapping
Bool_t IsOverlapping() const
Definition: TGeoNode.h:105
TGeoNavigator::GotoSafeLevel
Bool_t GotoSafeLevel()
Go upwards the tree until a non-overlapping node.
Definition: TGeoNavigator.cxx:2200
TGeoNode::GetMatrix
virtual TGeoMatrix * GetMatrix() const =0
TGeoNode::cd
virtual void cd() const
Definition: TGeoNode.h:73
TGeoNodeCache::GetBranchNumbers
void GetBranchNumbers(Int_t *copyNumbers, Int_t *volumeNumbers) const
Fill copy numbers of current branch nodes.
Definition: TGeoCache.cxx:296
TGeoShape::ComputeNormal
virtual void ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm)=0
TGeoNode
A node represent a volume positioned inside another.They store links to both volumes and to the TGeoM...
Definition: TGeoNode.h:41
TGeoParallelWorld::FindNextBoundary
TGeoPhysicalNode * FindNextBoundary(Double_t point[3], Double_t dir[3], Double_t &step, Double_t stepmax=1.E30)
Same functionality as TGeoNavigator::FindNextDaughterBoundary for the parallel world.
Definition: TGeoParallelWorld.cxx:216
TGeoNavigator::SearchNode
TGeoNode * SearchNode(Bool_t downwards=kFALSE, const TGeoNode *skipnode=0)
Returns the deepest node containing fPoint, which must be set a priori.
Definition: TGeoNavigator.cxx:1793
TGeoPatternFinder
Base finder class for patterns.
Definition: TGeoPatternFinder.h:32
bool
TObjArray::Add
void Add(TObject *obj)
Definition: TObjArray.h:74
id
XFontStruct * id
Definition: TGX11.cxx:109
TGeoNavigator::fGeometry
TGeoManager * fGeometry
flag that last geometric step was null
Definition: TGeoNavigator.h:73
TGeoNavigator::FindNode
TGeoNode * FindNode(Bool_t safe_start=kTRUE)
Returns deepest node containing current point.
Definition: TGeoNavigator.cxx:1480
TGeoNavigator::fNextNode
TGeoNode * fNextNode
last searched node
Definition: TGeoNavigator.h:79
TGeoNavigator::DoBackupState
void DoBackupState()
Backup the current state without affecting the cache stack.
Definition: TGeoNavigator.cxx:2465
TGeoNavigator::DoRestoreState
void DoRestoreState()
Restore a backed-up state without affecting the cache stack.
Definition: TGeoNavigator.cxx:2473
TGeoNavigator::fNormal
Double_t fNormal[3]
last computed safety radius
Definition: TGeoNavigator.h:49
TGeoNavigator::cd
Bool_t cd(const char *path="")
Browse the tree of nodes starting from top node according to pathname.
Definition: TGeoNavigator.cxx:200
TGeoNavigator::FindNextBoundary
TGeoNode * FindNextBoundary(Double_t stepmax=TGeoShape::Big(), const char *path="", Bool_t frombdr=kFALSE)
Find distance to next boundary and store it in fStep.
Definition: TGeoNavigator.cxx:594
TGeoNavigator::InspectState
void InspectState() const
Inspects path and all flags for the current state.
Definition: TGeoNavigator.cxx:2260
TGeoPatternFinder::IsOnBoundary
virtual Bool_t IsOnBoundary(const Double_t *) const
Definition: TGeoPatternFinder.h:93
ROOT::Math::gv_detail::dist
double dist(Rotation3D const &r1, Rotation3D const &r2)
Definition: 3DDistances.cxx:48
TGeoStateInfo
Statefull info for the current geometry level.
Definition: TGeoStateInfo.h:21
TGeoNavigator::CdUp
void CdUp()
Go one level up in geometry.
Definition: TGeoNavigator.cxx:333
TGeoNavigator::fCldirChecked
Double_t fCldirChecked[3]
unit vector to current closest shape
Definition: TGeoNavigator.h:51
TGeoMatrix::LocalToMasterVect
virtual void LocalToMasterVect(const Double_t *local, Double_t *master) const
convert a vector by multiplying its column vector (x, y, z, 1) to matrix inverse
Definition: TGeoMatrix.cxx:363
TGeoMatrix::MasterToLocal
virtual void MasterToLocal(const Double_t *master, Double_t *local) const
convert a point by multiplying its column vector (x, y, z, 1) to matrix
Definition: TGeoMatrix.cxx:406
TGeoNode::GetDaughter
TGeoNode * GetDaughter(Int_t ind) const
Definition: TGeoNode.h:85
kN3
const Int_t kN3
Definition: TGeoNavigator.cxx:48
TGeoNodeCache::GetNode
TGeoNode * GetNode() const
Definition: TGeoCache.h:107
TGeoHMatrix::CopyFrom
void CopyFrom(const TGeoMatrix *other)
Fast copy method.
Definition: TGeoMatrix.cxx:2409
TGeoNavigator::fLastSafety
Double_t fLastSafety
safety radius from current point
Definition: TGeoNavigator.h:48
TGeoNavigator::fThreadId
Int_t fThreadId
last point for which safety was computed
Definition: TGeoNavigator.h:55
TGeoNavigator::fLastPoint
Double_t fLastPoint[3]
current direction
Definition: TGeoNavigator.h:54
TGeoHMatrix
Matrix class used for computing global transformations Should NOT be used for node definition.
Definition: TGeoMatrix.h:421
TGeoNavigator::GetMotherMatrix
TGeoHMatrix * GetMotherMatrix(Int_t up=1) const
Definition: TGeoNavigator.h:155
TGeoManager::GetParallelWorld
TGeoParallelWorld * GetParallelWorld() const
Definition: TGeoManager.h:595
TGeoNavigator::ResetState
void ResetState()
Reset current state flags.
Definition: TGeoNavigator.cxx:1577
TGeoNavigator::fSearchOverlaps
Bool_t fSearchOverlaps
internal array for overlaps
Definition: TGeoNavigator.h:62
TGeoVoxelFinder::SortCrossedVoxels
virtual void SortCrossedVoxels(const Double_t *point, const Double_t *dir, TGeoStateInfo &td)
get the list in the next voxel crossed by a ray
Definition: TGeoVoxelFinder.cxx:1071
TGeoVolume::GetNodes
TObjArray * GetNodes()
Definition: TGeoVolume.h:167
TObjArray::GetEntriesFast
Int_t GetEntriesFast() const
Definition: TObjArray.h:64
TGeoNodeCache::CdUp
void CdUp()
Make mother of current node the active state.
Definition: TGeoCache.cxx:252
TGeoNavigator::~TGeoNavigator
virtual ~TGeoNavigator()
Destructor.
Definition: TGeoNavigator.cxx:165
TGeoNavigator::CdNext
void CdNext()
Do a cd to the node found next by FindNextBoundary.
Definition: TGeoNavigator.cxx:382
kFALSE
const Bool_t kFALSE
Definition: RtypesCore.h:101
TGeoVolume::GetCurrentNodeIndex
virtual Int_t GetCurrentNodeIndex() const
Definition: TGeoVolume.h:165
TGeoNavigator::fDirection
Double_t fDirection[3]
current point
Definition: TGeoNavigator.h:53
TGeoNavigator::CrossBoundaryAndLocate
TGeoNode * CrossBoundaryAndLocate(Bool_t downwards, TGeoNode *skipnode)
Cross next boundary and locate within current node The current point must be on the boundary of fCurr...
Definition: TGeoNavigator.cxx:496
TGeoNavigator::fCurrentMatrix
TGeoHMatrix * fCurrentMatrix
backup state
Definition: TGeoNavigator.h:82
TGeoNavigator::fPoint
Double_t fPoint[3]
unit vector to current checked shape
Definition: TGeoNavigator.h:52
TGeoNavigator::fIsStepEntering
Bool_t fIsStepEntering
flag that current track is about to leave current node
Definition: TGeoNavigator.h:67
kGeoOutsidePath
const char * kGeoOutsidePath
Definition: TGeoNavigator.cxx:47
TGeoNavigator::IsSamePoint
Bool_t IsSamePoint(Double_t x, Double_t y, Double_t z) const
Check if a new point with given coordinates is the same as the last located one.
Definition: TGeoNavigator.cxx:2452
TGeoNavigator::fLevel
Int_t fLevel
thread id for this navigator
Definition: TGeoNavigator.h:56
TGeoPatternFinder::GetDivIndex
Int_t GetDivIndex()
Definition: TGeoPatternFinder.h:83
TGeoNodeCache::GetCurrentMatrix
TGeoHMatrix * GetCurrentMatrix() const
Definition: TGeoCache.h:103
TGeoNavigator::PopPoint
Bool_t PopPoint()
Definition: TGeoNavigator.h:200
TGeoNavigator::MasterToTop
void MasterToTop(const Double_t *master, Double_t *top) const
Convert coordinates from master volume frame to top.
Definition: TGeoNavigator.cxx:2507
y
Double_t y[n]
Definition: legend1.C:17
TGeoNavigator::fStep
Double_t fStep
Definition: TGeoNavigator.h:46
TGeoNavigator::fIsEntering
Bool_t fIsEntering
flag a safe start for point classification
Definition: TGeoNavigator.h:65
TGeoNavigator::fIsSameLocation
Bool_t fIsSameLocation
flag that current point is on some boundary
Definition: TGeoNavigator.h:71
TGeoNodeCache::GetLevel
Int_t GetLevel() const
Definition: TGeoCache.h:112
TGeoNavigator::PushPoint
Int_t PushPoint(Int_t startlevel=0)
Definition: TGeoNavigator.h:199
TGeoNavigator.h
TGeoVoxelFinder::Voxelize
virtual void Voxelize(Option_t *option="")
Voxelize attached volume according to option If the volume is an assembly, make sure the bbox is comp...
Definition: TGeoVoxelFinder.cxx:2221
TGeoMatrix::LocalToMaster
virtual void LocalToMaster(const Double_t *local, Double_t *master) const
convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
Definition: TGeoMatrix.cxx:339
TGeoNavigator::FindNextDaughterBoundary
TGeoNode * FindNextDaughterBoundary(Double_t *point, Double_t *dir, Int_t &idaughter, Bool_t compmatrix=kFALSE)
Computes as fStep the distance to next daughter of the current volume.
Definition: TGeoNavigator.cxx:945
TGeoVolume::IsAssembly
virtual Bool_t IsAssembly() const
Returns true if the volume is an assembly or a scaled assembly.
Definition: TGeoVolume.cxx:1705
TGeoVoxelFinder.h
TGeoNodeCache::GetInfo
TGeoStateInfo * GetInfo()
Get next state info pointer.
Definition: TGeoCache.cxx:319
TGeoVolume::FindOverlaps
void FindOverlaps() const
loop all nodes marked as overlaps and find overlapping brothers
Definition: TGeoVolume.cxx:2090
TMath::Min
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:180
TGeoNavigator::fStartSafe
Bool_t fStartSafe
flags the type of the current node
Definition: TGeoNavigator.h:64
TGeoMatrix.h
TGeoNodeCache::ReleaseInfo
void ReleaseInfo()
Release last used state info pointer.
Definition: TGeoCache.cxx:336
TGeoNavigator::fIsOnBoundary
Bool_t fIsOnBoundary
flag that current point is outside geometry
Definition: TGeoNavigator.h:70
TString::Index
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:639
TGeoShape::Contains
virtual Bool_t Contains(const Double_t *point) const =0
TGeoNavigator::CheckPath
Bool_t CheckPath(const char *path) const
Check if a geometry path is valid without changing the state of the navigator.
Definition: TGeoNavigator.cxx:243
TGeoManager.h
TGeoNode::GetIndex
virtual Int_t GetIndex() const
Definition: TGeoNode.h:89
TGeoPatternFinder.h
TGeoNavigator::TopToMaster
void TopToMaster(const Double_t *top, Double_t *master) const
Convert coordinates from top volume frame to master.
Definition: TGeoNavigator.cxx:2515
TGeoNavigator
Class providing navigation API for TGeo geometries.
Definition: TGeoNavigator.h:34
gTolerance
static Double_t gTolerance
Definition: TGeoNavigator.cxx:46
TGeoNodeCache::IsDummy
Bool_t IsDummy() const
Definition: TGeoCache.h:117
TGeoVolume::GetVoxels
TGeoVoxelFinder * GetVoxels() const
Getter for optimization structure.
Definition: TGeoVolume.cxx:1687
Double_t
double Double_t
Definition: RtypesCore.h:59
TGeoShape::DistFromInside
virtual Double_t DistFromInside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=0) const =0
TGeoVoxelFinder::NeedRebuild
Bool_t NeedRebuild() const
Definition: TGeoVoxelFinder.h:105
TGeoNavigator::PushPath
Int_t PushPath(Int_t startlevel=0)
Definition: TGeoNavigator.h:196
TGeoVolume::GetNextNodeIndex
virtual Int_t GetNextNodeIndex() const
Definition: TGeoVolume.h:166
TGeoNodeCache::CdTop
void CdTop()
Definition: TGeoCache.h:94
TGeoNavigator::fCache
TGeoNodeCache * fCache
current geometry
Definition: TGeoNavigator.h:74
TGeoNavigatorArray::fGeoManager
TGeoManager * fGeoManager
Definition: TGeoNavigator.h:220
TGeoVolume::GetNode
TGeoNode * GetNode(const char *name) const
get the pointer to a daughter node
Definition: TGeoVolume.cxx:2060
TGeoNavigator::GetNodeId
Int_t GetNodeId() const
Definition: TGeoNavigator.h:151
TGeoParallelWorld.h
TGeoNavigator::GetCurrentNodeId
Int_t GetCurrentNodeId() const
Definition: TGeoNavigator.h:159
TGeoNode::GetNdaughters
Int_t GetNdaughters() const
Definition: TGeoNode.h:93
TGeoCacheState::SetState
void SetState(Int_t level, Int_t startlevel, Int_t nmany, Bool_t ovlp, Double_t *point=0)
Fill current modeller state.
Definition: TGeoCache.cxx:564
TGeoNavigator::fGlobalMatrix
TGeoHMatrix * fGlobalMatrix
current stored global matrix
Definition: TGeoNavigator.h:83
TGeoNavigator::fOverlapSize
Int_t fOverlapSize
next daughter index after FindNextBoundary
Definition: TGeoNavigator.h:59
name
char name[80]
Definition: TGX11.cxx:110
TGeoNavigator::GetMother
TGeoNode * GetMother(Int_t up=1) const
Definition: TGeoNavigator.h:154
TGeoNavigator::SetCurrentPoint
void SetCurrentPoint(const Double_t *point)
Definition: TGeoNavigator.h:171
TGeoVolume::IsActive
Bool_t IsActive() const
Definition: TGeoVolume.h:143
genreflex::verbose
bool verbose
Definition: rootcling_impl.cxx:133
TGeoNavigator::TGeoNavigator
TGeoNavigator()
path to current node
Definition: TGeoNavigator.cxx:55
TGeoNavigator::InitTrack
TGeoNode * InitTrack(const Double_t *point, const Double_t *dir)
Initialize current point and current direction vector (normalized) in MARS.
Definition: TGeoNavigator.cxx:1556
TGeoNavigator::fOverlapMark
Int_t fOverlapMark
current size of fOverlapClusters
Definition: TGeoNavigator.h:60
TGeoNodeCache::GetBranchNames
void GetBranchNames(Int_t *names) const
Fill names with current branch volume names (4 char - used by GEANT3 interface).
Definition: TGeoCache.cxx:284
TGeoManager::GetVerboseLevel
static Int_t GetVerboseLevel()
Set verbosity level (static function).
Definition: TGeoManager.cxx:3789
TGeoShape::Tolerance
static Double_t Tolerance()
Definition: TGeoShape.h:91
TGeoMatrix::RegisterYourself
virtual void RegisterYourself()
Register the matrix in the current manager, which will become the owner.
Definition: TGeoMatrix.cxx:526
TGeoManager::GetMaxLevel
Int_t GetMaxLevel() const
Definition: TGeoManager.h:528
TGeoManager::GetTopNode
TGeoNode * GetTopNode() const
Definition: TGeoManager.h:533
TGeoManager::MasterToLocal
void MasterToLocal(const Double_t *master, Double_t *local) const
Definition: TGeoManager.h:546
TGeoVoxelFinder::GetBoxes
Double_t * GetBoxes() const
Definition: TGeoVoxelFinder.h:106
TGeoNavigator::GetSafeLevel
Int_t GetSafeLevel() const
Go upwards the tree until a non-overlapping node.
Definition: TGeoNavigator.cxx:2243
TGeoNavigator::SafetyOverlaps
void SafetyOverlaps()
Compute safe distance from the current point within an overlapping node.
Definition: TGeoNavigator.cxx:1721
TGeoMedium
Media are used to store properties related to tracking and which are useful only when using geometry ...
Definition: TGeoMedium.h:24
TNamed::GetName
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
TGeoNavigator::ResetAll
void ResetAll()
Reset the navigator.
Definition: TGeoNavigator.cxx:2523
TGeoNavigator::Step
TGeoNode * Step(Bool_t is_geom=kTRUE, Bool_t cross=kTRUE)
Make a rectiliniar step of length fStep from current point (fPoint) on current direction (fDirection)...
Definition: TGeoNavigator.cxx:2141
TGeoShape::Big
static Double_t Big()
Definition: TGeoShape.h:88
TGeoNodeCache::GetPath
const char * GetPath()
Returns the current geometry path.
Definition: TGeoCache.cxx:344
TGeoNode::MasterToLocalVect
virtual void MasterToLocalVect(const Double_t *master, Double_t *local) const
Convert a vector from mother reference to local reference system.
Definition: TGeoNode.cxx:526
TGeoNavigator::fCurrentOverlapping
Bool_t fCurrentOverlapping
flag set when an overlapping cluster is searched
Definition: TGeoNavigator.h:63
TGeoVoxelFinder
Finder class handling voxels.
Definition: TGeoVoxelFinder.h:21
TGeoShape::Safety
virtual Double_t Safety(const Double_t *point, Bool_t in=kTRUE) const =0
TGeoManager
The manager class for any TGeo geometry.
Definition: TGeoManager.h:45
TObject::ClassName
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:130
TGeoNavigator::fNmany
Int_t fNmany
current geometry level;
Definition: TGeoNavigator.h:57
TMath::E
constexpr Double_t E()
Base of natural log:
Definition: TMath.h:96
TGeoPatternFinder::GetNext
Int_t GetNext() const
Get index of next division.
Definition: TGeoPatternFinder.cxx:196
TGeoVolume
TGeoVolume, TGeoVolumeMulti, TGeoVolumeAssembly are the volume classes.
Definition: TGeoVolume.h:49
TGeoParallelWorld::Safety
Double_t Safety(Double_t point[3], Double_t safmax=1.E30)
Compute safety for the parallel world.
Definition: TGeoParallelWorld.cxx:302
TGeoNavigator::fCldir
Double_t fCldir[3]
cosine of incident angle on current checked surface
Definition: TGeoNavigator.h:50
TGeoPatternFinder::FindNode
virtual TGeoNode * FindNode(Double_t *, const Double_t *=0)
Definition: TGeoPatternFinder.h:80
TGeoVolumeAssembly
Volume assemblies.
Definition: TGeoVolume.h:303
TGeoNode.h
TGeoNavigator::fPath
TString fPath
current local matrix of the selected division cell
Definition: TGeoNavigator.h:85
snext
#define snext(osub1, osub2)
Definition: triangle.c:1167
TGeoNavigator::GetBranchNumbers
void GetBranchNumbers(Int_t *copyNumbers, Int_t *volumeNumbers) const
Fill node copy numbers of current branch into an array.
Definition: TGeoNavigator.cxx:419
TGeoNavigator::FindNextBoundaryAndStep
TGeoNode * FindNextBoundaryAndStep(Double_t stepmax=TGeoShape::Big(), Bool_t compsafe=kFALSE)
Compute distance to next boundary within STEPMAX.
Definition: TGeoNavigator.cxx:1123
TGeoNode::GetOverlaps
Int_t * GetOverlaps(Int_t &novlp) const
Definition: TGeoNode.h:96
TMath.h
TGeoNavigator::fLastNode
TGeoNode * fLastNode
top physical node
Definition: TGeoNavigator.h:78
TGeoNavigator::fForcedNode
TGeoNode * fForcedNode
next node that will be crossed
Definition: TGeoNavigator.h:80
int
TGeoNode::Safety
Double_t Safety(const Double_t *point, Bool_t in=kTRUE) const
computes the closest distance from given point to this shape
Definition: TGeoNode.cxx:630
TGeoNavigator::SetCurrentDirection
void SetCurrentDirection(const Double_t *dir)
Definition: TGeoNavigator.h:176
TGeoNavigator::FindNormalFast
Double_t * FindNormalFast()
Computes fast normal to next crossed boundary, assuming that the current point is close enough to the...
Definition: TGeoNavigator.cxx:1528
TGeoNavigator::fNextDaughterIndex
Int_t fNextDaughterIndex
number of overlapping nodes on current branch
Definition: TGeoNavigator.h:58