Logo ROOT   6.12/07
Reference Guide
TGeoVolume.cxx
Go to the documentation of this file.
1 // @(#)root/geom:$Id$
2 // Author: Andrei Gheata 30/05/02
3 // Divide(), CheckOverlaps() implemented by Mihaela Gheata
4 
5 /*************************************************************************
6  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
7  * All rights reserved. *
8  * *
9  * For the licensing terms see $ROOTSYS/LICENSE. *
10  * For the list of contributors see $ROOTSYS/README/CREDITS. *
11  *************************************************************************/
12 
13 /** \class TGeoVolume
14 \ingroup Geometry_classes
15 
16 TGeoVolume, TGeoVolumeMulti, TGeoVolumeAssembly are the volume classes
17 
18  Volumes are the basic objects used in building the geometrical hierarchy.
19 They represent unpositioned objects but store all information about the
20 placement of the other volumes they may contain. Therefore a volume can
21 be replicated several times in the geometry. In order to create a volume, one
22 has to put together a shape and a medium which are already defined. Volumes
23 have to be named by users at creation time. Every different name may represent a
24 an unique volume object, but may also represent more general a family (class)
25 of volume objects having the same shape type and medium, but possibly
26 different shape parameters. It is the user's task to provide different names
27 for different volume families in order to avoid ambiguities at tracking time.
28 A generic family rather than a single volume is created only in two cases :
29 when a generic shape is provided to the volume constructor or when a division
30 operation is applied. Each volume in the geometry stores an unique
31 ID corresponding to its family. In order to ease-up their creation, the manager
32 class is providing an API that allows making a shape and a volume in a single step.
33 
34  Volumes are objects that can be visualized, therefore having visibility,
35 colour, line and fill attributes that can be defined or modified any time after
36 the volume creation. It is advisable however to define these properties just
37 after the first creation of a volume namespace, since in case of volume families
38 any new member created by the modeler inherits these properties.
39 
40  In order to provide navigation features, volumes have to be able to find
41 the proper container of any point defined in the local reference frame. This
42 can be the volume itself, one of its positioned daughter volumes or none if
43 the point is actually outside. On the other hand, volumes have to provide also
44 other navigation methods such as finding the distances to its shape boundaries
45 or which daughter will be crossed first. The implementation of these features
46 is done at shape level, but the local mother-daughters management is handled
47 by volumes that builds additional optimisation structures upon geometry closure.
48 In order to have navigation features properly working one has to follow the
49 general rules for building a valid geometry (see TGeoManager class).
50 
51  Now let's make a simple volume representing a copper wire. We suppose that
52 a medium is already created (see TGeoMedium class on how to create media).
53 We will create a TUBE shape for our wire, having Rmin=0cm, Rmax=0.01cm
54 and a half-length dZ=1cm :
55 
56 ~~~ {.cpp}
57  TGeoTube *tube = new TGeoTube("wire_tube", 0, 0.01, 1);
58 ~~~
59 
60 One may omit the name for the shape if no retrieving by name is further needed
61 during geometry building. The same shape can be shared by different volumes
62 having different names and materials. Now let's make the volume for our wire.
63 The prototype for volumes constructor looks like :
64 
65  TGeoVolume::TGeoVolume(const char *name, TGeoShape *shape, TGeoMedium *med)
66 
67 Since TGeoTube derives from the base shape class, we can provide it to the volume
68 constructor :
69 
70 ~~~ {.cpp}
71  TGeoVolume *wire_co = new TGeoVolume("WIRE_CO", tube, ptrCOPPER);
72 ~~~
73 
74 Do not bother to delete neither the media, shapes or volumes that you have
75 created since all will be automatically cleaned on exit by the manager class.
76 If we would have taken a look inside TGeoManager::MakeTube() method, we would
77 have been able to create our wire with a single line :
78 
79 ~~~ {.cpp}
80  TGeoVolume *wire_co = gGeoManager->MakeTube("WIRE_CO", ptrCOPPER, 0, 0.01, 1);
81 ~~~
82 
83 The same applies for all primitive shapes, for which there can be found
84 corresponding MakeSHAPE() methods. Their usage is much more convenient unless
85 a shape has to be shared between more volumes. Let's make now an aluminium wire
86 having the same shape, supposing that we have created the copper wire with the
87 line above :
88 
89 ~~~ {.cpp}
90  TGeoVolume *wire_al = new TGeoVolume("WIRE_AL", wire_co->GetShape(), ptrAL);
91 ~~~
92 
93 Now that we have learned how to create elementary volumes, let's see how we
94 can create a geometrical hierarchy.
95 
96 
97 ### Positioning volumes
98 
99  When creating a volume one does not specify if this will contain or not other
100 volumes. Adding daughters to a volume implies creating those and adding them
101 one by one to the list of daughters. Since the volume has to know the position
102 of all its daughters, we will have to supply at the same time a geometrical
103 transformation with respect to its local reference frame for each of them.
104 The objects referencing a volume and a transformation are called NODES and
105 their creation is fully handled by the modeler. They represent the link
106 elements in the hierarchy of volumes. Nodes are unique and distinct geometrical
107 objects ONLY from their container point of view. Since volumes can be replicated
108 in the geometry, the same node may be found on different branches.
109 
110 \image html geom_t_example.png
111 
112  An important observation is that volume objects are owned by the TGeoManager
113 class. This stores a list of all volumes in the geometry, that is cleaned
114 upon destruction.
115 
116  Let's consider positioning now our wire in the middle of a gas chamber. We
117 need first to define the gas chamber :
118 
119 ~~~ {.cpp}
120  TGeoVolume *chamber = gGeoManager->MakeTube("CHAMBER", ptrGAS, 0, 1, 1);
121 ~~~
122 
123 Now we can put the wire inside :
124 
125 ~~~ {.cpp}
126  chamber->AddNode(wire_co, 1);
127 ~~~
128 
129 If we inspect now the chamber volume in a browser, we will notice that it has
130 one daughter. Of course the gas has some container also, but let's keep it like
131 that for the sake of simplicity. The full prototype of AddNode() is :
132 
133 ~~~ {.cpp}
134  TGeoVolume::AddNode(TGeoVolume *daughter, Int_t usernumber,
135  TGeoMatrix *matrix=gGeoIdentity)
136 ~~~
137 
138 Since we did not supplied the third argument, the wire will be positioned with
139 an identity transformation inside the chamber. One will notice that the inner
140 radii of the wire and chamber are both zero - therefore, aren't the two volumes
141 overlapping ? The answer is no, the modeler is even relaying on the fact that
142 any daughter is fully contained by its mother. On the other hand, neither of
143 the nodes positioned inside a volume should overlap with each other. We will
144 see that there are allowed some exceptions to those rules.
145 
146 ### Overlapping volumes
147 
148  Positioning volumes that does not overlap their neighbours nor extrude
149 their container is sometimes quite strong constraint. Some parts of the geometry
150 might overlap naturally, e.g. two crossing tubes. The modeller supports such
151 cases only if the overlapping nodes are declared by the user. In order to do
152 that, one should use TGeoVolume::AddNodeOverlap() instead of TGeoVolume::AddNode().
153  When 2 or more positioned volumes are overlapping, not all of them have to
154 be declared so, but at least one. A point inside an overlapping region equally
155 belongs to all overlapping nodes, but the way these are defined can enforce
156 the modeler to give priorities.
157  The general rule is that the deepest node in the hierarchy containing a point
158 have the highest priority. For the same geometry level, non-overlapping is
159 prioritised over overlapping. In order to illustrate this, we will consider
160 few examples. We will designate non-overlapping nodes as ONLY and the others
161 MANY as in GEANT3, where this concept was introduced:
162  1. The part of a MANY node B extruding its container A will never be "seen"
163 during navigation, as if B was in fact the result of the intersection of A and B.
164  2. If we have two nodes A (ONLY) and B (MANY) inside the same container, all
165 points in the overlapping region of A and B will be designated as belonging to A.
166  3. If A an B in the above case were both MANY, points in the overlapping
167 part will be designated to the one defined first. Both nodes must have the
168 same medium.
169  4. The slices of a divided MANY will be as well MANY.
170 
171 One needs to know that navigation inside geometry parts MANY nodes is much
172 slower. Any overlapping part can be defined based on composite shapes - this
173 is always recommended.
174 
175 ### Replicating volumes
176 
177  What can we do if our chamber contains two identical wires instead of one ?
178 What if then we would need 1000 chambers in our detector ? Should we create
179 2000 wires and 1000 chamber volumes ? No, we will just need to replicate the
180 ones that we have already created.
181 
182 ~~~ {.cpp}
183  chamber->AddNode(wire_co, 1, new TGeoTranslation(-0.2,0,0));
184  chamber->AddNode(wire_co, 2, new TGeoTranslation(0.2,0,0));
185 ~~~
186 
187  The 2 nodes that we have created inside chamber will both point to a wire_co
188 object, but will be completely distinct : WIRE_CO_1 and WIRE_CO_2. We will
189 want now to place symmetrically 1000 chambers on a pad, following a pattern
190 of 20 rows and 50 columns. One way to do this will be to replicate our chamber
191 by positioning it 1000 times in different positions of the pad. Unfortunately,
192 this is far from being the optimal way of doing what we want.
193 Imagine that we would like to find out which of the 1000 chambers is containing
194 a (x,y,z) point defined in the pad reference. You will never have to do that,
195 since the modeller will take care of it for you, but let's guess what it has
196 to do. The most simple algorithm will just loop over all daughters, convert
197 the point from mother to local reference and check if the current chamber
198 contains the point or not. This might be efficient for pads with few chambers,
199 but definitely not for 1000. Fortunately the modeler is smarter than that and
200 create for each volume some optimization structures called voxels (see Voxelization)
201 to minimize the penalty having too many daughters, but if you have 100 pads like
202 this in your geometry you will anyway loose a lot in your tracking performance.
203 
204  The way out when volumes can be arranged according to simple patterns is the
205 usage of divisions. We will describe them in detail later on. Let's think now
206 at a different situation : instead of 1000 chambers of the same type, we may
207 have several types of chambers. Let's say all chambers are cylindrical and have
208 a wire inside, but their dimensions are different. However, we would like all
209 to be represented by a single volume family, since they have the same properties.
210 */
211 
212 /** \class TGeoVolumeMulti
213 \ingroup Geometry_classes
214 
215 Volume families
216 
217 A volume family is represented by the class TGeoVolumeMulti. It represents
218 a class of volumes having the same shape type and each member will be
219 identified by the same name and volume ID. Any operation applied to a
220 TGeoVolume equally affects all volumes in that family. The creation of a
221 family is generally not a user task, but can be forced in particular cases:
222 
223 ~~~ {.cpp}
224  TGeoManager::Volume(const char *vname, const char *shape, Int_t nmed);
225 ~~~
226 
227 where VNAME is the family name, NMED is the medium number and SHAPE is the
228 shape type that can be:
229 
230 ~~~ {.cpp}
231  box - for TGeoBBox
232  trd1 - for TGeoTrd1
233  trd2 - for TGeoTrd2
234  trap - for TGeoTrap
235  gtra - for TGeoGtra
236  para - for TGeoPara
237  tube, tubs - for TGeoTube, TGeoTubeSeg
238  cone, cons - for TGeoCone, TgeoCons
239  eltu - for TGeoEltu
240  ctub - for TGeoCtub
241  pcon - for TGeoPcon
242  pgon - for TGeoPgon
243 ~~~
244 
245 Volumes are then added to a given family upon adding the generic name as node
246 inside other volume:
247 
248 ~~~ {.cpp}
249  TGeoVolume *box_family = gGeoManager->Volume("BOXES", "box", nmed);
250  ...
251  gGeoManager->Node("BOXES", Int_t copy_no, "mother_name",
252  Double_t x, Double_t y, Double_t z, Int_t rot_index,
253  Bool_t is_only, Double_t *upar, Int_t npar);
254 ~~~
255 
256 here:
257 
258 ~~~ {.cpp}
259  BOXES - name of the family of boxes
260  copy_no - user node number for the created node
261  mother_name - name of the volume to which we want to add the node
262  x,y,z - translation components
263  rot_index - indx of a rotation matrix in the list of matrices
264  upar - array of actual shape parameters
265  npar - number of parameters
266 ~~~
267 
268 The parameters order and number are the same as in the corresponding shape
269 constructors.
270 
271  Another particular case where volume families are used is when we want
272 that a volume positioned inside a container to match one ore more container
273 limits. Suppose we want to position the same box inside 2 different volumes
274 and we want the Z size to match the one of each container:
275 
276 ~~~ {.cpp}
277  TGeoVolume *container1 = gGeoManager->MakeBox("C1", imed, 10,10,30);
278  TGeoVolume *container2 = gGeoManager->MakeBox("C2", imed, 10,10,20);
279  TGeoVolume *pvol = gGeoManager->MakeBox("PVOL", jmed, 3,3,-1);
280  container1->AddNode(pvol, 1);
281  container2->AddNode(pvol, 1);
282 ~~~
283 
284  Note that the third parameter of PVOL is negative, which does not make sense
285 as half-length on Z. This is interpreted as: when positioned, create a box
286 replacing all invalid parameters with the corresponding dimensions of the
287 container. This is also internally handled by the TGeoVolumeMulti class, which
288 does not need to be instantiated by users.
289 
290 ### Dividing volumes
291 
292  Volumes can be divided according a pattern. The most simple division can
293 be done along one axis, that can be: X, Y, Z, Phi, Rxy or Rxyz. Let's take
294 the most simple case: we would like to divide a box in N equal slices along X
295 coordinate, representing a new volume family. Supposing we already have created
296 the initial box, this can be done like:
297 
298 ~~~ {.cpp}
299  TGeoVolume *slicex = box->Divide("SLICEX", 1, N);
300 ~~~
301 
302 where SLICE is the name of the new family representing all slices and 1 is the
303 slicing axis. The meaning of the axis index is the following: for all volumes
304 having shapes like box, trd1, trd2, trap, gtra or para - 1,2,3 means X,Y,Z; for
305 tube, tubs, cone, cons - 1 means Rxy, 2 means phi and 3 means Z; for pcon and
306 pgon - 2 means phi and 3 means Z; for spheres 1 means R and 2 means phi.
307  In fact, the division operation has the same effect as positioning volumes
308 in a given order inside the divided container - the advantage being that the
309 navigation in such a structure is much faster. When a volume is divided, a
310 volume family corresponding to the slices is created. In case all slices can
311 be represented by a single shape, only one volume is added to the family and
312 positioned N times inside the divided volume, otherwise, each slice will be
313 represented by a distinct volume in the family.
314  Divisions can be also performed in a given range of one axis. For that, one
315 have to specify also the starting coordinate value and the step:
316 
317 ~~~ {.cpp}
318  TGeoVolume *slicex = box->Divide("SLICEX", 1, N, start, step);
319 ~~~
320 
321 A check is always done on the resulting division range : if not fitting into
322 the container limits, an error message is posted. If we will browse the divided
323 volume we will notice that it will contain N nodes starting with index 1 upto
324 N. The first one has the lower X limit at START position, while the last one
325 will have the upper X limit at START+N*STEP. The resulting slices cannot
326 be positioned inside an other volume (they are by default positioned inside the
327 divided one) but can be further divided and may contain other volumes:
328 
329 ~~~ {.cpp}
330  TGeoVolume *slicey = slicex->Divide("SLICEY", 2, N1);
331  slicey->AddNode(other_vol, index, some_matrix);
332 ~~~
333 
334  When doing that, we have to remember that SLICEY represents a family, therefore
335 all members of the family will be divided on Y and the other volume will be
336 added as node inside all.
337  In the example above all the resulting slices had the same shape as the
338 divided volume (box). This is not always the case. For instance, dividing a
339 volume with TUBE shape on PHI axis will create equal slices having TUBESEG
340 shape. Other divisions can also create slices having shapes with different
341 dimensions, e.g. the division of a TRD1 volume on Z.
342  When positioning volumes inside slices, one can do it using the generic
343 volume family (e.g. slicey). This should be done as if the coordinate system
344 of the generic slice was the same as the one of the divided volume. The generic
345 slice in case of PHI division is centered with respect to X axis. If the
346 family contains slices of different sizes, any volume positioned inside should
347 fit into the smallest one.
348  Examples for specific divisions according to shape types can be found inside
349 shape classes.
350 
351 ~~~ {.cpp}
352  TGeoVolume::Divide(N, Xmin, Xmax, "X");
353 ~~~
354 
355  The GEANT3 option MANY is supported by TGeoVolumeOverlap class. An overlapping
356 volume is in fact a virtual container that does not represent a physical object.
357 It contains a list of nodes that are not its daughters but that must be checked
358 always before the container itself. This list must be defined by users and it
359 is checked and resolved in a priority order. Note that the feature is non-standard
360 to geometrical modelers and it was introduced just to support conversions of
361 GEANT3 geometries, therefore its extensive usage should be avoided.
362 */
363 
364 /** \class TGeoVolumeAssembly
365 \ingroup Geometry_classes
366 
367 Volume assemblies
368 
369 Assemblies a volumes that have neither a shape or a material/medium. Assemblies
370 behave exactly like normal volumes grouping several daughters together, but
371 the daughters can never extrude the assembly since this has no shape. However,
372 a bounding box and a voxelization structure are built for assemblies as for
373 normal volumes, so that navigation is still optimized. Assemblies are useful
374 for grouping hierarchically volumes which are otherwise defined in a flat
375 manner, but also to avoid clashes between container shapes.
376 To define an assembly one should just input a name, then start adding other
377 volumes (or volume assemblies) as content.
378 */
379 
380 #include "Riostream.h"
381 #include "TString.h"
382 #include "TBrowser.h"
383 #include "TStyle.h"
384 #include "TH2F.h"
385 #include "TPad.h"
386 #include "TROOT.h"
387 #include "TClass.h"
388 #include "TEnv.h"
389 #include "TMap.h"
390 #include "TFile.h"
391 #include "TKey.h"
392 
393 #include "TGeoManager.h"
394 #include "TGeoNode.h"
395 #include "TGeoMatrix.h"
396 #include "TVirtualGeoPainter.h"
397 #include "TGeoVolume.h"
398 #include "TGeoShapeAssembly.h"
399 #include "TGeoScaledShape.h"
400 #include "TGeoCompositeShape.h"
401 #include "TGeoVoxelFinder.h"
402 #include "TGeoExtension.h"
403 
405 
407 
408 ////////////////////////////////////////////////////////////////////////////////
409 /// Create a dummy medium
410 
412 {
413  if (fgDummyMedium) return;
414  fgDummyMedium = new TGeoMedium();
415  fgDummyMedium->SetName("dummy");
416  TGeoMaterial *dummyMaterial = new TGeoMaterial();
417  dummyMaterial->SetName("dummy");
418  fgDummyMedium->SetMaterial(dummyMaterial);
419 }
420 
421 ////////////////////////////////////////////////////////////////////////////////
422 
424 {
426  if (fShape) fShape->ClearThreadData();
427 }
428 
429 ////////////////////////////////////////////////////////////////////////////////
430 
432 {
433  if (fFinder) fFinder->CreateThreadData(nthreads);
434  if (fShape) fShape->CreateThreadData(nthreads);
435 }
436 
437 ////////////////////////////////////////////////////////////////////////////////
438 
440 {
441  return fgDummyMedium;
442 }
443 
444 ////////////////////////////////////////////////////////////////////////////////
445 /// dummy constructor
446 
448 {
449  fNodes = 0;
450  fShape = 0;
451  fMedium = 0;
452  fFinder = 0;
453  fVoxels = 0;
455  fField = 0;
456  fOption = "";
457  fNumber = 0;
458  fNtotal = 0;
459  fRefCount = 0;
460  fUserExtension = 0;
461  fFWExtension = 0;
463 }
464 
465 ////////////////////////////////////////////////////////////////////////////////
466 /// default constructor
467 
468 TGeoVolume::TGeoVolume(const char *name, const TGeoShape *shape, const TGeoMedium *med)
469  :TNamed(name, "")
470 {
471  fName = fName.Strip();
472  fNodes = 0;
473  fShape = (TGeoShape*)shape;
474  if (fShape) {
476  Warning("Ctor", "volume %s has invalid shape", name);
477  }
478  if (!fShape->IsValid()) {
479  Fatal("ctor", "Shape of volume %s invalid. Aborting!", fName.Data());
480  }
481  }
482  fMedium = (TGeoMedium*)med;
483  if (fMedium && fMedium->GetMaterial()) fMedium->GetMaterial()->SetUsed();
484  fFinder = 0;
485  fVoxels = 0;
487  fField = 0;
488  fOption = "";
489  fNumber = 0;
490  fNtotal = 0;
491  fRefCount = 0;
492  fUserExtension = 0;
493  fFWExtension = 0;
496 }
497 
498 ////////////////////////////////////////////////////////////////////////////////
499 ///copy constructor
500 
502  TNamed(gv),
503  TGeoAtt(gv),
504  TAttLine(gv),
505  TAttFill(gv),
506  TAtt3D(gv),
507  fNodes(gv.fNodes),
508  fShape(gv.fShape),
509  fMedium(gv.fMedium),
510  fFinder(gv.fFinder),
511  fVoxels(gv.fVoxels),
513  fField(gv.fField),
514  fOption(gv.fOption),
515  fNumber(gv.fNumber),
516  fNtotal(gv.fNtotal),
517  fRefCount(0),
520 {
521 }
522 
523 ////////////////////////////////////////////////////////////////////////////////
524 ///assignment operator
525 
527 {
528  if(this!=&gv) {
529  TNamed::operator=(gv);
530  TGeoAtt::operator=(gv);
533  TAtt3D::operator=(gv);
534  fNodes=gv.fNodes;
535  fShape=gv.fShape;
536  fMedium=gv.fMedium;
537  fFinder=gv.fFinder;
538  fVoxels=gv.fVoxels;
540  fField=gv.fField;
541  fOption=gv.fOption;
542  fNumber=gv.fNumber;
543  fRefCount = 0;
544  fNtotal=gv.fNtotal;
547  }
548  return *this;
549 }
550 
551 ////////////////////////////////////////////////////////////////////////////////
552 /// Destructor
553 
555 {
556  if (fNodes) {
558  fNodes->Delete();
559  }
560  delete fNodes;
561  }
563  if (fVoxels) delete fVoxels;
566 }
567 
568 ////////////////////////////////////////////////////////////////////////////////
569 /// How to browse a volume
570 
572 {
573  if (!b) return;
574 
575 // if (!GetNdaughters()) b->Add(this, GetName(), IsVisible());
576  TGeoVolume *daughter;
577  TString title;
578  for (Int_t i=0; i<GetNdaughters(); i++) {
579  daughter = GetNode(i)->GetVolume();
580  if(daughter->GetTitle()[0]) {
581  if (daughter->IsAssembly()) title.TString::Format("Assembly with %d daughter(s)",
582  daughter->GetNdaughters());
583  else if (daughter->GetFinder()) {
584  TString s1 = daughter->GetFinder()->ClassName();
585  s1.ReplaceAll("TGeoPattern","");
586  title.TString::Format("Volume having %s shape divided in %d %s slices",
587  daughter->GetShape()->ClassName(),daughter->GetNdaughters(), s1.Data());
588 
589  } else title.TString::Format("Volume with %s shape having %d daughter(s)",
590  daughter->GetShape()->ClassName(),daughter->GetNdaughters());
591  daughter->SetTitle(title.Data());
592  }
593  b->Add(daughter, daughter->GetName(), daughter->IsVisible());
594 // if (IsVisDaughters())
595 // b->AddCheckBox(daughter, daughter->IsVisible());
596 // else
597 // b->AddCheckBox(daughter, kFALSE);
598  }
599 }
600 
601 ////////////////////////////////////////////////////////////////////////////////
602 /// Computes the capacity of this [cm^3] as the capacity of its shape.
603 /// In case of assemblies, the capacity is computed as the sum of daughter's capacities.
604 
606 {
607  if (!IsAssembly()) return fShape->Capacity();
608  Double_t capacity = 0.0;
609  Int_t nd = GetNdaughters();
610  Int_t i;
611  for (i=0; i<nd; i++) capacity += GetNode(i)->GetVolume()->Capacity();
612  return capacity;
613 }
614 
615 ////////////////////////////////////////////////////////////////////////////////
616 /// Shoot nrays with random directions from starting point (startx, starty, startz)
617 /// in the reference frame of this volume. Track each ray until exiting geometry, then
618 /// shoot backwards from exiting point and compare boundary crossing points.
619 
620 void TGeoVolume::CheckGeometry(Int_t nrays, Double_t startx, Double_t starty, Double_t startz) const
621 {
622  TGeoVolume *old_vol = fGeoManager->GetTopVolume();
623  if (old_vol!=this) fGeoManager->SetTopVolume((TGeoVolume*)this);
624  else old_vol=0;
627  painter->CheckGeometry(nrays, startx, starty, startz);
628 }
629 
630 ////////////////////////////////////////////////////////////////////////////////
631 /// Overlap checking tool. Check for illegal overlaps within a limit OVLP.
632 /// Use option="s[number]" to force overlap checking by sampling volume with
633 /// [number] points.
634 ///
635 /// Ex:
636 /// ~~~ {.cpp}
637 /// myVol->CheckOverlaps(0.01, "s10000000"); // shoot 10000000 points
638 /// myVol->CheckOverlaps(0.01, "s"); // shoot the default value of 1e6 points
639 /// ~~~
640 
641 void TGeoVolume::CheckOverlaps(Double_t ovlp, Option_t *option) const
642 {
643  if (!GetNdaughters() || fFinder) return;
644  Bool_t sampling = kFALSE;
645  TString opt(option);
646  opt.ToLower();
647  if (opt.Contains("s")) sampling = kTRUE;
649  if (!sampling) fGeoManager->SetNsegments(80);
652 // Info("CheckOverlaps", "=== Checking overlaps for volume %s ===\n", GetName());
653  }
654  painter->CheckOverlaps(this, ovlp, option);
655 // if (sampling) return;
658  TObjArray *overlaps = fGeoManager->GetListOfOverlaps();
659  Int_t novlps = overlaps->GetEntriesFast();
660  TNamed *obj;
661  TString name;
662  for (Int_t i=0; i<novlps; i++) {
663  obj = (TNamed*)overlaps->At(i);
664  if (novlps<1000) name = TString::Format("ov%03d", i);
665  else name = TString::Format("ov%06d", i);
666  obj->SetName(name);
667  }
668  if (novlps) Info("CheckOverlaps", "Number of illegal overlaps/extrusions for volume %s: %d\n", GetName(), novlps);
669  }
670 }
671 
672 ////////////////////////////////////////////////////////////////////////////////
673 /// Tests for checking the shape navigation algorithms. See TGeoShape::CheckShape()
674 
675 void TGeoVolume::CheckShape(Int_t testNo, Int_t nsamples, Option_t *option)
676 {
677  fShape->CheckShape(testNo,nsamples,option);
678 }
679 
680 ////////////////////////////////////////////////////////////////////////////////
681 /// Clean data of the volume.
682 
684 {
685  ClearNodes();
686  ClearShape();
687 }
688 
689 ////////////////////////////////////////////////////////////////////////////////
690 /// Clear the shape of this volume from the list held by the current manager.
691 
693 {
695 }
696 
697 ////////////////////////////////////////////////////////////////////////////////
698 /// check for negative parameters in shapes.
699 
701 {
702  if (fShape->IsRunTimeShape()) {
703  Error("CheckShapes", "volume %s has run-time shape", GetName());
704  InspectShape();
705  return;
706  }
707  if (!fNodes) return;
709  TGeoNode *node = 0;
710  TGeoNode *new_node;
711  const TGeoShape *shape = 0;
712  TGeoVolume *old_vol;
713  for (Int_t i=0; i<nd; i++) {
714  node=(TGeoNode*)fNodes->At(i);
715  // check if node has name
716  if (!node->GetName()[0]) printf("Daughter %i of volume %s - NO NAME!!!\n",
717  i, GetName());
718  old_vol = node->GetVolume();
719  shape = old_vol->GetShape();
720  if (shape->IsRunTimeShape()) {
721 // printf(" Node %s/%s has shape with negative parameters. \n",
722 // GetName(), node->GetName());
723 // old_vol->InspectShape();
724  // make a copy of the node
725  new_node = node->MakeCopyNode();
726  if (!new_node) {
727  Fatal("CheckShapes", "Cannot make copy node for %s", node->GetName());
728  return;
729  }
730  TGeoShape *new_shape = shape->GetMakeRuntimeShape(fShape, node->GetMatrix());
731  if (!new_shape) {
732  Error("CheckShapes","cannot resolve runtime shape for volume %s/%s\n",
733  GetName(),old_vol->GetName());
734  continue;
735  }
736  TGeoVolume *new_volume = old_vol->MakeCopyVolume(new_shape);
737 // printf(" new volume %s shape params :\n", new_volume->GetName());
738 // new_volume->InspectShape();
739  new_node->SetVolume(new_volume);
740  // decouple the old node and put the new one instead
741  fNodes->AddAt(new_node, i);
742 // new_volume->CheckShapes();
743  }
744  }
745 }
746 
747 ////////////////////////////////////////////////////////////////////////////////
748 /// Count total number of subnodes starting from this volume, nlevels down
749 /// - option = 0 (default) - count only once per volume
750 /// - option = 1 - count every time
751 /// - option = 2 - count volumes on visible branches
752 /// - option = 3 - return maximum level counted already with option = 0
753 
755 {
756  static Int_t maxlevel = 0;
757  static Int_t nlev = 0;
758 
759  if (option<0 || option>3) option = 0;
760  Int_t visopt = 0;
761  Int_t nd = GetNdaughters();
762  Bool_t last = (!nlevels || !nd)?kTRUE:kFALSE;
763  switch (option) {
764  case 0:
765  if (fNtotal) return fNtotal;
766  case 1:
767  fNtotal = 1;
768  break;
769  case 2:
770  visopt = fGeoManager->GetVisOption();
771  if (!IsVisDaughters()) last = kTRUE;
772  switch (visopt) {
774  fNtotal = (IsVisible())?1:0;
775  break;
777  fNtotal = (IsVisible() && last)?1:0;
778  }
779  if (!IsVisibleDaughters()) return fNtotal;
780  break;
781  case 3:
782  return maxlevel;
783  }
784  if (last) return fNtotal;
785  if (gGeoManager->GetTopVolume() == this) {
786  maxlevel=0;
787  nlev = 0;
788  }
789  if (nlev>maxlevel) maxlevel = nlev;
790  TGeoNode *node;
791  TGeoVolume *vol;
792  nlev++;
793  for (Int_t i=0; i<nd; i++) {
794  node = GetNode(i);
795  vol = node->GetVolume();
796  fNtotal += vol->CountNodes(nlevels-1, option);
797  }
798  nlev--;
799  return fNtotal;
800 }
801 
802 ////////////////////////////////////////////////////////////////////////////////
803 /// Return TRUE if volume and all daughters are invisible.
804 
806 {
807  if (IsVisible()) return kFALSE;
808  Int_t nd = GetNdaughters();
809  for (Int_t i=0; i<nd; i++) if (GetNode(i)->GetVolume()->IsVisible()) return kFALSE;
810  return kTRUE;
811 }
812 
813 ////////////////////////////////////////////////////////////////////////////////
814 /// Make volume and each of it daughters (in)visible.
815 
817 {
818  SetAttVisibility(!flag);
819  Int_t nd = GetNdaughters();
820  TObjArray *list = new TObjArray(nd+1);
821  list->Add(this);
822  TGeoVolume *vol;
823  for (Int_t i=0; i<nd; i++) {
824  vol = GetNode(i)->GetVolume();
825  vol->SetAttVisibility(!flag);
826  list->Add(vol);
827  }
828  TIter next(gROOT->GetListOfBrowsers());
829  TBrowser *browser = 0;
830  while ((browser=(TBrowser*)next())) {
831  for (Int_t i=0; i<nd+1; i++) {
832  vol = (TGeoVolume*)list->At(i);
833  browser->CheckObjectItem(vol, !flag);
834  }
835  browser->Refresh();
836  }
837  delete list;
839 }
840 
841 ////////////////////////////////////////////////////////////////////////////////
842 /// Return TRUE if volume contains nodes
843 
845 {
846  return kTRUE;
847 }
848 
849 ////////////////////////////////////////////////////////////////////////////////
850 /// check if the visibility and attributes are the default ones
851 
853 {
854  if (!IsVisible()) return kFALSE;
855  if (GetLineColor() != gStyle->GetLineColor()) return kFALSE;
856  if (GetLineStyle() != gStyle->GetLineStyle()) return kFALSE;
857  if (GetLineWidth() != gStyle->GetLineWidth()) return kFALSE;
858  return kTRUE;
859 }
860 
861 ////////////////////////////////////////////////////////////////////////////////
862 /// True if this is the top volume of the geometry
863 
865 {
866  if (fGeoManager->GetTopVolume() == this) return kTRUE;
867  return kFALSE;
868 }
869 
870 ////////////////////////////////////////////////////////////////////////////////
871 /// Check if the painter is currently ray-tracing the content of this volume.
872 
874 {
875  return TGeoAtt::IsVisRaytrace();
876 }
877 
878 ////////////////////////////////////////////////////////////////////////////////
879 /// Inspect the material for this volume.
880 
882 {
883  GetMaterial()->Print();
884 }
885 
886 ////////////////////////////////////////////////////////////////////////////////
887 /// Import a volume from a file.
888 
889 TGeoVolume *TGeoVolume::Import(const char *filename, const char *name, Option_t * /*option*/)
890 {
891  if (!gGeoManager) gGeoManager = new TGeoManager("geometry","");
892  if (!filename) return 0;
893  TGeoVolume *volume = 0;
894  if (strstr(filename,".gdml")) {
895  // import from a gdml file
896  } else {
897  // import from a root file
899  TFile *f = TFile::Open(filename);
900  if (!f || f->IsZombie()) {
901  printf("Error: TGeoVolume::Import : Cannot open file %s\n", filename);
902  return 0;
903  }
904  if (name && name[0]) {
905  volume = (TGeoVolume*)f->Get(name);
906  } else {
907  TIter next(f->GetListOfKeys());
908  TKey *key;
909  while ((key = (TKey*)next())) {
910  if (strcmp(key->GetClassName(),"TGeoVolume") != 0) continue;
911  volume = (TGeoVolume*)key->ReadObj();
912  break;
913  }
914  }
915  delete f;
916  }
917  if (!volume) return NULL;
918  volume->RegisterYourself();
919  return volume;
920 }
921 
922 ////////////////////////////////////////////////////////////////////////////////
923 /// Export this volume to a file.
924 ///
925 /// - Case 1: root file or root/xml file
926 /// if filename end with ".root". The key will be named name
927 /// if filename end with ".xml" a root/xml file is produced.
928 ///
929 /// - Case 2: C++ script
930 /// if filename end with ".C"
931 ///
932 /// - Case 3: gdml file
933 /// if filename end with ".gdml"
934 ///
935 /// NOTE that to use this option, the PYTHONPATH must be defined like
936 /// export PYTHONPATH=$ROOTSYS/lib:$ROOTSYS/gdml
937 ///
938 
939 Int_t TGeoVolume::Export(const char *filename, const char *name, Option_t *option)
940 {
941  TString sfile(filename);
942  if (sfile.Contains(".C")) {
943  //Save volume as a C++ script
944  Info("Export","Exporting volume %s as C++ code", GetName());
945  SaveAs(filename, "");
946  return 1;
947  }
948  if (sfile.Contains(".gdml")) {
949  //Save geometry as a gdml file
950  Info("Export","Exporting %s as gdml code - not implemented yet", GetName());
951  return 0;
952  }
953  if (sfile.Contains(".root") || sfile.Contains(".xml")) {
954  //Save volume in a root file
955  Info("Export","Exporting %s as root file.", GetName());
956  TString opt(option);
957  if (!opt.Length()) opt = "recreate";
958  TFile *f = TFile::Open(filename,opt.Data());
959  if (!f || f->IsZombie()) {
960  Error("Export","Cannot open file");
961  return 0;
962  }
963  TString keyname(name);
964  if (keyname.IsNull()) keyname = GetName();
965  Int_t nbytes = Write(keyname);
966  delete f;
967  return nbytes;
968  }
969  return 0;
970 }
971 
972 ////////////////////////////////////////////////////////////////////////////////
973 /// Actualize matrix of node indexed <inode>
974 
975 void TGeoVolume::cd(Int_t inode) const
976 {
977  if (fFinder) fFinder->cd(inode-fFinder->GetDivIndex());
978 }
979 
980 ////////////////////////////////////////////////////////////////////////////////
981 /// Add a TGeoNode to the list of nodes. This is the usual method for adding
982 /// daughters inside the container volume.
983 
984 void TGeoVolume::AddNode(TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat, Option_t * /*option*/)
985 {
986  TGeoMatrix *matrix = mat;
987  if (matrix==0) matrix = gGeoIdentity;
988  else matrix->RegisterYourself();
989  if (!vol) {
990  Error("AddNode", "Volume is NULL");
991  return;
992  }
993  if (!vol->IsValid()) {
994  Error("AddNode", "Won't add node with invalid shape");
995  printf("### invalid volume was : %s\n", vol->GetName());
996  return;
997  }
998  if (!fNodes) fNodes = new TObjArray();
999 
1000  if (fFinder) {
1001  // volume already divided.
1002  Error("AddNode", "Cannot add node %s_%i into divided volume %s", vol->GetName(), copy_no, GetName());
1003  return;
1004  }
1005 
1006  TGeoNodeMatrix *node = 0;
1007  node = new TGeoNodeMatrix(vol, matrix);
1008  node->SetMotherVolume(this);
1009  fNodes->Add(node);
1010  TString name = TString::Format("%s_%d", vol->GetName(), copy_no);
1011 // if (fNodes->FindObject(name))
1012 // Warning("AddNode", "Volume %s : added node %s with same name", GetName(), name.Data());
1013  node->SetName(name);
1014  node->SetNumber(copy_no);
1015  fRefCount++;
1016  vol->Grab();
1017 }
1018 
1019 ////////////////////////////////////////////////////////////////////////////////
1020 /// Add a division node to the list of nodes. The method is called by
1021 /// TGeoVolume::Divide() for creating the division nodes.
1022 
1023 void TGeoVolume::AddNodeOffset(TGeoVolume *vol, Int_t copy_no, Double_t offset, Option_t * /*option*/)
1024 {
1025  if (!vol) {
1026  Error("AddNodeOffset", "invalid volume");
1027  return;
1028  }
1029  if (!vol->IsValid()) {
1030  Error("AddNode", "Won't add node with invalid shape");
1031  printf("### invalid volume was : %s\n", vol->GetName());
1032  return;
1033  }
1034  if (!fNodes) fNodes = new TObjArray();
1035  TGeoNode *node = new TGeoNodeOffset(vol, copy_no, offset);
1036  node->SetMotherVolume(this);
1037  fNodes->Add(node);
1038  TString name = TString::Format("%s_%d", vol->GetName(), copy_no+1);
1039  node->SetName(name);
1040  node->SetNumber(copy_no+1);
1041  vol->Grab();
1042 }
1043 
1044 ////////////////////////////////////////////////////////////////////////////////
1045 /// Add a TGeoNode to the list of nodes. This is the usual method for adding
1046 /// daughters inside the container volume.
1047 
1049 {
1050  if (!vol) {
1051  Error("AddNodeOverlap", "Volume is NULL");
1052  return;
1053  }
1054  if (!vol->IsValid()) {
1055  Error("AddNodeOverlap", "Won't add node with invalid shape");
1056  printf("### invalid volume was : %s\n", vol->GetName());
1057  return;
1058  }
1059  if (vol->IsAssembly()) {
1060  Warning("AddNodeOverlap", "Declaring assembly %s as possibly overlapping inside %s not allowed. Using AddNode instead !",vol->GetName(),GetName());
1061  AddNode(vol, copy_no, mat, option);
1062  return;
1063  }
1064  TGeoMatrix *matrix = mat;
1065  if (matrix==0) matrix = gGeoIdentity;
1066  else matrix->RegisterYourself();
1067  if (!fNodes) fNodes = new TObjArray();
1068 
1069  if (fFinder) {
1070  // volume already divided.
1071  Error("AddNodeOverlap", "Cannot add node %s_%i into divided volume %s", vol->GetName(), copy_no, GetName());
1072  return;
1073  }
1074 
1075  TGeoNodeMatrix *node = new TGeoNodeMatrix(vol, matrix);
1076  node->SetMotherVolume(this);
1077  fNodes->Add(node);
1078  TString name = TString::Format("%s_%d", vol->GetName(), copy_no);
1079  if (fNodes->FindObject(name))
1080  Warning("AddNode", "Volume %s : added node %s with same name", GetName(), name.Data());
1081  node->SetName(name);
1082  node->SetNumber(copy_no);
1083  node->SetOverlapping();
1084  if (vol->GetMedium() == fMedium)
1085  node->SetVirtual();
1086  vol->Grab();
1087 }
1088 
1089 ////////////////////////////////////////////////////////////////////////////////
1090 /// Division a la G3. The volume will be divided along IAXIS (see shape classes), in NDIV
1091 /// slices, from START with given STEP. The division volumes will have medium number NUMED.
1092 /// If NUMED=0 they will get the medium number of the divided volume (this). If NDIV<=0,
1093 /// all range of IAXIS will be divided and the resulting number of divisions will be centered on
1094 /// IAXIS. If STEP<=0, the real STEP will be computed as the full range of IAXIS divided by NDIV.
1095 /// Options (case insensitive):
1096 /// - N - divide all range in NDIV cells (same effect as STEP<=0) (GSDVN in G3)
1097 /// - NX - divide range starting with START in NDIV cells (GSDVN2 in G3)
1098 /// - S - divide all range with given STEP. NDIV is computed and divisions will be centered
1099 /// in full range (same effect as NDIV<=0) (GSDVS, GSDVT in G3)
1100 /// - SX - same as DVS, but from START position. (GSDVS2, GSDVT2 in G3)
1101 
1102 TGeoVolume *TGeoVolume::Divide(const char *divname, Int_t iaxis, Int_t ndiv, Double_t start, Double_t step, Int_t numed, Option_t *option)
1103 {
1104  if (fFinder) {
1105  // volume already divided.
1106  Fatal("Divide","volume %s already divided", GetName());
1107  return 0;
1108  }
1109  TString opt(option);
1110  opt.ToLower();
1111  TString stype = fShape->ClassName();
1112  if (!fNodes) fNodes = new TObjArray();
1113  Double_t xlo, xhi, range;
1114  range = fShape->GetAxisRange(iaxis, xlo, xhi);
1115  // for phi divisions correct the range
1116  if (!strcmp(fShape->GetAxisName(iaxis), "PHI")) {
1117  if ((start-xlo)<-1E-3) start+=360.;
1118  if (TGeoShape::IsSameWithinTolerance(range,360)) {
1119  xlo = start;
1120  xhi = start+range;
1121  }
1122  }
1123  if (range <=0) {
1124  InspectShape();
1125  Fatal("Divide", "cannot divide volume %s (%s) on %s axis", GetName(), stype.Data(), fShape->GetAxisName(iaxis));
1126  return 0;
1127  }
1128  if (ndiv<=0 || opt.Contains("s")) {
1129  if (step<=0) {
1130  Fatal("Divide", "invalid division type for volume %s : ndiv=%i, step=%g", GetName(), ndiv, step);
1131  return 0;
1132  }
1133  if (opt.Contains("x")) {
1134  if ((xlo-start)>1E-3 || (xhi-start)<-1E-3) {
1135  Fatal("Divide", "invalid START=%g for division on axis %s of volume %s. Range is (%g, %g)",
1136  start, fShape->GetAxisName(iaxis), GetName(), xlo, xhi);
1137  return 0;
1138  }
1139  xlo = start;
1140  range = xhi-xlo;
1141  }
1142  ndiv = Int_t((range+0.1*step)/step);
1143  Double_t ddx = range - ndiv*step;
1144  // always center the division in this case
1145  if (ddx>1E-3) Warning("Divide", "division of volume %s on %s axis (ndiv=%d) will be centered in the full range",
1146  GetName(), fShape->GetAxisName(iaxis), ndiv);
1147  start = xlo + 0.5*ddx;
1148  }
1149  if (step<=0 || opt.Contains("n")) {
1150  if (opt.Contains("x")) {
1151  if ((xlo-start)>1E-3 || (xhi-start)<-1E-3) {
1152  Fatal("Divide", "invalid START=%g for division on axis %s of volume %s. Range is (%g, %g)",
1153  start, fShape->GetAxisName(iaxis), GetName(), xlo, xhi);
1154  return 0;
1155  }
1156  xlo = start;
1157  range = xhi-xlo;
1158  }
1159  step = range/ndiv;
1160  start = xlo;
1161  }
1162 
1163  Double_t end = start+ndiv*step;
1164  if (((start-xlo)<-1E-3) || ((end-xhi)>1E-3)) {
1165  Fatal("Divide", "division of volume %s on axis %s exceed range (%g, %g)",
1166  GetName(), fShape->GetAxisName(iaxis), xlo, xhi);
1167  return 0;
1168  }
1169  TGeoVolume *voldiv = fShape->Divide(this, divname, iaxis, ndiv, start, step);
1170  if (numed) {
1171  TGeoMedium *medium = fGeoManager->GetMedium(numed);
1172  if (!medium) {
1173  Fatal("Divide", "invalid medium number %d for division volume %s", numed, divname);
1174  return voldiv;
1175  }
1176  voldiv->SetMedium(medium);
1177  if (medium->GetMaterial()) medium->GetMaterial()->SetUsed();
1178  }
1179  return voldiv;
1180 }
1181 
1182 ////////////////////////////////////////////////////////////////////////////////
1183 /// compute the closest distance of approach from point px,py to this volume
1184 
1186 {
1189  Int_t dist = 9999;
1190  if (!painter) return dist;
1191  dist = painter->DistanceToPrimitiveVol(this, px, py);
1192  return dist;
1193 }
1194 
1195 ////////////////////////////////////////////////////////////////////////////////
1196 /// draw top volume according to option
1197 
1199 {
1204  if (!IsVisContainers()) SetVisLeaves();
1205  if (option && option[0] > 0) {
1206  painter->DrawVolume(this, option);
1207  } else {
1208  painter->DrawVolume(this, gEnv->GetValue("Viewer3D.DefaultDrawOption",""));
1209  }
1210 }
1211 
1212 ////////////////////////////////////////////////////////////////////////////////
1213 /// draw only this volume
1214 
1216 {
1217  if (IsAssembly()) {
1218  Info("DrawOnly", "Volume assemblies do not support this option.");
1219  return;
1220  }
1222  SetVisOnly();
1225  if (option && option[0] > 0) {
1226  painter->DrawVolume(this, option);
1227  } else {
1228  painter->DrawVolume(this, gEnv->GetValue("Viewer3D.DefaultDrawOption",""));
1229  }
1230 }
1231 
1232 ////////////////////////////////////////////////////////////////////////////////
1233 /// Perform an extensive sampling to find which type of voxelization is
1234 /// most efficient.
1235 
1237 {
1238  printf("Optimizing volume %s ...\n", GetName());
1240  return painter->TestVoxels(this);
1241 }
1242 
1243 ////////////////////////////////////////////////////////////////////////////////
1244 /// Print volume info
1245 
1247 {
1248  printf("== Volume: %s type %s positioned %d times\n", GetName(), ClassName(), fRefCount);
1249  InspectShape();
1250  InspectMaterial();
1251 }
1252 
1253 ////////////////////////////////////////////////////////////////////////////////
1254 /// paint volume
1255 
1257 {
1259  painter->SetTopVolume(this);
1260 // painter->Paint(option);
1261  if (option && option[0] > 0) {
1262  painter->Paint(option);
1263  } else {
1264  painter->Paint(gEnv->GetValue("Viewer3D.DefaultDrawOption",""));
1265  }
1266 }
1267 
1268 ////////////////////////////////////////////////////////////////////////////////
1269 /// Print the voxels for this volume.
1270 
1272 {
1273  if (fVoxels) fVoxels->Print();
1274 }
1275 
1276 ////////////////////////////////////////////////////////////////////////////////
1277 /// Recreate the content of the other volume without pointer copying. Voxels are
1278 /// ignored and supposed to be created in a later step via Voxelize.
1279 
1281 {
1282  Int_t nd = other->GetNdaughters();
1283  if (!nd) return;
1284  TGeoPatternFinder *finder = other->GetFinder();
1285  if (finder) {
1286  Int_t iaxis = finder->GetDivAxis();
1287  Int_t ndiv = finder->GetNdiv();
1288  Double_t start = finder->GetStart();
1289  Double_t step = finder->GetStep();
1290  Int_t numed = other->GetNode(0)->GetVolume()->GetMedium()->GetId();
1291  TGeoVolume *voldiv = Divide(other->GetNode(0)->GetVolume()->GetName(), iaxis, ndiv, start, step, numed);
1292  voldiv->ReplayCreation(other->GetNode(0)->GetVolume());
1293  return;
1294  }
1295  for (Int_t i=0; i<nd; i++) {
1296  TGeoNode *node = other->GetNode(i);
1297  if (node->IsOverlapping()) AddNodeOverlap(node->GetVolume(), node->GetNumber(), node->GetMatrix());
1298  else AddNode(node->GetVolume(), node->GetNumber(), node->GetMatrix());
1299  }
1300 }
1301 
1302 ////////////////////////////////////////////////////////////////////////////////
1303 /// print nodes
1304 
1306 {
1307  Int_t nd = GetNdaughters();
1308  for (Int_t i=0; i<nd; i++) {
1309  printf("%s\n", GetNode(i)->GetName());
1310  cd(i);
1311  GetNode(i)->GetMatrix()->Print();
1312  }
1313 }
1314 ////////////////////////////////////////////////////////////////////////////////
1315 /// Generate a lego plot fot the top volume, according to option.
1316 
1318  Int_t nphi, Double_t phimin, Double_t phimax,
1319  Double_t rmin, Double_t rmax, Option_t *option)
1320 {
1322  TGeoVolume *old_vol = fGeoManager->GetTopVolume();
1323  if (old_vol!=this) fGeoManager->SetTopVolume(this);
1324  else old_vol=0;
1325  TH2F *hist = p->LegoPlot(ntheta, themin, themax, nphi, phimin, phimax, rmin, rmax, option);
1326  hist->Draw("lego1sph");
1327  return hist;
1328 }
1329 
1330 ////////////////////////////////////////////////////////////////////////////////
1331 /// Register the volume and all materials/media/matrices/shapes to the manager.
1332 
1334 {
1335  if (fGeoManager->GetListOfVolumes()->FindObject(this)) return;
1336  // Register volume
1337  fGeoManager->AddVolume(this);
1338  // Register shape
1340  if (fShape->IsComposite()) {
1342  comp->RegisterYourself();
1343  } else {
1345  }
1346  }
1347  // Register medium/material
1352  }
1353  // Register matrices for nodes.
1354  TGeoMatrix *matrix;
1355  TGeoNode *node;
1356  Int_t nd = GetNdaughters();
1357  Int_t i;
1358  for (i=0; i<nd; i++) {
1359  node = GetNode(i);
1360  matrix = node->GetMatrix();
1361  if (!matrix->IsRegistered()) matrix->RegisterYourself();
1362  else if (!fGeoManager->GetListOfMatrices()->FindObject(matrix)) {
1363  fGeoManager->GetListOfMatrices()->Add(matrix);
1364  }
1365  }
1366  // Call RegisterYourself recursively
1367  for (i=0; i<nd; i++) GetNode(i)->GetVolume()->RegisterYourself(option);
1368 }
1369 
1370 ////////////////////////////////////////////////////////////////////////////////
1371 /// Draw random points in the bounding box of this volume.
1372 
1374 {
1376  TGeoVolume *old_vol = fGeoManager->GetTopVolume();
1377  if (old_vol!=this) fGeoManager->SetTopVolume(this);
1378  else old_vol=0;
1379  fGeoManager->RandomPoints(this, npoints, option);
1380  if (old_vol) fGeoManager->SetTopVolume(old_vol);
1381 }
1382 
1383 ////////////////////////////////////////////////////////////////////////////////
1384 /// Random raytracing method.
1385 
1386 void TGeoVolume::RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz, const char *target_vol, Bool_t check_norm)
1387 {
1389  TGeoVolume *old_vol = fGeoManager->GetTopVolume();
1390  if (old_vol!=this) fGeoManager->SetTopVolume(this);
1391  else old_vol=0;
1392  fGeoManager->RandomRays(nrays, startx, starty, startz, target_vol, check_norm);
1393  if (old_vol) fGeoManager->SetTopVolume(old_vol);
1394 }
1395 
1396 ////////////////////////////////////////////////////////////////////////////////
1397 /// Draw this volume with current settings and perform raytracing in the pad.
1398 
1400 {
1404  Bool_t drawn = (painter->GetDrawnVolume()==this)?kTRUE:kFALSE;
1405  if (!drawn) {
1406  painter->DrawVolume(this, "");
1408  painter->ModifiedPad();
1409  return;
1410  }
1412  painter->ModifiedPad();
1413 }
1414 
1415 ////////////////////////////////////////////////////////////////////////////////
1416 /// Save geometry having this as top volume as a C++ macro.
1417 
1418 void TGeoVolume::SaveAs(const char *filename, Option_t *option) const
1419 {
1420  if (!filename) return;
1421  std::ofstream out;
1422  out.open(filename, std::ios::out);
1423  if (out.bad()) {
1424  Error("SavePrimitive", "Bad file name: %s", filename);
1425  return;
1426  }
1427  if (fGeoManager->GetTopVolume() != this) fGeoManager->SetTopVolume((TGeoVolume*)this);
1428 
1429  TString fname(filename);
1430  Int_t ind = fname.Index(".");
1431  if (ind>0) fname.Remove(ind);
1432  out << "void "<<fname<<"() {" << std::endl;
1433  out << " gSystem->Load(\"libGeom\");" << std::endl;
1434  ((TGeoVolume*)this)->SavePrimitive(out,option);
1435  out << "}" << std::endl;
1436 }
1437 
1438 ////////////////////////////////////////////////////////////////////////////////
1439 /// Connect user-defined extension to the volume. The volume "grabs" a copy, so
1440 /// the original object can be released by the producer. Release the previously
1441 /// connected extension if any.
1442 ///
1443 /// NOTE: This interface is intended for user extensions and is guaranteed not
1444 /// to be used by TGeo
1445 
1447 {
1449  fUserExtension = 0;
1450  if (ext) fUserExtension = ext->Grab();
1451 }
1452 
1453 ////////////////////////////////////////////////////////////////////////////////
1454 /// Connect framework defined extension to the volume. The volume "grabs" a copy,
1455 /// so the original object can be released by the producer. Release the previously
1456 /// connected extension if any.
1457 ///
1458 /// NOTE: This interface is intended for the use by TGeo and the users should
1459 /// NOT connect extensions using this method
1460 
1462 {
1464  fFWExtension = 0;
1465  if (ext) fFWExtension = ext->Grab();
1466 }
1467 
1468 ////////////////////////////////////////////////////////////////////////////////
1469 /// Get a copy of the user extension pointer. The user must call Release() on
1470 /// the copy pointer once this pointer is not needed anymore (equivalent to
1471 /// delete() after calling new())
1472 
1474 {
1475  if (fUserExtension) return fUserExtension->Grab();
1476  return 0;
1477 }
1478 
1479 ////////////////////////////////////////////////////////////////////////////////
1480 /// Get a copy of the framework extension pointer. The user must call Release() on
1481 /// the copy pointer once this pointer is not needed anymore (equivalent to
1482 /// delete() after calling new())
1483 
1485 {
1486  if (fFWExtension) return fFWExtension->Grab();
1487  return 0;
1488 }
1489 
1490 ////////////////////////////////////////////////////////////////////////////////
1491 /// Save a primitive as a C++ statement(s) on output stream "out".
1492 
1493 void TGeoVolume::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
1494 {
1495  out.precision(6);
1496  out.setf(std::ios::fixed);
1497  Int_t i,icopy;
1498  Int_t nd = GetNdaughters();
1499  TGeoVolume *dvol;
1500  TGeoNode *dnode;
1501  TGeoMatrix *matrix;
1502 
1503  // check if we need to save shape/volume
1504  Bool_t mustDraw = kFALSE;
1505  if (fGeoManager->GetGeomPainter()->GetTopVolume()==this) mustDraw = kTRUE;
1506  if (!option[0]) {
1508  out << " new TGeoManager(\"" << fGeoManager->GetName() << "\", \"" << fGeoManager->GetTitle() << "\");" << std::endl << std::endl;
1509 // if (mustDraw) out << " Bool_t mustDraw = kTRUE;" << std::endl;
1510 // else out << " Bool_t mustDraw = kFALSE;" << std::endl;
1511  out << " Double_t dx,dy,dz;" << std::endl;
1512  out << " Double_t dx1, dx2, dy1, dy2;" << std::endl;
1513  out << " Double_t vert[20], par[20];" << std::endl;
1514  out << " Double_t theta, phi, h1, bl1, tl1, alpha1, h2, bl2, tl2, alpha2;" << std::endl;
1515  out << " Double_t twist;" << std::endl;
1516  out << " Double_t origin[3];" << std::endl;
1517  out << " Double_t rmin, rmax, rmin1, rmax1, rmin2, rmax2;" << std::endl;
1518  out << " Double_t r, rlo, rhi;" << std::endl;
1519  out << " Double_t phi1, phi2;" << std::endl;
1520  out << " Double_t a,b;" << std::endl;
1521  out << " Double_t point[3], norm[3];" << std::endl;
1522  out << " Double_t rin, stin, rout, stout;" << std::endl;
1523  out << " Double_t thx, phx, thy, phy, thz, phz;" << std::endl;
1524  out << " Double_t alpha, theta1, theta2, phi1, phi2, dphi;" << std::endl;
1525  out << " Double_t tr[3], rot[9];" << std::endl;
1526  out << " Double_t z, density, radl, absl, w;" << std::endl;
1527  out << " Double_t lx,ly,lz,tx,ty,tz;" << std::endl;
1528  out << " Double_t xvert[50], yvert[50];" << std::endl;
1529  out << " Double_t zsect,x0,y0,scale0;" << std::endl;
1530  out << " Int_t nel, numed, nz, nedges, nvert;" << std::endl;
1531  out << " TGeoBoolNode *pBoolNode = 0;" << std::endl << std::endl;
1532  // first save materials/media
1533  out << " // MATERIALS, MIXTURES AND TRACKING MEDIA" << std::endl;
1534  SavePrimitive(out, "m");
1535  // then, save matrices
1536  out << std::endl << " // TRANSFORMATION MATRICES" << std::endl;
1537  SavePrimitive(out, "x");
1538  // save this volume and shape
1539  SavePrimitive(out, "s");
1540  out << std::endl << " // SET TOP VOLUME OF GEOMETRY" << std::endl;
1541  out << " gGeoManager->SetTopVolume(" << GetPointerName() << ");" << std::endl;
1542  // save daughters
1543  out << std::endl << " // SHAPES, VOLUMES AND GEOMETRICAL HIERARCHY" << std::endl;
1544  SavePrimitive(out, "d");
1545  out << std::endl << " // CLOSE GEOMETRY" << std::endl;
1546  out << " gGeoManager->CloseGeometry();" << std::endl;
1547  if (mustDraw) {
1548  if (!IsRaytracing()) out << " gGeoManager->GetTopVolume()->Draw();" << std::endl;
1549  else out << " gGeoManager->GetTopVolume()->Raytrace();" << std::endl;
1550  }
1551  return;
1552  }
1553  // check if we need to save shape/volume
1554  if (!strcmp(option, "s")) {
1555  // create the shape for this volume
1557  if (!IsAssembly()) {
1558  fShape->SavePrimitive(out,option);
1559  out << " // Volume: " << GetName() << std::endl;
1560  if (fMedium) out << " " << GetPointerName() << " = new TGeoVolume(\"" << GetName() << "\"," << fShape->GetPointerName() << ", "<< fMedium->GetPointerName() << ");" << std::endl;
1561  else out << " " << GetPointerName() << " = new TGeoVolume(\"" << GetName() << "\"," << fShape->GetPointerName() << ");" << std::endl;
1562 
1563  } else {
1564  out << " // Assembly: " << GetName() << std::endl;
1565  out << " " << GetPointerName() << " = new TGeoVolumeAssembly(\"" << GetName() << "\"" << ");" << std::endl;
1566  }
1567  if (fLineColor != 1) out << " " << GetPointerName() << "->SetLineColor(" << fLineColor << ");" << std::endl;
1568  if (fLineWidth != 1) out << " " << GetPointerName() << "->SetLineWidth(" << fLineWidth << ");" << std::endl;
1569  if (fLineStyle != 1) out << " " << GetPointerName() << "->SetLineStyle(" << fLineStyle << ");" << std::endl;
1570  if (!IsVisible() && !IsAssembly()) out << " " << GetPointerName() << "->SetVisibility(kFALSE);" << std::endl;
1571  if (!IsVisibleDaughters()) out << " " << GetPointerName() << "->VisibleDaughters(kFALSE);" << std::endl;
1572  if (IsVisContainers()) out << " " << GetPointerName() << "->SetVisContainers(kTRUE);" << std::endl;
1573  if (IsVisLeaves()) out << " " << GetPointerName() << "->SetVisLeaves(kTRUE);" << std::endl;
1575  }
1576  // check if we need to save the media
1577  if (!strcmp(option, "m")) {
1578  if (fMedium) fMedium->SavePrimitive(out,option);
1579  for (i=0; i<nd; i++) {
1580  dvol = GetNode(i)->GetVolume();
1581  dvol->SavePrimitive(out,option);
1582  }
1583  return;
1584  }
1585  // check if we need to save the matrices
1586  if (!strcmp(option, "x")) {
1587  if (fFinder) {
1588  dvol = GetNode(0)->GetVolume();
1589  dvol->SavePrimitive(out,option);
1590  return;
1591  }
1592  for (i=0; i<nd; i++) {
1593  dnode = GetNode(i);
1594  matrix = dnode->GetMatrix();
1595  if (!matrix->IsIdentity()) matrix->SavePrimitive(out,option);
1596  dnode->GetVolume()->SavePrimitive(out,option);
1597  }
1598  return;
1599  }
1600  // check if we need to save volume daughters
1601  if (!strcmp(option, "d")) {
1602  if (!nd) return;
1603  if (TestAttBit(TGeoAtt::kSaveNodesAtt)) return;
1605  if (fFinder) {
1606  // volume divided: generate volume->Divide()
1607  dnode = GetNode(0);
1608  dvol = dnode->GetVolume();
1609  out << " TGeoVolume *" << dvol->GetPointerName() << " = ";
1610  out << GetPointerName() << "->Divide(\"" << dvol->GetName() << "\", ";
1611  fFinder->SavePrimitive(out,option);
1612  if (fMedium != dvol->GetMedium()) {
1613  out << ", " << dvol->GetMedium()->GetId();
1614  }
1615  out << ");" << std::endl;
1616  dvol->SavePrimitive(out,"d");
1617  return;
1618  }
1619  for (i=0; i<nd; i++) {
1620  dnode = GetNode(i);
1621  dvol = dnode->GetVolume();
1622  dvol->SavePrimitive(out,"s");
1623  matrix = dnode->GetMatrix();
1624  icopy = dnode->GetNumber();
1625  // generate AddNode()
1626  out << " " << GetPointerName() << "->AddNode";
1627  if (dnode->IsOverlapping()) out << "Overlap";
1628  out << "(" << dvol->GetPointerName() << ", " << icopy;
1629  if (!matrix->IsIdentity()) out << ", " << matrix->GetPointerName();
1630  out << ");" << std::endl;
1631  }
1632  // Recursive loop to daughters
1633  for (i=0; i<nd; i++) {
1634  dnode = GetNode(i);
1635  dvol = dnode->GetVolume();
1636  dvol->SavePrimitive(out,"d");
1637  }
1638  }
1639 }
1640 
1641 ////////////////////////////////////////////////////////////////////////////////
1642 /// Reset SavePrimitive bits.
1643 
1645 {
1649 }
1650 
1651 ////////////////////////////////////////////////////////////////////////////////
1652 /// Execute mouse actions on this volume.
1653 
1655 {
1657  if (!painter) return;
1658  painter->ExecuteVolumeEvent(this, event, px, py);
1659 }
1660 
1661 ////////////////////////////////////////////////////////////////////////////////
1662 /// search a daughter inside the list of nodes
1663 
1665 {
1666  return ((TGeoNode*)fNodes->FindObject(name));
1667 }
1668 
1669 ////////////////////////////////////////////////////////////////////////////////
1670 /// Get the index of a daughter within check_list by providing the node pointer.
1671 
1672 Int_t TGeoVolume::GetNodeIndex(const TGeoNode *node, Int_t *check_list, Int_t ncheck) const
1673 {
1674  TGeoNode *current = 0;
1675  for (Int_t i=0; i<ncheck; i++) {
1676  current = (TGeoNode*)fNodes->At(check_list[i]);
1677  if (current==node) return check_list[i];
1678  }
1679  return -1;
1680 }
1681 
1682 ////////////////////////////////////////////////////////////////////////////////
1683 /// get index number for a given daughter
1684 
1686 {
1687  TGeoNode *current = 0;
1688  Int_t nd = GetNdaughters();
1689  if (!nd) return -1;
1690  for (Int_t i=0; i<nd; i++) {
1691  current = (TGeoNode*)fNodes->At(i);
1692  if (current==node) return i;
1693  }
1694  return -1;
1695 }
1696 
1697 ////////////////////////////////////////////////////////////////////////////////
1698 /// Get volume info for the browser.
1699 
1701 {
1702  TGeoVolume *vol = (TGeoVolume*)this;
1704  if (!painter) return 0;
1705  return (char*)painter->GetVolumeInfo(vol, px, py);
1706 }
1707 
1708 ////////////////////////////////////////////////////////////////////////////////
1709 /// Returns true if cylindrical voxelization is optimal.
1710 
1712 {
1713  Int_t nd = GetNdaughters();
1714  if (!nd) return kFALSE;
1715  Int_t id;
1716  Int_t ncyl = 0;
1717  TGeoNode *node;
1718  for (id=0; id<nd; id++) {
1719  node = (TGeoNode*)fNodes->At(id);
1720  ncyl += node->GetOptimalVoxels();
1721  }
1722  if (ncyl>(nd/2)) return kTRUE;
1723  return kFALSE;
1724 }
1725 
1726 ////////////////////////////////////////////////////////////////////////////////
1727 /// Provide a pointer name containing uid.
1728 
1730 {
1731  static TString name;
1732  name = TString::Format("p%s_%lx", GetName(), (ULong_t)this);
1733  return (char*)name.Data();
1734 }
1735 
1736 ////////////////////////////////////////////////////////////////////////////////
1737 /// Getter for optimization structure.
1738 
1740 {
1741  if (fVoxels && !fVoxels->IsInvalid()) return fVoxels;
1742  return NULL;
1743 }
1744 
1745 ////////////////////////////////////////////////////////////////////////////////
1746 /// Move perspective view focus to this volume
1747 
1749 {
1751  if (painter) painter->GrabFocus();
1752 }
1753 
1754 ////////////////////////////////////////////////////////////////////////////////
1755 /// Returns true if the volume is an assembly or a scaled assembly.
1756 
1758 {
1759  return fShape->IsAssembly();
1760 }
1761 
1762 ////////////////////////////////////////////////////////////////////////////////
1763 /// Clone this volume.
1764 /// build a volume with same name, shape and medium
1765 
1767 {
1768  TGeoVolume *vol = new TGeoVolume(GetName(), fShape, fMedium);
1769  Int_t i;
1770  // copy volume attributes
1771  vol->SetLineColor(GetLineColor());
1772  vol->SetLineStyle(GetLineStyle());
1773  vol->SetLineWidth(GetLineWidth());
1774  vol->SetFillColor(GetFillColor());
1775  vol->SetFillStyle(GetFillStyle());
1776  // copy other attributes
1777  Int_t nbits = 8*sizeof(UInt_t);
1778  for (i=0; i<nbits; i++)
1779  vol->SetAttBit(1<<i, TGeoAtt::TestAttBit(1<<i));
1780  for (i=14; i<24; i++)
1781  vol->SetBit(1<<i, TestBit(1<<i));
1782 
1783  // copy field
1784  vol->SetField(fField);
1785  // Set bits
1786  for (i=0; i<nbits; i++)
1787  vol->SetBit(1<<i, TObject::TestBit(1<<i));
1788  vol->SetBit(kVolumeClone);
1789  // copy nodes
1790 // CloneNodesAndConnect(vol);
1791  vol->MakeCopyNodes(this);
1792  // if volume is divided, copy finder
1793  vol->SetFinder(fFinder);
1794  // copy voxels
1795  TGeoVoxelFinder *voxels = 0;
1796  if (fVoxels) {
1797  voxels = new TGeoVoxelFinder(vol);
1798  vol->SetVoxelFinder(voxels);
1799  }
1800  // copy option, uid
1801  vol->SetOption(fOption);
1802  vol->SetNumber(fNumber);
1803  vol->SetNtotal(fNtotal);
1804  // copy extensions
1808  return vol;
1809 }
1810 
1811 ////////////////////////////////////////////////////////////////////////////////
1812 /// Clone the array of nodes.
1813 
1815 {
1816  if (!fNodes) return;
1817  TGeoNode *node;
1818  Int_t nd = fNodes->GetEntriesFast();
1819  if (!nd) return;
1820  // create new list of nodes
1821  TObjArray *list = new TObjArray(nd);
1822  // attach it to new volume
1823  newmother->SetNodes(list);
1824 // ((TObject*)newmother)->SetBit(kVolumeImportNodes);
1825  for (Int_t i=0; i<nd; i++) {
1826  //create copies of nodes and add them to list
1827  node = GetNode(i)->MakeCopyNode();
1828  if (!node) {
1829  Fatal("CloneNodesAndConnect", "cannot make copy node");
1830  return;
1831  }
1832  node->SetMotherVolume(newmother);
1833  list->Add(node);
1834  }
1835 }
1836 
1837 ////////////////////////////////////////////////////////////////////////////////
1838 /// make a new list of nodes and copy all nodes of other volume inside
1839 
1841 {
1842  Int_t nd = other->GetNdaughters();
1843  if (!nd) return;
1844  if (fNodes) {
1846  delete fNodes;
1847  }
1848  fNodes = new TObjArray();
1849  for (Int_t i=0; i<nd; i++) fNodes->Add(other->GetNode(i));
1851 }
1852 
1853 ////////////////////////////////////////////////////////////////////////////////
1854 /// make a copy of this volume
1855 /// build a volume with same name, shape and medium
1856 
1858 {
1859  TGeoVolume *vol = new TGeoVolume(GetName(), newshape, fMedium);
1860  // copy volume attributes
1861  vol->SetVisibility(IsVisible());
1862  vol->SetLineColor(GetLineColor());
1863  vol->SetLineStyle(GetLineStyle());
1864  vol->SetLineWidth(GetLineWidth());
1865  vol->SetFillColor(GetFillColor());
1866  vol->SetFillStyle(GetFillStyle());
1867  // copy field
1868  vol->SetField(fField);
1869  // if divided, copy division object
1870  if (fFinder) {
1871 // Error("MakeCopyVolume", "volume %s divided", GetName());
1872  vol->SetFinder(fFinder);
1873  }
1874  // Copy extensions
1877  CloneNodesAndConnect(vol);
1878 // ((TObject*)vol)->SetBit(kVolumeImportNodes);
1879  ((TObject*)vol)->SetBit(kVolumeClone);
1881  return vol;
1882 }
1883 
1884 ////////////////////////////////////////////////////////////////////////////////
1885 /// Make a copy of this volume which is reflected with respect to XY plane.
1886 
1887 TGeoVolume *TGeoVolume::MakeReflectedVolume(const char *newname) const
1888 {
1889  static TMap map(100);
1890  if (!fGeoManager->IsClosed()) {
1891  Error("MakeReflectedVolume", "Geometry must be closed.");
1892  return NULL;
1893  }
1894  TGeoVolume *vol = (TGeoVolume*)map.GetValue(this);
1895  if (vol) {
1896  if (newname && newname[0]) vol->SetName(newname);
1897  return vol;
1898  }
1899 // printf("Making reflection for volume: %s\n", GetName());
1900  vol = CloneVolume();
1901  if (!vol) {
1902  Fatal("MakeReflectedVolume", "Cannot clone volume %s\n", GetName());
1903  return 0;
1904  }
1905  map.Add((TObject*)this, vol);
1906  if (newname && newname[0]) vol->SetName(newname);
1907  delete vol->GetNodes();
1908  vol->SetNodes(NULL);
1910  CloneNodesAndConnect(vol);
1911  // The volume is now properly cloned, but with the same shape.
1912  // Reflect the shape (if any) and connect it.
1913  if (fShape) {
1914  TGeoShape *reflected_shape =
1915  TGeoScaledShape::MakeScaledShape("", fShape, new TGeoScale(1.,1.,-1.));
1916  vol->SetShape(reflected_shape);
1917  }
1918  // Reflect the daughters.
1919  Int_t nd = vol->GetNdaughters();
1920  if (!nd) return vol;
1921  TGeoNodeMatrix *node;
1922  TGeoMatrix *local, *local_cloned;
1923  TGeoVolume *new_vol;
1924  if (!vol->GetFinder()) {
1925  for (Int_t i=0; i<nd; i++) {
1926  node = (TGeoNodeMatrix*)vol->GetNode(i);
1927  local = node->GetMatrix();
1928 // printf("%s before\n", node->GetName());
1929 // local->Print();
1930  Bool_t reflected = local->IsReflection();
1931  local_cloned = new TGeoCombiTrans(*local);
1932  local_cloned->RegisterYourself();
1933  node->SetMatrix(local_cloned);
1934  if (!reflected) {
1935  // We need to reflect only the translation and propagate to daughters.
1936  // H' = Sz * H * Sz
1937  local_cloned->ReflectZ(kTRUE);
1938  local_cloned->ReflectZ(kFALSE);
1939 // printf("%s after\n", node->GetName());
1940 // node->GetMatrix()->Print();
1941  new_vol = node->GetVolume()->MakeReflectedVolume();
1942  node->SetVolume(new_vol);
1943  continue;
1944  }
1945  // The next daughter is already reflected, so reflect on Z everything and stop
1946  local_cloned->ReflectZ(kTRUE); // rot + tr
1947 // printf("%s already reflected... After:\n", node->GetName());
1948 // node->GetMatrix()->Print();
1949  }
1950  if (vol->GetVoxels()) vol->GetVoxels()->Voxelize();
1951  return vol;
1952  }
1953  // Volume is divided, so we have to reflect the division.
1954 // printf(" ... divided %s\n", fFinder->ClassName());
1955  TGeoPatternFinder *new_finder = fFinder->MakeCopy(kTRUE);
1956  if (!new_finder) {
1957  Fatal("MakeReflectedVolume", "Could not copy finder for volume %s", GetName());
1958  return 0;
1959  }
1960  new_finder->SetVolume(vol);
1961  vol->SetFinder(new_finder);
1962  TGeoNodeOffset *nodeoff;
1963  new_vol = 0;
1964  for (Int_t i=0; i<nd; i++) {
1965  nodeoff = (TGeoNodeOffset*)vol->GetNode(i);
1966  nodeoff->SetFinder(new_finder);
1967  new_vol = nodeoff->GetVolume()->MakeReflectedVolume();
1968  nodeoff->SetVolume(new_vol);
1969  }
1970  return vol;
1971 }
1972 
1973 ////////////////////////////////////////////////////////////////////////////////
1974 /// Set this volume as the TOP one (the whole geometry starts from here)
1975 
1977 {
1978  fGeoManager->SetTopVolume(this);
1979 }
1980 
1981 ////////////////////////////////////////////////////////////////////////////////
1982 /// Set the current tracking point.
1983 
1985 {
1986  fGeoManager->SetCurrentPoint(x,y,z);
1987 }
1988 
1989 ////////////////////////////////////////////////////////////////////////////////
1990 /// set the shape associated with this volume
1991 
1993 {
1994  if (!shape) {
1995  Error("SetShape", "No shape");
1996  return;
1997  }
1998  fShape = (TGeoShape*)shape;
1999 }
2000 
2001 ////////////////////////////////////////////////////////////////////////////////
2002 /// sort nodes by decreasing volume of the bounding box. ONLY nodes comes first,
2003 /// then overlapping nodes and finally division nodes.
2004 
2006 {
2007  if (!Valid()) {
2008  Error("SortNodes", "Bounding box not valid");
2009  return;
2010  }
2011  Int_t nd = GetNdaughters();
2012 // printf("volume : %s, nd=%i\n", GetName(), nd);
2013  if (!nd) return;
2014  if (fFinder) return;
2015 // printf("Nodes for %s\n", GetName());
2016  Int_t id = 0;
2017  TGeoNode *node = 0;
2018  TObjArray *nodes = new TObjArray(nd);
2019  Int_t inode = 0;
2020  // first put ONLY's
2021  for (id=0; id<nd; id++) {
2022  node = GetNode(id);
2023  if (node->InheritsFrom(TGeoNodeOffset::Class()) || node->IsOverlapping()) continue;
2024  nodes->Add(node);
2025 // printf("inode %i ONLY\n", inode);
2026  inode++;
2027  }
2028  // second put overlapping nodes
2029  for (id=0; id<nd; id++) {
2030  node = GetNode(id);
2031  if (node->InheritsFrom(TGeoNodeOffset::Class()) || (!node->IsOverlapping())) continue;
2032  nodes->Add(node);
2033 // printf("inode %i MANY\n", inode);
2034  inode++;
2035  }
2036  // third put the divided nodes
2037  if (fFinder) {
2038  fFinder->SetDivIndex(inode);
2039  for (id=0; id<nd; id++) {
2040  node = GetNode(id);
2041  if (!node->InheritsFrom(TGeoNodeOffset::Class())) continue;
2042  nodes->Add(node);
2043 // printf("inode %i DIV\n", inode);
2044  inode++;
2045  }
2046  }
2047  if (inode != nd) printf(" volume %s : number of nodes does not match!!!\n", GetName());
2048  delete fNodes;
2049  fNodes = nodes;
2050 }
2051 
2052 ////////////////////////////////////////////////////////////////////////////////
2053 /// Stream an object of class TGeoVolume.
2054 
2055 void TGeoVolume::Streamer(TBuffer &R__b)
2056 {
2057  if (R__b.IsReading()) {
2058  R__b.ReadClassBuffer(TGeoVolume::Class(), this);
2059  if (fVoxels && fVoxels->IsInvalid()) Voxelize("");
2060  } else {
2061  if (!fVoxels) {
2062  R__b.WriteClassBuffer(TGeoVolume::Class(), this);
2063  } else {
2064  if (!fGeoManager->IsStreamingVoxels()) {
2065  TGeoVoxelFinder *voxels = fVoxels;
2066  fVoxels = 0;
2067  R__b.WriteClassBuffer(TGeoVolume::Class(), this);
2068  fVoxels = voxels;
2069  } else {
2070  R__b.WriteClassBuffer(TGeoVolume::Class(), this);
2071  }
2072  }
2073  }
2074 }
2075 
2076 ////////////////////////////////////////////////////////////////////////////////
2077 /// Set the current options (none implemented)
2078 
2079 void TGeoVolume::SetOption(const char *option)
2080 {
2081  fOption = option;
2082 }
2083 
2084 ////////////////////////////////////////////////////////////////////////////////
2085 /// Set the line color.
2086 
2088 {
2089  TAttLine::SetLineColor(lcolor);
2090 }
2091 
2092 ////////////////////////////////////////////////////////////////////////////////
2093 /// Set the line style.
2094 
2096 {
2097  TAttLine::SetLineStyle(lstyle);
2098 }
2099 
2100 ////////////////////////////////////////////////////////////////////////////////
2101 /// Set the line width.
2102 
2104 {
2105  TAttLine::SetLineWidth(lwidth);
2106 }
2107 
2108 ////////////////////////////////////////////////////////////////////////////////
2109 /// get the pointer to a daughter node
2110 
2111 TGeoNode *TGeoVolume::GetNode(const char *name) const
2112 {
2113  if (!fNodes) return 0;
2114  TGeoNode *node = (TGeoNode *)fNodes->FindObject(name);
2115  return node;
2116 }
2117 
2118 ////////////////////////////////////////////////////////////////////////////////
2119 /// get the total size in bytes for this volume
2120 
2122 {
2123  Int_t count = 28+2+6+4+0; // TNamed+TGeoAtt+TAttLine+TAttFill+TAtt3D
2124  count += fName.Capacity() + fTitle.Capacity(); // name+title
2125  count += 7*sizeof(char*); // fShape + fMedium + fFinder + fField + fNodes + 2 extensions
2126  count += fOption.Capacity(); // fOption
2127  if (fShape) count += fShape->GetByteCount();
2128  if (fFinder) count += fFinder->GetByteCount();
2129  if (fNodes) {
2130  count += 32 + 4*fNodes->GetEntries(); // TObjArray
2131  TIter next(fNodes);
2132  TGeoNode *node;
2133  while ((node=(TGeoNode*)next())) count += node->GetByteCount();
2134  }
2135  return count;
2136 }
2137 
2138 ////////////////////////////////////////////////////////////////////////////////
2139 /// loop all nodes marked as overlaps and find overlapping brothers
2140 
2142 {
2143  if (!Valid()) {
2144  Error("FindOverlaps","Bounding box not valid");
2145  return;
2146  }
2147  if (!fVoxels) return;
2148  Int_t nd = GetNdaughters();
2149  if (!nd) return;
2150  TGeoNode *node=0;
2151  Int_t inode = 0;
2152  for (inode=0; inode<nd; inode++) {
2153  node = GetNode(inode);
2154  if (!node->IsOverlapping()) continue;
2155  fVoxels->FindOverlaps(inode);
2156  }
2157 }
2158 
2159 ////////////////////////////////////////////////////////////////////////////////
2160 /// Remove an existing daughter.
2161 
2163 {
2164  if (!fNodes || !fNodes->GetEntriesFast()) return;
2165  if (!fNodes->Remove(node)) return;
2166  fNodes->Compress();
2167  if (fVoxels) fVoxels->SetNeedRebuild();
2168  if (IsAssembly()) fShape->ComputeBBox();
2169 }
2170 
2171 ////////////////////////////////////////////////////////////////////////////////
2172 /// Replace an existing daughter with a new volume having the same name but
2173 /// possibly a new shape, position or medium. Not allowed for positioned assemblies.
2174 /// For division cells, the new shape/matrix are ignored.
2175 
2177 {
2178  Int_t ind = GetIndex(nodeorig);
2179  if (ind < 0) return NULL;
2180  TGeoVolume *oldvol = nodeorig->GetVolume();
2181  if (oldvol->IsAssembly()) {
2182  Error("ReplaceNode", "Cannot replace node %s since it is an assembly", nodeorig->GetName());
2183  return NULL;
2184  }
2185  TGeoShape *shape = oldvol->GetShape();
2186  if (newshape && !nodeorig->IsOffset()) shape = newshape;
2187  TGeoMedium *med = oldvol->GetMedium();
2188  if (newmed) med = newmed;
2189  // Make a new volume
2190  TGeoVolume *vol = new TGeoVolume(oldvol->GetName(), shape, med);
2191  // copy volume attributes
2192  vol->SetVisibility(oldvol->IsVisible());
2193  vol->SetLineColor(oldvol->GetLineColor());
2194  vol->SetLineStyle(oldvol->GetLineStyle());
2195  vol->SetLineWidth(oldvol->GetLineWidth());
2196  vol->SetFillColor(oldvol->GetFillColor());
2197  vol->SetFillStyle(oldvol->GetFillStyle());
2198  // copy field
2199  vol->SetField(oldvol->GetField());
2200  // Make a copy of the node
2201  TGeoNode *newnode = nodeorig->MakeCopyNode();
2202  if (!newnode) {
2203  Fatal("ReplaceNode", "Cannot make copy node for %s", nodeorig->GetName());
2204  return 0;
2205  }
2206  // Change the volume for the new node
2207  newnode->SetVolume(vol);
2208  // Replace the matrix
2209  if (newpos && !nodeorig->IsOffset()) {
2210  TGeoNodeMatrix *nodemat = (TGeoNodeMatrix*)newnode;
2211  nodemat->SetMatrix(newpos);
2212  }
2213  // Replace nodeorig with new one
2214  fNodes->RemoveAt(ind);
2215  fNodes->AddAt(newnode, ind);
2216  if (fVoxels) fVoxels->SetNeedRebuild();
2217  if (IsAssembly()) fShape->ComputeBBox();
2218  return newnode;
2219 }
2220 
2221 ////////////////////////////////////////////////////////////////////////////////
2222 /// Select this volume as matching an arbitrary criteria. The volume is added to
2223 /// a static list and the flag TGeoVolume::kVolumeSelected is set. All flags need
2224 /// to be reset at the end by calling the method with CLEAR=true. This will also clear
2225 /// the list.
2226 
2228 {
2229  static TObjArray array(256);
2230  static Int_t len = 0;
2231  Int_t i;
2232  TObject *vol;
2233  if (clear) {
2234  for (i=0; i<len; i++) {
2235  vol = array.At(i);
2237  }
2238  array.Clear();
2239  len = 0;
2240  return;
2241  }
2243  array.AddAtAndExpand(this, len++);
2244 }
2245 
2246 ////////////////////////////////////////////////////////////////////////////////
2247 /// set visibility of this volume
2248 
2250 {
2254  TSeqCollection *brlist = gROOT->GetListOfBrowsers();
2255  TIter next(brlist);
2256  TBrowser *browser = 0;
2257  while ((browser=(TBrowser*)next())) {
2258  browser->CheckObjectItem(this, vis);
2259  browser->Refresh();
2260  }
2261 }
2262 
2263 ////////////////////////////////////////////////////////////////////////////////
2264 /// Set visibility for containers.
2265 
2267 {
2269  if (fGeoManager && fGeoManager->IsClosed()) {
2272  }
2273 }
2274 
2275 ////////////////////////////////////////////////////////////////////////////////
2276 /// Set visibility for leaves.
2277 
2279 {
2280  TGeoAtt::SetVisLeaves(flag);
2281  if (fGeoManager && fGeoManager->IsClosed()) {
2284  }
2285 }
2286 
2287 ////////////////////////////////////////////////////////////////////////////////
2288 /// Set visibility for leaves.
2289 
2291 {
2292  if (IsAssembly()) return;
2293  TGeoAtt::SetVisOnly(flag);
2294  if (fGeoManager && fGeoManager->IsClosed()) {
2297  }
2298 }
2299 
2300 ////////////////////////////////////////////////////////////////////////////////
2301 /// Check if the shape of this volume is valid.
2302 
2304 {
2305  return fShape->IsValidBox();
2306 }
2307 
2308 ////////////////////////////////////////////////////////////////////////////////
2309 /// Find a daughter node having VOL as volume and fill TGeoManager::fHMatrix
2310 /// with its global matrix.
2311 
2313 {
2314  if (vol == this) return kTRUE;
2315  Int_t nd = GetNdaughters();
2316  if (!nd) return kFALSE;
2317  TGeoHMatrix *global = fGeoManager->GetHMatrix();
2318  if (!global) return kFALSE;
2319  TGeoNode *dnode;
2320  TGeoVolume *dvol;
2321  TGeoMatrix *local;
2322  Int_t i;
2323  for (i=0; i<nd; i++) {
2324  dnode = GetNode(i);
2325  dvol = dnode->GetVolume();
2326  if (dvol == vol) {
2327  local = dnode->GetMatrix();
2328  global->MultiplyLeft(local);
2329  return kTRUE;
2330  }
2331  }
2332  for (i=0; i<nd; i++) {
2333  dnode = GetNode(i);
2334  dvol = dnode->GetVolume();
2335  if (dvol->FindMatrixOfDaughterVolume(vol)) return kTRUE;
2336  }
2337  return kFALSE;
2338 }
2339 
2340 ////////////////////////////////////////////////////////////////////////////////
2341 /// set visibility for daughters
2342 
2344 {
2345  SetVisDaughters(vis);
2348 }
2349 
2350 ////////////////////////////////////////////////////////////////////////////////
2351 /// build the voxels for this volume
2352 
2354 {
2355  if (!Valid()) {
2356  Error("Voxelize", "Bounding box not valid");
2357  return;
2358  }
2359  // do not voxelize divided volumes
2360  if (fFinder) return;
2361  // or final leaves
2362  Int_t nd = GetNdaughters();
2363  if (!nd) return;
2364  // If this is an assembly, re-compute bounding box
2365  if (IsAssembly()) fShape->ComputeBBox();
2366  // delete old voxelization if any
2367  if (fVoxels) {
2368  if (!TObject::TestBit(kVolumeClone)) delete fVoxels;
2369  fVoxels = 0;
2370  }
2371  // Create the voxels structure
2372  fVoxels = new TGeoVoxelFinder(this);
2373  fVoxels->Voxelize(option);
2374  if (fVoxels) {
2375  if (fVoxels->IsInvalid()) {
2376  delete fVoxels;
2377  fVoxels = 0;
2378  }
2379  }
2380 }
2381 
2382 ////////////////////////////////////////////////////////////////////////////////
2383 /// Estimate the weight of a volume (in kg) with SIGMA(M)/M better than PRECISION.
2384 /// Option can contain : v - verbose, a - analytical (default)
2385 
2387 {
2389  if (top != this) fGeoManager->SetTopVolume(this);
2390  else top = 0;
2391  Double_t weight = fGeoManager->Weight(precision, option);
2392  if (top) fGeoManager->SetTopVolume(top);
2393  return weight;
2394 }
2395 
2396 ////////////////////////////////////////////////////////////////////////////////
2397 /// Analytical computation of the weight.
2398 
2400 {
2401  Double_t capacity = Capacity();
2402  Double_t weight = 0.0;
2403  Int_t i;
2404  Int_t nd = GetNdaughters();
2405  TGeoVolume *daughter;
2406  for (i=0; i<nd; i++) {
2407  daughter = GetNode(i)->GetVolume();
2408  weight += daughter->WeightA();
2409  capacity -= daughter->Capacity();
2410  }
2411  Double_t density = 0.0;
2412  if (!IsAssembly()) {
2413  if (fMedium) density = fMedium->GetMaterial()->GetDensity();
2414  if (density<0.01) density = 0.0; // do not weight gases
2415  }
2416  weight += 0.001*capacity * density; //[kg]
2417  return weight;
2418 }
2419 
2421 
2422 
2423 ////////////////////////////////////////////////////////////////////////////////
2424 /// dummy constructor
2425 
2427 {
2428  fVolumes = 0;
2429  fDivision = 0;
2430  fNumed = 0;
2431  fNdiv = 0;
2432  fAxis = 0;
2433  fStart = 0;
2434  fStep = 0;
2435  fAttSet = kFALSE;
2437 }
2438 
2439 ////////////////////////////////////////////////////////////////////////////////
2440 /// default constructor
2441 
2443 {
2444  fVolumes = new TObjArray();
2445  fDivision = 0;
2446  fNumed = 0;
2447  fNdiv = 0;
2448  fAxis = 0;
2449  fStart = 0;
2450  fStep = 0;
2451  fAttSet = kFALSE;
2453  SetName(name);
2454  SetMedium(med);
2455  fGeoManager->AddVolume(this);
2456 // printf("--- volume multi %s created\n", name);
2457 }
2458 
2459 ////////////////////////////////////////////////////////////////////////////////
2460 ///copy constructor
2461 
2463  TGeoVolume(vm),
2464  fVolumes(vm.fVolumes),
2465  fDivision(vm.fDivision),
2466  fNumed(vm.fNumed),
2467  fNdiv(vm.fNdiv),
2468  fAxis(vm.fAxis),
2469  fStart(vm.fStart),
2470  fStep(vm.fStep),
2471  fAttSet(vm.fAttSet)
2472 {
2473 }
2474 
2475 ////////////////////////////////////////////////////////////////////////////////
2476 ///assignment operator
2477 
2479 {
2480  if(this!=&vm) {
2482  fVolumes=vm.fVolumes;
2483  fDivision=vm.fDivision;
2484  fNumed=vm.fNumed;
2485  fNdiv=vm.fNdiv;
2486  fAxis=vm.fAxis;
2487  fStart=vm.fStart;
2488  fStep=vm.fStep;
2489  fAttSet=vm.fAttSet;
2490  }
2491  return *this;
2492 }
2493 
2494 ////////////////////////////////////////////////////////////////////////////////
2495 /// Destructor
2496 
2498 {
2499  if (fVolumes) delete fVolumes;
2500 }
2501 
2502 ////////////////////////////////////////////////////////////////////////////////
2503 /// Add a volume with valid shape to the list of volumes. Copy all existing nodes
2504 /// to this volume
2505 
2507 {
2508  Int_t idx = fVolumes->GetEntriesFast();
2509  fVolumes->AddAtAndExpand(vol,idx);
2510  vol->SetUniqueID(idx+1);
2511  TGeoVolumeMulti *div;
2512  TGeoVolume *cell;
2513  if (fDivision) {
2515  if (!div) {
2516  Fatal("AddVolume", "Cannot divide volume %s", vol->GetName());
2517  return;
2518  }
2519  for (Int_t i=0; i<div->GetNvolumes(); i++) {
2520  cell = div->GetVolume(i);
2521  fDivision->AddVolume(cell);
2522  }
2523  }
2524  if (fNodes) {
2525  Int_t nd = fNodes->GetEntriesFast();
2526  for (Int_t id=0; id<nd; id++) {
2527  TGeoNode *node = (TGeoNode*)fNodes->At(id);
2528  Bool_t many = node->IsOverlapping();
2529  if (many) vol->AddNodeOverlap(node->GetVolume(), node->GetNumber(), node->GetMatrix());
2530  else vol->AddNode(node->GetVolume(), node->GetNumber(), node->GetMatrix());
2531  }
2532  }
2533 // vol->MakeCopyNodes(this);
2534 }
2535 
2536 
2537 ////////////////////////////////////////////////////////////////////////////////
2538 /// Add a new node to the list of nodes. This is the usual method for adding
2539 /// daughters inside the container volume.
2540 
2542 {
2543  TGeoVolume::AddNode(vol, copy_no, mat, option);
2544  Int_t nvolumes = fVolumes->GetEntriesFast();
2545  TGeoVolume *volume = 0;
2546  for (Int_t ivo=0; ivo<nvolumes; ivo++) {
2547  volume = GetVolume(ivo);
2548  volume->SetLineColor(GetLineColor());
2549  volume->SetLineStyle(GetLineStyle());
2550  volume->SetLineWidth(GetLineWidth());
2551  volume->SetVisibility(IsVisible());
2552  volume->AddNode(vol, copy_no, mat, option);
2553  }
2554 // printf("--- vmulti %s : node %s added to %i components\n", GetName(), vol->GetName(), nvolumes);
2555 }
2556 
2557 ////////////////////////////////////////////////////////////////////////////////
2558 /// Add a new node to the list of nodes, This node is possibly overlapping with other
2559 /// daughters of the volume or extruding the volume.
2560 
2562 {
2563  TGeoVolume::AddNodeOverlap(vol, copy_no, mat, option);
2564  Int_t nvolumes = fVolumes->GetEntriesFast();
2565  TGeoVolume *volume = 0;
2566  for (Int_t ivo=0; ivo<nvolumes; ivo++) {
2567  volume = GetVolume(ivo);
2568  volume->SetLineColor(GetLineColor());
2569  volume->SetLineStyle(GetLineStyle());
2570  volume->SetLineWidth(GetLineWidth());
2571  volume->SetVisibility(IsVisible());
2572  volume->AddNodeOverlap(vol, copy_no, mat, option);
2573  }
2574 // printf("--- vmulti %s : node ovlp %s added to %i components\n", GetName(), vol->GetName(), nvolumes);
2575 }
2576 
2577 ////////////////////////////////////////////////////////////////////////////////
2578 /// Returns the last shape.
2579 
2581 {
2583  if (!vol) return 0;
2584  return vol->GetShape();
2585 }
2586 
2587 ////////////////////////////////////////////////////////////////////////////////
2588 /// division of multiple volumes
2589 
2590 TGeoVolume *TGeoVolumeMulti::Divide(const char *divname, Int_t iaxis, Int_t ndiv, Double_t start, Double_t step, Int_t numed, const char *option)
2591 {
2592  if (fDivision) {
2593  Error("Divide", "volume %s already divided", GetName());
2594  return 0;
2595  }
2596  Int_t nvolumes = fVolumes->GetEntriesFast();
2597  TGeoMedium *medium = fMedium;
2598  if (numed) {
2599  medium = fGeoManager->GetMedium(numed);
2600  if (!medium) {
2601  Error("Divide", "Invalid medium number %d for division volume %s", numed, divname);
2602  medium = fMedium;
2603  }
2604  }
2605  if (!nvolumes) {
2606  // this is a virtual volume
2607  fDivision = new TGeoVolumeMulti(divname, medium);
2608  fNumed = medium->GetId();
2609  fOption = option;
2610  fAxis = iaxis;
2611  fNdiv = ndiv;
2612  fStart = start;
2613  fStep = step;
2614  // nothing else to do at this stage
2615  return fDivision;
2616  }
2617  TGeoVolume *vol = 0;
2618  fDivision = new TGeoVolumeMulti(divname, medium);
2619  if (medium) fNumed = medium->GetId();
2620  fOption = option;
2621  fAxis = iaxis;
2622  fNdiv = ndiv;
2623  fStart = start;
2624  fStep = step;
2625  for (Int_t ivo=0; ivo<nvolumes; ivo++) {
2626  vol = GetVolume(ivo);
2627  vol->SetLineColor(GetLineColor());
2628  vol->SetLineStyle(GetLineStyle());
2629  vol->SetLineWidth(GetLineWidth());
2630  vol->SetVisibility(IsVisible());
2631  fDivision->AddVolume(vol->Divide(divname,iaxis,ndiv,start,step, numed, option));
2632  }
2633 // printf("--- volume multi %s (%i volumes) divided\n", GetName(), nvolumes);
2634  if (numed) fDivision->SetMedium(medium);
2635  return fDivision;
2636 }
2637 
2638 ////////////////////////////////////////////////////////////////////////////////
2639 /// Make a copy of this volume
2640 /// build a volume with same name, shape and medium
2641 
2643 {
2644  TGeoVolume *vol = new TGeoVolume(GetName(), newshape, fMedium);
2645  Int_t i=0;
2646  // copy volume attributes
2647  vol->SetVisibility(IsVisible());
2648  vol->SetLineColor(GetLineColor());
2649  vol->SetLineStyle(GetLineStyle());
2650  vol->SetLineWidth(GetLineWidth());
2651  vol->SetFillColor(GetFillColor());
2652  vol->SetFillStyle(GetFillStyle());
2653  // copy field
2654  vol->SetField(fField);
2655  // Copy extensions
2658  // if divided, copy division object
2659 // if (fFinder) {
2660 // Error("MakeCopyVolume", "volume %s divided", GetName());
2661 // vol->SetFinder(fFinder);
2662 // }
2663  if (fDivision) {
2664  TGeoVolume *cell;
2666  if (!div) {
2667  Fatal("MakeCopyVolume", "Cannot divide volume %s", vol->GetName());
2668  return 0;
2669  }
2670  for (i=0; i<div->GetNvolumes(); i++) {
2671  cell = div->GetVolume(i);
2672  fDivision->AddVolume(cell);
2673  }
2674  }
2675 
2676  if (!fNodes) return vol;
2677  TGeoNode *node;
2678  Int_t nd = fNodes->GetEntriesFast();
2679  if (!nd) return vol;
2680  // create new list of nodes
2681  TObjArray *list = new TObjArray();
2682  // attach it to new volume
2683  vol->SetNodes(list);
2684  ((TObject*)vol)->SetBit(kVolumeImportNodes);
2685  for (i=0; i<nd; i++) {
2686  //create copies of nodes and add them to list
2687  node = GetNode(i)->MakeCopyNode();
2688  if (!node) {
2689  Fatal("MakeCopyNode", "cannot make copy node for daughter %d of %s", i, GetName());
2690  return 0;
2691  }
2692  node->SetMotherVolume(vol);
2693  list->Add(node);
2694  }
2695  return vol;
2696 }
2697 
2698 ////////////////////////////////////////////////////////////////////////////////
2699 /// Set the line color for all components.
2700 
2702 {
2703  TGeoVolume::SetLineColor(lcolor);
2704  Int_t nvolumes = fVolumes->GetEntriesFast();
2705  TGeoVolume *vol = 0;
2706  for (Int_t ivo=0; ivo<nvolumes; ivo++) {
2707  vol = GetVolume(ivo);
2708  vol->SetLineColor(lcolor);
2709  }
2710 }
2711 
2712 ////////////////////////////////////////////////////////////////////////////////
2713 /// Set the line style for all components.
2714 
2716 {
2717  TGeoVolume::SetLineStyle(lstyle);
2718  Int_t nvolumes = fVolumes->GetEntriesFast();
2719  TGeoVolume *vol = 0;
2720  for (Int_t ivo=0; ivo<nvolumes; ivo++) {
2721  vol = GetVolume(ivo);
2722  vol->SetLineStyle(lstyle);
2723  }
2724 }
2725 
2726 ////////////////////////////////////////////////////////////////////////////////
2727 /// Set the line width for all components.
2728 
2730 {
2731  TGeoVolume::SetLineWidth(lwidth);
2732  Int_t nvolumes = fVolumes->GetEntriesFast();
2733  TGeoVolume *vol = 0;
2734  for (Int_t ivo=0; ivo<nvolumes; ivo++) {
2735  vol = GetVolume(ivo);
2736  vol->SetLineWidth(lwidth);
2737  }
2738 }
2739 
2740 ////////////////////////////////////////////////////////////////////////////////
2741 /// Set medium for a multiple volume.
2742 
2744 {
2745  TGeoVolume::SetMedium(med);
2746  Int_t nvolumes = fVolumes->GetEntriesFast();
2747  TGeoVolume *vol = 0;
2748  for (Int_t ivo=0; ivo<nvolumes; ivo++) {
2749  vol = GetVolume(ivo);
2750  vol->SetMedium(med);
2751  }
2752 }
2753 
2754 
2755 ////////////////////////////////////////////////////////////////////////////////
2756 /// Set visibility for all components.
2757 
2759 {
2761  Int_t nvolumes = fVolumes->GetEntriesFast();
2762  TGeoVolume *vol = 0;
2763  for (Int_t ivo=0; ivo<nvolumes; ivo++) {
2764  vol = GetVolume(ivo);
2765  vol->SetVisibility(vis);
2766  }
2767 }
2768 
2770 
2771 ////////////////////////////////////////////////////////////////////////////////
2772 /// Constructor.
2773 
2775  fCurrent(-1), fNext(-1)
2776 {
2777 }
2778 
2779 ////////////////////////////////////////////////////////////////////////////////
2780 /// Destructor.
2781 
2783 {
2784 }
2785 
2786 ////////////////////////////////////////////////////////////////////////////////
2787 
2789 {
2790  Int_t tid = TGeoManager::ThreadId();
2791  return *fThreadData[tid];
2792 }
2793 
2794 ////////////////////////////////////////////////////////////////////////////////
2795 
2797 {
2798  std::lock_guard<std::mutex> guard(fMutex);
2800  std::vector<ThreadData_t*>::iterator i = fThreadData.begin();
2801  while (i != fThreadData.end())
2802  {
2803  delete *i;
2804  ++i;
2805  }
2806  fThreadData.clear();
2807  fThreadSize = 0;
2808 }
2809 
2810 ////////////////////////////////////////////////////////////////////////////////
2811 
2813 {
2814  std::lock_guard<std::mutex> guard(fMutex);
2815  // Create assembly thread data here
2816  fThreadData.resize(nthreads);
2817  fThreadSize = nthreads;
2818  for (Int_t tid=0; tid<nthreads; tid++) {
2819  if (fThreadData[tid] == 0) {
2820  fThreadData[tid] = new ThreadData_t;
2821  }
2822  }
2823  TGeoVolume::CreateThreadData(nthreads);
2824 }
2825 
2826 ////////////////////////////////////////////////////////////////////////////////
2827 
2829 {
2830  return fThreadData[TGeoManager::ThreadId()]->fCurrent;
2831 }
2832 
2833 ////////////////////////////////////////////////////////////////////////////////
2834 
2836 {
2837  return fThreadData[TGeoManager::ThreadId()]->fNext;
2838 }
2839 
2840 ////////////////////////////////////////////////////////////////////////////////
2841 
2843 {
2844  fThreadData[TGeoManager::ThreadId()]->fCurrent = index;
2845 }
2846 
2847 ////////////////////////////////////////////////////////////////////////////////
2848 
2850 {
2851  fThreadData[TGeoManager::ThreadId()]->fNext = index;
2852 }
2853 
2854 ////////////////////////////////////////////////////////////////////////////////
2855 /// Default constructor
2856 
2858  :TGeoVolume()
2859 {
2860  fThreadSize = 0;
2861  CreateThreadData(1);
2862 }
2863 
2864 ////////////////////////////////////////////////////////////////////////////////
2865 /// Constructor. Just the name has to be provided. Assemblies does not have their own
2866 /// shape or medium.
2867 
2869  :TGeoVolume()
2870 {
2871  fName = name;
2872  fName = fName.Strip();
2873  fShape = new TGeoShapeAssembly(this);
2874  if (fGeoManager) fNumber = fGeoManager->AddVolume(this);
2875  fThreadSize = 0;
2876  CreateThreadData(1);
2877 }
2878 
2879 ////////////////////////////////////////////////////////////////////////////////
2880 /// Destructor. The assembly is owner of its "shape".
2881 
2883 {
2884  ClearThreadData();
2885  if (fShape) delete fShape;
2886 }
2887 
2888 ////////////////////////////////////////////////////////////////////////////////
2889 /// Add a component to the assembly.
2890 
2892 {
2893  TGeoVolume::AddNode(vol,copy_no,mat,option);
2894 // ((TGeoShapeAssembly*)fShape)->RecomputeBoxLast();
2895  ((TGeoShapeAssembly*)fShape)->NeedsBBoxRecompute();
2896 }
2897 
2898 ////////////////////////////////////////////////////////////////////////////////
2899 /// Add an overlapping node - not allowed for assemblies.
2900 
2902 {
2903  Warning("AddNodeOverlap", "Declaring assembly %s as possibly overlapping inside %s not allowed. Using AddNode instead !",vol->GetName(),GetName());
2904  AddNode(vol, copy_no, mat, option);
2905 }
2906 
2907 ////////////////////////////////////////////////////////////////////////////////
2908 /// Clone this volume.
2909 /// build a volume with same name, shape and medium
2910 
2912 {
2913  TGeoVolume *vol = new TGeoVolumeAssembly(GetName());
2914  Int_t i;
2915  // copy other attributes
2916  Int_t nbits = 8*sizeof(UInt_t);
2917  for (i=0; i<nbits; i++)
2918  vol->SetAttBit(1<<i, TGeoAtt::TestAttBit(1<<i));
2919  for (i=14; i<24; i++)
2920  vol->SetBit(1<<i, TestBit(1<<i));
2921 
2922  // copy field
2923  vol->SetField(fField);
2924  // Set bits
2925  for (i=0; i<nbits; i++)
2926  vol->SetBit(1<<i, TObject::TestBit(1<<i));
2927  vol->SetBit(kVolumeClone);
2928  // make copy nodes
2929  vol->MakeCopyNodes(this);
2930 // CloneNodesAndConnect(vol);
2931  ((TGeoShapeAssembly*)vol->GetShape())->NeedsBBoxRecompute();
2932  // copy voxels
2933  TGeoVoxelFinder *voxels = 0;
2934  if (fVoxels) {
2935  voxels = new TGeoVoxelFinder(vol);
2936  vol->SetVoxelFinder(voxels);
2937  }
2938  // copy option, uid
2939  vol->SetOption(fOption);
2940  vol->SetNumber(fNumber);
2941  vol->SetNtotal(fNtotal);
2942  return vol;
2943 }
2944 
2945 ////////////////////////////////////////////////////////////////////////////////
2946 /// Division makes no sense for assemblies.
2947 
2949 {
2950  Error("Divide","Assemblies cannot be divided");
2951  return 0;
2952 }
2953 
2954 ////////////////////////////////////////////////////////////////////////////////
2955 /// Assign to the assembly a collection of identical volumes positioned according
2956 /// a predefined pattern. The option can be spaced out or touching depending on the empty
2957 /// space between volumes.
2958 
2960 {
2961  if (fNodes) {
2962  Error("Divide", "Cannot divide assembly %s since it has nodes", GetName());
2963  return NULL;
2964  }
2965  if (fFinder) {
2966  Error("Divide", "Assembly %s already divided", GetName());
2967  return NULL;
2968  }
2969  Int_t ncells = pattern->GetNdiv();
2970  if (!ncells || pattern->GetStep()<=0) {
2971  Error("Divide", "Pattern finder for dividing assembly %s not initialized. Use SetRange() method.", GetName());
2972  return NULL;
2973  }
2974  fFinder = pattern;
2975  TString opt(option);
2976  opt.ToLower();
2977  if (opt.Contains("spacedout")) fFinder->SetSpacedOut(kTRUE);
2978  else fFinder->SetSpacedOut(kFALSE);
2979  // Position volumes
2980  for (Int_t i=0; i<ncells; i++) {
2981  fFinder->cd(i);
2982  TGeoNodeOffset *node = new TGeoNodeOffset(cell, i, 0.);
2983  node->SetFinder(fFinder);
2984  fNodes->Add(node);
2985  }
2986  return cell;
2987 }
2988 
2989 ////////////////////////////////////////////////////////////////////////////////
2990 /// Make a clone of volume VOL but which is an assembly.
2991 
2993 {
2994  if (volorig->IsAssembly() || volorig->IsVolumeMulti()) return 0;
2995  Int_t nd = volorig->GetNdaughters();
2996  if (!nd) return 0;
2997  TGeoVolumeAssembly *vol = new TGeoVolumeAssembly(volorig->GetName());
2998  Int_t i;
2999  // copy other attributes
3000  Int_t nbits = 8*sizeof(UInt_t);
3001  for (i=0; i<nbits; i++)
3002  vol->SetAttBit(1<<i, volorig->TestAttBit(1<<i));
3003  for (i=14; i<24; i++)
3004  vol->SetBit(1<<i, volorig->TestBit(1<<i));
3005 
3006  // copy field
3007  vol->SetField(volorig->GetField());
3008  // Set bits
3009  for (i=0; i<nbits; i++)
3010  vol->SetBit(1<<i, volorig->TestBit(1<<i));
3011  vol->SetBit(kVolumeClone);
3012  // make copy nodes
3013  vol->MakeCopyNodes(volorig);
3014 // volorig->CloneNodesAndConnect(vol);
3015  vol->GetShape()->ComputeBBox();
3016  // copy voxels
3017  TGeoVoxelFinder *voxels = 0;
3018  if (volorig->GetVoxels()) {
3019  voxels = new TGeoVoxelFinder(vol);
3020  vol->SetVoxelFinder(voxels);
3021  }
3022  // copy option, uid
3023  vol->SetOption(volorig->GetOption());
3024  vol->SetNumber(volorig->GetNumber());
3025  vol->SetNtotal(volorig->GetNtotal());
3026  return vol;
3027 }
TString fTitle
Definition: TNamed.h:33
void Add(TObject *obj, const char *name=0, Int_t check=-1)
Add object with name to browser.
Definition: TBrowser.cxx:261
TGeoManager * fGeoManager
Definition: TGeoVolume.h:61
TGeoVolume()
dummy constructor
Definition: TGeoVolume.cxx:447
void CreateThreadData(Int_t nthreads)
Create thread data for n threads max.
virtual TGeoVolume * CloneVolume() const
Clone this volume.
virtual void Paint(Option_t *option="")=0
This method must be overridden if a class wants to paint itself.
void CleanAll()
Clean data of the volume.
Definition: TGeoVolume.cxx:683
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
Write this object to the current directory.
Definition: TObject.cxx:785
std::mutex fMutex
Thread vector size.
Definition: TGeoVolume.h:326
TGeoVolumeAssembly()
Mutex for concurrent operations.
virtual void SetLineWidth(Width_t lwidth)
Set the line width.
Definition: TAttLine.h:43
void CheckShape(Int_t testNo, Int_t nsamples=10000, Option_t *option="")
Test for shape navigation methods.
Definition: TGeoShape.cxx:209
Bool_t IsReading() const
Definition: TBuffer.h:83
void PrintNodes() const
print nodes
Volume families.
Definition: TGeoVolume.h:256
A node containing local transformation.
Definition: TGeoNode.h:149
double dist(Rotation3D const &r1, Rotation3D const &r2)
Definition: 3DDistances.cxx:48
Bool_t IsCheckingOverlaps() const
Definition: TGeoManager.h:388
Ssiz_t Capacity() const
Definition: TString.h:333
An array of TObjects.
Definition: TObjArray.h:37
void SetNodes(TObjArray *nodes)
Definition: TGeoVolume.h:217
void ResetAttBit(UInt_t f)
Definition: TGeoAtt.h:67
virtual void SetLineColor(Color_t lcolor)
Set the line color for all components.
void Print(Option_t *option="") const
print the matrix in 4x4 format
Definition: TGeoMatrix.cxx:486
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
void ClearShape()
Clear the shape of this volume from the list held by the current manager.
Definition: TGeoVolume.cxx:692
virtual void SetLineWidth(Width_t lwidth)
Set the line width for all components.
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:854
Bool_t TestAttBit(UInt_t f) const
Definition: TGeoAtt.h:68
static TGeoMedium * fgDummyMedium
Definition: TGeoVolume.h:58
The manager class for any TGeo geometry.
Definition: TGeoManager.h:38
virtual void CreateThreadData(Int_t nthreads)
Definition: TGeoVolume.cxx:431
virtual void SetVisContainers(Bool_t flag=kTRUE)
Set branch type visibility.
Definition: TGeoAtt.cxx:77
char * GetPointerName() const
Provide a pointer name containing uid.
Volume assemblies.
Definition: TGeoVolume.h:307
void Voxelize(Option_t *option)
build the voxels for this volume
void SetFinder(TGeoPatternFinder *finder)
Definition: TGeoVolume.h:234
virtual void ModifiedPad(Bool_t update=kFALSE) const =0
Bool_t IsValid() const
Definition: TGeoShape.h:140
short Style_t
Definition: RtypesCore.h:76
virtual TGeoNode * MakeCopyNode() const
Definition: TGeoNode.h:108
void SetAllIndex()
Assigns uid&#39;s for all materials,media and matrices.
virtual void Voxelize(Option_t *option="")
Voxelize attached volume according to option If the volume is an assembly, make sure the bbox is comp...
TGeoExtension * fUserExtension
Definition: TGeoVolume.h:68
virtual void ClearThreadData() const
TGeoVolume * GetVolume(Int_t id) const
Definition: TGeoVolume.h:278
virtual void ExecuteVolumeEvent(TGeoVolume *volume, Int_t event, Int_t px, Int_t py)=0
void SetVolume(TGeoVolume *vol)
virtual void Clear(Option_t *option="")
Remove all objects from the array.
Definition: TObjArray.cxx:320
void MultiplyLeft(const TGeoMatrix *left)
multiply to the left with an other transformation if right is identity matrix, just return ...
void AddNodeOffset(TGeoVolume *vol, Int_t copy_no, Double_t offset=0, Option_t *option="")
Add a division node to the list of nodes.
virtual Double_t GetDensity() const
Definition: TGeoMaterial.h:87
Bool_t IsOverlapping() const
Definition: TGeoNode.h:102
void SetVirtual()
Definition: TGeoNode.h:116
const char Option_t
Definition: RtypesCore.h:62
Geometrical transformation package.
Definition: TGeoMatrix.h:40
virtual Int_t GetByteCount() const =0
Visualization and tracking attributes for volumes and nodes.
Definition: TGeoAtt.h:17
ThreadData_t & GetThreadData() const
virtual void Delete(Option_t *option="")
Remove all objects from the array AND delete all heap based objects.
Definition: TObjArray.cxx:355
virtual void CheckGeometry(Int_t nrays, Double_t startx, Double_t starty, Double_t startz) const =0
virtual Int_t GetByteCount() const
TGeoExtension * fFWExtension
Transient user-defined extension to volumes.
Definition: TGeoVolume.h:69
Bool_t IsStyleDefault() const
check if the visibility and attributes are the default ones
Definition: TGeoVolume.cxx:852
static TGeoMedium * DummyMedium()
Definition: TGeoVolume.cxx:439
TGeoNode * GetNode(const char *name) const
get the pointer to a daughter node
virtual void CreateThreadData(Int_t)
Definition: TGeoShape.h:68
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:638
TVirtualGeoPainter * GetPainter() const
Definition: TGeoManager.h:190
virtual void CheckOverlaps(const TGeoVolume *vol, Double_t ovlp=0.1, Option_t *option="") const =0
R__EXTERN TStyle * gStyle
Definition: TStyle.h:402
TGeoVolumeMulti & operator=(const TGeoVolumeMulti &)
assignment operator
ThreadData_t()
index of next node to be entered
virtual void SetVisibility(Bool_t vis=kTRUE)
Set visibility for this object.
Definition: TGeoAtt.cxx:105
TGeoMaterial * GetMaterial() const
Definition: TGeoMedium.h:52
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:140
TGeoMedium * fMedium
Definition: TGeoVolume.h:57
TGeoVolume, TGeoVolumeMulti, TGeoVolumeAssembly are the volume classes.
Definition: TGeoVolume.h:48
Double_t fStart
Definition: TGeoVolume.h:264
virtual void AddNodeOverlap(TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat=0, Option_t *option="")
Add a TGeoNode to the list of nodes.
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format...
Definition: TFile.h:46
virtual void Draw(Option_t *option="")
draw top volume according to option
void RegisterYourself()
Register the shape and all components to TGeoManager class.
virtual void Print(Option_t *option="") const
Print volume info.
Use this attribute class when an object should have 3D capabilities.
Definition: TAtt3D.h:19
Buffer base class used for serializing objects.
Definition: TBuffer.h:40
virtual TObject * Get(const char *namecycle)
Return pointer to object identified by namecycle.
void Add(TObject *obj)
This function may not be used (but we need to provide it since it is a pure virtual in TCollection)...
Definition: TMap.cxx:53
virtual void SetVisibility(Bool_t vis=kTRUE)
Set visibility for all components.
#define gROOT
Definition: TROOT.h:402
virtual TObject * Remove(TObject *obj)
Remove object from array.
Definition: TObjArray.cxx:703
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:585
void InspectShape() const
Definition: TGeoVolume.h:196
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
void SetTopVolume(TGeoVolume *vol)
Set the top volume and corresponding node as starting point of the geometry.
Int_t GetId() const
Definition: TGeoMedium.h:48
virtual void SetTopVolume(TGeoVolume *vol)=0
Basic string class.
Definition: TString.h:125
Matrix class used for computing global transformations Should NOT be used for node definition...
Definition: TGeoMatrix.h:420
Base class describing materials.
Definition: TGeoMaterial.h:29
virtual void DrawOnly(Option_t *option="")
draw only this volume
virtual TGeoShape * GetMakeRuntimeShape(TGeoShape *mother, TGeoMatrix *mat) const =0
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1099
int Int_t
Definition: RtypesCore.h:41
void VisibleDaughters(Bool_t vis=kTRUE)
set visibility for daughters
bool Bool_t
Definition: RtypesCore.h:59
void SetOption(const char *option)
Set the current options (none implemented)
Double_t Capacity() const
Computes the capacity of this [cm^3] as the capacity of its shape.
Definition: TGeoVolume.cxx:605
virtual ~TGeoVolumeAssembly()
Destructor. The assembly is owner of its "shape".
virtual void SetFillStyle(Style_t fstyle)
Set the fill area style.
Definition: TAttFill.h:39
Int_t GetNdiv() const
void RemoveNode(TGeoNode *node)
Remove an existing daughter.
Bool_t IsAllInvisible() const
Return TRUE if volume and all daughters are invisible.
Definition: TGeoVolume.cxx:805
void ReplayCreation(const TGeoVolume *other)
Recreate the content of the other volume without pointer copying.
void CheckObjectItem(TObject *obj, Bool_t check=kFALSE)
Change status of checkbox for this item.
Definition: TBrowser.cxx:304
TObject * At(Int_t idx) const
Definition: TObjArray.h:165
Bool_t IsVisibleDaughters() const
Definition: TGeoVolume.h:157
Bool_t IsOffset() const
Definition: TGeoNode.h:100
The shape encapsulating an assembly (union) of volumes.
void SetAsTopVolume()
Set this volume as the TOP one (the whole geometry starts from here)
TGeoVoxelFinder * GetVoxels() const
Getter for optimization structure.
virtual Bool_t TestVoxels(TGeoVolume *vol)=0
Bool_t IsVisContainers() const
Definition: TGeoVolume.h:158
void RegisterYourself(Option_t *option="")
Register the volume and all materials/media/matrices/shapes to the manager.
virtual Width_t GetLineWidth() const
Return the line width.
Definition: TAttLine.h:35
void SetFWExtension(TGeoExtension *ext)
Connect framework defined extension to the volume.
void Raytrace(Bool_t flag=kTRUE)
Draw this volume with current settings and perform raytracing in the pad.
static Bool_t IsSameWithinTolerance(Double_t a, Double_t b)
Check if two numbers differ with less than a tolerance.
Definition: TGeoShape.cxx:326
TObject * GetField() const
Definition: TGeoVolume.h:177
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:694
virtual Int_t GetByteCount() const
get the total size in bytes for this volume
TList * GetListOfMaterials() const
Definition: TGeoManager.h:463
TGeoHMatrix * GetHMatrix()
Return stored current matrix (global matrix of the next touched node).
virtual TObject * FindObject(const char *name) const
Delete a TObjLink object.
Definition: TList.cxx:574
virtual Bool_t IsAssembly() const
Definition: TGeoShape.h:129
Bool_t IsRaytracing() const
Check if the painter is currently ray-tracing the content of this volume.
Definition: TGeoVolume.cxx:873
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=1, Int_t netopt=0)
Create / open a file.
Definition: TFile.cxx:3950
Int_t CountNodes(Int_t nlevels=1000, Int_t option=0)
Count total number of subnodes starting from this volume, nlevels down.
Definition: TGeoVolume.cxx:754
TObjArray * GetNodes()
Definition: TGeoVolume.h:170
Int_t fNtotal
Definition: TGeoVolume.h:66
void Browse(TBrowser *b)
How to browse a volume.
Definition: TGeoVolume.cxx:571
virtual void CreateThreadData(Int_t nthreads)
Int_t GetNdaughters() const
Definition: TGeoVolume.h:350
void SetVisRaytrace(Bool_t flag=kTRUE)
Definition: TGeoAtt.h:70
TList * GetListOfMedia() const
Definition: TGeoManager.h:464
TObject * fField
pointer to TGeoManager owning this volume
Definition: TGeoVolume.h:63
virtual Style_t GetLineStyle() const
Return the line style.
Definition: TAttLine.h:34
Sequenceable collection abstract base class.
virtual ~TGeoVolume()
Destructor.
Definition: TGeoVolume.cxx:554
void SetUserPaintVolume(TGeoVolume *vol)
Definition: TGeoManager.h:215
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:128
TGeoPatternFinder * GetFinder() const
Definition: TGeoVolume.h:178
Fill Area Attributes class.
Definition: TAttFill.h:19
Double_t x[n]
Definition: legend1.C:17
TGeoNode * ReplaceNode(TGeoNode *nodeorig, TGeoShape *newshape=0, TGeoMatrix *newpos=0, TGeoMedium *newmed=0)
Replace an existing daughter with a new volume having the same name but possibly a new shape...
virtual void SetVisLeaves(Bool_t flag=kTRUE)
Set visibility for leaves.
Int_t GetNvolumes() const
Definition: TGeoVolume.h:283
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString...
Definition: TString.cxx:2365
void RandomRays(Int_t nrays=1000, Double_t startx=0, Double_t starty=0, Double_t startz=0, const char *target_vol=0, Bool_t check_norm=kFALSE)
Randomly shoot nrays and plot intersections with surfaces for current top node.
void SetMaterial(TGeoMaterial *mat)
Definition: TGeoMedium.h:55
virtual void GrabFocus(Int_t nfr=0, Double_t dlong=0, Double_t dlat=0, Double_t dpsi=0)=0
void Class()
Definition: Class.C:29
Bool_t FindMatrixOfDaughterVolume(TGeoVolume *vol) const
Find a daughter node having VOL as volume and fill TGeoManager::fHMatrix with its global matrix...
virtual TGeoVolume * Divide(const char *divname, Int_t iaxis, Int_t ndiv, Double_t start, Double_t step, Int_t numed=0, Option_t *option="")
Division makes no sense for assemblies.
void PrintVoxels() const
Print the voxels for this volume.
void SetCurrentPoint(Double_t *point)
Definition: TGeoManager.h:503
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
void AddVolume(TGeoVolume *vol)
Add a volume with valid shape to the list of volumes.
virtual TObject * FindObject(const char *name) const
Find an object in this collection using its name.
Definition: TObjArray.cxx:414
void InvisibleAll(Bool_t flag=kTRUE)
Make volume and each of it daughters (in)visible.
Definition: TGeoVolume.cxx:816
Int_t fThreadSize
Thread specific data vector.
Definition: TGeoVolume.h:325
void ClearShape(const TGeoShape *shape)
Remove a shape from the list of shapes.
void SortOverlaps()
Sort overlaps by decreasing overlap distance. Extrusions comes first.
Bool_t GetOptimalVoxels() const
Returns true if cylindrical voxelization is optimal.
TGeoVolume * MakeReflectedVolume(const char *newname="") const
Make a copy of this volume which is reflected with respect to XY plane.
TGeoMedium * GetMedium() const
Definition: TGeoVolume.h:176
Bool_t IsIdentity() const
Definition: TGeoMatrix.h:66
Int_t AddVolume(TGeoVolume *volume)
Add a volume to the list. Returns index of the volume in list.
virtual void SetVisLeaves(Bool_t flag=kTRUE)
Set branch type visibility.
Definition: TGeoAtt.cxx:85
virtual Bool_t IsVisible() const
Definition: TGeoVolume.h:156
virtual TGeoMatrix * GetMatrix() const =0
virtual TGeoVolume * MakeCopyVolume(TGeoShape *newshape)
Make a copy of this volume build a volume with same name, shape and medium.
TGeoMaterial * GetMaterial() const
Definition: TGeoVolume.h:175
Int_t GetVisOption() const
Returns current depth to which geometry is drawn.
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition: TKey.h:24
virtual void Print(Option_t *option="") const
Print the voxels.
XFontStruct * id
Definition: TGX11.cxx:108
char * GetPointerName() const
Provide a pointer name containing uid.
Definition: TGeoMatrix.cxx:294
void RandomPoints(Int_t npoints=1000000, Option_t *option="")
Draw random points in the bounding box of this volume.
virtual Int_t DistanceToPrimitiveVol(TGeoVolume *vol, Int_t px, Int_t py)=0
virtual void SetMedium(TGeoMedium *medium)
Set medium for a multiple volume.
virtual void Paint(Option_t *option="")
paint volume
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
Definition: TGeoMedium.cxx:137
virtual Bool_t IsValidBox() const =0
virtual TGeoVolume * Divide(const char *divname, Int_t iaxis, Int_t ndiv, Double_t start, Double_t step, Int_t numed=0, Option_t *option="")
Division a la G3.
TString fOption
just a hook for now
Definition: TGeoVolume.h:64
short Color_t
Definition: RtypesCore.h:79
static TGeoVolumeAssembly * MakeAssemblyFromVolume(TGeoVolume *vol)
Make a clone of volume VOL but which is an assembly.
R__ALWAYS_INLINE Bool_t IsZombie() const
Definition: TObject.h:134
virtual void ClearThreadData() const
Definition: TGeoVolume.cxx:423
TObjArray * fVolumes
Definition: TGeoVolume.h:259
void SortNodes()
sort nodes by decreasing volume of the bounding box.
const char * GetPointerName() const
Provide a pointer name containing uid.
Definition: TGeoShape.cxx:699
Option_t * GetOption() const
Definition: TGeoVolume.h:188
virtual void SetUniqueID(UInt_t uid)
Set the unique object id.
Definition: TObject.cxx:705
virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py)
Execute mouse actions on this volume.
virtual void AddNode(TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat=0, Option_t *option="")
Add a TGeoNode to the list of nodes.
Definition: TGeoVolume.cxx:984
virtual void SetLineWidth(Width_t lwidth)
Set the line width.
virtual char * GetObjectInfo(Int_t px, Int_t py) const
Get volume info for the browser.
Base finder class for patterns.
virtual void AddNode(TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat, Option_t *option="")
Add a new node to the list of nodes.
void SetShape(const TGeoShape *shape)
set the shape associated with this volume
Class handling Boolean composition of shapes.
Double_t GetStep() const
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition: TAttLine.h:40
Using a TBrowser one can browse all ROOT objects.
Definition: TBrowser.h:37
virtual Int_t GetCurrentNodeIndex() const
virtual TGeoVolume * CloneVolume() const
Clone this volume.
Int_t GetNumber() const
Definition: TGeoNode.h:92
TGeoVoxelFinder * fVoxels
Definition: TGeoVolume.h:60
virtual void AddNodeOverlap(TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat, Option_t *option="")
Add a new node to the list of nodes, This node is possibly overlapping with other daughters of the vo...
virtual void Release() const =0
void SetNeedRebuild(Bool_t flag=kTRUE)
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
compute the closest distance of approach from point px,py to this volume
TNamed & operator=(const TNamed &rhs)
TNamed assignment operator.
Definition: TNamed.cxx:51
Style_t fLineStyle
Line style.
Definition: TAttLine.h:22
Base abstract class for all shapes.
Definition: TGeoShape.h:25
virtual void AddAtAndExpand(TObject *obj, Int_t idx)
Add object at position idx.
Definition: TObjArray.cxx:234
void SetMotherVolume(TGeoVolume *mother)
Definition: TGeoNode.h:120
virtual void Draw(Option_t *option="")
Draw this histogram with options.
Definition: TH1.cxx:2969
TGeoPatternFinder * fFinder
dummy medium
Definition: TGeoVolume.h:59
Class describing rotation + translation.
Definition: TGeoMatrix.h:291
void SetSpacedOut(Bool_t flag)
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition: TAttFill.h:37
void SetField(TObject *field)
Definition: TGeoVolume.h:221
virtual void SetVisOnly(Bool_t flag=kTRUE)
Set branch type visibility.
Definition: TGeoAtt.cxx:95
ABC for user objects attached to TGeoVolume or TGeoNode.
Definition: TGeoExtension.h:19
virtual void FindOverlaps(Int_t inode) const
create the list of nodes for which the bboxes overlap with inode&#39;s bbox
virtual TObject * RemoveAt(Int_t idx)
Remove object at index idx.
Definition: TObjArray.cxx:678
Int_t GetIndex(const TGeoNode *node) const
get index number for a given daughter
Double_t Weight(Double_t precision=0.01, Option_t *option="va")
Estimate the weight of a volume (in kg) with SIGMA(M)/M better than PRECISION.
Color_t fLineColor
Line color.
Definition: TAttLine.h:21
virtual TGeoPatternFinder * MakeCopy(Bool_t reflect=kFALSE)=0
2-D histogram with a float per channel (see TH1 documentation)}
Definition: TH2.h:249
virtual Bool_t IsComposite() const
Definition: TGeoShape.h:130
Double_t GetStart() const
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:443
TObjArray * GetListOfShapes() const
Definition: TGeoManager.h:467
void RandomRays(Int_t nrays=10000, Double_t startx=0, Double_t starty=0, Double_t startz=0, const char *target_vol=0, Bool_t check_norm=kFALSE)
Random raytracing method.
void SetMatrix(const TGeoMatrix *matrix)
Matrix setter.
Definition: TGeoNode.cxx:816
unsigned int UInt_t
Definition: RtypesCore.h:42
Bool_t IsRegistered() const
Definition: TGeoMatrix.h:77
Width_t fLineWidth
Line width.
Definition: TAttLine.h:23
TGeoShape * fShape
Definition: TGeoVolume.h:56
Int_t GetEntriesFast() const
Definition: TObjArray.h:64
void UnmarkSaved()
Reset SavePrimitive bits.
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
Bool_t IsInvalid() const
Ssiz_t Length() const
Definition: TString.h:386
virtual void RegisterYourself()
Register the matrix in the current manager, which will become the owner.
Definition: TGeoMatrix.cxx:526
TSubString Strip(EStripType s=kTrailing, char c=' ') const
Return a substring of self stripped at beginning and/or end.
Definition: TString.cxx:1080
Bool_t IsVisRaytrace() const
Definition: TGeoAtt.h:87
virtual Bool_t IsFolder() const
Return TRUE if volume contains nodes.
Definition: TGeoVolume.cxx:844
void CheckOverlaps(Double_t ovlp=0.1, Option_t *option="") const
Overlap checking tool.
Definition: TGeoVolume.cxx:641
void CheckGeometry(Int_t nrays=1, Double_t startx=0, Double_t starty=0, Double_t startz=0) const
Shoot nrays with random directions from starting point (startx, starty, startz) in the reference fram...
Definition: TGeoVolume.cxx:620
void CloneNodesAndConnect(TGeoVolume *newmother) const
Clone the array of nodes.
virtual Int_t GetNextNodeIndex() const
TString fName
Definition: TNamed.h:32
void SetDivIndex(Int_t index)
virtual void DrawVolume(TGeoVolume *vol, Option_t *option="")=0
virtual void AddNode(TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat=0, Option_t *option="")
Add a component to the assembly.
virtual void AddAt(TObject *obj, Int_t idx)
Add object at position ids.
Definition: TObjArray.cxx:253
virtual TGeoVolume * Divide(const char *divname, Int_t iaxis, Int_t ndiv, Double_t start, Double_t step, Int_t numed=0, Option_t *option="")
division of multiple volumes
void SetUserExtension(TGeoExtension *ext)
Connect user-defined extension to the volume.
TObjArray * GetListOfMatrices() const
Definition: TGeoManager.h:462
constexpr Double_t E()
Definition: TMath.h:74
virtual TGeoVolume * GetTopVolume() const =0
void RandomPoints(const TGeoVolume *vol, Int_t npoints=10000, Option_t *option="")
Draw random points in the bounding box of a volume.
virtual const char * GetAxisName(Int_t iaxis) const =0
virtual void ClearThreadData() const
Definition: TGeoShape.h:67
short Width_t
Definition: RtypesCore.h:78
const Bool_t kFALSE
Definition: RtypesCore.h:88
void SetFinder(TGeoPatternFinder *finder)
Definition: TGeoNode.h:205
void SetAttVisibility(Bool_t vis)
Definition: TGeoVolume.h:223
virtual Color_t GetLineColor() const
Return the line color.
Definition: TAttLine.h:33
TGeoMedium * GetMedium(const char *medium) const
Search for a named tracking medium. All trailing blanks stripped.
void SetOverlapping(Bool_t flag=kTRUE)
Definition: TGeoNode.h:115
Bool_t IsTopVolume() const
True if this is the top volume of the geometry.
Definition: TGeoVolume.cxx:864
TString & Remove(Ssiz_t pos)
Definition: TString.h:619
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
void SetNextNodeIndex(Int_t index)
TGeoExtension * GrabUserExtension() const
Get a copy of the user extension pointer.
Double_t Weight(Double_t precision=0.01, Option_t *option="va")
Estimate weight of volume VOL with a precision SIGMA(W)/W better than PRECISION.
virtual void ReflectZ(Bool_t leftside, Bool_t rotonly=kFALSE)
Multiply by a reflection respect to XY.
Definition: TGeoMatrix.cxx:519
Class describing scale transformations.
Definition: TGeoMatrix.h:244
#define ClassImp(name)
Definition: Rtypes.h:359
R__EXTERN TGeoManager * gGeoManager
Definition: TGeoManager.h:559
virtual TGeoVolume * MakeCopyVolume(TGeoShape *newshape)
make a copy of this volume build a volume with same name, shape and medium
Int_t Export(const char *filename, const char *name="", Option_t *option="")
Export this volume to a file.
Definition: TGeoVolume.cxx:939
double Double_t
Definition: RtypesCore.h:55
Int_t GetNumber() const
Definition: TGeoVolume.h:185
void SetVoxelFinder(TGeoVoxelFinder *finder)
Definition: TGeoVolume.h:233
TObjArray * fNodes
Definition: TGeoVolume.h:55
virtual void SetVisibility(Bool_t vis=kTRUE)
set visibility of this volume
void MakeCopyNodes(const TGeoVolume *other)
make a new list of nodes and copy all nodes of other volume inside
void SaveAs(const char *filename, Option_t *option="") const
Save geometry having this as top volume as a C++ macro.
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Bool_t TestShapeBit(UInt_t f) const
Definition: TGeoShape.h:163
TMap implements an associative array of (key,value) pairs using a THashTable for efficient retrieval ...
Definition: TMap.h:40
R__EXTERN TEnv * gEnv
Definition: TEnv.h:171
TGeoExtension * GrabFWExtension() const
Get a copy of the framework extension pointer.
unsigned long ULong_t
Definition: RtypesCore.h:51
Bool_t Valid() const
Check if the shape of this volume is valid.
Int_t fNumber
option - if any
Definition: TGeoVolume.h:65
virtual const char * GetVolumeInfo(const TGeoVolume *volume, Int_t px, Int_t py) const =0
Double_t y[n]
Definition: legend1.C:17
virtual Color_t GetFillColor() const
Return the fill area color.
Definition: TAttFill.h:30
Node containing an offset.
Definition: TGeoNode.h:181
void ClearNodes()
Definition: TGeoVolume.h:103
virtual void SetVisContainers(Bool_t flag=kTRUE)
Set visibility for containers.
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:570
Finder class handling voxels.
virtual TGeoVolume * Divide(TGeoVolume *voldiv, const char *divname, Int_t iaxis, Int_t ndiv, Double_t start, Double_t step)=0
virtual void ComputeBBox()=0
Int_t AddShape(const TGeoShape *shape)
Add a shape to the list. Returns index of the shape in list.
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Definition: TAttLine.h:42
Bool_t IsReflection() const
Definition: TGeoMatrix.h:69
Media are used to store properties related to tracking and which are useful only when using geometry ...
Definition: TGeoMedium.h:23
Bool_t IsVisLeaves() const
Definition: TGeoVolume.h:159
Bool_t IsNull() const
Definition: TString.h:383
virtual Double_t Capacity() const =0
virtual void SetLineColor(Color_t lcolor)
Set the line color.
void SetVolume(TGeoVolume *volume)
Definition: TGeoNode.h:112
void InspectMaterial() const
Inspect the material for this volume.
Definition: TGeoVolume.cxx:881
static void CreateDummyMedium()
Create a dummy medium.
Definition: TGeoVolume.cxx:411
Binding & operator=(OUT(*fun)(void))
TH2F * LegoPlot(Int_t ntheta=20, Double_t themin=0., Double_t themax=180., Int_t nphi=60, Double_t phimin=0., Double_t phimax=360., Double_t rmin=0., Double_t rmax=9999999, Option_t *option="")
Generate a lego plot fot the top volume, according to option.
virtual Int_t GetDivAxis()
Double_t fStep
Definition: TGeoVolume.h:265
Mother of all ROOT objects.
Definition: TObject.h:37
static TGeoShape * MakeScaledShape(const char *name, TGeoShape *shape, TGeoScale *scale)
Create a scaled shape starting from a non-scaled one.
TGeoVolume & operator=(const TGeoVolume &)
assignment operator
Definition: TGeoVolume.cxx:526
you should not use this method at all Int_t Int_t z
Definition: TRolke.cxx:630
void SetAttBit(UInt_t f)
Definition: TGeoAtt.h:65
virtual ~TGeoVolumeMulti()
Destructor.
void CheckShape(Int_t testNo, Int_t nsamples=10000, Option_t *option="")
Tests for checking the shape navigation algorithms. See TGeoShape::CheckShape()
Definition: TGeoVolume.cxx:675
static TGeoVolume * Import(const char *filename, const char *name="", Option_t *option="")
Import a volume from a file.
Definition: TGeoVolume.cxx:889
Abstract class for geometry painters.
void ClearOverlaps()
Clear the list of overlaps.
A node represent a volume positioned inside another.They store links to both volumes and to the TGeoM...
Definition: TGeoNode.h:39
void SetNsegments(Int_t nseg)
Set number of segments for approximating circles in drawing.
TGeoVolumeMulti()
dummy constructor
virtual TGeoExtension * Grab()=0
char * GetPointerName() const
Provide a pointer name containing uid.
Definition: TGeoMedium.cxx:127
R__EXTERN TGeoIdentity * gGeoIdentity
Definition: TGeoMatrix.h:478
Bool_t IsVisDaughters() const
Definition: TGeoAtt.h:89
static Int_t ThreadId()
Translates the current thread id to an ordinal number.
TGeoVolumeMulti * fDivision
Definition: TGeoVolume.h:260
virtual void Add(TObject *obj)
Definition: TList.h:87
void SetVisDaughters(Bool_t vis=kTRUE)
Set visibility for the daughters.
Definition: TGeoAtt.cxx:114
void SetUsed(Bool_t flag=kTRUE)
Definition: TGeoMaterial.h:117
virtual TList * GetListOfKeys() const
TObjArray * GetListOfVolumes() const
Definition: TGeoManager.h:465
void SetCurrentNodeIndex(Int_t index)
virtual void SetLineStyle(Style_t lstyle)
Set the line style for all components.
Bool_t IsOverlappingCandidate() const
Definition: TGeoVolume.h:149
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
Definition: TRolke.cxx:630
void SetCurrentPoint(Double_t x, Double_t y, Double_t z)
Set the current tracking point.
Int_t AddMaterial(const TGeoMaterial *material)
Add a material to the list. Returns index of the material in list.
virtual Double_t GetAxisRange(Int_t iaxis, Double_t &xlo, Double_t &xhi) const =0
Int_t GetEntries() const
Return the number of objects in array (i.e.
Definition: TObjArray.cxx:522
Double_t WeightA() const
Analytical computation of the weight.
virtual Int_t GetByteCount() const
Definition: TGeoNode.h:81
TObject * GetValue(const char *keyname) const
Returns a pointer to the value associated with keyname as name of the key.
Definition: TMap.cxx:235
void SetOverlappingCandidate(Bool_t flag)
Definition: TGeoVolume.h:218
void GrabFocus()
Move perspective view focus to this volume.
void Add(TObject *obj)
Definition: TObjArray.h:73
virtual void cd(Int_t)
virtual Bool_t IsVolumeMulti() const
Definition: TGeoVolume.h:118
void ResetBit(UInt_t f)
Definition: TObject.h:171
TObjArray * GetListOfOverlaps()
Definition: TGeoManager.h:461
void ClearThreadData() const
Bool_t IsStreamingVoxels() const
Definition: TGeoManager.h:455
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition: TAttFill.h:31
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition: TObject.cxx:908
virtual void SetMedium(TGeoMedium *medium)
Definition: TGeoVolume.h:232
TGeoVolume * GetTopVolume() const
Definition: TGeoManager.h:500
void FindOverlaps() const
loop all nodes marked as overlaps and find overlapping brothers
virtual TGeoVolume * GetDrawnVolume() const =0
Bool_t IsClosed() const
Definition: TGeoManager.h:282
Int_t GetNodeIndex(const TGeoNode *node, Int_t *check_list, Int_t ncheck) const
Get the index of a daughter within check_list by providing the node pointer.
TGeoShape * GetShape() const
Definition: TGeoVolume.h:191
virtual void Compress()
Remove empty slots from array.
Definition: TObjArray.cxx:333
TGeoShape * GetLastShape() const
Returns the last shape.
std::vector< ThreadData_t * > fThreadData
Definition: TGeoVolume.h:324
virtual TGeoMatrix * GetMatrix() const
Definition: TGeoNode.h:168
void SetVisTouched(Bool_t vis=kTRUE)
Mark visualization attributes as "modified".
Definition: TGeoAtt.cxx:131
void SetNumber(Int_t number)
Definition: TGeoVolume.h:235
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:164
void CheckShapes()
check for negative parameters in shapes.
Definition: TGeoVolume.cxx:700
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition: TEnv.cxx:491
const Bool_t kTRUE
Definition: RtypesCore.h:87
void Grab()
Definition: TGeoVolume.h:142
void SetVisOption(Int_t option=0)
set drawing mode :
void SelectVolume(Bool_t clear=kFALSE)
Select this volume as matching an arbitrary criteria.
TVirtualGeoPainter * GetGeomPainter()
Make a default painter if none present. Returns pointer to it.
Bool_t OptimizeVoxels()
Perform an extensive sampling to find which type of voxelization is most efficient.
TGeoNode * FindNode(const char *name) const
search a daughter inside the list of nodes
TGeoVolume * GetVolume() const
Definition: TGeoNode.h:94
virtual Int_t GetOptimalVoxels() const
Definition: TGeoNode.h:96
Line Attributes class.
Definition: TAttLine.h:18
virtual void AddNodeOverlap(TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat, Option_t *option)
Add an overlapping node - not allowed for assemblies.
void Refresh()
Refresh browser contents.
Definition: TBrowser.cxx:377
char name[80]
Definition: TGX11.cxx:109
virtual void cd(Int_t inode) const
Actualize matrix of node indexed <inode>
Definition: TGeoVolume.cxx:975
virtual void Print(const Option_t *option="") const
print characteristics of this material
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:866
Int_t GetNtotal() const
Definition: TGeoVolume.h:172
void SetNumber(Int_t number)
Definition: TGeoNode.h:113
virtual void SetVisOnly(Bool_t flag=kTRUE)
Set visibility for leaves.
Bool_t IsValid() const
Definition: TGeoVolume.h:155
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
Int_t fRefCount
Definition: TGeoVolume.h:67
virtual TH2F * LegoPlot(Int_t ntheta=60, Double_t themin=0., Double_t themax=180., Int_t nphi=90, Double_t phimin=0., Double_t phimax=360., Double_t rmin=0., Double_t rmax=9999999, Option_t *option="")=0
Bool_t IsRunTimeShape() const
Definition: TGeoShape.h:139
const char * Data() const
Definition: TString.h:345
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
Definition: TObject.cxx:664
void SetNtotal(Int_t ntotal)
Definition: TGeoVolume.h:236
virtual Bool_t IsAssembly() const
Returns true if the volume is an assembly or a scaled assembly.