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