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

/*************************************************************************
*                                                                       *
* 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(const 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(const 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");
}
//   fShapeId = gGeoManager->GetListOfShapes()->GetSize();
}

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

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

//_____________________________________________________________________________
void TGeoShape::CheckShape(Int_t testNo, Int_t nsamples, Option_t *option)
{
// Test for shape navigation methods. Summary for test numbers:
//  1: DistFromInside/Outside. Sample points inside the shape. Generate
//    directions randomly in cos(theta). Compute DistFromInside and move the
//    point with bigger distance. Compute DistFromOutside back from new point.
//    Plot d-(d1+d2)
//
if (!gGeoManager) {
Error("CheckShape","No geometry manager");
return;
}
TGeoShape *shape = (TGeoShape*)this;
gGeoManager->CheckShape(shape, testNo, nsamples, option);
}

//_____________________________________________________________________________
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 = 0.;
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 (!fName[0]) {
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, const 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(const 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(const Double_t *point, const 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(const Double_t *point, const 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(const Double_t *point, const 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(const 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();
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;
}

//_____________________________________________________________________________
Double_t TGeoShape::SafetySeg(Double_t r, Double_t z, Double_t r1, Double_t z1, Double_t r2, Double_t z2, Bool_t outer)
{
// Compute distance from point of coordinates (r,z) to segment (r1,z1):(r2,z2)
Double_t crossp = (z2-z1)*(r-r1)-(z-z1)*(r2-r1);
crossp *= (outer) ? 1. : -1.;
// Positive crossp means point on the requested side of the (1,2) segment
if (crossp < 0) {
if (((z-z1)*(z2-z)) > -1.E-10) return 0;
return TGeoShape::Big();
}
// Compute (1,P) dot (1,2)
Double_t c1 = (z-z1)*(z2-z1)+(r-r1)*(r2-r1);
// Negative c1 means point (1) is closest
if (c1<1.E-10) return TMath::Sqrt((r-r1)*(r-r1)+(z-z1)*(z-z1));
// Compute (2,P) dot (1,2)
Double_t c2 = (z-z2)*(z2-z1)+(r-r2)*(r2-r1);
// Positive c2 means point (2) is closest
if (c2>-1.E-10) return TMath::Sqrt((r-r2)*(r-r2)+(z-z2)*(z-z2));
// The closest point is between (1) and (2)
c2 = (z2-z1)*(z2-z1)+(r2-r1)*(r2-r1);
// projected length factor with respect to (1,2) length
Double_t alpha = c1/c2;
Double_t rp = r1 + alpha*(r2-r1);
Double_t zp = z1 + alpha*(z2-z1);
return TMath::Sqrt((r-rp)*(r-rp)+(z-zp)*(z-zp));
}

//_____________________________________________________________________________
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 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;
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;
}

//_____________________________________________________________________________
const char *TGeoShape::GetPointerName() const
{
// Provide a pointer name containing uid.
static TString name;
Int_t uid = GetUniqueID();
if (uid) name = TString::Format("p%s_%d", GetName(),uid);
else     name = TString::Format("p%s", GetName());
return name.Data();
}

//_____________________________________________________________________________
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 && 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 && 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
TGeoShape.cxx:674
TGeoShape.cxx:675
TGeoShape.cxx:676
TGeoShape.cxx:677
TGeoShape.cxx:678
TGeoShape.cxx:679
TGeoShape.cxx:680
TGeoShape.cxx:681
TGeoShape.cxx:682
TGeoShape.cxx:683
TGeoShape.cxx:684
TGeoShape.cxx:685
TGeoShape.cxx:686
TGeoShape.cxx:687
TGeoShape.cxx:688
TGeoShape.cxx:689
TGeoShape.cxx:690
TGeoShape.cxx:691
TGeoShape.cxx:692
TGeoShape.cxx:693
TGeoShape.cxx:694
TGeoShape.cxx:695
TGeoShape.cxx:696
TGeoShape.cxx:697
TGeoShape.cxx:698
TGeoShape.cxx:699
TGeoShape.cxx:700
TGeoShape.cxx:701
TGeoShape.cxx:702
TGeoShape.cxx:703
TGeoShape.cxx:704
TGeoShape.cxx:705
TGeoShape.cxx:706
TGeoShape.cxx:707
TGeoShape.cxx:708
TGeoShape.cxx:709
TGeoShape.cxx:710
TGeoShape.cxx:711
TGeoShape.cxx:712
TGeoShape.cxx:713
TGeoShape.cxx:714