ROOT logo
// @(#)root/geom:$Id: TGeoShape.cxx 27731 2009-03-09 17:40:56Z brun $
// 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.             *
 *************************************************************************/

//____________________________________________________________________________
// TGeoShape - Base abstract class for all shapes. 
//____________________________________________________________________________
//
//
//   Shapes are geometrical objects that provide the basic modelling 
// functionality. They provide the definition of the LOCAL frame of coordinates,
// with respect to which they are defined. Any implementation of a shape deriving
// from the base TGeoShape class has to provide methods for :
//  - finding out if a point defined in their local frame is or not contained 
// inside;
//  - computing the distance from a local point to getting outside/entering the
// shape, given a known direction;
//  - computing the maximum distance in any direction from a local point that
// does NOT result in a boundary crossing of the shape (safe distance); 
//  - computing the cosines of the normal vector to the crossed shape surface,
// given a starting local point and an ongoing direction.
//   All the features above are globally managed by the modeller in order to
// provide navigation functionality. In addition to those, shapes have also to
// implement additional specific abstract methods :
//  - computation of the minimal box bounding the shape, given that this box have
// to be aligned with the local coordinates;
//  - algorithms for dividing the shape along a given axis and producing resulting
// divisions volumes.
//
//   The modeler currently provides a set of 16 basic shapes, which we will call
// primitives. It also provides a special class allowing the creation of shapes
// made as a result of boolean operations between primitives. These are called
// composite shapes and the composition operation can be recursive (composition
// of composites). This allows the creation of a quite large number of different
// shape topologies and combinations.
//
//   Shapes are named objects and register themselves to the manager class at 
// creation time. This is responsible for their final deletion. Shapes 
// can be created without name if their retreival by name is no needed. Generally
// shapes are objects that are usefull only at geometry creation stage. The pointer
// to a shape is in fact needed only when referring to a given volume and it is 
// always accessible at that level. A shape may be referenced by several volumes,
// therefore its deletion is not possible once volumes were defined based on it.
// 
// 
// 
// Creating shapes
//================
//   Shape objects embeed only the minimum set of parameters that are fully
// describing a valid physical shape. For instance, a tube is represented by
// its half length, the minimum radius and the maximum radius. Shapes are used
// togeather with media in order to create volumes, which in their turn 
// are the main components of the geometrical tree. A specific shape can be created
// stand-alone : 
//
//   TGeoBBox *box = new TGeoBBox("s_box", halfX, halfY, halfZ); // named
//   TGeoTube *tub = new TGeoTube(rmin, rmax, halfZ);            // no name
//   ...  (see each specific shape constructors)
//
//   Sometimes it is much easier to create a volume having a given shape in one 
// step, since shapes are not direcly linked in the geometrical tree but volumes 
// are :
//
//   TGeoVolume *vol_box = gGeoManager->MakeBox("BOX_VOL", "mat1", halfX, halfY, halfZ);
//   TGeoVolume *vol_tub = gGeoManager->MakeTube("TUB_VOL", "mat2", rmin, rmax, halfZ);
//   ...  (see MakeXXX() utilities in TGeoManager class)
//
//
// Shape queries
//===============
// Note that global queries related to a geometry are handled by the manager class.
// However, shape-related queries might be sometimes usefull.
//
// A) Bool_t TGeoShape::Contains(Double_t *point[3])
//   - this method returns true if POINT is actually inside the shape. The point
// has to be defined in the local shape reference. For instance, for a box having
// DX, DY and DZ half-lengths a point will be considered inside if :
//   | -DX <= point[0] <= DX
//   | -DY <= point[1] <= DY
//   | -DZ <= point[2] <= DZ
//
// B) Double_t TGeoShape::DistFromInside(Double_t *point[3], Double_t *dir[3],
//                                  Int_t iact, Double_t step, Double_t *safe)
//   - computes the distance to exiting a shape from a given point INSIDE, along
// a given direction. The direction is given by its director cosines with respect
// to the local shape coordinate system. This method provides additional
// information according the value of IACT input parameter :
//   IACT = 0     => compute only safe distance and fill it at the location 
//                   given by SAFE
//   IACT = 1     => a proposed STEP is supplied. The safe distance is computed
//                   first. If this is bigger than STEP than the proposed step
//                   is approved and returned by the method since it does not
//                   cross the shape boundaries. Otherwise, the distance to
//                   exiting the shape is computed and returned.
//   IACT = 2     => compute both safe distance and distance to exiting, ignoring
//                   the proposed step.
//   IACT > 2     => compute only the distance to exiting, ignoring anything else.
//
// C) Double_t TGeoShape::DistFromOutside(Double_t *point[3], Double_t *dir[3],
//                                  Int_t iact, Double_t step, Double_t *safe)
//   - computes the distance to entering a shape from a given point OUTSIDE. Acts
// in the same way as B).
//
// D) Double_t Safety(Double_t *point[3], Bool_t inside)
//
//   - compute maximum shift of a point in any direction that does not change its
// INSIDE/OUTSIDE state (does not cross shape boundaries). The state of the point
// have to be properly supplied.
//
// E) Double_t *Normal(Double_t *point[3], Double_t *dir[3], Bool_t inside)
//
//   - returns director cosines of normal to the crossed shape surface from a
// given point towards a direction. One has to specify if the point is inside 
// or outside shape. According to this, the normal will be outwards or inwards
// shape respectively. Normal components are statically stored by shape class,
// so it has to be copied after retreival in a different array. 
//
// Dividing shapes
//=================
//   Shapes can generally be divided along a given axis. Supported axis are
// X, Y, Z, Rxy, Phi, Rxyz. A given shape cannot be divided however on any axis.
// The general rule is that that divisions are possible on whatever axis that
// produces still known shapes as slices. The division of shapes should not be
// performed by TGeoShape::Divide() calls, but rather by TGeoVolume::Divide().
// The algorithm for dividing a specific shape is known by the shape object, but
// is always invoked in a generic way from the volume level. Details on how to
// do that can be found in TGeoVolume class. One can see how all division options
// are interpreted and which is their result inside specific shape classes.
//_____________________________________________________________________________
//
//Begin_Html
/*
<img src="gif/t_shape.jpg">
*/
//End_Html

#include "TObjArray.h"
#include "TEnv.h"
#include "TError.h"

#include "TGeoMatrix.h"
#include "TGeoManager.h"
#include "TGeoVolume.h"
#include "TGeoShape.h"
#include "TVirtualGeoPainter.h"
#include "TBuffer3D.h"
#include "TBuffer3DTypes.h"
#include "TMath.h"

ClassImp(TGeoShape)

TGeoMatrix *TGeoShape::fgTransform = NULL;
Double_t    TGeoShape::fgEpsMch = 2.220446049250313e-16;
//_____________________________________________________________________________
TGeoShape::TGeoShape()
{
// Default constructor
   fShapeBits = 0;
   fShapeId   = 0;
   if (!gGeoManager) {
      gGeoManager = new TGeoManager("Geometry", "default geometry");
      // gROOT->AddGeoManager(gGeoManager);
   }
//   fShapeId = gGeoManager->GetListOfShapes()->GetSize();
//   gGeoManager->AddShape(this);
}

//_____________________________________________________________________________
TGeoShape::TGeoShape(const char *name)
          :TNamed(name, "")
{
// Default constructor
   fShapeBits = 0;
   fShapeId   = 0;
   if (!gGeoManager) {
      gGeoManager = new TGeoManager("Geometry", "default geometry");
      // gROOT->AddGeoManager(gGeoManager);
   }
   fShapeId = gGeoManager->GetListOfShapes()->GetSize();
   gGeoManager->AddShape(this);
}

//_____________________________________________________________________________
TGeoShape::~TGeoShape()
{
// Destructor
   if (gGeoManager) gGeoManager->GetListOfShapes()->Remove(this);
}

//_____________________________________________________________________________
Double_t TGeoShape::ComputeEpsMch()
{
// Compute machine round-off double precision error as the smallest number that
// if added to 1.0 is different than 1.0.
   Double_t temp1 = 1.0; 
   Double_t temp2 = 1.0 + temp1;
   Double_t mchEps;
   while (temp2>1.0) {
      mchEps = temp1;
      temp1 /= 2;
      temp2 = 1.0 + temp1;
   }
   fgEpsMch = mchEps;
   return fgEpsMch;
}   
   
//_____________________________________________________________________________
Double_t TGeoShape::EpsMch()
{
   //static function returning the machine round-off error
   
   return fgEpsMch;
}
   
//_____________________________________________________________________________
const char *TGeoShape::GetName() const
{
// Get the shape name.
   if (!strlen(fName)) {
      return ((TObject *)this)->ClassName();
   }
   return TNamed::GetName();
}

//_____________________________________________________________________________
Int_t TGeoShape::ShapeDistancetoPrimitive(Int_t numpoints, Int_t px, Int_t py) const
{
// Returns distance to shape primitive mesh.
   TVirtualGeoPainter *painter = gGeoManager->GetGeomPainter();
   if (!painter) return 9999;
   return painter->ShapeDistancetoPrimitive(this, numpoints, px, py);
}

//_____________________________________________________________________________
Bool_t TGeoShape::IsCloseToPhi(Double_t epsil, Double_t *point, Double_t c1, Double_t s1, Double_t c2, Double_t s2)
{
// True if point is closer than epsil to one of the phi planes defined by c1,s1 or c2,s2
   Double_t saf1 = TGeoShape::Big();
   Double_t saf2 = TGeoShape::Big();
   if (point[0]*c1+point[1]*s1 >= 0) saf1 = TMath::Abs(-point[0]*s1 + point[1]*c1);
   if (point[0]*c2+point[1]*s2 >= 0) saf2 = TMath::Abs(point[0]*s2 - point[1]*c2);
   Double_t saf = TMath::Min(saf1,saf2);
   if (saf<epsil) return kTRUE;
   return kFALSE;
}   

//_____________________________________________________________________________
Bool_t TGeoShape::IsInPhiRange(Double_t *point, Double_t phi1, Double_t phi2)
{
// Static method to check if a point is in the phi range (phi1, phi2) [degrees]
   Double_t phi = TMath::ATan2(point[1], point[0]) * TMath::RadToDeg();
   while (phi<phi1) phi+=360.;
   Double_t ddp = phi-phi1;
   if (ddp>phi2-phi1) return kFALSE;
   return kTRUE;
}   

//_____________________________________________________________________________  
Bool_t TGeoShape::IsCrossingSemiplane(Double_t *point, Double_t *dir, Double_t cphi, Double_t sphi, Double_t &snext, Double_t &rxy)
{
// Compute distance from POINT to semiplane defined by PHI angle along DIR. Computes
// also radius at crossing point. This might be negative in case the crossing is
// on the other side of the semiplane.
   snext = rxy = TGeoShape::Big();
   Double_t nx = -sphi;
   Double_t ny = cphi;
   Double_t rxy0 = point[0]*cphi+point[1]*sphi;
   Double_t rdotn = point[0]*nx + point[1]*ny;
   if (TMath::Abs(rdotn)<TGeoShape::Tolerance()) {
      snext = 0.0;
      rxy = rxy0;
      return kTRUE;
   }
   if (rdotn<0) {
      rdotn = -rdotn;
   } else {
      nx = -nx;
      ny = -ny;
   }
   Double_t ddotn = dir[0]*nx + dir[1]*ny;
   if (ddotn<=0) return kFALSE;
   snext = rdotn/ddotn;
   rxy = rxy0+snext*(dir[0]*cphi+dir[1]*sphi);
   if (rxy<0) return kFALSE;
   return kTRUE;
}

//_____________________________________________________________________________  
Bool_t TGeoShape::IsSameWithinTolerance(Double_t a, Double_t b)
{
// Check if two numbers differ with less than a tolerance.
   if (TMath::Abs(a-b)<1.E-10) return kTRUE;
   return kFALSE;
}   

//_____________________________________________________________________________  
Bool_t TGeoShape::IsSegCrossing(Double_t x1, Double_t y1, Double_t x2, Double_t y2,Double_t x3, Double_t y3,Double_t x4, Double_t y4)
{
// Check if segments (A,B) and (C,D) are crossing,
// where: A(x1,y1), B(x2,y2), C(x3,y3), D(x4,y4)
   Double_t eps = TGeoShape::Tolerance();
   Bool_t stand1 = kFALSE;
   Double_t dx1 = x2-x1;
   Bool_t stand2 = kFALSE;
   Double_t dx2 = x4-x3;
   Double_t xm = 0.;
   Double_t ym = 0.;
   Double_t a1 = 0.;
   Double_t b1 = 0.;
   Double_t a2 = 0.;
   Double_t b2 = 0.;
   if (TMath::Abs(dx1) < eps) stand1 = kTRUE;
   if (TMath::Abs(dx2) < eps) stand2 = kTRUE;
   if (!stand1) {
      a1 = (x2*y1-x1*y2)/dx1;
      b1 = (y2-y1)/dx1;
   }   
   if (!stand2) {
      a2 = (x4*y3-x3*y4)/dx2;
      b2 = (y4-y3)/dx2;
   }   
   if (stand1 && stand2) {
      // Segments parallel and vertical
      if (TMath::Abs(x1-x3)<eps) {
         // Check if segments are overlapping
         if ((y3-y1)*(y3-y2)<-eps || (y4-y1)*(y4-y2)<-eps ||
             (y1-y3)*(y1-y4)<-eps || (y2-y3)*(y2-y4)<-eps) return kTRUE;
         return kFALSE;
      }
      // Different x values
      return kFALSE;
   }
   
   if (stand1) {
      // First segment vertical
      xm = x1;
      ym = a2+b2*xm;
   } else {
      if (stand2) {
         // Second segment vertical
         xm = x3;
         ym = a1+b1*xm;
      } else {
         // Normal crossing
         if (TMath::Abs(b1-b2)<eps) {
            // Parallel segments, are they aligned
            if (TMath::Abs(y3-(a1+b1*x3))>eps) return kFALSE;
            // Aligned segments, are they overlapping
            if ((x3-x1)*(x3-x2)<-eps || (x4-x1)*(x4-x2)<-eps ||
                (x1-x3)*(x1-x4)<-eps || (x2-x3)*(x2-x4)<-eps) return kTRUE;
            return kFALSE;
         }
         xm = (a1-a2)/(b2-b1);
         ym = (a1*b2-a2*b1)/(b2-b1);
      }
   }
   // Check if crossing point is both between A,B and C,D
   Double_t check = (xm-x1)*(xm-x2)+(ym-y1)*(ym-y2);
   if (check > -eps) return kFALSE;
   check = (xm-x3)*(xm-x4)+(ym-y3)*(ym-y4);
   if (check > -eps) return kFALSE;
   return kTRUE;
}         

//_____________________________________________________________________________
Double_t TGeoShape::DistToPhiMin(Double_t *point, Double_t *dir, Double_t s1, Double_t c1,
                                 Double_t s2, Double_t c2, Double_t sm, Double_t cm, Bool_t in)
{
// compute distance from point (inside phi) to both phi planes. Return minimum.
   Double_t sfi1=TGeoShape::Big();
   Double_t sfi2=TGeoShape::Big();
   Double_t s=0;
   Double_t un = dir[0]*s1-dir[1]*c1;
   if (!in) un=-un;
   if (un>0) {
      s=-point[0]*s1+point[1]*c1;
      if (!in) s=-s;
      if (s>=0) {
         s /= un;
         if (((point[0]+s*dir[0])*sm-(point[1]+s*dir[1])*cm)>=0) sfi1=s;
      }
   }
   un = -dir[0]*s2+dir[1]*c2;
   if (!in) un=-un;
   if (un>0) {
      s=point[0]*s2-point[1]*c2;
      if (!in) s=-s;
      if (s>=0) {
         s /= un;
         if ((-(point[0]+s*dir[0])*sm+(point[1]+s*dir[1])*cm)>=0) sfi2=s;
      }
   }
   return TMath::Min(sfi1, sfi2);
}

//_____________________________________________________________________________
void TGeoShape::NormalPhi(Double_t *point, Double_t *dir, Double_t *norm, Double_t c1, Double_t s1, Double_t c2, Double_t s2)
{
// Static method to compute normal to phi planes.
   Double_t saf1 = TGeoShape::Big();
   Double_t saf2 = TGeoShape::Big();
   if (point[0]*c1+point[1]*s1 >= 0) saf1 = TMath::Abs(-point[0]*s1 + point[1]*c1);
   if (point[0]*c2+point[1]*s2 >= 0) saf2 =  TMath::Abs(point[0]*s2 - point[1]*c2);
   Double_t c,s;
   if (saf1<saf2) {
      c=c1;
      s=s1;
   } else {
      c=c2;
      s=s2;
   }
   norm[2] = 0;
   norm[0] = -s;
   norm[1] = c;
   if (dir[0]*norm[0]+dir[1]*norm[1] < 0) { 
      norm[0] = s;
      norm[1] = -c;
   }
}           
 
//_____________________________________________________________________________
Double_t TGeoShape::SafetyPhi(Double_t *point, Bool_t in, Double_t phi1, Double_t phi2)
{
// Static method to compute safety w.r.t a phi corner defined by cosines/sines
// of the angles phi1, phi2.
   Bool_t inphi = TGeoShape::IsInPhiRange(point, phi1, phi2);
   if (inphi && !in) return -TGeoShape::Big(); 
   phi1 *= TMath::DegToRad();
   phi2 *= TMath::DegToRad();  
   Double_t c1 = TMath::Cos(phi1);
   Double_t s1 = TMath::Sin(phi1);
   Double_t c2 = TMath::Cos(phi2);
   Double_t s2 = TMath::Sin(phi2);
   Double_t rsq = point[0]*point[0]+point[1]*point[1];
   Double_t rproj = point[0]*c1+point[1]*s1;
   Double_t safsq = rsq-rproj*rproj;
   if (safsq<0) return 0.;
   Double_t saf1 = (rproj<0)?TGeoShape::Big():TMath::Sqrt(safsq);
   rproj = point[0]*c2+point[1]*s2;
   safsq = rsq-rproj*rproj;
   if (safsq<0) return 0.;   
   Double_t saf2 = (rproj<0)?TGeoShape::Big():TMath::Sqrt(safsq);
   Double_t safe = TMath::Min(saf1, saf2); // >0
   if (safe>1E10) {
      if (in) return TGeoShape::Big();
      return -TGeoShape::Big();
   }
   return safe;   
}        

//_____________________________________________________________________________
void TGeoShape::SetShapeBit(UInt_t f, Bool_t set)
{
// Equivalent of TObject::SetBit.
   if (set) {
      SetShapeBit(f);
   } else {
      ResetShapeBit(f);
   }
}

//_____________________________________________________________________________
TGeoMatrix *TGeoShape::GetTransform()
{
// Returns current transformation matrix that applies to shape.
   return fgTransform;
}   

//_____________________________________________________________________________
void TGeoShape::SetTransform(TGeoMatrix *matrix)
{
// Set current transformation matrix that applies to shape.
   fgTransform = matrix;
}   

//_____________________________________________________________________________
void TGeoShape::TransformPoints(Double_t *points, UInt_t NbPnts) const
{
   // Tranform a set of points (LocalToMaster)
   UInt_t i,j;
   Double_t dlocal[3];
   Double_t dmaster[3];
   if (fgTransform) {
      for (j = 0; j < NbPnts; j++) {
         i = 3*j;
         fgTransform->LocalToMaster(&points[i], dmaster);
         points[i]   = dmaster[0];
         points[i+1] = dmaster[1];
         points[i+2] = dmaster[2];
      }
      return;   
   }   
   if (!gGeoManager) return;
   Bool_t bomb = (gGeoManager->GetBombMode()==0)?kFALSE:kTRUE;

   for (j = 0; j < NbPnts; j++) {
      i = 3*j;
      dlocal[0] = points[3*j];
      dlocal[1] = points[3*j+1];
      dlocal[2] = points[3*j+2];
      if (gGeoManager->IsMatrixTransform()) {
         TGeoHMatrix *glmat = gGeoManager->GetGLMatrix();
         if (bomb) glmat->LocalToMasterBomb(&points[i], dmaster);
         else      glmat->LocalToMaster(&points[i], dmaster);
      } else {
         if (bomb) gGeoManager->LocalToMasterBomb(&points[i], dmaster);
         else      gGeoManager->LocalToMaster(&points[i],dmaster);
      }
      points[i]   = dmaster[0];
      points[i+1] = dmaster[1];
      points[i+2] = dmaster[2];
   }
}

//_____________________________________________________________________________
void TGeoShape::FillBuffer3D(TBuffer3D & buffer, Int_t reqSections, Bool_t localFrame) const
{
   // Fill the supplied buffer, with sections in desired frame
   // See TBuffer3D.h for explanation of sections, frame etc.
  
   // Catch this common potential error here
   // We have to set kRawSize (unless already done) to allocate buffer space 
   // before kRaw can be filled
   if (reqSections & TBuffer3D::kRaw) {
      if (!(reqSections & TBuffer3D::kRawSizes) && !buffer.SectionsValid(TBuffer3D::kRawSizes)) {
         R__ASSERT(kFALSE);
      }
   }

   if (reqSections & TBuffer3D::kCore) {
      // If writing core section all others will be invalid
      buffer.ClearSectionsValid();
 
      // Check/grab some objects we need
      if (!gGeoManager) { 
         R__ASSERT(kFALSE); 
         return; 
      }
      const TGeoVolume * paintVolume = gGeoManager->GetPaintVolume();
      if (!paintVolume) paintVolume = gGeoManager->GetTopVolume();
      if (!paintVolume) { 
         buffer.fID = const_cast<TGeoShape *>(this);
         buffer.fColor = 0;
         buffer.fTransparency = 0;
//         R__ASSERT(kFALSE); 
//         return; 
      } else {
         buffer.fID = const_cast<TGeoVolume *>(paintVolume);
         buffer.fColor = paintVolume->GetLineColor();

         buffer.fTransparency = paintVolume->GetTransparency();
         Double_t visdensity = gGeoManager->GetVisDensity();
         if (visdensity>0 && paintVolume->GetMedium()) {
            if (paintVolume->GetMaterial()->GetDensity() < visdensity) {
               buffer.fTransparency = 90;
            }
         }   
      }

      buffer.fLocalFrame = localFrame;
      Bool_t r1,r2=kFALSE;
      r1 = gGeoManager->IsMatrixReflection();
      if (paintVolume && paintVolume->GetShape()) {
         if (paintVolume->GetShape()->IsReflected()) {
         // Temporary trick to deal with reflected shapes.
         // Still lighting gets wrong...
            if (buffer.Type() < TBuffer3DTypes::kTube) r2 = kTRUE;
         }
      }      
      buffer.fReflection = ((r1&(!r2))|(r2&!(r1)));
      
      // Set up local -> master translation matrix
      if (localFrame) {
         TGeoMatrix * localMasterMat = 0;
         if (TGeoShape::GetTransform()) {
            localMasterMat = TGeoShape::GetTransform();
         } else {   
            localMasterMat = gGeoManager->GetCurrentMatrix();

         // For overlap drawing the correct matrix needs to obtained in 
         // from GetGLMatrix() - this should not be applied in the case
         // of composite shapes
            if (gGeoManager->IsMatrixTransform() && !IsComposite()) {
               localMasterMat = gGeoManager->GetGLMatrix();
            }
         }
         if (!localMasterMat) { 
            R__ASSERT(kFALSE); 
            return; 
         }
         localMasterMat->GetHomogenousMatrix(buffer.fLocalMaster);
      } else {
         buffer.SetLocalMasterIdentity();
      }

      buffer.SetSectionsValid(TBuffer3D::kCore);
   }
}

//_____________________________________________________________________________
Int_t TGeoShape::GetBasicColor() const
{
// Get the basic color (0-7).
   Int_t basicColor = 0; // TODO: Check on sensible fallback
   if (gGeoManager) {
      const TGeoVolume * volume = gGeoManager->GetPaintVolume();
      if (volume) {
            basicColor = ((volume->GetLineColor() %8) -1) * 4;
            if (basicColor < 0) basicColor = 0;
      }
   }
   return basicColor;
}

//_____________________________________________________________________________
const TBuffer3D &TGeoShape::GetBuffer3D(Int_t /*reqSections*/, Bool_t /*localFrame*/) const
{
   // Stub implementation to avoid forcing implementation at this stage
   static TBuffer3D buffer(TBuffer3DTypes::kGeneric);
   Warning("GetBuffer3D", "this must be implemented for shapes in a TGeoPainter hierarchy. This will be come a pure virtual fn eventually.");
   return buffer;
}

//_____________________________________________________________________________
char *TGeoShape::GetPointerName() const
{
// Provide a pointer name containing uid.
   static char name[20];
   Int_t uid = GetUniqueID();
   if (uid) sprintf(name,"p%s_%i", GetName(),uid);
   else     sprintf(name,"p%s", GetName());
   return name;
}

//_____________________________________________________________________________
void TGeoShape::ExecuteEvent(Int_t event, Int_t px, Int_t py)
{
// Execute mouse actions on this shape.
   if (!gGeoManager) return;
   TVirtualGeoPainter *painter = gGeoManager->GetPainter();
   painter->ExecuteShapeEvent(this, event, px, py);
}

//_____________________________________________________________________________
void TGeoShape::Draw(Option_t *option)
{
// Draw this shape.
   TVirtualGeoPainter *painter = gGeoManager->GetGeomPainter();
   if (option && strlen(option) > 0) {
      painter->DrawShape(this, option); 
   } else {
      painter->DrawShape(this, gEnv->GetValue("Viewer3D.DefaultDrawOption",""));
   }  
}

//_____________________________________________________________________________
void TGeoShape::Paint(Option_t *option)
{
// Paint this shape.
   TVirtualGeoPainter *painter = gGeoManager->GetGeomPainter();
   if (option && strlen(option) > 0) {
      painter->PaintShape(this, option); 
   } else {
      painter->PaintShape(this, gEnv->GetValue("Viewer3D.DefaultDrawOption",""));
   }  
}
 TGeoShape.cxx:1
 TGeoShape.cxx:2
 TGeoShape.cxx:3
 TGeoShape.cxx:4
 TGeoShape.cxx:5
 TGeoShape.cxx:6
 TGeoShape.cxx:7
 TGeoShape.cxx:8
 TGeoShape.cxx:9
 TGeoShape.cxx:10
 TGeoShape.cxx:11
 TGeoShape.cxx:12
 TGeoShape.cxx:13
 TGeoShape.cxx:14
 TGeoShape.cxx:15
 TGeoShape.cxx:16
 TGeoShape.cxx:17
 TGeoShape.cxx:18
 TGeoShape.cxx:19
 TGeoShape.cxx:20
 TGeoShape.cxx:21
 TGeoShape.cxx:22
 TGeoShape.cxx:23
 TGeoShape.cxx:24
 TGeoShape.cxx:25
 TGeoShape.cxx:26
 TGeoShape.cxx:27
 TGeoShape.cxx:28
 TGeoShape.cxx:29
 TGeoShape.cxx:30
 TGeoShape.cxx:31
 TGeoShape.cxx:32
 TGeoShape.cxx:33
 TGeoShape.cxx:34
 TGeoShape.cxx:35
 TGeoShape.cxx:36
 TGeoShape.cxx:37
 TGeoShape.cxx:38
 TGeoShape.cxx:39
 TGeoShape.cxx:40
 TGeoShape.cxx:41
 TGeoShape.cxx:42
 TGeoShape.cxx:43
 TGeoShape.cxx:44
 TGeoShape.cxx:45
 TGeoShape.cxx:46
 TGeoShape.cxx:47
 TGeoShape.cxx:48
 TGeoShape.cxx:49
 TGeoShape.cxx:50
 TGeoShape.cxx:51
 TGeoShape.cxx:52
 TGeoShape.cxx:53
 TGeoShape.cxx:54
 TGeoShape.cxx:55
 TGeoShape.cxx:56
 TGeoShape.cxx:57
 TGeoShape.cxx:58
 TGeoShape.cxx:59
 TGeoShape.cxx:60
 TGeoShape.cxx:61
 TGeoShape.cxx:62
 TGeoShape.cxx:63
 TGeoShape.cxx:64
 TGeoShape.cxx:65
 TGeoShape.cxx:66
 TGeoShape.cxx:67
 TGeoShape.cxx:68
 TGeoShape.cxx:69
 TGeoShape.cxx:70
 TGeoShape.cxx:71
 TGeoShape.cxx:72
 TGeoShape.cxx:73
 TGeoShape.cxx:74
 TGeoShape.cxx:75
 TGeoShape.cxx:76
 TGeoShape.cxx:77
 TGeoShape.cxx:78
 TGeoShape.cxx:79
 TGeoShape.cxx:80
 TGeoShape.cxx:81
 TGeoShape.cxx:82
 TGeoShape.cxx:83
 TGeoShape.cxx:84
 TGeoShape.cxx:85
 TGeoShape.cxx:86
 TGeoShape.cxx:87
 TGeoShape.cxx:88
 TGeoShape.cxx:89
 TGeoShape.cxx:90
 TGeoShape.cxx:91
 TGeoShape.cxx:92
 TGeoShape.cxx:93
 TGeoShape.cxx:94
 TGeoShape.cxx:95
 TGeoShape.cxx:96
 TGeoShape.cxx:97
 TGeoShape.cxx:98
 TGeoShape.cxx:99
 TGeoShape.cxx:100
 TGeoShape.cxx:101
 TGeoShape.cxx:102
 TGeoShape.cxx:103
 TGeoShape.cxx:104
 TGeoShape.cxx:105
 TGeoShape.cxx:106
 TGeoShape.cxx:107
 TGeoShape.cxx:108
 TGeoShape.cxx:109
 TGeoShape.cxx:110
 TGeoShape.cxx:111
 TGeoShape.cxx:112
 TGeoShape.cxx:113
 TGeoShape.cxx:114
 TGeoShape.cxx:115
 TGeoShape.cxx:116
 TGeoShape.cxx:117
 TGeoShape.cxx:118
 TGeoShape.cxx:119
 TGeoShape.cxx:120
 TGeoShape.cxx:121
 TGeoShape.cxx:122
 TGeoShape.cxx:123
 TGeoShape.cxx:124
 TGeoShape.cxx:125
 TGeoShape.cxx:126
 TGeoShape.cxx:127
 TGeoShape.cxx:128
 TGeoShape.cxx:129
 TGeoShape.cxx:130
 TGeoShape.cxx:131
 TGeoShape.cxx:132
 TGeoShape.cxx:133
 TGeoShape.cxx:134
 TGeoShape.cxx:135
 TGeoShape.cxx:136
 TGeoShape.cxx:137
 TGeoShape.cxx:138
 TGeoShape.cxx:139
 TGeoShape.cxx:140
 TGeoShape.cxx:141
 TGeoShape.cxx:142
 TGeoShape.cxx:143
 TGeoShape.cxx:144
 TGeoShape.cxx:145
 TGeoShape.cxx:146
 TGeoShape.cxx:147
 TGeoShape.cxx:148
 TGeoShape.cxx:149
 TGeoShape.cxx:150
 TGeoShape.cxx:151
 TGeoShape.cxx:152
 TGeoShape.cxx:153
 TGeoShape.cxx:154
 TGeoShape.cxx:155
 TGeoShape.cxx:156
 TGeoShape.cxx:157
 TGeoShape.cxx:158
 TGeoShape.cxx:159
 TGeoShape.cxx:160
 TGeoShape.cxx:161
 TGeoShape.cxx:162
 TGeoShape.cxx:163
 TGeoShape.cxx:164
 TGeoShape.cxx:165
 TGeoShape.cxx:166
 TGeoShape.cxx:167
 TGeoShape.cxx:168
 TGeoShape.cxx:169
 TGeoShape.cxx:170
 TGeoShape.cxx:171
 TGeoShape.cxx:172
 TGeoShape.cxx:173
 TGeoShape.cxx:174
 TGeoShape.cxx:175
 TGeoShape.cxx:176
 TGeoShape.cxx:177
 TGeoShape.cxx:178
 TGeoShape.cxx:179
 TGeoShape.cxx:180
 TGeoShape.cxx:181
 TGeoShape.cxx:182
 TGeoShape.cxx:183
 TGeoShape.cxx:184
 TGeoShape.cxx:185
 TGeoShape.cxx:186
 TGeoShape.cxx:187
 TGeoShape.cxx:188
 TGeoShape.cxx:189
 TGeoShape.cxx:190
 TGeoShape.cxx:191
 TGeoShape.cxx:192
 TGeoShape.cxx:193
 TGeoShape.cxx:194
 TGeoShape.cxx:195
 TGeoShape.cxx:196
 TGeoShape.cxx:197
 TGeoShape.cxx:198
 TGeoShape.cxx:199
 TGeoShape.cxx:200
 TGeoShape.cxx:201
 TGeoShape.cxx:202
 TGeoShape.cxx:203
 TGeoShape.cxx:204
 TGeoShape.cxx:205
 TGeoShape.cxx:206
 TGeoShape.cxx:207
 TGeoShape.cxx:208
 TGeoShape.cxx:209
 TGeoShape.cxx:210
 TGeoShape.cxx:211
 TGeoShape.cxx:212
 TGeoShape.cxx:213
 TGeoShape.cxx:214
 TGeoShape.cxx:215
 TGeoShape.cxx:216
 TGeoShape.cxx:217
 TGeoShape.cxx:218
 TGeoShape.cxx:219
 TGeoShape.cxx:220
 TGeoShape.cxx:221
 TGeoShape.cxx:222
 TGeoShape.cxx:223
 TGeoShape.cxx:224
 TGeoShape.cxx:225
 TGeoShape.cxx:226
 TGeoShape.cxx:227
 TGeoShape.cxx:228
 TGeoShape.cxx:229
 TGeoShape.cxx:230
 TGeoShape.cxx:231
 TGeoShape.cxx:232
 TGeoShape.cxx:233
 TGeoShape.cxx:234
 TGeoShape.cxx:235
 TGeoShape.cxx:236
 TGeoShape.cxx:237
 TGeoShape.cxx:238
 TGeoShape.cxx:239
 TGeoShape.cxx:240
 TGeoShape.cxx:241
 TGeoShape.cxx:242
 TGeoShape.cxx:243
 TGeoShape.cxx:244
 TGeoShape.cxx:245
 TGeoShape.cxx:246
 TGeoShape.cxx:247
 TGeoShape.cxx:248
 TGeoShape.cxx:249
 TGeoShape.cxx:250
 TGeoShape.cxx:251
 TGeoShape.cxx:252
 TGeoShape.cxx:253
 TGeoShape.cxx:254
 TGeoShape.cxx:255
 TGeoShape.cxx:256
 TGeoShape.cxx:257
 TGeoShape.cxx:258
 TGeoShape.cxx:259
 TGeoShape.cxx:260
 TGeoShape.cxx:261
 TGeoShape.cxx:262
 TGeoShape.cxx:263
 TGeoShape.cxx:264
 TGeoShape.cxx:265
 TGeoShape.cxx:266
 TGeoShape.cxx:267
 TGeoShape.cxx:268
 TGeoShape.cxx:269
 TGeoShape.cxx:270
 TGeoShape.cxx:271
 TGeoShape.cxx:272
 TGeoShape.cxx:273
 TGeoShape.cxx:274
 TGeoShape.cxx:275
 TGeoShape.cxx:276
 TGeoShape.cxx:277
 TGeoShape.cxx:278
 TGeoShape.cxx:279
 TGeoShape.cxx:280
 TGeoShape.cxx:281
 TGeoShape.cxx:282
 TGeoShape.cxx:283
 TGeoShape.cxx:284
 TGeoShape.cxx:285
 TGeoShape.cxx:286
 TGeoShape.cxx:287
 TGeoShape.cxx:288
 TGeoShape.cxx:289
 TGeoShape.cxx:290
 TGeoShape.cxx:291
 TGeoShape.cxx:292
 TGeoShape.cxx:293
 TGeoShape.cxx:294
 TGeoShape.cxx:295
 TGeoShape.cxx:296
 TGeoShape.cxx:297
 TGeoShape.cxx:298
 TGeoShape.cxx:299
 TGeoShape.cxx:300
 TGeoShape.cxx:301
 TGeoShape.cxx:302
 TGeoShape.cxx:303
 TGeoShape.cxx:304
 TGeoShape.cxx:305
 TGeoShape.cxx:306
 TGeoShape.cxx:307
 TGeoShape.cxx:308
 TGeoShape.cxx:309
 TGeoShape.cxx:310
 TGeoShape.cxx:311
 TGeoShape.cxx:312
 TGeoShape.cxx:313
 TGeoShape.cxx:314
 TGeoShape.cxx:315
 TGeoShape.cxx:316
 TGeoShape.cxx:317
 TGeoShape.cxx:318
 TGeoShape.cxx:319
 TGeoShape.cxx:320
 TGeoShape.cxx:321
 TGeoShape.cxx:322
 TGeoShape.cxx:323
 TGeoShape.cxx:324
 TGeoShape.cxx:325
 TGeoShape.cxx:326
 TGeoShape.cxx:327
 TGeoShape.cxx:328
 TGeoShape.cxx:329
 TGeoShape.cxx:330
 TGeoShape.cxx:331
 TGeoShape.cxx:332
 TGeoShape.cxx:333
 TGeoShape.cxx:334
 TGeoShape.cxx:335
 TGeoShape.cxx:336
 TGeoShape.cxx:337
 TGeoShape.cxx:338
 TGeoShape.cxx:339
 TGeoShape.cxx:340
 TGeoShape.cxx:341
 TGeoShape.cxx:342
 TGeoShape.cxx:343
 TGeoShape.cxx:344
 TGeoShape.cxx:345
 TGeoShape.cxx:346
 TGeoShape.cxx:347
 TGeoShape.cxx:348
 TGeoShape.cxx:349
 TGeoShape.cxx:350
 TGeoShape.cxx:351
 TGeoShape.cxx:352
 TGeoShape.cxx:353
 TGeoShape.cxx:354
 TGeoShape.cxx:355
 TGeoShape.cxx:356
 TGeoShape.cxx:357
 TGeoShape.cxx:358
 TGeoShape.cxx:359
 TGeoShape.cxx:360
 TGeoShape.cxx:361
 TGeoShape.cxx:362
 TGeoShape.cxx:363
 TGeoShape.cxx:364
 TGeoShape.cxx:365
 TGeoShape.cxx:366
 TGeoShape.cxx:367
 TGeoShape.cxx:368
 TGeoShape.cxx:369
 TGeoShape.cxx:370
 TGeoShape.cxx:371
 TGeoShape.cxx:372
 TGeoShape.cxx:373
 TGeoShape.cxx:374
 TGeoShape.cxx:375
 TGeoShape.cxx:376
 TGeoShape.cxx:377
 TGeoShape.cxx:378
 TGeoShape.cxx:379
 TGeoShape.cxx:380
 TGeoShape.cxx:381
 TGeoShape.cxx:382
 TGeoShape.cxx:383
 TGeoShape.cxx:384
 TGeoShape.cxx:385
 TGeoShape.cxx:386
 TGeoShape.cxx:387
 TGeoShape.cxx:388
 TGeoShape.cxx:389
 TGeoShape.cxx:390
 TGeoShape.cxx:391
 TGeoShape.cxx:392
 TGeoShape.cxx:393
 TGeoShape.cxx:394
 TGeoShape.cxx:395
 TGeoShape.cxx:396
 TGeoShape.cxx:397
 TGeoShape.cxx:398
 TGeoShape.cxx:399
 TGeoShape.cxx:400
 TGeoShape.cxx:401
 TGeoShape.cxx:402
 TGeoShape.cxx:403
 TGeoShape.cxx:404
 TGeoShape.cxx:405
 TGeoShape.cxx:406
 TGeoShape.cxx:407
 TGeoShape.cxx:408
 TGeoShape.cxx:409
 TGeoShape.cxx:410
 TGeoShape.cxx:411
 TGeoShape.cxx:412
 TGeoShape.cxx:413
 TGeoShape.cxx:414
 TGeoShape.cxx:415
 TGeoShape.cxx:416
 TGeoShape.cxx:417
 TGeoShape.cxx:418
 TGeoShape.cxx:419
 TGeoShape.cxx:420
 TGeoShape.cxx:421
 TGeoShape.cxx:422
 TGeoShape.cxx:423
 TGeoShape.cxx:424
 TGeoShape.cxx:425
 TGeoShape.cxx:426
 TGeoShape.cxx:427
 TGeoShape.cxx:428
 TGeoShape.cxx:429
 TGeoShape.cxx:430
 TGeoShape.cxx:431
 TGeoShape.cxx:432
 TGeoShape.cxx:433
 TGeoShape.cxx:434
 TGeoShape.cxx:435
 TGeoShape.cxx:436
 TGeoShape.cxx:437
 TGeoShape.cxx:438
 TGeoShape.cxx:439
 TGeoShape.cxx:440
 TGeoShape.cxx:441
 TGeoShape.cxx:442
 TGeoShape.cxx:443
 TGeoShape.cxx:444
 TGeoShape.cxx:445
 TGeoShape.cxx:446
 TGeoShape.cxx:447
 TGeoShape.cxx:448
 TGeoShape.cxx:449
 TGeoShape.cxx:450
 TGeoShape.cxx:451
 TGeoShape.cxx:452
 TGeoShape.cxx:453
 TGeoShape.cxx:454
 TGeoShape.cxx:455
 TGeoShape.cxx:456
 TGeoShape.cxx:457
 TGeoShape.cxx:458
 TGeoShape.cxx:459
 TGeoShape.cxx:460
 TGeoShape.cxx:461
 TGeoShape.cxx:462
 TGeoShape.cxx:463
 TGeoShape.cxx:464
 TGeoShape.cxx:465
 TGeoShape.cxx:466
 TGeoShape.cxx:467
 TGeoShape.cxx:468
 TGeoShape.cxx:469
 TGeoShape.cxx:470
 TGeoShape.cxx:471
 TGeoShape.cxx:472
 TGeoShape.cxx:473
 TGeoShape.cxx:474
 TGeoShape.cxx:475
 TGeoShape.cxx:476
 TGeoShape.cxx:477
 TGeoShape.cxx:478
 TGeoShape.cxx:479
 TGeoShape.cxx:480
 TGeoShape.cxx:481
 TGeoShape.cxx:482
 TGeoShape.cxx:483
 TGeoShape.cxx:484
 TGeoShape.cxx:485
 TGeoShape.cxx:486
 TGeoShape.cxx:487
 TGeoShape.cxx:488
 TGeoShape.cxx:489
 TGeoShape.cxx:490
 TGeoShape.cxx:491
 TGeoShape.cxx:492
 TGeoShape.cxx:493
 TGeoShape.cxx:494
 TGeoShape.cxx:495
 TGeoShape.cxx:496
 TGeoShape.cxx:497
 TGeoShape.cxx:498
 TGeoShape.cxx:499
 TGeoShape.cxx:500
 TGeoShape.cxx:501
 TGeoShape.cxx:502
 TGeoShape.cxx:503
 TGeoShape.cxx:504
 TGeoShape.cxx:505
 TGeoShape.cxx:506
 TGeoShape.cxx:507
 TGeoShape.cxx:508
 TGeoShape.cxx:509
 TGeoShape.cxx:510
 TGeoShape.cxx:511
 TGeoShape.cxx:512
 TGeoShape.cxx:513
 TGeoShape.cxx:514
 TGeoShape.cxx:515
 TGeoShape.cxx:516
 TGeoShape.cxx:517
 TGeoShape.cxx:518
 TGeoShape.cxx:519
 TGeoShape.cxx:520
 TGeoShape.cxx:521
 TGeoShape.cxx:522
 TGeoShape.cxx:523
 TGeoShape.cxx:524
 TGeoShape.cxx:525
 TGeoShape.cxx:526
 TGeoShape.cxx:527
 TGeoShape.cxx:528
 TGeoShape.cxx:529
 TGeoShape.cxx:530
 TGeoShape.cxx:531
 TGeoShape.cxx:532
 TGeoShape.cxx:533
 TGeoShape.cxx:534
 TGeoShape.cxx:535
 TGeoShape.cxx:536
 TGeoShape.cxx:537
 TGeoShape.cxx:538
 TGeoShape.cxx:539
 TGeoShape.cxx:540
 TGeoShape.cxx:541
 TGeoShape.cxx:542
 TGeoShape.cxx:543
 TGeoShape.cxx:544
 TGeoShape.cxx:545
 TGeoShape.cxx:546
 TGeoShape.cxx:547
 TGeoShape.cxx:548
 TGeoShape.cxx:549
 TGeoShape.cxx:550
 TGeoShape.cxx:551
 TGeoShape.cxx:552
 TGeoShape.cxx:553
 TGeoShape.cxx:554
 TGeoShape.cxx:555
 TGeoShape.cxx:556
 TGeoShape.cxx:557
 TGeoShape.cxx:558
 TGeoShape.cxx:559
 TGeoShape.cxx:560
 TGeoShape.cxx:561
 TGeoShape.cxx:562
 TGeoShape.cxx:563
 TGeoShape.cxx:564
 TGeoShape.cxx:565
 TGeoShape.cxx:566
 TGeoShape.cxx:567
 TGeoShape.cxx:568
 TGeoShape.cxx:569
 TGeoShape.cxx:570
 TGeoShape.cxx:571
 TGeoShape.cxx:572
 TGeoShape.cxx:573
 TGeoShape.cxx:574
 TGeoShape.cxx:575
 TGeoShape.cxx:576
 TGeoShape.cxx:577
 TGeoShape.cxx:578
 TGeoShape.cxx:579
 TGeoShape.cxx:580
 TGeoShape.cxx:581
 TGeoShape.cxx:582
 TGeoShape.cxx:583
 TGeoShape.cxx:584
 TGeoShape.cxx:585
 TGeoShape.cxx:586
 TGeoShape.cxx:587
 TGeoShape.cxx:588
 TGeoShape.cxx:589
 TGeoShape.cxx:590
 TGeoShape.cxx:591
 TGeoShape.cxx:592
 TGeoShape.cxx:593
 TGeoShape.cxx:594
 TGeoShape.cxx:595
 TGeoShape.cxx:596
 TGeoShape.cxx:597
 TGeoShape.cxx:598
 TGeoShape.cxx:599
 TGeoShape.cxx:600
 TGeoShape.cxx:601
 TGeoShape.cxx:602
 TGeoShape.cxx:603
 TGeoShape.cxx:604
 TGeoShape.cxx:605
 TGeoShape.cxx:606
 TGeoShape.cxx:607
 TGeoShape.cxx:608
 TGeoShape.cxx:609
 TGeoShape.cxx:610
 TGeoShape.cxx:611
 TGeoShape.cxx:612
 TGeoShape.cxx:613
 TGeoShape.cxx:614
 TGeoShape.cxx:615
 TGeoShape.cxx:616
 TGeoShape.cxx:617
 TGeoShape.cxx:618
 TGeoShape.cxx:619
 TGeoShape.cxx:620
 TGeoShape.cxx:621
 TGeoShape.cxx:622
 TGeoShape.cxx:623
 TGeoShape.cxx:624
 TGeoShape.cxx:625
 TGeoShape.cxx:626
 TGeoShape.cxx:627
 TGeoShape.cxx:628
 TGeoShape.cxx:629
 TGeoShape.cxx:630
 TGeoShape.cxx:631
 TGeoShape.cxx:632
 TGeoShape.cxx:633
 TGeoShape.cxx:634
 TGeoShape.cxx:635
 TGeoShape.cxx:636
 TGeoShape.cxx:637
 TGeoShape.cxx:638
 TGeoShape.cxx:639
 TGeoShape.cxx:640
 TGeoShape.cxx:641
 TGeoShape.cxx:642
 TGeoShape.cxx:643
 TGeoShape.cxx:644
 TGeoShape.cxx:645
 TGeoShape.cxx:646
 TGeoShape.cxx:647
 TGeoShape.cxx:648
 TGeoShape.cxx:649
 TGeoShape.cxx:650
 TGeoShape.cxx:651
 TGeoShape.cxx:652
 TGeoShape.cxx:653
 TGeoShape.cxx:654
 TGeoShape.cxx:655
 TGeoShape.cxx:656
 TGeoShape.cxx:657
 TGeoShape.cxx:658
 TGeoShape.cxx:659
 TGeoShape.cxx:660
 TGeoShape.cxx:661
 TGeoShape.cxx:662
 TGeoShape.cxx:663
 TGeoShape.cxx:664
 TGeoShape.cxx:665
 TGeoShape.cxx:666
 TGeoShape.cxx:667
 TGeoShape.cxx:668
 TGeoShape.cxx:669
 TGeoShape.cxx:670
 TGeoShape.cxx:671
 TGeoShape.cxx:672
 TGeoShape.cxx:673