// @(#)root/geom:$Id$
// Author: Andrei Gheata   31/01/02

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/


///////////////////////////////////////////////////////////////////////////////
// TGeoCompositeShape - class handling Boolean composition of shapes
//
//   Composite shapes are Boolean combination of two or more shape
// components. The supported boolean operations are union (+), intersection (*)
// and subtraction. Composite shapes derive from the base TGeoShape class,
// therefore providing all shape features : computation of bounding box, finding
// if a given point is inside or outside the combination, as well as computing the
// distance to entering/exiting. It can be directly used for creating volumes or
// used in the definition of other composite shapes.
//   Composite shapes are provided in order to complement and extend the set of
// basic shape primitives. They have a binary tree internal structure, therefore
// all shape-related geometry queries are signals propagated from top level down
// to the final leaves, while the provided answers are assembled and interpreted
// back at top. This CSG hierarchy is effective for small number of components,
// while performance drops dramatically for large structures. Building a complete
// geometry in this style is virtually possible but highly not recommended.
//
//   Structure of composite shapes
//
//   A composite shape can always be regarded as the result of a Boolean operation
// between only two shape components. All information identifying these two
// components as well as their positions with respect to the frame of the composite
// is represented by an object called Boolean node. A composite shape just have
// a pointer to such a Boolean node. Since the shape components may also be
// composites, they will also contain binary Boolean nodes branching other two
// shapes in the hierarcy. Any such branch ends-up when the final leaves are no
// longer composite shapes, but basic primitives.
//
//Begin_Html
/*
<img src="gif/t_booltree.jpg">
*/
//End_Html
//
//   Suppose that A, B, C and D represent basic shapes, we will illustrate
// how the internal representation of few combinations look like. We do this
// only for the sake of understanding how to create them in a proper way, since
// the user interface for this purpose is in fact very simple. We will ignore
// for the time being the positioning of components. The definition of a composite
// shape takes an expression where the identifiers are shape names. The
// expression is parsed and decomposed in 2 sub-expressions and the top-level
// Boolean operator.
//
// 1.     A+B+C
//   This represent the union of A, B and C. Both union operators are at the
// same level. Since:
//        A+B+C = (A+B)+C = A+(B+C)
// the first (+) is taken as separator, hence the expression split:
//        A and B+C
// A Boolean node of type TGeoUnion("A", "B+C") is created. This tries to replace
// the 2 expressions by actual pointers to corresponding shapes.
// The first expression (A) contains no operators therefore is interpreted as
// representing a shape. The shape named "A" is searched into the list of shapes
// handled by the manager class and stored as the "left" shape in the Boolean
// union node. Since the second expression is not yet fully decomposed, the "right"
// shape in the combination is created as a new composite shape. This will split
// at its turn B+C into B and C and create a TGeoUnion("B","C"). The B and C
// identifiers will be looked for and replaced by the pointers to the actual shapes
// into the new node. Finally, the composite "A+B+C" will be represented as:
//
//                 A
//                |
//   [A+B+C] = (+)             B
//                |           |
//                 [B+C] = (+)
//                            |
//                             C
//
// where [] is a composite shape, (+) is a Boolean node of type union and A, B,
// C are pointers to the corresponding shapes.
//   Building this composite shapes takes the following line :
//      TGeoCompositeShape *cs1 = new TGeoCompositeShape("CS1", "A+B+C");
//
// 2.      (A+B)-(C+D)
//   This expression means: subtract the union of C and D from the union of A and
// B. The usage of paranthesys to force operator precedence is always recommended.
// The representation of the corresponding composite shape looks like:
//
//                                   A
//                                  |
//                       [A+B] = (+)
//                      |           |
//   [(A+B)-(C+D)] = (-)           C B
//                      |         |
//                       [C+D]=(+)
//                                |
//                                 D
//
//      TGeoCompositeShape *cs2 = new TGeoCompositeShape("CS2", "(A+B)-(C+D)");
//
//   Building composite shapes as in the 2 examples above is not always quite
// usefull since we were using unpositioned shapes. When suplying just shape
// names as identifiers, the created boolean nodes will assume that the shapes
// are positioned with an identity transformation with respect to the frame of
// the created composite. In order to provide some positioning of the combination
// components, we have to attach after each shape identifier the name of an
// existing transformation, separated by a colon. Obviously all transformations
// created for this purpose have to be objects with unique names in order to be
// properly substituted during parsing.
//   Let's look at the code implementing the second example :
//
//      TGeoTranslation *t1 = new TGeoTranslation("t1",0,0,-20);
//      TGeoTranslation *t2 = new TGeoTranslation("t2",0,0, 20);
//      TGeoRotation *r1 = new TGeoRotation("r1"); // transformations need names
//      r1->SetAngles(90,30,90,120,0,0); // rotation with 30 degrees about Z
//      TGeoTube *a = new TGeoTube(0, 10,20);
//      a->SetName("A");                 // shapes need names too
//      TGeoTube *b = new TGeoTube(0, 20,20);
//      b->SetName("B");
//      TGeoBBox *c = new TGeoBBox(10,10,50);
//      c->SetName("C");
//      TGeoBBox *d = new TGeoBBox(50,10,10);
//      d->SetName("D");
//
//      TGeoCompositeShape *cs;
//      cs = new TGeoCompositeShape("CS", "(A:t1+B:t2)-(C+D:r1)");
//
//   The newly created composite looks like 2 cylinders of different radii sitting
// one on top of the other and having 2 rectangular holes : a longitudinal one
// along Z axis corresponding to C and an other one in the XY plane due to D.
//   One should have in mind that the same shape or matrix identifier can be
// used many times in the same expression. For instance:
//
//      (A:t1-A:t2)*B:t1
//
// is a valid expression. Expressions that cannot be parsed or identifiers that
// cannot be substituted by existing objects generate error messages.
//   Composite shapes can be subsequently used for defining volumes. Moreover,
// these volumes may have daughters but these have to obbey overlapping/extruding
// rules (see TGeoVolume). Volumes created based on composite shapes cannot be
// divided. Visualization of such volumes is currently not implemented.

#include "Riostream.h"
#include "TRandom3.h"

#include "TGeoManager.h"
#include "TGeoMatrix.h"
#include "TGeoBoolNode.h"
#include "TVirtualGeoPainter.h"

#include "TVirtualPad.h"
#include "TVirtualViewer3D.h"
#include "TBuffer3D.h"
#include "TBuffer3DTypes.h"

#include "TGeoCompositeShape.h"
ClassImp(TGeoCompositeShape)

//______________________________________________________________________________
void TGeoCompositeShape::ClearThreadData() const
{
   // Needed just for cleanup.
   if (fNode) fNode->ClearThreadData();
}

//______________________________________________________________________________
void TGeoCompositeShape::CreateThreadData(Int_t nthreads)
{
   // Needed just for cleanup.
   if (fNode) fNode->CreateThreadData(nthreads);
}

//_____________________________________________________________________________
TGeoCompositeShape::TGeoCompositeShape()
                   :TGeoBBox(0, 0, 0)
{
// Default constructor
   SetShapeBit(TGeoShape::kGeoComb);
   fNode  = 0;
}

//_____________________________________________________________________________
TGeoCompositeShape::TGeoCompositeShape(const char *name, const char *expression)
                   :TGeoBBox(0, 0, 0)
{
// Default constructor
   SetShapeBit(TGeoShape::kGeoComb);
   SetName(name);
   fNode  = 0;
   MakeNode(expression);
   if (!fNode) {
      Error("ctor", "Composite %s: cannot parse expression: %s", name, expression);
      return;
   }
   ComputeBBox();
}

//_____________________________________________________________________________
TGeoCompositeShape::TGeoCompositeShape(const char *expression)
                   :TGeoBBox(0, 0, 0)
{
// Default constructor
   SetShapeBit(TGeoShape::kGeoComb);
   fNode  = 0;
   MakeNode(expression);
   if (!fNode) {
      TString message = TString::Format("Composite (no name) could not parse expression %s", expression);
      Error("ctor", "%s", message.Data());
      return;
   }
   ComputeBBox();
}

//_____________________________________________________________________________
TGeoCompositeShape::TGeoCompositeShape(const char *name, TGeoBoolNode *node)
                   :TGeoBBox(0,0,0)
{
// Constructor with a Boolean node
   SetName(name);
   fNode = node;
   if (!fNode) {
      Error("ctor", "Composite shape %s has null node", name);
      return;
   }
   ComputeBBox();
}

//_____________________________________________________________________________
TGeoCompositeShape::~TGeoCompositeShape()
{
// destructor
   if (fNode) delete fNode;
}

//_____________________________________________________________________________
Double_t TGeoCompositeShape::Capacity() const
{
// Computes capacity of this shape [length^3] by sampling with 1% error.
   Double_t pt[3];
   if (!gRandom) gRandom = new TRandom3();
   Double_t vbox = 8*fDX*fDY*fDZ; // cm3
   Int_t igen=0;
   Int_t iin = 0;
   while (iin<10000) {
      pt[0] = fOrigin[0]-fDX+2*fDX*gRandom->Rndm();
      pt[1] = fOrigin[1]-fDY+2*fDY*gRandom->Rndm();
      pt[2] = fOrigin[2]-fDZ+2*fDZ*gRandom->Rndm();
      igen++;
      if (Contains(pt)) iin++;
   }
   Double_t capacity = iin*vbox/igen;
   return capacity;
}

//_____________________________________________________________________________
void TGeoCompositeShape::ComputeBBox()
{
// compute bounding box of the sphere
   if(fNode) fNode->ComputeBBox(fDX, fDY, fDZ, fOrigin);
}

//_____________________________________________________________________________
void TGeoCompositeShape::ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm)
{
// Computes normal vector in POINT to the composite shape.
   if (fNode) fNode->ComputeNormal(point,dir,norm);
}

//_____________________________________________________________________________
Bool_t TGeoCompositeShape::Contains(const Double_t *point) const
{
// Tests if point is inside the shape.
   if (fNode) return fNode->Contains(point);
   return kFALSE;
}

//_____________________________________________________________________________
Int_t TGeoCompositeShape::DistancetoPrimitive(Int_t px, Int_t py)
{
// Compute closest distance from point px,py to each corner.
   const Int_t numPoints = GetNmeshVertices();
   return ShapeDistancetoPrimitive(numPoints, px, py);
}

//_____________________________________________________________________________
Double_t TGeoCompositeShape::DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact,
                                      Double_t step, Double_t *safe) const
{
// Compute distance from outside point to this composite shape.
// Check if the bounding box is crossed within the requested distance
   Double_t sdist = TGeoBBox::DistFromOutside(point,dir, fDX, fDY, fDZ, fOrigin, step);
   if (sdist>=step) return TGeoShape::Big();
   if (fNode) return fNode->DistFromOutside(point, dir, iact, step, safe);
   return TGeoShape::Big();
}

//_____________________________________________________________________________
Double_t TGeoCompositeShape::DistFromInside(const Double_t *point, const Double_t *dir, Int_t iact,
                                      Double_t step, Double_t *safe) const
{
// Compute distance from inside point to outside of this composite shape.
   if (fNode) return fNode->DistFromInside(point, dir, iact, step, safe);
   return TGeoShape::Big();
}

//_____________________________________________________________________________
TGeoVolume *TGeoCompositeShape::Divide(TGeoVolume  * /*voldiv*/, const char * /*divname*/, Int_t /*iaxis*/,
                                       Int_t /*ndiv*/, Double_t /*start*/, Double_t /*step*/)
{
// Divide all range of iaxis in range/step cells
   Error("Divide", "Composite shapes cannot be divided");
   return 0;
}

//_____________________________________________________________________________
void TGeoCompositeShape::GetMeshNumbers(Int_t &nvert, Int_t &nsegs, Int_t &npols) const
{
// Returns numbers of vertices, segments and polygons composing the shape mesh.
   nvert = GetNmeshVertices();
   nsegs = 0;
   npols = 0;
}

//_____________________________________________________________________________
void TGeoCompositeShape::InspectShape() const
{
// print shape parameters
   printf("*** TGeoCompositeShape : %s = %s\n", GetName(), GetTitle());
   printf(" Bounding box:\n");
   TGeoBBox::InspectShape();
}

//_____________________________________________________________________________
void TGeoCompositeShape::MakeNode(const char *expression)
{
// Make a booleann node according to the top level boolean operation of expression.
// Propagates signal to branches until expression is fully decomposed.
//   printf("Making node for : %s\n", expression);
   if (fNode) delete fNode;
   fNode = 0;
   SetTitle(expression);
   TString sleft, sright, smat;
   Int_t boolop;
   boolop = TGeoManager::Parse(expression, sleft, sright, smat);
   if (boolop<0) {
      // fail
      Error("MakeNode", "parser error");
      return;
   }
   if (smat.Length())
      Warning("MakeNode", "no geometrical transformation allowed at this level");
   switch (boolop) {
      case 0:
         Error("MakeNode", "Expression has no boolean operation");
         return;
      case 1:
         fNode = new TGeoUnion(sleft.Data(), sright.Data());
         return;
      case 2:
         fNode = new TGeoSubtraction(sleft.Data(), sright.Data());
         return;
      case 3:
         fNode = new TGeoIntersection(sleft.Data(), sright.Data());
   }
}

//_____________________________________________________________________________
Bool_t TGeoCompositeShape::PaintComposite(Option_t *option) const
{
   // Paint this composite shape into the current 3D viewer
   // Returns bool flag indicating if the caller should continue to
   // paint child objects

   Bool_t addChildren = kTRUE;

   TVirtualGeoPainter *painter = gGeoManager->GetGeomPainter();
   TVirtualViewer3D * viewer = gPad->GetViewer3D();
   if (!painter || !viewer) return kFALSE;

   if (fNode) {
      // Fill out the buffer for the composite shape - nothing extra
      // over TGeoBBox
      Bool_t preferLocal = viewer->PreferLocalFrame();
      if (TBuffer3D::GetCSLevel()) preferLocal = kFALSE;
      static TBuffer3D buffer(TBuffer3DTypes::kComposite);
      FillBuffer3D(buffer, TBuffer3D::kCore|TBuffer3D::kBoundingBox,
                   preferLocal);

      Bool_t paintComponents = kTRUE;

      // Start a composite shape, identified by this buffer
      if (!TBuffer3D::GetCSLevel())
         paintComponents = viewer->OpenComposite(buffer, &addChildren);

      TBuffer3D::IncCSLevel();

      // Paint the boolean node - will add more buffers to viewer
      TGeoHMatrix *matrix = (TGeoHMatrix*)TGeoShape::GetTransform();
      TGeoHMatrix backup(*matrix);
      if (preferLocal) matrix->Clear();
      if (paintComponents) fNode->Paint(option);
      if (preferLocal) *matrix = backup;
      // Close the composite shape
      if (!TBuffer3D::DecCSLevel())
         viewer->CloseComposite();
   }

   return addChildren;
}

//_____________________________________________________________________________
void TGeoCompositeShape::RegisterYourself()
{
// Register the shape and all components to TGeoManager class.
   if (gGeoManager->GetListOfShapes()->FindObject(this)) return;
   gGeoManager->AddShape(this);
   TGeoMatrix *matrix;
   TGeoShape  *shape;
   TGeoCompositeShape *comp;
   if (fNode) {
      matrix = fNode->GetLeftMatrix();
      if (!matrix->IsRegistered()) matrix->RegisterYourself();
      else if (!gGeoManager->GetListOfMatrices()->FindObject(matrix)) {
         gGeoManager->GetListOfMatrices()->Add(matrix);
      }
      matrix = fNode->GetRightMatrix();
      if (!matrix->IsRegistered()) matrix->RegisterYourself();
      else if (!gGeoManager->GetListOfMatrices()->FindObject(matrix)) {
         gGeoManager->GetListOfMatrices()->Add(matrix);
      }
      shape = fNode->GetLeftShape();
      if (!gGeoManager->GetListOfShapes()->FindObject(shape)) {
         if (shape->IsComposite()) {
            comp = (TGeoCompositeShape*)shape;
            comp->RegisterYourself();
         } else {
            gGeoManager->AddShape(shape);
         }
      }
      shape = fNode->GetRightShape();
      if (!gGeoManager->GetListOfShapes()->FindObject(shape)) {
         if (shape->IsComposite()) {
            comp = (TGeoCompositeShape*)shape;
            comp->RegisterYourself();
         } else {
            gGeoManager->AddShape(shape);
         }
      }
   }
}

//_____________________________________________________________________________
Double_t TGeoCompositeShape::Safety(const Double_t *point, Bool_t in) const
{
// computes the closest distance from given point to this shape, according
// to option. The matching point on the shape is stored in spoint.
   if (fNode) return fNode->Safety(point,in);
   return 0.;
}

//_____________________________________________________________________________
void TGeoCompositeShape::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
{
// Save a primitive as a C++ statement(s) on output stream "out".
   if (TObject::TestBit(kGeoSavePrimitive)) return;
   if (fNode) fNode->SavePrimitive(out,option);
   out << "   // Shape: " << GetName() << " type: " << ClassName() << std::endl;
   out << "   TGeoShape *" << GetPointerName() << " = new TGeoCompositeShape(\"" << GetName() << "\", pBoolNode);" << std::endl;
   if (strlen(GetTitle())) out << "   " << GetPointerName() << "->SetTitle(\"" << GetTitle() << "\");" << std::endl;
   TObject::SetBit(TGeoShape::kGeoSavePrimitive);
}

//_____________________________________________________________________________
void TGeoCompositeShape::SetPoints(Double_t *points) const
{
// create points for a composite shape
   if (fNode) fNode->SetPoints(points);
}

//_____________________________________________________________________________
void TGeoCompositeShape::SetPoints(Float_t *points) const
{
// create points for a composite shape
   if (fNode) fNode->SetPoints(points);
}

//_____________________________________________________________________________
void TGeoCompositeShape::Sizeof3D() const
{
// compute size of this 3D object
   if (fNode) fNode->Sizeof3D();
}

//_____________________________________________________________________________
Int_t TGeoCompositeShape::GetNmeshVertices() const
{
// Return number of vertices of the mesh representation
   if (!fNode) return 0;
   return fNode->GetNpoints();
}

//_____________________________________________________________________________
void TGeoCompositeShape::Contains_v(const Double_t *points, Bool_t *inside, Int_t vecsize) const
{
// Check the inside status for each of the points in the array.
// Input: Array of point coordinates + vector size
// Output: Array of Booleans for the inside of each point
   for (Int_t i=0; i<vecsize; i++) inside[i] = Contains(&points[3*i]);
}

//_____________________________________________________________________________
void TGeoCompositeShape::ComputeNormal_v(const Double_t *points, const Double_t *dirs, Double_t *norms, Int_t vecsize)
{
// Compute the normal for an array o points so that norm.dot.dir is positive
// Input: Arrays of point coordinates and directions + vector size
// Output: Array of normal directions
   for (Int_t i=0; i<vecsize; i++) ComputeNormal(&points[3*i], &dirs[3*i], &norms[3*i]);
}

//_____________________________________________________________________________
void TGeoCompositeShape::DistFromInside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t* step) const
{
// Compute distance from array of input points having directions specisied by dirs. Store output in dists
   for (Int_t i=0; i<vecsize; i++) dists[i] = DistFromInside(&points[3*i], &dirs[3*i], 3, step[i]);
}

//_____________________________________________________________________________
void TGeoCompositeShape::DistFromOutside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t* step) const
{
// Compute distance from array of input points having directions specisied by dirs. Store output in dists
   for (Int_t i=0; i<vecsize; i++) dists[i] = DistFromOutside(&points[3*i], &dirs[3*i], 3, step[i]);
}

//_____________________________________________________________________________
void TGeoCompositeShape::Safety_v(const Double_t *points, const Bool_t *inside, Double_t *safe, Int_t vecsize) const
{
// Compute safe distance from each of the points in the input array.
// Input: Array of point coordinates, array of statuses for these points, size of the arrays
// Output: Safety values
   for (Int_t i=0; i<vecsize; i++) safe[i] = Safety(&points[3*i], inside[i]);
}
 TGeoCompositeShape.cxx:1
 TGeoCompositeShape.cxx:2
 TGeoCompositeShape.cxx:3
 TGeoCompositeShape.cxx:4
 TGeoCompositeShape.cxx:5
 TGeoCompositeShape.cxx:6
 TGeoCompositeShape.cxx:7
 TGeoCompositeShape.cxx:8
 TGeoCompositeShape.cxx:9
 TGeoCompositeShape.cxx:10
 TGeoCompositeShape.cxx:11
 TGeoCompositeShape.cxx:12
 TGeoCompositeShape.cxx:13
 TGeoCompositeShape.cxx:14
 TGeoCompositeShape.cxx:15
 TGeoCompositeShape.cxx:16
 TGeoCompositeShape.cxx:17
 TGeoCompositeShape.cxx:18
 TGeoCompositeShape.cxx:19
 TGeoCompositeShape.cxx:20
 TGeoCompositeShape.cxx:21
 TGeoCompositeShape.cxx:22
 TGeoCompositeShape.cxx:23
 TGeoCompositeShape.cxx:24
 TGeoCompositeShape.cxx:25
 TGeoCompositeShape.cxx:26
 TGeoCompositeShape.cxx:27
 TGeoCompositeShape.cxx:28
 TGeoCompositeShape.cxx:29
 TGeoCompositeShape.cxx:30
 TGeoCompositeShape.cxx:31
 TGeoCompositeShape.cxx:32
 TGeoCompositeShape.cxx:33
 TGeoCompositeShape.cxx:34
 TGeoCompositeShape.cxx:35
 TGeoCompositeShape.cxx:36
 TGeoCompositeShape.cxx:37
 TGeoCompositeShape.cxx:38
 TGeoCompositeShape.cxx:39
 TGeoCompositeShape.cxx:40
 TGeoCompositeShape.cxx:41
 TGeoCompositeShape.cxx:42
 TGeoCompositeShape.cxx:43
 TGeoCompositeShape.cxx:44
 TGeoCompositeShape.cxx:45
 TGeoCompositeShape.cxx:46
 TGeoCompositeShape.cxx:47
 TGeoCompositeShape.cxx:48
 TGeoCompositeShape.cxx:49
 TGeoCompositeShape.cxx:50
 TGeoCompositeShape.cxx:51
 TGeoCompositeShape.cxx:52
 TGeoCompositeShape.cxx:53
 TGeoCompositeShape.cxx:54
 TGeoCompositeShape.cxx:55
 TGeoCompositeShape.cxx:56
 TGeoCompositeShape.cxx:57
 TGeoCompositeShape.cxx:58
 TGeoCompositeShape.cxx:59
 TGeoCompositeShape.cxx:60
 TGeoCompositeShape.cxx:61
 TGeoCompositeShape.cxx:62
 TGeoCompositeShape.cxx:63
 TGeoCompositeShape.cxx:64
 TGeoCompositeShape.cxx:65
 TGeoCompositeShape.cxx:66
 TGeoCompositeShape.cxx:67
 TGeoCompositeShape.cxx:68
 TGeoCompositeShape.cxx:69
 TGeoCompositeShape.cxx:70
 TGeoCompositeShape.cxx:71
 TGeoCompositeShape.cxx:72
 TGeoCompositeShape.cxx:73
 TGeoCompositeShape.cxx:74
 TGeoCompositeShape.cxx:75
 TGeoCompositeShape.cxx:76
 TGeoCompositeShape.cxx:77
 TGeoCompositeShape.cxx:78
 TGeoCompositeShape.cxx:79
 TGeoCompositeShape.cxx:80
 TGeoCompositeShape.cxx:81
 TGeoCompositeShape.cxx:82
 TGeoCompositeShape.cxx:83
 TGeoCompositeShape.cxx:84
 TGeoCompositeShape.cxx:85
 TGeoCompositeShape.cxx:86
 TGeoCompositeShape.cxx:87
 TGeoCompositeShape.cxx:88
 TGeoCompositeShape.cxx:89
 TGeoCompositeShape.cxx:90
 TGeoCompositeShape.cxx:91
 TGeoCompositeShape.cxx:92
 TGeoCompositeShape.cxx:93
 TGeoCompositeShape.cxx:94
 TGeoCompositeShape.cxx:95
 TGeoCompositeShape.cxx:96
 TGeoCompositeShape.cxx:97
 TGeoCompositeShape.cxx:98
 TGeoCompositeShape.cxx:99
 TGeoCompositeShape.cxx:100
 TGeoCompositeShape.cxx:101
 TGeoCompositeShape.cxx:102
 TGeoCompositeShape.cxx:103
 TGeoCompositeShape.cxx:104
 TGeoCompositeShape.cxx:105
 TGeoCompositeShape.cxx:106
 TGeoCompositeShape.cxx:107
 TGeoCompositeShape.cxx:108
 TGeoCompositeShape.cxx:109
 TGeoCompositeShape.cxx:110
 TGeoCompositeShape.cxx:111
 TGeoCompositeShape.cxx:112
 TGeoCompositeShape.cxx:113
 TGeoCompositeShape.cxx:114
 TGeoCompositeShape.cxx:115
 TGeoCompositeShape.cxx:116
 TGeoCompositeShape.cxx:117
 TGeoCompositeShape.cxx:118
 TGeoCompositeShape.cxx:119
 TGeoCompositeShape.cxx:120
 TGeoCompositeShape.cxx:121
 TGeoCompositeShape.cxx:122
 TGeoCompositeShape.cxx:123
 TGeoCompositeShape.cxx:124
 TGeoCompositeShape.cxx:125
 TGeoCompositeShape.cxx:126
 TGeoCompositeShape.cxx:127
 TGeoCompositeShape.cxx:128
 TGeoCompositeShape.cxx:129
 TGeoCompositeShape.cxx:130
 TGeoCompositeShape.cxx:131
 TGeoCompositeShape.cxx:132
 TGeoCompositeShape.cxx:133
 TGeoCompositeShape.cxx:134
 TGeoCompositeShape.cxx:135
 TGeoCompositeShape.cxx:136
 TGeoCompositeShape.cxx:137
 TGeoCompositeShape.cxx:138
 TGeoCompositeShape.cxx:139
 TGeoCompositeShape.cxx:140
 TGeoCompositeShape.cxx:141
 TGeoCompositeShape.cxx:142
 TGeoCompositeShape.cxx:143
 TGeoCompositeShape.cxx:144
 TGeoCompositeShape.cxx:145
 TGeoCompositeShape.cxx:146
 TGeoCompositeShape.cxx:147
 TGeoCompositeShape.cxx:148
 TGeoCompositeShape.cxx:149
 TGeoCompositeShape.cxx:150
 TGeoCompositeShape.cxx:151
 TGeoCompositeShape.cxx:152
 TGeoCompositeShape.cxx:153
 TGeoCompositeShape.cxx:154
 TGeoCompositeShape.cxx:155
 TGeoCompositeShape.cxx:156
 TGeoCompositeShape.cxx:157
 TGeoCompositeShape.cxx:158
 TGeoCompositeShape.cxx:159
 TGeoCompositeShape.cxx:160
 TGeoCompositeShape.cxx:161
 TGeoCompositeShape.cxx:162
 TGeoCompositeShape.cxx:163
 TGeoCompositeShape.cxx:164
 TGeoCompositeShape.cxx:165
 TGeoCompositeShape.cxx:166
 TGeoCompositeShape.cxx:167
 TGeoCompositeShape.cxx:168
 TGeoCompositeShape.cxx:169
 TGeoCompositeShape.cxx:170
 TGeoCompositeShape.cxx:171
 TGeoCompositeShape.cxx:172
 TGeoCompositeShape.cxx:173
 TGeoCompositeShape.cxx:174
 TGeoCompositeShape.cxx:175
 TGeoCompositeShape.cxx:176
 TGeoCompositeShape.cxx:177
 TGeoCompositeShape.cxx:178
 TGeoCompositeShape.cxx:179
 TGeoCompositeShape.cxx:180
 TGeoCompositeShape.cxx:181
 TGeoCompositeShape.cxx:182
 TGeoCompositeShape.cxx:183
 TGeoCompositeShape.cxx:184
 TGeoCompositeShape.cxx:185
 TGeoCompositeShape.cxx:186
 TGeoCompositeShape.cxx:187
 TGeoCompositeShape.cxx:188
 TGeoCompositeShape.cxx:189
 TGeoCompositeShape.cxx:190
 TGeoCompositeShape.cxx:191
 TGeoCompositeShape.cxx:192
 TGeoCompositeShape.cxx:193
 TGeoCompositeShape.cxx:194
 TGeoCompositeShape.cxx:195
 TGeoCompositeShape.cxx:196
 TGeoCompositeShape.cxx:197
 TGeoCompositeShape.cxx:198
 TGeoCompositeShape.cxx:199
 TGeoCompositeShape.cxx:200
 TGeoCompositeShape.cxx:201
 TGeoCompositeShape.cxx:202
 TGeoCompositeShape.cxx:203
 TGeoCompositeShape.cxx:204
 TGeoCompositeShape.cxx:205
 TGeoCompositeShape.cxx:206
 TGeoCompositeShape.cxx:207
 TGeoCompositeShape.cxx:208
 TGeoCompositeShape.cxx:209
 TGeoCompositeShape.cxx:210
 TGeoCompositeShape.cxx:211
 TGeoCompositeShape.cxx:212
 TGeoCompositeShape.cxx:213
 TGeoCompositeShape.cxx:214
 TGeoCompositeShape.cxx:215
 TGeoCompositeShape.cxx:216
 TGeoCompositeShape.cxx:217
 TGeoCompositeShape.cxx:218
 TGeoCompositeShape.cxx:219
 TGeoCompositeShape.cxx:220
 TGeoCompositeShape.cxx:221
 TGeoCompositeShape.cxx:222
 TGeoCompositeShape.cxx:223
 TGeoCompositeShape.cxx:224
 TGeoCompositeShape.cxx:225
 TGeoCompositeShape.cxx:226
 TGeoCompositeShape.cxx:227
 TGeoCompositeShape.cxx:228
 TGeoCompositeShape.cxx:229
 TGeoCompositeShape.cxx:230
 TGeoCompositeShape.cxx:231
 TGeoCompositeShape.cxx:232
 TGeoCompositeShape.cxx:233
 TGeoCompositeShape.cxx:234
 TGeoCompositeShape.cxx:235
 TGeoCompositeShape.cxx:236
 TGeoCompositeShape.cxx:237
 TGeoCompositeShape.cxx:238
 TGeoCompositeShape.cxx:239
 TGeoCompositeShape.cxx:240
 TGeoCompositeShape.cxx:241
 TGeoCompositeShape.cxx:242
 TGeoCompositeShape.cxx:243
 TGeoCompositeShape.cxx:244
 TGeoCompositeShape.cxx:245
 TGeoCompositeShape.cxx:246
 TGeoCompositeShape.cxx:247
 TGeoCompositeShape.cxx:248
 TGeoCompositeShape.cxx:249
 TGeoCompositeShape.cxx:250
 TGeoCompositeShape.cxx:251
 TGeoCompositeShape.cxx:252
 TGeoCompositeShape.cxx:253
 TGeoCompositeShape.cxx:254
 TGeoCompositeShape.cxx:255
 TGeoCompositeShape.cxx:256
 TGeoCompositeShape.cxx:257
 TGeoCompositeShape.cxx:258
 TGeoCompositeShape.cxx:259
 TGeoCompositeShape.cxx:260
 TGeoCompositeShape.cxx:261
 TGeoCompositeShape.cxx:262
 TGeoCompositeShape.cxx:263
 TGeoCompositeShape.cxx:264
 TGeoCompositeShape.cxx:265
 TGeoCompositeShape.cxx:266
 TGeoCompositeShape.cxx:267
 TGeoCompositeShape.cxx:268
 TGeoCompositeShape.cxx:269
 TGeoCompositeShape.cxx:270
 TGeoCompositeShape.cxx:271
 TGeoCompositeShape.cxx:272
 TGeoCompositeShape.cxx:273
 TGeoCompositeShape.cxx:274
 TGeoCompositeShape.cxx:275
 TGeoCompositeShape.cxx:276
 TGeoCompositeShape.cxx:277
 TGeoCompositeShape.cxx:278
 TGeoCompositeShape.cxx:279
 TGeoCompositeShape.cxx:280
 TGeoCompositeShape.cxx:281
 TGeoCompositeShape.cxx:282
 TGeoCompositeShape.cxx:283
 TGeoCompositeShape.cxx:284
 TGeoCompositeShape.cxx:285
 TGeoCompositeShape.cxx:286
 TGeoCompositeShape.cxx:287
 TGeoCompositeShape.cxx:288
 TGeoCompositeShape.cxx:289
 TGeoCompositeShape.cxx:290
 TGeoCompositeShape.cxx:291
 TGeoCompositeShape.cxx:292
 TGeoCompositeShape.cxx:293
 TGeoCompositeShape.cxx:294
 TGeoCompositeShape.cxx:295
 TGeoCompositeShape.cxx:296
 TGeoCompositeShape.cxx:297
 TGeoCompositeShape.cxx:298
 TGeoCompositeShape.cxx:299
 TGeoCompositeShape.cxx:300
 TGeoCompositeShape.cxx:301
 TGeoCompositeShape.cxx:302
 TGeoCompositeShape.cxx:303
 TGeoCompositeShape.cxx:304
 TGeoCompositeShape.cxx:305
 TGeoCompositeShape.cxx:306
 TGeoCompositeShape.cxx:307
 TGeoCompositeShape.cxx:308
 TGeoCompositeShape.cxx:309
 TGeoCompositeShape.cxx:310
 TGeoCompositeShape.cxx:311
 TGeoCompositeShape.cxx:312
 TGeoCompositeShape.cxx:313
 TGeoCompositeShape.cxx:314
 TGeoCompositeShape.cxx:315
 TGeoCompositeShape.cxx:316
 TGeoCompositeShape.cxx:317
 TGeoCompositeShape.cxx:318
 TGeoCompositeShape.cxx:319
 TGeoCompositeShape.cxx:320
 TGeoCompositeShape.cxx:321
 TGeoCompositeShape.cxx:322
 TGeoCompositeShape.cxx:323
 TGeoCompositeShape.cxx:324
 TGeoCompositeShape.cxx:325
 TGeoCompositeShape.cxx:326
 TGeoCompositeShape.cxx:327
 TGeoCompositeShape.cxx:328
 TGeoCompositeShape.cxx:329
 TGeoCompositeShape.cxx:330
 TGeoCompositeShape.cxx:331
 TGeoCompositeShape.cxx:332
 TGeoCompositeShape.cxx:333
 TGeoCompositeShape.cxx:334
 TGeoCompositeShape.cxx:335
 TGeoCompositeShape.cxx:336
 TGeoCompositeShape.cxx:337
 TGeoCompositeShape.cxx:338
 TGeoCompositeShape.cxx:339
 TGeoCompositeShape.cxx:340
 TGeoCompositeShape.cxx:341
 TGeoCompositeShape.cxx:342
 TGeoCompositeShape.cxx:343
 TGeoCompositeShape.cxx:344
 TGeoCompositeShape.cxx:345
 TGeoCompositeShape.cxx:346
 TGeoCompositeShape.cxx:347
 TGeoCompositeShape.cxx:348
 TGeoCompositeShape.cxx:349
 TGeoCompositeShape.cxx:350
 TGeoCompositeShape.cxx:351
 TGeoCompositeShape.cxx:352
 TGeoCompositeShape.cxx:353
 TGeoCompositeShape.cxx:354
 TGeoCompositeShape.cxx:355
 TGeoCompositeShape.cxx:356
 TGeoCompositeShape.cxx:357
 TGeoCompositeShape.cxx:358
 TGeoCompositeShape.cxx:359
 TGeoCompositeShape.cxx:360
 TGeoCompositeShape.cxx:361
 TGeoCompositeShape.cxx:362
 TGeoCompositeShape.cxx:363
 TGeoCompositeShape.cxx:364
 TGeoCompositeShape.cxx:365
 TGeoCompositeShape.cxx:366
 TGeoCompositeShape.cxx:367
 TGeoCompositeShape.cxx:368
 TGeoCompositeShape.cxx:369
 TGeoCompositeShape.cxx:370
 TGeoCompositeShape.cxx:371
 TGeoCompositeShape.cxx:372
 TGeoCompositeShape.cxx:373
 TGeoCompositeShape.cxx:374
 TGeoCompositeShape.cxx:375
 TGeoCompositeShape.cxx:376
 TGeoCompositeShape.cxx:377
 TGeoCompositeShape.cxx:378
 TGeoCompositeShape.cxx:379
 TGeoCompositeShape.cxx:380
 TGeoCompositeShape.cxx:381
 TGeoCompositeShape.cxx:382
 TGeoCompositeShape.cxx:383
 TGeoCompositeShape.cxx:384
 TGeoCompositeShape.cxx:385
 TGeoCompositeShape.cxx:386
 TGeoCompositeShape.cxx:387
 TGeoCompositeShape.cxx:388
 TGeoCompositeShape.cxx:389
 TGeoCompositeShape.cxx:390
 TGeoCompositeShape.cxx:391
 TGeoCompositeShape.cxx:392
 TGeoCompositeShape.cxx:393
 TGeoCompositeShape.cxx:394
 TGeoCompositeShape.cxx:395
 TGeoCompositeShape.cxx:396
 TGeoCompositeShape.cxx:397
 TGeoCompositeShape.cxx:398
 TGeoCompositeShape.cxx:399
 TGeoCompositeShape.cxx:400
 TGeoCompositeShape.cxx:401
 TGeoCompositeShape.cxx:402
 TGeoCompositeShape.cxx:403
 TGeoCompositeShape.cxx:404
 TGeoCompositeShape.cxx:405
 TGeoCompositeShape.cxx:406
 TGeoCompositeShape.cxx:407
 TGeoCompositeShape.cxx:408
 TGeoCompositeShape.cxx:409
 TGeoCompositeShape.cxx:410
 TGeoCompositeShape.cxx:411
 TGeoCompositeShape.cxx:412
 TGeoCompositeShape.cxx:413
 TGeoCompositeShape.cxx:414
 TGeoCompositeShape.cxx:415
 TGeoCompositeShape.cxx:416
 TGeoCompositeShape.cxx:417
 TGeoCompositeShape.cxx:418
 TGeoCompositeShape.cxx:419
 TGeoCompositeShape.cxx:420
 TGeoCompositeShape.cxx:421
 TGeoCompositeShape.cxx:422
 TGeoCompositeShape.cxx:423
 TGeoCompositeShape.cxx:424
 TGeoCompositeShape.cxx:425
 TGeoCompositeShape.cxx:426
 TGeoCompositeShape.cxx:427
 TGeoCompositeShape.cxx:428
 TGeoCompositeShape.cxx:429
 TGeoCompositeShape.cxx:430
 TGeoCompositeShape.cxx:431
 TGeoCompositeShape.cxx:432
 TGeoCompositeShape.cxx:433
 TGeoCompositeShape.cxx:434
 TGeoCompositeShape.cxx:435
 TGeoCompositeShape.cxx:436
 TGeoCompositeShape.cxx:437
 TGeoCompositeShape.cxx:438
 TGeoCompositeShape.cxx:439
 TGeoCompositeShape.cxx:440
 TGeoCompositeShape.cxx:441
 TGeoCompositeShape.cxx:442
 TGeoCompositeShape.cxx:443
 TGeoCompositeShape.cxx:444
 TGeoCompositeShape.cxx:445
 TGeoCompositeShape.cxx:446
 TGeoCompositeShape.cxx:447
 TGeoCompositeShape.cxx:448
 TGeoCompositeShape.cxx:449
 TGeoCompositeShape.cxx:450
 TGeoCompositeShape.cxx:451
 TGeoCompositeShape.cxx:452
 TGeoCompositeShape.cxx:453
 TGeoCompositeShape.cxx:454
 TGeoCompositeShape.cxx:455
 TGeoCompositeShape.cxx:456
 TGeoCompositeShape.cxx:457
 TGeoCompositeShape.cxx:458
 TGeoCompositeShape.cxx:459
 TGeoCompositeShape.cxx:460
 TGeoCompositeShape.cxx:461
 TGeoCompositeShape.cxx:462
 TGeoCompositeShape.cxx:463
 TGeoCompositeShape.cxx:464
 TGeoCompositeShape.cxx:465
 TGeoCompositeShape.cxx:466
 TGeoCompositeShape.cxx:467
 TGeoCompositeShape.cxx:468
 TGeoCompositeShape.cxx:469
 TGeoCompositeShape.cxx:470
 TGeoCompositeShape.cxx:471
 TGeoCompositeShape.cxx:472
 TGeoCompositeShape.cxx:473
 TGeoCompositeShape.cxx:474
 TGeoCompositeShape.cxx:475
 TGeoCompositeShape.cxx:476
 TGeoCompositeShape.cxx:477
 TGeoCompositeShape.cxx:478
 TGeoCompositeShape.cxx:479
 TGeoCompositeShape.cxx:480
 TGeoCompositeShape.cxx:481
 TGeoCompositeShape.cxx:482
 TGeoCompositeShape.cxx:483
 TGeoCompositeShape.cxx:484
 TGeoCompositeShape.cxx:485
 TGeoCompositeShape.cxx:486
 TGeoCompositeShape.cxx:487
 TGeoCompositeShape.cxx:488
 TGeoCompositeShape.cxx:489
 TGeoCompositeShape.cxx:490
 TGeoCompositeShape.cxx:491
 TGeoCompositeShape.cxx:492
 TGeoCompositeShape.cxx:493
 TGeoCompositeShape.cxx:494
 TGeoCompositeShape.cxx:495
 TGeoCompositeShape.cxx:496
 TGeoCompositeShape.cxx:497
 TGeoCompositeShape.cxx:498
 TGeoCompositeShape.cxx:499
 TGeoCompositeShape.cxx:500
 TGeoCompositeShape.cxx:501
 TGeoCompositeShape.cxx:502
 TGeoCompositeShape.cxx:503
 TGeoCompositeShape.cxx:504
 TGeoCompositeShape.cxx:505
 TGeoCompositeShape.cxx:506
 TGeoCompositeShape.cxx:507
 TGeoCompositeShape.cxx:508
 TGeoCompositeShape.cxx:509
 TGeoCompositeShape.cxx:510
 TGeoCompositeShape.cxx:511
 TGeoCompositeShape.cxx:512
 TGeoCompositeShape.cxx:513
 TGeoCompositeShape.cxx:514
 TGeoCompositeShape.cxx:515
 TGeoCompositeShape.cxx:516
 TGeoCompositeShape.cxx:517
 TGeoCompositeShape.cxx:518
 TGeoCompositeShape.cxx:519
 TGeoCompositeShape.cxx:520
 TGeoCompositeShape.cxx:521
 TGeoCompositeShape.cxx:522
 TGeoCompositeShape.cxx:523
 TGeoCompositeShape.cxx:524
 TGeoCompositeShape.cxx:525
 TGeoCompositeShape.cxx:526
 TGeoCompositeShape.cxx:527
 TGeoCompositeShape.cxx:528
 TGeoCompositeShape.cxx:529
 TGeoCompositeShape.cxx:530
 TGeoCompositeShape.cxx:531
 TGeoCompositeShape.cxx:532
 TGeoCompositeShape.cxx:533
 TGeoCompositeShape.cxx:534
 TGeoCompositeShape.cxx:535
 TGeoCompositeShape.cxx:536
 TGeoCompositeShape.cxx:537
 TGeoCompositeShape.cxx:538
 TGeoCompositeShape.cxx:539
 TGeoCompositeShape.cxx:540
 TGeoCompositeShape.cxx:541
 TGeoCompositeShape.cxx:542
 TGeoCompositeShape.cxx:543
 TGeoCompositeShape.cxx:544