ROOT logo
// @(#)root/geom:$Id: TGeoTorus.cxx 39203 2011-05-16 14:20:43Z agheata $
// Author: Andrei Gheata   28/07/03

/*************************************************************************
 * 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.             *
 *************************************************************************/

//_____________________________________________________________________________
// TGeoTorus - Torus segment class. A torus has 5 parameters :
//            R    - axial radius
//            Rmin - inner radius
//            Rmax - outer radius 
//            Phi1 - starting phi
//            Dphi - phi extent
//
//_____________________________________________________________________________

//Begin_Html
/*
<img src="gif/t_ctorus.gif">
*/
//End_Html

#include "Riostream.h"

#include "TGeoManager.h"
#include "TGeoVolume.h"
#include "TGeoTube.h"
#include "TVirtualGeoPainter.h"
#include "TGeoTorus.h"
#include "TVirtualPad.h"
#include "TBuffer3D.h"
#include "TBuffer3DTypes.h"
#include "TMath.h"

ClassImp(TGeoTorus)

//_____________________________________________________________________________
TGeoTorus::TGeoTorus()
{
// Default constructor
   SetShapeBit(TGeoShape::kGeoTorus);
   fR    = 0.0;
   fRmin = 0.0;
   fRmax = 0.0;
   fPhi1 = 0.0;
   fDphi = 0.0;
}   

//_____________________________________________________________________________
TGeoTorus::TGeoTorus(Double_t r, Double_t rmin, Double_t rmax, Double_t phi1, Double_t dphi)
          :TGeoBBox(0, 0, 0)
{
// Constructor without name.
   SetShapeBit(TGeoShape::kGeoTorus);
   SetTorusDimensions(r, rmin, rmax, phi1, dphi);
   if ((fRmin<0) || (fRmax<0)) 
      SetShapeBit(kGeoRunTimeShape);
   ComputeBBox();
}

//_____________________________________________________________________________
TGeoTorus::TGeoTorus(const char *name, Double_t r, Double_t rmin, Double_t rmax, Double_t phi1, Double_t dphi)
          :TGeoBBox(name, 0, 0, 0)
{
// Constructor with name.
   SetShapeBit(TGeoShape::kGeoTorus);
   SetTorusDimensions(r, rmin, rmax, phi1, dphi);
   if ((fRmin<0) || (fRmax<0)) 
      SetShapeBit(kGeoRunTimeShape);
   ComputeBBox();
}

//_____________________________________________________________________________
TGeoTorus::TGeoTorus(Double_t *param)
          :TGeoBBox(0, 0, 0)
{
// Constructor based on an array of parameters.
// param[0] = R
// param[1] = Rmin
// param[2] = Rmax
// param[3] = Phi1
// param[4] = Dphi
   SetShapeBit(TGeoShape::kGeoTorus);
   SetDimensions(param);
   if (fRmin<0 || fRmax<0) SetShapeBit(kGeoRunTimeShape);
   ComputeBBox();
}

//_____________________________________________________________________________
Double_t TGeoTorus::Capacity() const
{
// Computes capacity of the shape in [length^3]
   Double_t capacity = (fDphi/180.)*TMath::Pi()*TMath::Pi()*fR*(fRmax*fRmax-fRmin*fRmin);
   return capacity;
}
   
//_____________________________________________________________________________
void TGeoTorus::ComputeBBox()
{
// Compute bounding box of the torus.
   fDZ = fRmax;
   if (TGeoShape::IsSameWithinTolerance(fDphi,360)) {
      fDX = fDY = fR+fRmax;
      return;
   }
   Double_t xc[4];
   Double_t yc[4];
   xc[0] = (fR+fRmax)*TMath::Cos(fPhi1*TMath::DegToRad());
   yc[0] = (fR+fRmax)*TMath::Sin(fPhi1*TMath::DegToRad());
   xc[1] = (fR+fRmax)*TMath::Cos((fPhi1+fDphi)*TMath::DegToRad());
   yc[1] = (fR+fRmax)*TMath::Sin((fPhi1+fDphi)*TMath::DegToRad());
   xc[2] = (fR-fRmax)*TMath::Cos(fPhi1*TMath::DegToRad());
   yc[2] = (fR-fRmax)*TMath::Sin(fPhi1*TMath::DegToRad());
   xc[3] = (fR-fRmax)*TMath::Cos((fPhi1+fDphi)*TMath::DegToRad());
   yc[3] = (fR-fRmax)*TMath::Sin((fPhi1+fDphi)*TMath::DegToRad());
      
   Double_t xmin = xc[TMath::LocMin(4, &xc[0])];
   Double_t xmax = xc[TMath::LocMax(4, &xc[0])]; 
   Double_t ymin = yc[TMath::LocMin(4, &yc[0])]; 
   Double_t ymax = yc[TMath::LocMax(4, &yc[0])];
   Double_t ddp = -fPhi1;
   if (ddp<0) ddp+= 360;
   if (ddp<=fDphi) xmax = fR+fRmax;
   ddp = 90-fPhi1;
   if (ddp<0) ddp+= 360;
   if (ddp>360) ddp-=360;
   if (ddp<=fDphi) ymax = fR+fRmax;
   ddp = 180-fPhi1;
   if (ddp<0) ddp+= 360;
   if (ddp>360) ddp-=360;
   if (ddp<=fDphi) xmin = -(fR+fRmax);
   ddp = 270-fPhi1;
   if (ddp<0) ddp+= 360;
   if (ddp>360) ddp-=360;
   if (ddp<=fDphi) ymin = -(fR+fRmax);
   fOrigin[0] = (xmax+xmin)/2;
   fOrigin[1] = (ymax+ymin)/2;
   fOrigin[2] = 0;
   fDX = (xmax-xmin)/2;
   fDY = (ymax-ymin)/2;
}

//-----------------------------------------------------------------------------   
void TGeoTorus::ComputeNormal(Double_t *point, Double_t *dir, Double_t *norm)
{
// Compute normal to closest surface from POINT. 
   Double_t phi = TMath::ATan2(point[1],point[0]);
   if (fDphi<360) {
      Double_t phi1 = fPhi1*TMath::DegToRad();
      Double_t phi2 = (fPhi1+fDphi)*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 daxis = Daxis(point,dir,0);
      if ((fRmax-daxis)>1E-5) {
         if (TGeoShape::IsSameWithinTolerance(fRmin,0) || (daxis-fRmin)>1E-5) {
            TGeoShape::NormalPhi(point,dir,norm,c1,s1,c2,s2);
            return;
         }
      }
   }   
   Double_t r0[3];
   r0[0] = fR*TMath::Cos(phi);
   r0[1] = fR*TMath::Sin(phi);           
   r0[2] = 0;
   Double_t normsq = 0;
   for (Int_t i=0; i<3; i++) {
      norm[i] = point[i] - r0[i];
      normsq += norm[i]*norm[i];
   }
   
   normsq = TMath::Sqrt(normsq);
   norm[0] /= normsq;
   norm[1] /= normsq;
   norm[2] /= normsq;
   if (dir[0]*norm[0]+dir[1]*norm[1]+dir[2]*norm[2] < 0) {
      norm[0] = -norm[0];
      norm[1] = -norm[1];
      norm[2] = -norm[2];
   }      
}

//_____________________________________________________________________________
Bool_t TGeoTorus::Contains(Double_t *point) const
{
// Test if point is inside the torus.
   // check phi range
   if (!TGeoShape::IsSameWithinTolerance(fDphi,360)) {
      Double_t phi = TMath::ATan2(point[1], point[0]) * TMath::RadToDeg();
      if (phi < 0) phi+=360.0;
      Double_t ddp = phi-fPhi1;
      if (ddp<0) ddp+=360.;
      if (ddp>fDphi) return kFALSE;
   }
   //check radius
   Double_t rxy = TMath::Sqrt(point[0]*point[0]+point[1]*point[1]);
   Double_t radsq = (rxy-fR)*(rxy-fR) + point[2]*point[2];
   if (radsq<fRmin*fRmin) return kFALSE;
   if (radsq>fRmax*fRmax) return kFALSE;
   return kTRUE;
}   

//_____________________________________________________________________________
Int_t TGeoTorus::DistancetoPrimitive(Int_t px, Int_t py)
{
// Compute closest distance from point px,py to each vertex.
   Int_t n = gGeoManager->GetNsegments()+1;
   Int_t numPoints = n*(n-1);
   if (fRmin>0) numPoints *= 2;
   else if (fDphi<360) numPoints += 2;
   return ShapeDistancetoPrimitive(numPoints, px, py);
}

//_____________________________________________________________________________
Double_t TGeoTorus::Daxis(Double_t *pt, Double_t *dir, Double_t t) const
{
// Computes distance to axis of the torus from point pt + t*dir;
   Double_t p[3];
   for (Int_t i=0; i<3; i++) p[i] = pt[i]+t*dir[i];
   Double_t rxy = TMath::Sqrt(p[0]*p[0]+p[1]*p[1]);
   return TMath::Sqrt((rxy-fR)*(rxy-fR)+p[2]*p[2]);
}   

//_____________________________________________________________________________
Double_t TGeoTorus::DDaxis(Double_t *pt, Double_t *dir, Double_t t) const
{
// Computes derivative w.r.t. t of the distance to axis of the torus from point pt + t*dir;
   Double_t p[3];
   for (Int_t i=0; i<3; i++) p[i] = pt[i]+t*dir[i];
   Double_t rxy = TMath::Sqrt(p[0]*p[0]+p[1]*p[1]);
   if (rxy<1E-4) return ((p[2]*dir[2]-fR*TMath::Sqrt(dir[0]*dir[0]+dir[1]*dir[1]))/TMath::Sqrt(fR*fR+p[2]*p[2]));
   Double_t d = TMath::Sqrt((rxy-fR)*(rxy-fR)+p[2]*p[2]);
   if (TGeoShape::IsSameWithinTolerance(d,0)) return 0.;
   Double_t dd = (p[0]*dir[0]+p[1]*dir[1]+p[2]*dir[2] - (p[0]*dir[0]+p[1]*dir[1])*fR/rxy)/d;
   return dd;
}   

//_____________________________________________________________________________
Double_t TGeoTorus::DDDaxis(Double_t *pt, Double_t *dir, Double_t t) const
{
// Second derivative of distance to torus axis w.r.t t.
   Double_t p[3];
   for (Int_t i=0; i<3; i++) p[i] = pt[i]+t*dir[i];
   Double_t rxy = TMath::Sqrt(p[0]*p[0]+p[1]*p[1]);
   if (rxy<1E-6) return 0;
   Double_t daxis = TMath::Sqrt((rxy-fR)*(rxy-fR)+p[2]*p[2]);
   if (TGeoShape::IsSameWithinTolerance(daxis,0)) return 0;
   Double_t ddaxis = (p[0]*dir[0]+p[1]*dir[1]+p[2]*dir[2] - (p[0]*dir[0]+p[1]*dir[1])*fR/rxy)/daxis;
   Double_t dddaxis = 1 - ddaxis*ddaxis - (1-dir[2]*dir[2])*fR/rxy +
                      fR*(p[0]*dir[0]+p[1]*dir[1])*(p[0]*dir[0]+p[1]*dir[1])/(rxy*rxy*rxy);
   dddaxis /= daxis;
   return dddaxis;
}
   
//_____________________________________________________________________________
Double_t TGeoTorus::DistFromInside(Double_t *point, Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
{
// Compute distance from inside point to surface of the torus.
   if (iact<3 && safe) {
      *safe = Safety(point, kTRUE);
      if (iact==0) return TGeoShape::Big();
      if ((iact==1) && (step<=*safe)) return TGeoShape::Big();
   }
   Double_t snext = TGeoShape::Big();
   Bool_t hasphi = (fDphi<360)?kTRUE:kFALSE;
   Bool_t hasrmin = (fRmin>0)?kTRUE:kFALSE;
   Double_t dout = ToBoundary(point,dir,fRmax,kTRUE);
//   Double_t dax = Daxis(point,dir,dout);
   Double_t din = (hasrmin)?ToBoundary(point,dir,fRmin,kTRUE):TGeoShape::Big();
   snext = TMath::Min(dout,din);
   if (snext>1E10) return TGeoShape::Tolerance();
   Double_t dphi = TGeoShape::Big();
   if (hasphi) {
      // Torus segment case.
      Double_t c1,s1,c2,s2,cm,sm,cdfi;
      Double_t phi1=fPhi1*TMath::DegToRad();
      Double_t phi2=(fPhi1+fDphi)*TMath::DegToRad();
      c1=TMath::Cos(phi1);
      s1=TMath::Sin(phi1);
      c2=TMath::Cos(phi2);
      s2=TMath::Sin(phi2);
      Double_t fio=0.5*(phi1+phi2);
      cm=TMath::Cos(fio);
      sm=TMath::Sin(fio);
      cdfi = TMath::Cos(0.5*(phi2-phi1));
      dphi = TGeoTubeSeg::DistFromInsideS(point,dir,fR-fRmax,fR+fRmax, fRmax, c1,s1,c2,s2,cm,sm,cdfi);
      Double_t daxis = Daxis(point,dir,dphi);
      if (daxis>=fRmin+1.E-8 && daxis<=fRmax-1.E-8) snext=TMath::Min(snext,dphi);
   }      
   return snext;
}

//_____________________________________________________________________________
Double_t TGeoTorus::DistFromOutside(Double_t *point, Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
{
// Compute distance from outside point to surface of the torus.
   if (iact<3 && safe) {
      *safe = Safety(point, kFALSE);
      if (iact==0) return TGeoShape::Big();
      if ((iact==1) && (step<=*safe)) return TGeoShape::Big();
   }
// 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();
   Double_t daxis;
   Bool_t hasphi = (fDphi<360)?kTRUE:kFALSE;
//   Bool_t hasrmin = (fRmin>0)?kTRUE:kFALSE;
   Double_t c1=0,s1=0,c2=0,s2=0,cm=0,sm=0,cdfi=0;
   Bool_t inphi = kFALSE;
   Double_t phi, ddp, phi1,phi2,fio;
   Double_t rxy2,dd;
   Double_t snext;
   Double_t pt[3];
   Int_t i;
      
   if (hasphi) {
      // Torus segment case.
      phi=TMath::ATan2(point[1], point[0])*TMath::RadToDeg();;
      if (phi<0) phi+=360;
      ddp = phi-fPhi1;
      if (ddp<0) ddp+=360;;
      if (ddp<=fDphi) inphi=kTRUE;
      phi1=fPhi1*TMath::DegToRad();
      phi2=(fPhi1+fDphi)*TMath::DegToRad();
      c1=TMath::Cos(phi1);
      s1=TMath::Sin(phi1);
      c2=TMath::Cos(phi2);
      s2=TMath::Sin(phi2);
      fio=0.5*(phi1+phi2);
      cm=TMath::Cos(fio);
      sm=TMath::Sin(fio);
      cdfi=TMath::Cos(0.5*(phi2-phi1));
   }
   // Check if we are inside or outside the bounding ring.
   Bool_t inbring = kFALSE;
   if (TMath::Abs(point[2]) <= fRmax) {
      rxy2 = point[0]*point[0]+point[1]*point[1];
      if ((rxy2>=(fR-fRmax)*(fR-fRmax)) && (rxy2<=(fR+fRmax)*(fR+fRmax))) {
         if (!hasphi || inphi) inbring=kTRUE;
      }
   }   
   
   // If outside the ring, compute distance to it.
   Double_t dring = TGeoShape::Big();
   Double_t eps = 1.E-8;
   snext = 0;
   daxis = -1;
   memcpy(pt,point,3*sizeof(Double_t));
   if (!inbring) {
      if (hasphi) dring = TGeoTubeSeg::DistFromOutsideS(point,dir,TMath::Max(0.,fR-fRmax-eps),fR+fRmax+eps, fRmax+eps, c1,s1,c2,s2,cm,sm,cdfi);
      else        dring = TGeoTube::DistFromOutsideS(point,dir,TMath::Max(0.,fR-fRmax-eps),fR+fRmax+eps, fRmax+eps);
      // If not crossing it, return BIG.
      if (dring>1E10) return TGeoShape::Big();
      snext = dring;
      // Check if the crossing is due to phi.
      daxis = Daxis(point,dir,snext);
      if (daxis>=fRmin && daxis<fRmax) return snext;
      // Not a phi crossing -> propagate until we cross the ring.
      for (i=0; i<3; i++) pt[i] = point[i]+snext*dir[i];      
   }
   // Point pt is inside the bounding ring, no phi crossing so far.
   // Check if we are in the hole.
   if (daxis<0) daxis = Daxis(pt,dir,0);
   if (daxis<fRmin+1.E-8) {
      // We are in the hole. Check if we came from outside.
      if (snext>0) {
         // we can cross either the inner torus or exit the other hole.
         snext += 0.1*eps;
         for (i=0; i<3; i++) pt[i] += 0.1*eps*dir[i];
      }
      // We are in the hole from the begining.   
      // find first crossing with inner torus
      dd = ToBoundary(pt,dir, fRmin,kFALSE);
      // find exit distance from inner bounding ring
      if (hasphi) dring = TGeoTubeSeg::DistFromInsideS(pt,dir,fR-fRmin,fR+fRmin, fRmin, c1,s1,c2,s2,cm,sm,cdfi);
      else        dring = TGeoTube::DistFromInsideS(pt,dir,fR-fRmin,fR+fRmin, fRmin);
      if (dd<dring) return (snext+dd);
      // we were exiting a hole inside phi hole
      snext += dring+ eps;
      for (i=0; i<3; i++) pt[i] = point[i] + snext*dir[i];
      snext += DistFromOutside(pt,dir,3);
      return snext;
   }    
   // We are inside the outer ring, having daxis>fRmax
   // Compute distance to exit the bounding ring (again)
   if (snext>0) {
      // we can cross either the inner torus or exit the other hole.
      snext += 0.1*eps;
      for (i=0; i<3; i++) pt[i] += 0.1*eps*dir[i];
   }
   // Check intersection with outer torus
   dd = ToBoundary(pt, dir, fRmax, kFALSE);
   if (hasphi) dring = TGeoTubeSeg::DistFromInsideS(pt,dir,TMath::Max(0.,fR-fRmax-eps),fR+fRmax+eps, fRmax+eps, c1,s1,c2,s2,cm,sm,cdfi);            
   else        dring = TGeoTube::DistFromInsideS(pt,dir,TMath::Max(0.,fR-fRmax-eps),fR+fRmax+eps, fRmax+eps);
   if (dd<dring) {
      snext += dd;
      return snext;
   }
   // We are exiting the bounding ring before crossing the torus -> propagate
   snext += dring+eps;   
   for (i=0; i<3; i++) pt[i] = point[i] + snext*dir[i];
   snext += DistFromOutside(pt,dir,3);
   return snext;
}      

//_____________________________________________________________________________
TGeoVolume *TGeoTorus::Divide(TGeoVolume * /*voldiv*/, const char * /*divname*/, Int_t /*iaxis*/, Int_t /*ndiv*/, 
                              Double_t /*start*/, Double_t /*step*/) 
{
//--- Divide this torus shape belonging to volume "voldiv" into ndiv volumes
// called divname, from start position with the given step. 
   return 0;
}

//_____________________________________________________________________________
const char *TGeoTorus::GetAxisName(Int_t iaxis) const
{
// Returns name of axis IAXIS.
   switch (iaxis) {
      case 1:
         return "R";
      case 2:
         return "PHI";
      case 3:
         return "Z";
      default:
         return "UNDEFINED";
   }
}   
   
//_____________________________________________________________________________
Double_t TGeoTorus::GetAxisRange(Int_t iaxis, Double_t &xlo, Double_t &xhi) const
{
// Get range of shape for a given axis.
   xlo = 0;
   xhi = 0;
   Double_t dx = 0;
   switch (iaxis) {
      case 1:
         xlo = fRmin;
         xhi = fRmax;
         dx = xhi-xlo;
         return dx;
      case 2:
         xlo = fPhi1;
         xhi = fPhi1+fDphi;
         dx = fDphi;
         return dx;
      case 3:
         dx = 0;
         return dx;
   }
   return dx;
}         
   
//_____________________________________________________________________________
void TGeoTorus::GetBoundingCylinder(Double_t *param) const
{
//--- Fill vector param[4] with the bounding cylinder parameters. The order
// is the following : Rmin, Rmax, Phi1, Phi2, dZ
   param[0] = (fR-fRmax); // Rmin
   param[1] = (fR+fRmax); // Rmax
   param[2] = fPhi1;    // Phi1
   param[3] = fPhi1+fDphi;  // Phi2
}   
 
//_____________________________________________________________________________
TGeoShape *TGeoTorus::GetMakeRuntimeShape(TGeoShape * /*mother*/, TGeoMatrix * /*mat*/) const
{
// Create a shape fitting the mother.
   if (!TestShapeBit(kGeoRunTimeShape)) return 0;
   Error("GetMakeRuntimeShape", "parametrized toruses not supported");
   return 0;
}
      
//_____________________________________________________________________________
void TGeoTorus::InspectShape() const
{
// print shape parameters
   printf("*** Shape %s: TGeoTorus ***\n", GetName());
   printf("    R    = %11.5f\n", fR);
   printf("    Rmin = %11.5f\n", fRmin);
   printf("    Rmax = %11.5f\n", fRmax);
   printf("    Phi1 = %11.5f\n", fPhi1);
   printf("    Dphi = %11.5f\n", fDphi);
   printf(" Bounding box:\n");
   TGeoBBox::InspectShape();
}

//_____________________________________________________________________________
TBuffer3D *TGeoTorus::MakeBuffer3D() const
{ 
   // Creates a TBuffer3D describing *this* shape.
   // Coordinates are in local reference frame.

   Int_t n = gGeoManager->GetNsegments()+1;
   Int_t nbPnts = n*(n-1);
   Bool_t hasrmin = (GetRmin()>0)?kTRUE:kFALSE;
   Bool_t hasphi  = (GetDphi()<360)?kTRUE:kFALSE;
   if (hasrmin) nbPnts *= 2;
   else if (hasphi) nbPnts += 2;

   Int_t nbSegs = (2*n-1)*(n-1);
   Int_t nbPols = (n-1)*(n-1);
   if (hasrmin) {
      nbSegs += (2*n-1)*(n-1);
      nbPols += (n-1)*(n-1);
   }
   if (hasphi) {
      nbSegs += 2*(n-1);
      nbPols += 2*(n-1);
   }

   TBuffer3D* buff = new TBuffer3D(TBuffer3DTypes::kGeneric,
                                   nbPnts, 3*nbPnts, nbSegs, 3*nbSegs, nbPols, 6*nbPols);
   if (buff)
   {
      SetPoints(buff->fPnts);   
      SetSegsAndPols(*buff);
   }

   return buff; 
}

//_____________________________________________________________________________
void TGeoTorus::SetSegsAndPols(TBuffer3D &buff) const
{
// Fill TBuffer3D structure for segments and polygons.
   Int_t i, j;
   Int_t n = gGeoManager->GetNsegments()+1;
   Int_t nbPnts = n*(n-1);
   Int_t indx, indp, startcap=0;
   Bool_t hasrmin = (GetRmin()>0)?kTRUE:kFALSE;
   Bool_t hasphi  = (GetDphi()<360)?kTRUE:kFALSE;
   if (hasrmin) nbPnts *= 2;
   else if (hasphi) nbPnts += 2;
   Int_t c = GetBasicColor();

   indp = n*(n-1); // start index for points on inner surface
   memset(buff.fSegs, 0, buff.NbSegs()*3*sizeof(Int_t));

   // outer surface phi circles = n*(n-1) -> [0, n*(n-1) -1]
   // connect point j with point j+1 on same row
   indx = 0;
   for (i = 0; i < n; i++) { // rows [0,n-1]
      for (j = 0; j < n-1; j++) {  // points on a row [0, n-2]
         buff.fSegs[indx+(i*(n-1)+j)*3] = c;
         buff.fSegs[indx+(i*(n-1)+j)*3+1] = i*(n-1)+j;   // j on row i
         buff.fSegs[indx+(i*(n-1)+j)*3+2] = i*(n-1)+((j+1)%(n-1)); // j+1 on row i
      }
   }
   indx += 3*n*(n-1);
   // outer surface generators = (n-1)*(n-1) -> [n*(n-1), (2*n-1)*(n-1) -1]
   // connect point j on row i with point j on row i+1
   for (i = 0; i < n-1; i++) { // rows [0, n-2]
      for (j = 0; j < n-1; j++) {  // points on a row [0, n-2]
         buff.fSegs[indx+(i*(n-1)+j)*3] = c;
         buff.fSegs[indx+(i*(n-1)+j)*3+1] = i*(n-1)+j;     // j on row i
         buff.fSegs[indx+(i*(n-1)+j)*3+2] = (i+1)*(n-1)+j; // j on row i+1
      }
   }
   indx += 3*(n-1)*(n-1);
   startcap = (2*n-1)*(n-1);

   if (hasrmin) {
      // inner surface phi circles = n*(n-1) -> [(2*n-1)*(n-1), (3*n-1)*(n-1) -1]
      // connect point j with point j+1 on same row
      for (i = 0; i < n; i++) { // rows [0, n-1]
         for (j = 0; j < n-1; j++) {  // points on a row [0, n-2]
            buff.fSegs[indx+(i*(n-1)+j)*3] = c;              // lighter color
            buff.fSegs[indx+(i*(n-1)+j)*3+1] = indp + i*(n-1)+j;   // j on row i
            buff.fSegs[indx+(i*(n-1)+j)*3+2] = indp + i*(n-1)+((j+1)%(n-1)); // j+1 on row i
         }
      }
      indx += 3*n*(n-1);
      // inner surface generators = (n-1)*n -> [(3*n-1)*(n-1), (4*n-2)*(n-1) -1]
      // connect point j on row i with point j on row i+1
      for (i = 0; i < n-1; i++) { // rows [0, n-2]
         for (j = 0; j < n-1; j++) {  // points on a row [0, n-2]
            buff.fSegs[indx+(i*(n-1)+j)*3] = c;                // lighter color
            buff.fSegs[indx+(i*(n-1)+j)*3+1] = indp + i*(n-1)+j;     // j on row i
            buff.fSegs[indx+(i*(n-1)+j)*3+2] = indp + (i+1)*(n-1)+j; // j on row i+1
         }
      }
      indx += 3*(n-1)*(n-1);
      startcap = (4*n-2)*(n-1);
   }

   if (hasphi) {
      if (hasrmin) {
         // endcaps = 2*(n-1) -> [(4*n-2)*(n-1), 4*n*(n-1)-1]
         i = 0;
         for (j = 0; j < n-1; j++) {
            buff.fSegs[indx+j*3] = c+1;
            buff.fSegs[indx+j*3+1] = (n-1)*i+j;     // outer j on row 0
            buff.fSegs[indx+j*3+2] = indp+(n-1)*i+j; // inner j on row 0
         }
         indx += 3*(n-1);
         i = n-1;
         for (j = 0; j < n-1; j++) {
            buff.fSegs[indx+j*3] = c+1;
            buff.fSegs[indx+j*3+1] = (n-1)*i+j;     // outer j on row n-1
            buff.fSegs[indx+j*3+2] = indp+(n-1)*i+j; // inner j on row n-1
         }
         indx += 3*(n-1);
      } else {
         i = 0;
         for (j = 0; j < n-1; j++) {
            buff.fSegs[indx+j*3] = c+1;
            buff.fSegs[indx+j*3+1] = (n-1)*i+j;     // outer j on row 0
            buff.fSegs[indx+j*3+2] = n*(n-1);       // center of first endcap
         }
         indx += 3*(n-1);
         i = n-1;
         for (j = 0; j < n-1; j++) {
            buff.fSegs[indx+j*3] = c+1;
            buff.fSegs[indx+j*3+1] = (n-1)*i+j;     // outer j on row n-1
            buff.fSegs[indx+j*3+2] = n*(n-1)+1;     // center of second endcap
         }
         indx += 3*(n-1);
      }
   }

   indx = 0;
   memset(buff.fPols, 0, buff.NbPols()*6*sizeof(Int_t));

   // outer surface = (n-1)*(n-1) -> [0, (n-1)*(n-1)-1]
   // normal pointing out
   for (i=0; i<n-1; i++) {
      for (j=0; j<n-1; j++) {
         buff.fPols[indx++] = c;
         buff.fPols[indx++] = 4;
         buff.fPols[indx++] = n*(n-1)+(n-1)*i+((j+1)%(n-1)); // generator j+1 on outer row i
         buff.fPols[indx++] = (n-1)*(i+1)+j; // seg j on outer row i+1
         buff.fPols[indx++] = n*(n-1)+(n-1)*i+j; // generator j on outer row i
         buff.fPols[indx++] = (n-1)*i+j; // seg j on outer row i
      }
   }
   if (hasrmin) {
      indp = (2*n-1)*(n-1); // start index of inner segments
      // inner surface = (n-1)*(n-1) -> [(n-1)*(n-1), 2*(n-1)*(n-1)-1]
      // normal pointing out
      for (i=0; i<n-1; i++) {
         for (j=0; j<n-1; j++) {
            buff.fPols[indx++] = c;
            buff.fPols[indx++] = 4;
            buff.fPols[indx++] = indp+n*(n-1)+(n-1)*i+j; // generator j on inner row i
            buff.fPols[indx++] = indp+(n-1)*(i+1)+j; // seg j on inner row i+1
            buff.fPols[indx++] = indp+n*(n-1)+(n-1)*i+((j+1)%(n-1)); // generator j+1 on inner r>
            buff.fPols[indx++] = indp+(n-1)*i+j; // seg j on inner row i
         }
      }
   }
   if (hasphi) {
      // endcaps = 2*(n-1) -> [2*(n-1)*(n-1), 2*n*(n-1)-1]
      i=0; // row 0
      Int_t np = (hasrmin)?4:3;
      for (j=0; j<n-1; j++) {
         buff.fPols[indx++] = c+1;
         buff.fPols[indx++] = np;
         buff.fPols[indx++] = j;         // seg j on outer row 0  a
         buff.fPols[indx++] = startcap+j;        // endcap j on row 0  d
         if(hasrmin)
            buff.fPols[indx++] = indp+j; // seg j on inner row 0  c
         buff.fPols[indx++] = startcap+((j+1)%(n-1)); // endcap j+1 on row 0  b
      }

      i=n-1; // row n-1
      for (j=0; j<n-1; j++) {
         buff.fPols[indx++] = c+1;
         buff.fPols[indx++] = np;
         buff.fPols[indx++] = (n-1)*i+j;         // seg j on outer row n-1 a
         buff.fPols[indx++] = startcap+(n-1)+((j+1)%(n-1));    // endcap j+1 on row n-1 d
         if (hasrmin)
            buff.fPols[indx++] = indp+(n-1)*i+j; // seg j on inner row n-1 c
         buff.fPols[indx++] = startcap+(n-1)+j;      // endcap j on row n-1 b
      }
   }
}

//_____________________________________________________________________________
Double_t TGeoTorus::Safety(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.
   Double_t saf[2];
   Int_t i;
   Double_t rxy = TMath::Sqrt(point[0]*point[0]+point[1]*point[1]);
   Double_t rad = TMath::Sqrt((rxy-fR)*(rxy-fR) + point[2]*point[2]);
   saf[0] = rad-fRmin;
   saf[1] = fRmax-rad;
   if (TGeoShape::IsSameWithinTolerance(fDphi,360)) {
      if (in) return TMath::Min(saf[0],saf[1]);
      for (i=0; i<2; i++) saf[i]=-saf[i];
      return TMath::Max(saf[0], saf[1]);
   }   

   Double_t safphi = TGeoShape::SafetyPhi(point,in,fPhi1, fPhi1+fDphi);
   Double_t safe = TGeoShape::Big();
   if (in) {
      safe = TMath::Min(saf[0], saf[1]);
      return TMath::Min(safe, safphi);
   }   
   for (i=0; i<2; i++) saf[i]=-saf[i];
   safe = TMath::Max(saf[0], saf[1]);
   return TMath::Max(safe, safphi);
}

//_____________________________________________________________________________
void TGeoTorus::SavePrimitive(ostream &out, Option_t * /*option*/ /*= ""*/)
{
// Save a primitive as a C++ statement(s) on output stream "out".
   if (TObject::TestBit(kGeoSavePrimitive)) return;  
   out << "   // Shape: " << GetName() << " type: " << ClassName() << endl;
   out << "   r    = " << fR << ";" << endl;
   out << "   rmin = " << fRmin << ";" << endl;
   out << "   rmax = " << fRmax << ";" << endl;
   out << "   phi1 = " << fPhi1 << ";" << endl;
   out << "   dphi = " << fDphi << ";" << endl;
   out << "   TGeoShape *" << GetPointerName() << " = new TGeoTorus(\"" << GetName() << "\",r,rmin,rmax,phi1,dphi);" << endl;
   TObject::SetBit(TGeoShape::kGeoSavePrimitive);
}

//_____________________________________________________________________________
void TGeoTorus::SetTorusDimensions(Double_t r, Double_t rmin, Double_t rmax,
                          Double_t phi1, Double_t dphi)
{
// Set torus dimensions.
   fR = r;
   fRmin = rmin;
   fRmax = rmax;
   fPhi1 = phi1;
   if (fPhi1<0) fPhi1+=360.;
   fDphi = dphi;
}

//_____________________________________________________________________________
void TGeoTorus::SetDimensions(Double_t *param)
{
// Set torus dimensions starting from a list.
   SetTorusDimensions(param[0], param[1], param[2], param[3], param[4]);
}

//_____________________________________________________________________________
void TGeoTorus::SetPoints(Double_t *points) const
{
// Create torus mesh points
   if (!points) return;
   Int_t n = gGeoManager->GetNsegments()+1;
   Double_t phin, phout;
   Double_t dpin = 360./(n-1);
   Double_t dpout = fDphi/(n-1);
   Double_t co,so,ci,si;
   Bool_t havermin = (fRmin<TGeoShape::Tolerance())?kFALSE:kTRUE;
   Int_t i,j;
   Int_t indx = 0;
   // loop outer mesh -> n*(n-1) points [0, 3*n*(n-1)-1]
   for (i=0; i<n; i++) {
      phout = (fPhi1+i*dpout)*TMath::DegToRad();
      co = TMath::Cos(phout);
      so = TMath::Sin(phout);
      for (j=0; j<n-1; j++) {
         phin = j*dpin*TMath::DegToRad();
         ci = TMath::Cos(phin);
         si = TMath::Sin(phin);
         points[indx++] = (fR+fRmax*ci)*co;
         points[indx++] = (fR+fRmax*ci)*so;
         points[indx++] = fRmax*si;
      }
   }     
    
   if (havermin) {
    // loop inner mesh -> n*(n-1) points [3*n*(n-1), 6*n*(n-1)]
      for (i=0; i<n; i++) {
         phout = (fPhi1+i*dpout)*TMath::DegToRad();
         co = TMath::Cos(phout);
         so = TMath::Sin(phout);
         for (j=0; j<n-1; j++) {
            phin = j*dpin*TMath::DegToRad();
            ci = TMath::Cos(phin);
            si = TMath::Sin(phin);
            points[indx++] = (fR+fRmin*ci)*co;
            points[indx++] = (fR+fRmin*ci)*so;
            points[indx++] = fRmin*si;
         }
      }  
   } else {
      if (fDphi<360.) {
      // just add extra 2 points on the centers of the 2 phi cuts [3*n*n, 3*n*n+1]
         points[indx++] = fR*TMath::Cos(fPhi1*TMath::DegToRad());
         points[indx++] = fR*TMath::Sin(fPhi1*TMath::DegToRad());
         points[indx++] = 0;
         points[indx++] = fR*TMath::Cos((fPhi1+fDphi)*TMath::DegToRad());
         points[indx++] = fR*TMath::Sin((fPhi1+fDphi)*TMath::DegToRad());
         points[indx++] = 0;
      }
   }      
}        

//_____________________________________________________________________________
void TGeoTorus::SetPoints(Float_t *points) const
{
// Create torus mesh points
   if (!points) return;
   Int_t n = gGeoManager->GetNsegments()+1;
   Double_t phin, phout;
   Double_t dpin = 360./(n-1);
   Double_t dpout = fDphi/(n-1);
   Double_t co,so,ci,si;
   Bool_t havermin = (fRmin<TGeoShape::Tolerance())?kFALSE:kTRUE;
   Int_t i,j;
   Int_t indx = 0;
   // loop outer mesh -> n*(n-1) points [0, 3*n*(n-1)-1]
   // plane i = 0, n-1  point j = 0, n-1  ipoint = n*i + j
   for (i=0; i<n; i++) {
      phout = (fPhi1+i*dpout)*TMath::DegToRad();
      co = TMath::Cos(phout);
      so = TMath::Sin(phout);
      for (j=0; j<n-1; j++) {
         phin = j*dpin*TMath::DegToRad();
         ci = TMath::Cos(phin);
         si = TMath::Sin(phin);
         points[indx++] = (fR+fRmax*ci)*co;
         points[indx++] = (fR+fRmax*ci)*so;
         points[indx++] = fRmax*si;
      }
   }     
    
   if (havermin) {
    // loop inner mesh -> n*(n-1) points [3*n*(n-1), 6*n*(n-1)]
      // plane i = 0, n-1  point j = 0, n-1  ipoint = n*n + n*i + j
      for (i=0; i<n; i++) {
         phout = (fPhi1+i*dpout)*TMath::DegToRad();
         co = TMath::Cos(phout);
         so = TMath::Sin(phout);
         for (j=0; j<n-1; j++) {
            phin = j*dpin*TMath::DegToRad();
            ci = TMath::Cos(phin);
            si = TMath::Sin(phin);
            points[indx++] = (fR+fRmin*ci)*co;
            points[indx++] = (fR+fRmin*ci)*so;
            points[indx++] = fRmin*si;
         }
      }  
   } else {
      if (fDphi<360.) {
      // just add extra 2 points on the centers of the 2 phi cuts [n*n, n*n+1]
      // ip1 = n*(n-1) + 0;
      // ip2 = n*(n-1) + 1
         points[indx++] = fR*TMath::Cos(fPhi1*TMath::DegToRad());
         points[indx++] = fR*TMath::Sin(fPhi1*TMath::DegToRad());
         points[indx++] = 0;
         points[indx++] = fR*TMath::Cos((fPhi1+fDphi)*TMath::DegToRad());
         points[indx++] = fR*TMath::Sin((fPhi1+fDphi)*TMath::DegToRad());
         points[indx++] = 0;
      }
   }      
}        

//_____________________________________________________________________________
Int_t TGeoTorus::GetNmeshVertices() const
{
// Return number of vertices of the mesh representation
   Int_t n = gGeoManager->GetNsegments()+1;
   Int_t numPoints = n*(n-1);
   if (fRmin>TGeoShape::Tolerance()) numPoints *= 2;
   else if (fDphi<360.)              numPoints += 2;
   return numPoints;
}

//_____________________________________________________________________________
void TGeoTorus::Sizeof3D() const
{
///// fill size of this 3-D object
///   TVirtualGeoPainter *painter = gGeoManager->GetGeomPainter();
///   if (!painter) return;
///   Int_t n = gGeoManager->GetNsegments()+1;
///   Int_t numPoints = n*(n-1);
///   Int_t numSegs   = (2*n-1)*(n-1);
///   Int_t numPolys  = (n-1)*(n-1);
///
///   Bool_t hasrmin = (fRmin>0)?kTRUE:kFALSE;
///   Bool_t hasphi  = (fDphi<360)?kTRUE:kFALSE;
///   if (hasrmin) numPoints *= 2;
///   else if (hasphi) numPoints += 2;
///   if (hasrmin) {
///      numSegs   += (2*n-1)*(n-1);
///      numPolys  += (n-1)*(n-1);
///   }   
///   if (hasphi) {
///      numSegs   += 2*(n-1);
///      numPolys  += 2*(n-1);
///   }   
///    
///   painter->AddSize3D(numPoints, numSegs, numPolys);
}

//_____________________________________________________________________________
Int_t TGeoTorus::SolveCubic(Double_t a, Double_t b, Double_t c, Double_t *x) const
{
// Find real solutions of the cubic equation : x^3 + a*x^2 + b*x + c = 0
// Input: a,b,c
// Output: x[3] real solutions
// Returns number of real solutions (1 or 3)
   const Double_t ott = 1./3.;
   const Double_t sq3 = TMath::Sqrt(3.);
   Int_t ireal = 1;
   Double_t p = b-a*a*ott;
   Double_t q = c-a*b*ott+2.*a*a*a*ott*ott*ott;
   Double_t delta = 4*p*p*p+27*q*q;
//   Double_t y1r, y1i, y2r, y2i;
   Double_t t,u;
   if (delta>=0) {
      delta = TMath::Sqrt(delta);
      t = (-3*q*sq3+delta)/(6*sq3);
      u = (3*q*sq3+delta)/(6*sq3);
      x[0] = TMath::Sign(1.,t)*TMath::Power(TMath::Abs(t),ott)-
             TMath::Sign(1.,u)*TMath::Power(TMath::Abs(u),ott)-a*ott;
   } else {
      delta = TMath::Sqrt(-delta);
      t = -0.5*q;
      u = delta/(6*sq3);
      x[0] = 2.*TMath::Power(t*t+u*u,0.5*ott) * TMath::Cos(ott*TMath::ATan2(u,t));
      x[0] -= a*ott;
   }   
         
   t = x[0]*x[0]+a*x[0]+b;
   u = a+x[0];
   delta = u*u-4.*t;
   if (delta>=0) {
      ireal = 3;
      delta = TMath::Sqrt(delta);
      x[1] = 0.5*(-u-delta);
      x[2] = 0.5*(-u+delta);
   }
   return ireal;
}

//_____________________________________________________________________________
Int_t TGeoTorus::SolveQuartic(Double_t a, Double_t b, Double_t c, Double_t d, Double_t *x) const
{
// Find real solutions of the quartic equation : x^4 + a*x^3 + b*x^2 + c*x + d = 0
// Input: a,b,c,d
// Output: x[4] - real solutions
// Returns number of real solutions (0 to 3)
   Double_t e = b-3.*a*a/8.;
   Double_t f = c+a*a*a/8.-0.5*a*b;
   Double_t g = d-3.*a*a*a*a/256. + a*a*b/16. - a*c/4.;
   Double_t xx[4];
   Int_t    ind[4];
   Double_t delta;
   Double_t h=0;
   Int_t ireal = 0;
   Int_t i;
   if (TGeoShape::IsSameWithinTolerance(f,0)) {
      delta = e*e-4.*g;
      if (delta<0) return 0;
      delta = TMath::Sqrt(delta);
      h = 0.5*(-e-delta);
      if (h>=0) {
         h = TMath::Sqrt(h);
         x[ireal++] = -h-0.25*a;
         x[ireal++] = h-0.25*a;
      }
      h = 0.5*(-e+delta);
      if (h>=0) {
         h = TMath::Sqrt(h);
         x[ireal++] = -h-0.25*a;
         x[ireal++] = h-0.25*a;
      }
      if (ireal>0) {
         TMath::Sort(ireal, x, ind,kFALSE);
         for (i=0; i<ireal; i++) xx[i] = x[ind[i]];
         memcpy(x,xx,ireal*sizeof(Double_t));
      }
      return ireal; 
   }     
   
   if (TGeoShape::IsSameWithinTolerance(g,0)) {
      x[ireal++] = -0.25*a;
      ind[0] = SolveCubic(0,e,f,xx);
      for (i=0; i<ind[0]; i++) x[ireal++] = xx[i]-0.25*a;      
      if (ireal>0) {
         TMath::Sort(ireal, x, ind,kFALSE);
         for (i=0; i<ireal; i++) xx[i] = x[ind[i]];
         memcpy(x,xx,ireal*sizeof(Double_t));
      }
      return ireal;
   }    
      
      
   ireal = SolveCubic(2.*e, e*e-4.*g, -f*f, xx);
   if (ireal==1) {
      if (xx[0]<=0) return 0;
      h = TMath::Sqrt(xx[0]);   
   } else {
      // 3 real solutions of the cubic
      for (i=0; i<3; i++) {
         h = xx[i];
         if (h>=0) break;
      }
      if (h<=0) return 0;
      h = TMath::Sqrt(h);
   }
   Double_t j = 0.5*(e+h*h-f/h);      
   ireal = 0;
   delta = h*h-4.*j;
   if (delta>=0) {
      delta = TMath::Sqrt(delta);
      x[ireal++] = 0.5*(-h-delta)-0.25*a;
      x[ireal++] = 0.5*(-h+delta)-0.25*a;
   }
   delta = h*h-4.*g/j;
   if (delta>=0) {
      delta = TMath::Sqrt(delta);
      x[ireal++] = 0.5*(h-delta)-0.25*a;
      x[ireal++] = 0.5*(h+delta)-0.25*a;
   }
   if (ireal>0) {
      TMath::Sort(ireal, x, ind,kFALSE);
      for (i=0; i<ireal; i++) xx[i] = x[ind[i]];
      memcpy(x,xx,ireal*sizeof(Double_t));
   }
   return ireal;
}

//_____________________________________________________________________________
Double_t TGeoTorus::ToBoundary(Double_t *pt, Double_t *dir, Double_t r, Bool_t in) const
{
// Returns distance to the surface or the torus (fR,r) from a point, along
// a direction. Point is close enough to the boundary so that the distance 
// to the torus is decreasing while moving along the given direction.
   
   // Compute coeficients of the quartic
   Double_t s = TGeoShape::Big();
   Double_t tol = TGeoShape::Tolerance();
   Double_t r0sq  = pt[0]*pt[0]+pt[1]*pt[1]+pt[2]*pt[2];
   Double_t rdotn = pt[0]*dir[0]+pt[1]*dir[1]+pt[2]*dir[2];
   Double_t rsumsq = fR*fR+r*r;
   Double_t a = 4.*rdotn;
   Double_t b = 2.*(r0sq+2.*rdotn*rdotn-rsumsq+2.*fR*fR*dir[2]*dir[2]);
   Double_t c = 4.*(r0sq*rdotn-rsumsq*rdotn+2.*fR*fR*pt[2]*dir[2]);
   Double_t d = r0sq*r0sq-2.*r0sq*rsumsq+4.*fR*fR*pt[2]*pt[2]+(fR*fR-r*r)*(fR*fR-r*r);
   
   Double_t x[4],y[4];
   Int_t nsol = 0;

   if (TMath::Abs(dir[2])<1E-3 && TMath::Abs(pt[2])<0.1*r) {
      Double_t r0 = fR - TMath::Sqrt((r-pt[2])*(r+pt[2]));
      Double_t b0 = (pt[0]*dir[0]+pt[1]*dir[1])/(dir[0]*dir[0]+dir[1]*dir[1]);
      Double_t c0 = (pt[0]*pt[0] + (pt[1]-r0)*(pt[1]+r0))/(dir[0]*dir[0]+dir[1]*dir[1]);
      Double_t delta = b0*b0-c0;
      if (delta>0) {
         y[nsol] = -b0-TMath::Sqrt(delta);
         if (y[nsol]>-tol) nsol++;
         y[nsol] = -b0+TMath::Sqrt(delta);
         if (y[nsol]>-tol) nsol++;
      }
      r0 = fR + TMath::Sqrt((r-pt[2])*(r+pt[2]));
      c0 = (pt[0]*pt[0] + (pt[1]-r0)*(pt[1]+r0))/(dir[0]*dir[0]+dir[1]*dir[1]);
      delta = b0*b0-c0;
      if (delta>0) {
         y[nsol] = -b0-TMath::Sqrt(delta);
         if (y[nsol]>-tol) nsol++;
         y[nsol] = -b0+TMath::Sqrt(delta);
         if (y[nsol]>-tol) nsol++;
      }
      if (nsol) {
         // Sort solutions
         Int_t ind[4];
         TMath::Sort(nsol, y, ind,kFALSE);
         for (Int_t j=0; j<nsol; j++) x[j] = y[ind[j]];
      }
   } else {               
      nsol = SolveQuartic(a,b,c,d,x);
   }   
   if (!nsol) return TGeoShape::Big();
   // look for first positive solution
   Double_t phi, ndotd;
   Double_t r0[3], norm[3];
   Bool_t inner = (TMath::Abs(r-fRmin)<TGeoShape::Tolerance())?kTRUE:kFALSE;
   for (Int_t i=0; i<nsol; i++) {
      if (x[i]<-10) continue;
      phi = TMath::ATan2(pt[1]+x[i]*dir[1],pt[0]+x[i]*dir[0]);
      r0[0] = fR*TMath::Cos(phi);
      r0[1] = fR*TMath::Sin(phi);           
      r0[2] = 0;
      for (Int_t ipt=0; ipt<3; ipt++) norm[ipt] = pt[ipt]+x[i]*dir[ipt] - r0[ipt];
      ndotd = norm[0]*dir[0]+norm[1]*dir[1]+norm[2]*dir[2];
      if (inner^in) {
         if (ndotd<0) continue;
      } else {
         if (ndotd>0) continue;
      }      
      s = x[i];
      Double_t eps = TGeoShape::Big();
      Double_t delta = s*s*s*s + a*s*s*s + b*s*s + c*s + d;
      Double_t eps0 = -delta/(4.*s*s*s + 3.*a*s*s + 2.*b*s + c);
      while (TMath::Abs(eps)>TGeoShape::Tolerance()) {
         if (TMath::Abs(eps0)>100) break;
         s += eps0;
         if (TMath::Abs(s+eps0)<TGeoShape::Tolerance()) break;
         delta = s*s*s*s + a*s*s*s + b*s*s + c*s + d;
         eps = -delta/(4.*s*s*s + 3.*a*s*s + 2.*b*s + c);
         if (TMath::Abs(eps)>TMath::Abs(eps0)) break;
         eps0 = eps;
      }
      if (s<-TGeoShape::Tolerance()) continue;
      return TMath::Max(0.,s);
   }
   return TGeoShape::Big();   
}      

//_____________________________________________________________________________
void TGeoTorus::GetMeshNumbers(Int_t &nvert, Int_t &nsegs, Int_t &npols) const
{
// Returns numbers of vertices, segments and polygons composing the shape mesh.
   Int_t n = gGeoManager->GetNsegments()+1;
   nvert = n*(n-1);
   Bool_t hasrmin = (GetRmin()>0)?kTRUE:kFALSE;
   Bool_t hasphi  = (GetDphi()<360)?kTRUE:kFALSE;
   if (hasrmin) nvert *= 2;
   else if (hasphi) nvert += 2;
   nsegs = (2*n-1)*(n-1);
   npols = (n-1)*(n-1);
   if (hasrmin) {
      nsegs += (2*n-1)*(n-1);
      npols += (n-1)*(n-1);
   }
   if (hasphi) {
      nsegs += 2*(n-1);
      npols += 2*(n-1);
   }
}

//_____________________________________________________________________________
const TBuffer3D & TGeoTorus::GetBuffer3D(Int_t reqSections, Bool_t localFrame) const
{
// Fills a static 3D buffer and returns a reference.
   static TBuffer3D buffer(TBuffer3DTypes::kGeneric);

   TGeoBBox::FillBuffer3D(buffer, reqSections, localFrame);

   if (reqSections & TBuffer3D::kRawSizes) {
      Int_t n = gGeoManager->GetNsegments()+1;
      Int_t nbPnts = n*(n-1);
      Bool_t hasrmin = (GetRmin()>0)?kTRUE:kFALSE;
      Bool_t hasphi  = (GetDphi()<360)?kTRUE:kFALSE;
      if (hasrmin) nbPnts *= 2;
      else if (hasphi) nbPnts += 2;

      Int_t nbSegs = (2*n-1)*(n-1);
      Int_t nbPols = (n-1)*(n-1);
      if (hasrmin) {
         nbSegs += (2*n-1)*(n-1);
         nbPols += (n-1)*(n-1);
      }
      if (hasphi) {
         nbSegs += 2*(n-1);
         nbPols += 2*(n-1);
      }

      if (buffer.SetRawSizes(nbPnts, 3*nbPnts, nbSegs, 3*nbSegs, nbPols, 6*nbPols)) {
         buffer.SetSectionsValid(TBuffer3D::kRawSizes);
      }
   }
   // TODO: Push down to TGeoShape?? But would have to do raw sizes set first..
   // can rest of TGeoShape be defered until after
   if ((reqSections & TBuffer3D::kRaw) && buffer.SectionsValid(TBuffer3D::kRawSizes)) {
      SetPoints(buffer.fPnts);
      if (!buffer.fLocalFrame) {
         TransformPoints(buffer.fPnts, buffer.NbPnts());
      }

      SetSegsAndPols(buffer);      
      buffer.SetSectionsValid(TBuffer3D::kRaw);
   }
      
   return buffer;
}

 TGeoTorus.cxx:1
 TGeoTorus.cxx:2
 TGeoTorus.cxx:3
 TGeoTorus.cxx:4
 TGeoTorus.cxx:5
 TGeoTorus.cxx:6
 TGeoTorus.cxx:7
 TGeoTorus.cxx:8
 TGeoTorus.cxx:9
 TGeoTorus.cxx:10
 TGeoTorus.cxx:11
 TGeoTorus.cxx:12
 TGeoTorus.cxx:13
 TGeoTorus.cxx:14
 TGeoTorus.cxx:15
 TGeoTorus.cxx:16
 TGeoTorus.cxx:17
 TGeoTorus.cxx:18
 TGeoTorus.cxx:19
 TGeoTorus.cxx:20
 TGeoTorus.cxx:21
 TGeoTorus.cxx:22
 TGeoTorus.cxx:23
 TGeoTorus.cxx:24
 TGeoTorus.cxx:25
 TGeoTorus.cxx:26
 TGeoTorus.cxx:27
 TGeoTorus.cxx:28
 TGeoTorus.cxx:29
 TGeoTorus.cxx:30
 TGeoTorus.cxx:31
 TGeoTorus.cxx:32
 TGeoTorus.cxx:33
 TGeoTorus.cxx:34
 TGeoTorus.cxx:35
 TGeoTorus.cxx:36
 TGeoTorus.cxx:37
 TGeoTorus.cxx:38
 TGeoTorus.cxx:39
 TGeoTorus.cxx:40
 TGeoTorus.cxx:41
 TGeoTorus.cxx:42
 TGeoTorus.cxx:43
 TGeoTorus.cxx:44
 TGeoTorus.cxx:45
 TGeoTorus.cxx:46
 TGeoTorus.cxx:47
 TGeoTorus.cxx:48
 TGeoTorus.cxx:49
 TGeoTorus.cxx:50
 TGeoTorus.cxx:51
 TGeoTorus.cxx:52
 TGeoTorus.cxx:53
 TGeoTorus.cxx:54
 TGeoTorus.cxx:55
 TGeoTorus.cxx:56
 TGeoTorus.cxx:57
 TGeoTorus.cxx:58
 TGeoTorus.cxx:59
 TGeoTorus.cxx:60
 TGeoTorus.cxx:61
 TGeoTorus.cxx:62
 TGeoTorus.cxx:63
 TGeoTorus.cxx:64
 TGeoTorus.cxx:65
 TGeoTorus.cxx:66
 TGeoTorus.cxx:67
 TGeoTorus.cxx:68
 TGeoTorus.cxx:69
 TGeoTorus.cxx:70
 TGeoTorus.cxx:71
 TGeoTorus.cxx:72
 TGeoTorus.cxx:73
 TGeoTorus.cxx:74
 TGeoTorus.cxx:75
 TGeoTorus.cxx:76
 TGeoTorus.cxx:77
 TGeoTorus.cxx:78
 TGeoTorus.cxx:79
 TGeoTorus.cxx:80
 TGeoTorus.cxx:81
 TGeoTorus.cxx:82
 TGeoTorus.cxx:83
 TGeoTorus.cxx:84
 TGeoTorus.cxx:85
 TGeoTorus.cxx:86
 TGeoTorus.cxx:87
 TGeoTorus.cxx:88
 TGeoTorus.cxx:89
 TGeoTorus.cxx:90
 TGeoTorus.cxx:91
 TGeoTorus.cxx:92
 TGeoTorus.cxx:93
 TGeoTorus.cxx:94
 TGeoTorus.cxx:95
 TGeoTorus.cxx:96
 TGeoTorus.cxx:97
 TGeoTorus.cxx:98
 TGeoTorus.cxx:99
 TGeoTorus.cxx:100
 TGeoTorus.cxx:101
 TGeoTorus.cxx:102
 TGeoTorus.cxx:103
 TGeoTorus.cxx:104
 TGeoTorus.cxx:105
 TGeoTorus.cxx:106
 TGeoTorus.cxx:107
 TGeoTorus.cxx:108
 TGeoTorus.cxx:109
 TGeoTorus.cxx:110
 TGeoTorus.cxx:111
 TGeoTorus.cxx:112
 TGeoTorus.cxx:113
 TGeoTorus.cxx:114
 TGeoTorus.cxx:115
 TGeoTorus.cxx:116
 TGeoTorus.cxx:117
 TGeoTorus.cxx:118
 TGeoTorus.cxx:119
 TGeoTorus.cxx:120
 TGeoTorus.cxx:121
 TGeoTorus.cxx:122
 TGeoTorus.cxx:123
 TGeoTorus.cxx:124
 TGeoTorus.cxx:125
 TGeoTorus.cxx:126
 TGeoTorus.cxx:127
 TGeoTorus.cxx:128
 TGeoTorus.cxx:129
 TGeoTorus.cxx:130
 TGeoTorus.cxx:131
 TGeoTorus.cxx:132
 TGeoTorus.cxx:133
 TGeoTorus.cxx:134
 TGeoTorus.cxx:135
 TGeoTorus.cxx:136
 TGeoTorus.cxx:137
 TGeoTorus.cxx:138
 TGeoTorus.cxx:139
 TGeoTorus.cxx:140
 TGeoTorus.cxx:141
 TGeoTorus.cxx:142
 TGeoTorus.cxx:143
 TGeoTorus.cxx:144
 TGeoTorus.cxx:145
 TGeoTorus.cxx:146
 TGeoTorus.cxx:147
 TGeoTorus.cxx:148
 TGeoTorus.cxx:149
 TGeoTorus.cxx:150
 TGeoTorus.cxx:151
 TGeoTorus.cxx:152
 TGeoTorus.cxx:153
 TGeoTorus.cxx:154
 TGeoTorus.cxx:155
 TGeoTorus.cxx:156
 TGeoTorus.cxx:157
 TGeoTorus.cxx:158
 TGeoTorus.cxx:159
 TGeoTorus.cxx:160
 TGeoTorus.cxx:161
 TGeoTorus.cxx:162
 TGeoTorus.cxx:163
 TGeoTorus.cxx:164
 TGeoTorus.cxx:165
 TGeoTorus.cxx:166
 TGeoTorus.cxx:167
 TGeoTorus.cxx:168
 TGeoTorus.cxx:169
 TGeoTorus.cxx:170
 TGeoTorus.cxx:171
 TGeoTorus.cxx:172
 TGeoTorus.cxx:173
 TGeoTorus.cxx:174
 TGeoTorus.cxx:175
 TGeoTorus.cxx:176
 TGeoTorus.cxx:177
 TGeoTorus.cxx:178
 TGeoTorus.cxx:179
 TGeoTorus.cxx:180
 TGeoTorus.cxx:181
 TGeoTorus.cxx:182
 TGeoTorus.cxx:183
 TGeoTorus.cxx:184
 TGeoTorus.cxx:185
 TGeoTorus.cxx:186
 TGeoTorus.cxx:187
 TGeoTorus.cxx:188
 TGeoTorus.cxx:189
 TGeoTorus.cxx:190
 TGeoTorus.cxx:191
 TGeoTorus.cxx:192
 TGeoTorus.cxx:193
 TGeoTorus.cxx:194
 TGeoTorus.cxx:195
 TGeoTorus.cxx:196
 TGeoTorus.cxx:197
 TGeoTorus.cxx:198
 TGeoTorus.cxx:199
 TGeoTorus.cxx:200
 TGeoTorus.cxx:201
 TGeoTorus.cxx:202
 TGeoTorus.cxx:203
 TGeoTorus.cxx:204
 TGeoTorus.cxx:205
 TGeoTorus.cxx:206
 TGeoTorus.cxx:207
 TGeoTorus.cxx:208
 TGeoTorus.cxx:209
 TGeoTorus.cxx:210
 TGeoTorus.cxx:211
 TGeoTorus.cxx:212
 TGeoTorus.cxx:213
 TGeoTorus.cxx:214
 TGeoTorus.cxx:215
 TGeoTorus.cxx:216
 TGeoTorus.cxx:217
 TGeoTorus.cxx:218
 TGeoTorus.cxx:219
 TGeoTorus.cxx:220
 TGeoTorus.cxx:221
 TGeoTorus.cxx:222
 TGeoTorus.cxx:223
 TGeoTorus.cxx:224
 TGeoTorus.cxx:225
 TGeoTorus.cxx:226
 TGeoTorus.cxx:227
 TGeoTorus.cxx:228
 TGeoTorus.cxx:229
 TGeoTorus.cxx:230
 TGeoTorus.cxx:231
 TGeoTorus.cxx:232
 TGeoTorus.cxx:233
 TGeoTorus.cxx:234
 TGeoTorus.cxx:235
 TGeoTorus.cxx:236
 TGeoTorus.cxx:237
 TGeoTorus.cxx:238
 TGeoTorus.cxx:239
 TGeoTorus.cxx:240
 TGeoTorus.cxx:241
 TGeoTorus.cxx:242
 TGeoTorus.cxx:243
 TGeoTorus.cxx:244
 TGeoTorus.cxx:245
 TGeoTorus.cxx:246
 TGeoTorus.cxx:247
 TGeoTorus.cxx:248
 TGeoTorus.cxx:249
 TGeoTorus.cxx:250
 TGeoTorus.cxx:251
 TGeoTorus.cxx:252
 TGeoTorus.cxx:253
 TGeoTorus.cxx:254
 TGeoTorus.cxx:255
 TGeoTorus.cxx:256
 TGeoTorus.cxx:257
 TGeoTorus.cxx:258
 TGeoTorus.cxx:259
 TGeoTorus.cxx:260
 TGeoTorus.cxx:261
 TGeoTorus.cxx:262
 TGeoTorus.cxx:263
 TGeoTorus.cxx:264
 TGeoTorus.cxx:265
 TGeoTorus.cxx:266
 TGeoTorus.cxx:267
 TGeoTorus.cxx:268
 TGeoTorus.cxx:269
 TGeoTorus.cxx:270
 TGeoTorus.cxx:271
 TGeoTorus.cxx:272
 TGeoTorus.cxx:273
 TGeoTorus.cxx:274
 TGeoTorus.cxx:275
 TGeoTorus.cxx:276
 TGeoTorus.cxx:277
 TGeoTorus.cxx:278
 TGeoTorus.cxx:279
 TGeoTorus.cxx:280
 TGeoTorus.cxx:281
 TGeoTorus.cxx:282
 TGeoTorus.cxx:283
 TGeoTorus.cxx:284
 TGeoTorus.cxx:285
 TGeoTorus.cxx:286
 TGeoTorus.cxx:287
 TGeoTorus.cxx:288
 TGeoTorus.cxx:289
 TGeoTorus.cxx:290
 TGeoTorus.cxx:291
 TGeoTorus.cxx:292
 TGeoTorus.cxx:293
 TGeoTorus.cxx:294
 TGeoTorus.cxx:295
 TGeoTorus.cxx:296
 TGeoTorus.cxx:297
 TGeoTorus.cxx:298
 TGeoTorus.cxx:299
 TGeoTorus.cxx:300
 TGeoTorus.cxx:301
 TGeoTorus.cxx:302
 TGeoTorus.cxx:303
 TGeoTorus.cxx:304
 TGeoTorus.cxx:305
 TGeoTorus.cxx:306
 TGeoTorus.cxx:307
 TGeoTorus.cxx:308
 TGeoTorus.cxx:309
 TGeoTorus.cxx:310
 TGeoTorus.cxx:311
 TGeoTorus.cxx:312
 TGeoTorus.cxx:313
 TGeoTorus.cxx:314
 TGeoTorus.cxx:315
 TGeoTorus.cxx:316
 TGeoTorus.cxx:317
 TGeoTorus.cxx:318
 TGeoTorus.cxx:319
 TGeoTorus.cxx:320
 TGeoTorus.cxx:321
 TGeoTorus.cxx:322
 TGeoTorus.cxx:323
 TGeoTorus.cxx:324
 TGeoTorus.cxx:325
 TGeoTorus.cxx:326
 TGeoTorus.cxx:327
 TGeoTorus.cxx:328
 TGeoTorus.cxx:329
 TGeoTorus.cxx:330
 TGeoTorus.cxx:331
 TGeoTorus.cxx:332
 TGeoTorus.cxx:333
 TGeoTorus.cxx:334
 TGeoTorus.cxx:335
 TGeoTorus.cxx:336
 TGeoTorus.cxx:337
 TGeoTorus.cxx:338
 TGeoTorus.cxx:339
 TGeoTorus.cxx:340
 TGeoTorus.cxx:341
 TGeoTorus.cxx:342
 TGeoTorus.cxx:343
 TGeoTorus.cxx:344
 TGeoTorus.cxx:345
 TGeoTorus.cxx:346
 TGeoTorus.cxx:347
 TGeoTorus.cxx:348
 TGeoTorus.cxx:349
 TGeoTorus.cxx:350
 TGeoTorus.cxx:351
 TGeoTorus.cxx:352
 TGeoTorus.cxx:353
 TGeoTorus.cxx:354
 TGeoTorus.cxx:355
 TGeoTorus.cxx:356
 TGeoTorus.cxx:357
 TGeoTorus.cxx:358
 TGeoTorus.cxx:359
 TGeoTorus.cxx:360
 TGeoTorus.cxx:361
 TGeoTorus.cxx:362
 TGeoTorus.cxx:363
 TGeoTorus.cxx:364
 TGeoTorus.cxx:365
 TGeoTorus.cxx:366
 TGeoTorus.cxx:367
 TGeoTorus.cxx:368
 TGeoTorus.cxx:369
 TGeoTorus.cxx:370
 TGeoTorus.cxx:371
 TGeoTorus.cxx:372
 TGeoTorus.cxx:373
 TGeoTorus.cxx:374
 TGeoTorus.cxx:375
 TGeoTorus.cxx:376
 TGeoTorus.cxx:377
 TGeoTorus.cxx:378
 TGeoTorus.cxx:379
 TGeoTorus.cxx:380
 TGeoTorus.cxx:381
 TGeoTorus.cxx:382
 TGeoTorus.cxx:383
 TGeoTorus.cxx:384
 TGeoTorus.cxx:385
 TGeoTorus.cxx:386
 TGeoTorus.cxx:387
 TGeoTorus.cxx:388
 TGeoTorus.cxx:389
 TGeoTorus.cxx:390
 TGeoTorus.cxx:391
 TGeoTorus.cxx:392
 TGeoTorus.cxx:393
 TGeoTorus.cxx:394
 TGeoTorus.cxx:395
 TGeoTorus.cxx:396
 TGeoTorus.cxx:397
 TGeoTorus.cxx:398
 TGeoTorus.cxx:399
 TGeoTorus.cxx:400
 TGeoTorus.cxx:401
 TGeoTorus.cxx:402
 TGeoTorus.cxx:403
 TGeoTorus.cxx:404
 TGeoTorus.cxx:405
 TGeoTorus.cxx:406
 TGeoTorus.cxx:407
 TGeoTorus.cxx:408
 TGeoTorus.cxx:409
 TGeoTorus.cxx:410
 TGeoTorus.cxx:411
 TGeoTorus.cxx:412
 TGeoTorus.cxx:413
 TGeoTorus.cxx:414
 TGeoTorus.cxx:415
 TGeoTorus.cxx:416
 TGeoTorus.cxx:417
 TGeoTorus.cxx:418
 TGeoTorus.cxx:419
 TGeoTorus.cxx:420
 TGeoTorus.cxx:421
 TGeoTorus.cxx:422
 TGeoTorus.cxx:423
 TGeoTorus.cxx:424
 TGeoTorus.cxx:425
 TGeoTorus.cxx:426
 TGeoTorus.cxx:427
 TGeoTorus.cxx:428
 TGeoTorus.cxx:429
 TGeoTorus.cxx:430
 TGeoTorus.cxx:431
 TGeoTorus.cxx:432
 TGeoTorus.cxx:433
 TGeoTorus.cxx:434
 TGeoTorus.cxx:435
 TGeoTorus.cxx:436
 TGeoTorus.cxx:437
 TGeoTorus.cxx:438
 TGeoTorus.cxx:439
 TGeoTorus.cxx:440
 TGeoTorus.cxx:441
 TGeoTorus.cxx:442
 TGeoTorus.cxx:443
 TGeoTorus.cxx:444
 TGeoTorus.cxx:445
 TGeoTorus.cxx:446
 TGeoTorus.cxx:447
 TGeoTorus.cxx:448
 TGeoTorus.cxx:449
 TGeoTorus.cxx:450
 TGeoTorus.cxx:451
 TGeoTorus.cxx:452
 TGeoTorus.cxx:453
 TGeoTorus.cxx:454
 TGeoTorus.cxx:455
 TGeoTorus.cxx:456
 TGeoTorus.cxx:457
 TGeoTorus.cxx:458
 TGeoTorus.cxx:459
 TGeoTorus.cxx:460
 TGeoTorus.cxx:461
 TGeoTorus.cxx:462
 TGeoTorus.cxx:463
 TGeoTorus.cxx:464
 TGeoTorus.cxx:465
 TGeoTorus.cxx:466
 TGeoTorus.cxx:467
 TGeoTorus.cxx:468
 TGeoTorus.cxx:469
 TGeoTorus.cxx:470
 TGeoTorus.cxx:471
 TGeoTorus.cxx:472
 TGeoTorus.cxx:473
 TGeoTorus.cxx:474
 TGeoTorus.cxx:475
 TGeoTorus.cxx:476
 TGeoTorus.cxx:477
 TGeoTorus.cxx:478
 TGeoTorus.cxx:479
 TGeoTorus.cxx:480
 TGeoTorus.cxx:481
 TGeoTorus.cxx:482
 TGeoTorus.cxx:483
 TGeoTorus.cxx:484
 TGeoTorus.cxx:485
 TGeoTorus.cxx:486
 TGeoTorus.cxx:487
 TGeoTorus.cxx:488
 TGeoTorus.cxx:489
 TGeoTorus.cxx:490
 TGeoTorus.cxx:491
 TGeoTorus.cxx:492
 TGeoTorus.cxx:493
 TGeoTorus.cxx:494
 TGeoTorus.cxx:495
 TGeoTorus.cxx:496
 TGeoTorus.cxx:497
 TGeoTorus.cxx:498
 TGeoTorus.cxx:499
 TGeoTorus.cxx:500
 TGeoTorus.cxx:501
 TGeoTorus.cxx:502
 TGeoTorus.cxx:503
 TGeoTorus.cxx:504
 TGeoTorus.cxx:505
 TGeoTorus.cxx:506
 TGeoTorus.cxx:507
 TGeoTorus.cxx:508
 TGeoTorus.cxx:509
 TGeoTorus.cxx:510
 TGeoTorus.cxx:511
 TGeoTorus.cxx:512
 TGeoTorus.cxx:513
 TGeoTorus.cxx:514
 TGeoTorus.cxx:515
 TGeoTorus.cxx:516
 TGeoTorus.cxx:517
 TGeoTorus.cxx:518
 TGeoTorus.cxx:519
 TGeoTorus.cxx:520
 TGeoTorus.cxx:521
 TGeoTorus.cxx:522
 TGeoTorus.cxx:523
 TGeoTorus.cxx:524
 TGeoTorus.cxx:525
 TGeoTorus.cxx:526
 TGeoTorus.cxx:527
 TGeoTorus.cxx:528
 TGeoTorus.cxx:529
 TGeoTorus.cxx:530
 TGeoTorus.cxx:531
 TGeoTorus.cxx:532
 TGeoTorus.cxx:533
 TGeoTorus.cxx:534
 TGeoTorus.cxx:535
 TGeoTorus.cxx:536
 TGeoTorus.cxx:537
 TGeoTorus.cxx:538
 TGeoTorus.cxx:539
 TGeoTorus.cxx:540
 TGeoTorus.cxx:541
 TGeoTorus.cxx:542
 TGeoTorus.cxx:543
 TGeoTorus.cxx:544
 TGeoTorus.cxx:545
 TGeoTorus.cxx:546
 TGeoTorus.cxx:547
 TGeoTorus.cxx:548
 TGeoTorus.cxx:549
 TGeoTorus.cxx:550
 TGeoTorus.cxx:551
 TGeoTorus.cxx:552
 TGeoTorus.cxx:553
 TGeoTorus.cxx:554
 TGeoTorus.cxx:555
 TGeoTorus.cxx:556
 TGeoTorus.cxx:557
 TGeoTorus.cxx:558
 TGeoTorus.cxx:559
 TGeoTorus.cxx:560
 TGeoTorus.cxx:561
 TGeoTorus.cxx:562
 TGeoTorus.cxx:563
 TGeoTorus.cxx:564
 TGeoTorus.cxx:565
 TGeoTorus.cxx:566
 TGeoTorus.cxx:567
 TGeoTorus.cxx:568
 TGeoTorus.cxx:569
 TGeoTorus.cxx:570
 TGeoTorus.cxx:571
 TGeoTorus.cxx:572
 TGeoTorus.cxx:573
 TGeoTorus.cxx:574
 TGeoTorus.cxx:575
 TGeoTorus.cxx:576
 TGeoTorus.cxx:577
 TGeoTorus.cxx:578
 TGeoTorus.cxx:579
 TGeoTorus.cxx:580
 TGeoTorus.cxx:581
 TGeoTorus.cxx:582
 TGeoTorus.cxx:583
 TGeoTorus.cxx:584
 TGeoTorus.cxx:585
 TGeoTorus.cxx:586
 TGeoTorus.cxx:587
 TGeoTorus.cxx:588
 TGeoTorus.cxx:589
 TGeoTorus.cxx:590
 TGeoTorus.cxx:591
 TGeoTorus.cxx:592
 TGeoTorus.cxx:593
 TGeoTorus.cxx:594
 TGeoTorus.cxx:595
 TGeoTorus.cxx:596
 TGeoTorus.cxx:597
 TGeoTorus.cxx:598
 TGeoTorus.cxx:599
 TGeoTorus.cxx:600
 TGeoTorus.cxx:601
 TGeoTorus.cxx:602
 TGeoTorus.cxx:603
 TGeoTorus.cxx:604
 TGeoTorus.cxx:605
 TGeoTorus.cxx:606
 TGeoTorus.cxx:607
 TGeoTorus.cxx:608
 TGeoTorus.cxx:609
 TGeoTorus.cxx:610
 TGeoTorus.cxx:611
 TGeoTorus.cxx:612
 TGeoTorus.cxx:613
 TGeoTorus.cxx:614
 TGeoTorus.cxx:615
 TGeoTorus.cxx:616
 TGeoTorus.cxx:617
 TGeoTorus.cxx:618
 TGeoTorus.cxx:619
 TGeoTorus.cxx:620
 TGeoTorus.cxx:621
 TGeoTorus.cxx:622
 TGeoTorus.cxx:623
 TGeoTorus.cxx:624
 TGeoTorus.cxx:625
 TGeoTorus.cxx:626
 TGeoTorus.cxx:627
 TGeoTorus.cxx:628
 TGeoTorus.cxx:629
 TGeoTorus.cxx:630
 TGeoTorus.cxx:631
 TGeoTorus.cxx:632
 TGeoTorus.cxx:633
 TGeoTorus.cxx:634
 TGeoTorus.cxx:635
 TGeoTorus.cxx:636
 TGeoTorus.cxx:637
 TGeoTorus.cxx:638
 TGeoTorus.cxx:639
 TGeoTorus.cxx:640
 TGeoTorus.cxx:641
 TGeoTorus.cxx:642
 TGeoTorus.cxx:643
 TGeoTorus.cxx:644
 TGeoTorus.cxx:645
 TGeoTorus.cxx:646
 TGeoTorus.cxx:647
 TGeoTorus.cxx:648
 TGeoTorus.cxx:649
 TGeoTorus.cxx:650
 TGeoTorus.cxx:651
 TGeoTorus.cxx:652
 TGeoTorus.cxx:653
 TGeoTorus.cxx:654
 TGeoTorus.cxx:655
 TGeoTorus.cxx:656
 TGeoTorus.cxx:657
 TGeoTorus.cxx:658
 TGeoTorus.cxx:659
 TGeoTorus.cxx:660
 TGeoTorus.cxx:661
 TGeoTorus.cxx:662
 TGeoTorus.cxx:663
 TGeoTorus.cxx:664
 TGeoTorus.cxx:665
 TGeoTorus.cxx:666
 TGeoTorus.cxx:667
 TGeoTorus.cxx:668
 TGeoTorus.cxx:669
 TGeoTorus.cxx:670
 TGeoTorus.cxx:671
 TGeoTorus.cxx:672
 TGeoTorus.cxx:673
 TGeoTorus.cxx:674
 TGeoTorus.cxx:675
 TGeoTorus.cxx:676
 TGeoTorus.cxx:677
 TGeoTorus.cxx:678
 TGeoTorus.cxx:679
 TGeoTorus.cxx:680
 TGeoTorus.cxx:681
 TGeoTorus.cxx:682
 TGeoTorus.cxx:683
 TGeoTorus.cxx:684
 TGeoTorus.cxx:685
 TGeoTorus.cxx:686
 TGeoTorus.cxx:687
 TGeoTorus.cxx:688
 TGeoTorus.cxx:689
 TGeoTorus.cxx:690
 TGeoTorus.cxx:691
 TGeoTorus.cxx:692
 TGeoTorus.cxx:693
 TGeoTorus.cxx:694
 TGeoTorus.cxx:695
 TGeoTorus.cxx:696
 TGeoTorus.cxx:697
 TGeoTorus.cxx:698
 TGeoTorus.cxx:699
 TGeoTorus.cxx:700
 TGeoTorus.cxx:701
 TGeoTorus.cxx:702
 TGeoTorus.cxx:703
 TGeoTorus.cxx:704
 TGeoTorus.cxx:705
 TGeoTorus.cxx:706
 TGeoTorus.cxx:707
 TGeoTorus.cxx:708
 TGeoTorus.cxx:709
 TGeoTorus.cxx:710
 TGeoTorus.cxx:711
 TGeoTorus.cxx:712
 TGeoTorus.cxx:713
 TGeoTorus.cxx:714
 TGeoTorus.cxx:715
 TGeoTorus.cxx:716
 TGeoTorus.cxx:717
 TGeoTorus.cxx:718
 TGeoTorus.cxx:719
 TGeoTorus.cxx:720
 TGeoTorus.cxx:721
 TGeoTorus.cxx:722
 TGeoTorus.cxx:723
 TGeoTorus.cxx:724
 TGeoTorus.cxx:725
 TGeoTorus.cxx:726
 TGeoTorus.cxx:727
 TGeoTorus.cxx:728
 TGeoTorus.cxx:729
 TGeoTorus.cxx:730
 TGeoTorus.cxx:731
 TGeoTorus.cxx:732
 TGeoTorus.cxx:733
 TGeoTorus.cxx:734
 TGeoTorus.cxx:735
 TGeoTorus.cxx:736
 TGeoTorus.cxx:737
 TGeoTorus.cxx:738
 TGeoTorus.cxx:739
 TGeoTorus.cxx:740
 TGeoTorus.cxx:741
 TGeoTorus.cxx:742
 TGeoTorus.cxx:743
 TGeoTorus.cxx:744
 TGeoTorus.cxx:745
 TGeoTorus.cxx:746
 TGeoTorus.cxx:747
 TGeoTorus.cxx:748
 TGeoTorus.cxx:749
 TGeoTorus.cxx:750
 TGeoTorus.cxx:751
 TGeoTorus.cxx:752
 TGeoTorus.cxx:753
 TGeoTorus.cxx:754
 TGeoTorus.cxx:755
 TGeoTorus.cxx:756
 TGeoTorus.cxx:757
 TGeoTorus.cxx:758
 TGeoTorus.cxx:759
 TGeoTorus.cxx:760
 TGeoTorus.cxx:761
 TGeoTorus.cxx:762
 TGeoTorus.cxx:763
 TGeoTorus.cxx:764
 TGeoTorus.cxx:765
 TGeoTorus.cxx:766
 TGeoTorus.cxx:767
 TGeoTorus.cxx:768
 TGeoTorus.cxx:769
 TGeoTorus.cxx:770
 TGeoTorus.cxx:771
 TGeoTorus.cxx:772
 TGeoTorus.cxx:773
 TGeoTorus.cxx:774
 TGeoTorus.cxx:775
 TGeoTorus.cxx:776
 TGeoTorus.cxx:777
 TGeoTorus.cxx:778
 TGeoTorus.cxx:779
 TGeoTorus.cxx:780
 TGeoTorus.cxx:781
 TGeoTorus.cxx:782
 TGeoTorus.cxx:783
 TGeoTorus.cxx:784
 TGeoTorus.cxx:785
 TGeoTorus.cxx:786
 TGeoTorus.cxx:787
 TGeoTorus.cxx:788
 TGeoTorus.cxx:789
 TGeoTorus.cxx:790
 TGeoTorus.cxx:791
 TGeoTorus.cxx:792
 TGeoTorus.cxx:793
 TGeoTorus.cxx:794
 TGeoTorus.cxx:795
 TGeoTorus.cxx:796
 TGeoTorus.cxx:797
 TGeoTorus.cxx:798
 TGeoTorus.cxx:799
 TGeoTorus.cxx:800
 TGeoTorus.cxx:801
 TGeoTorus.cxx:802
 TGeoTorus.cxx:803
 TGeoTorus.cxx:804
 TGeoTorus.cxx:805
 TGeoTorus.cxx:806
 TGeoTorus.cxx:807
 TGeoTorus.cxx:808
 TGeoTorus.cxx:809
 TGeoTorus.cxx:810
 TGeoTorus.cxx:811
 TGeoTorus.cxx:812
 TGeoTorus.cxx:813
 TGeoTorus.cxx:814
 TGeoTorus.cxx:815
 TGeoTorus.cxx:816
 TGeoTorus.cxx:817
 TGeoTorus.cxx:818
 TGeoTorus.cxx:819
 TGeoTorus.cxx:820
 TGeoTorus.cxx:821
 TGeoTorus.cxx:822
 TGeoTorus.cxx:823
 TGeoTorus.cxx:824
 TGeoTorus.cxx:825
 TGeoTorus.cxx:826
 TGeoTorus.cxx:827
 TGeoTorus.cxx:828
 TGeoTorus.cxx:829
 TGeoTorus.cxx:830
 TGeoTorus.cxx:831
 TGeoTorus.cxx:832
 TGeoTorus.cxx:833
 TGeoTorus.cxx:834
 TGeoTorus.cxx:835
 TGeoTorus.cxx:836
 TGeoTorus.cxx:837
 TGeoTorus.cxx:838
 TGeoTorus.cxx:839
 TGeoTorus.cxx:840
 TGeoTorus.cxx:841
 TGeoTorus.cxx:842
 TGeoTorus.cxx:843
 TGeoTorus.cxx:844
 TGeoTorus.cxx:845
 TGeoTorus.cxx:846
 TGeoTorus.cxx:847
 TGeoTorus.cxx:848
 TGeoTorus.cxx:849
 TGeoTorus.cxx:850
 TGeoTorus.cxx:851
 TGeoTorus.cxx:852
 TGeoTorus.cxx:853
 TGeoTorus.cxx:854
 TGeoTorus.cxx:855
 TGeoTorus.cxx:856
 TGeoTorus.cxx:857
 TGeoTorus.cxx:858
 TGeoTorus.cxx:859
 TGeoTorus.cxx:860
 TGeoTorus.cxx:861
 TGeoTorus.cxx:862
 TGeoTorus.cxx:863
 TGeoTorus.cxx:864
 TGeoTorus.cxx:865
 TGeoTorus.cxx:866
 TGeoTorus.cxx:867
 TGeoTorus.cxx:868
 TGeoTorus.cxx:869
 TGeoTorus.cxx:870
 TGeoTorus.cxx:871
 TGeoTorus.cxx:872
 TGeoTorus.cxx:873
 TGeoTorus.cxx:874
 TGeoTorus.cxx:875
 TGeoTorus.cxx:876
 TGeoTorus.cxx:877
 TGeoTorus.cxx:878
 TGeoTorus.cxx:879
 TGeoTorus.cxx:880
 TGeoTorus.cxx:881
 TGeoTorus.cxx:882
 TGeoTorus.cxx:883
 TGeoTorus.cxx:884
 TGeoTorus.cxx:885
 TGeoTorus.cxx:886
 TGeoTorus.cxx:887
 TGeoTorus.cxx:888
 TGeoTorus.cxx:889
 TGeoTorus.cxx:890
 TGeoTorus.cxx:891
 TGeoTorus.cxx:892
 TGeoTorus.cxx:893
 TGeoTorus.cxx:894
 TGeoTorus.cxx:895
 TGeoTorus.cxx:896
 TGeoTorus.cxx:897
 TGeoTorus.cxx:898
 TGeoTorus.cxx:899
 TGeoTorus.cxx:900
 TGeoTorus.cxx:901
 TGeoTorus.cxx:902
 TGeoTorus.cxx:903
 TGeoTorus.cxx:904
 TGeoTorus.cxx:905
 TGeoTorus.cxx:906
 TGeoTorus.cxx:907
 TGeoTorus.cxx:908
 TGeoTorus.cxx:909
 TGeoTorus.cxx:910
 TGeoTorus.cxx:911
 TGeoTorus.cxx:912
 TGeoTorus.cxx:913
 TGeoTorus.cxx:914
 TGeoTorus.cxx:915
 TGeoTorus.cxx:916
 TGeoTorus.cxx:917
 TGeoTorus.cxx:918
 TGeoTorus.cxx:919
 TGeoTorus.cxx:920
 TGeoTorus.cxx:921
 TGeoTorus.cxx:922
 TGeoTorus.cxx:923
 TGeoTorus.cxx:924
 TGeoTorus.cxx:925
 TGeoTorus.cxx:926
 TGeoTorus.cxx:927
 TGeoTorus.cxx:928
 TGeoTorus.cxx:929
 TGeoTorus.cxx:930
 TGeoTorus.cxx:931
 TGeoTorus.cxx:932
 TGeoTorus.cxx:933
 TGeoTorus.cxx:934
 TGeoTorus.cxx:935
 TGeoTorus.cxx:936
 TGeoTorus.cxx:937
 TGeoTorus.cxx:938
 TGeoTorus.cxx:939
 TGeoTorus.cxx:940
 TGeoTorus.cxx:941
 TGeoTorus.cxx:942
 TGeoTorus.cxx:943
 TGeoTorus.cxx:944
 TGeoTorus.cxx:945
 TGeoTorus.cxx:946
 TGeoTorus.cxx:947
 TGeoTorus.cxx:948
 TGeoTorus.cxx:949
 TGeoTorus.cxx:950
 TGeoTorus.cxx:951
 TGeoTorus.cxx:952
 TGeoTorus.cxx:953
 TGeoTorus.cxx:954
 TGeoTorus.cxx:955
 TGeoTorus.cxx:956
 TGeoTorus.cxx:957
 TGeoTorus.cxx:958
 TGeoTorus.cxx:959
 TGeoTorus.cxx:960
 TGeoTorus.cxx:961
 TGeoTorus.cxx:962
 TGeoTorus.cxx:963
 TGeoTorus.cxx:964
 TGeoTorus.cxx:965
 TGeoTorus.cxx:966
 TGeoTorus.cxx:967
 TGeoTorus.cxx:968
 TGeoTorus.cxx:969
 TGeoTorus.cxx:970
 TGeoTorus.cxx:971
 TGeoTorus.cxx:972
 TGeoTorus.cxx:973
 TGeoTorus.cxx:974
 TGeoTorus.cxx:975
 TGeoTorus.cxx:976
 TGeoTorus.cxx:977
 TGeoTorus.cxx:978
 TGeoTorus.cxx:979
 TGeoTorus.cxx:980
 TGeoTorus.cxx:981
 TGeoTorus.cxx:982
 TGeoTorus.cxx:983
 TGeoTorus.cxx:984
 TGeoTorus.cxx:985
 TGeoTorus.cxx:986
 TGeoTorus.cxx:987
 TGeoTorus.cxx:988
 TGeoTorus.cxx:989
 TGeoTorus.cxx:990
 TGeoTorus.cxx:991
 TGeoTorus.cxx:992
 TGeoTorus.cxx:993
 TGeoTorus.cxx:994
 TGeoTorus.cxx:995
 TGeoTorus.cxx:996
 TGeoTorus.cxx:997
 TGeoTorus.cxx:998
 TGeoTorus.cxx:999
 TGeoTorus.cxx:1000
 TGeoTorus.cxx:1001
 TGeoTorus.cxx:1002
 TGeoTorus.cxx:1003
 TGeoTorus.cxx:1004
 TGeoTorus.cxx:1005
 TGeoTorus.cxx:1006
 TGeoTorus.cxx:1007
 TGeoTorus.cxx:1008
 TGeoTorus.cxx:1009
 TGeoTorus.cxx:1010
 TGeoTorus.cxx:1011
 TGeoTorus.cxx:1012
 TGeoTorus.cxx:1013
 TGeoTorus.cxx:1014
 TGeoTorus.cxx:1015
 TGeoTorus.cxx:1016
 TGeoTorus.cxx:1017
 TGeoTorus.cxx:1018
 TGeoTorus.cxx:1019
 TGeoTorus.cxx:1020
 TGeoTorus.cxx:1021
 TGeoTorus.cxx:1022
 TGeoTorus.cxx:1023
 TGeoTorus.cxx:1024
 TGeoTorus.cxx:1025
 TGeoTorus.cxx:1026
 TGeoTorus.cxx:1027
 TGeoTorus.cxx:1028
 TGeoTorus.cxx:1029
 TGeoTorus.cxx:1030
 TGeoTorus.cxx:1031
 TGeoTorus.cxx:1032
 TGeoTorus.cxx:1033
 TGeoTorus.cxx:1034
 TGeoTorus.cxx:1035
 TGeoTorus.cxx:1036
 TGeoTorus.cxx:1037
 TGeoTorus.cxx:1038
 TGeoTorus.cxx:1039
 TGeoTorus.cxx:1040
 TGeoTorus.cxx:1041
 TGeoTorus.cxx:1042
 TGeoTorus.cxx:1043
 TGeoTorus.cxx:1044
 TGeoTorus.cxx:1045
 TGeoTorus.cxx:1046
 TGeoTorus.cxx:1047
 TGeoTorus.cxx:1048
 TGeoTorus.cxx:1049
 TGeoTorus.cxx:1050
 TGeoTorus.cxx:1051
 TGeoTorus.cxx:1052
 TGeoTorus.cxx:1053
 TGeoTorus.cxx:1054
 TGeoTorus.cxx:1055
 TGeoTorus.cxx:1056
 TGeoTorus.cxx:1057
 TGeoTorus.cxx:1058
 TGeoTorus.cxx:1059
 TGeoTorus.cxx:1060
 TGeoTorus.cxx:1061
 TGeoTorus.cxx:1062
 TGeoTorus.cxx:1063
 TGeoTorus.cxx:1064
 TGeoTorus.cxx:1065
 TGeoTorus.cxx:1066
 TGeoTorus.cxx:1067
 TGeoTorus.cxx:1068
 TGeoTorus.cxx:1069
 TGeoTorus.cxx:1070
 TGeoTorus.cxx:1071
 TGeoTorus.cxx:1072
 TGeoTorus.cxx:1073
 TGeoTorus.cxx:1074
 TGeoTorus.cxx:1075
 TGeoTorus.cxx:1076
 TGeoTorus.cxx:1077
 TGeoTorus.cxx:1078
 TGeoTorus.cxx:1079
 TGeoTorus.cxx:1080
 TGeoTorus.cxx:1081
 TGeoTorus.cxx:1082
 TGeoTorus.cxx:1083
 TGeoTorus.cxx:1084
 TGeoTorus.cxx:1085
 TGeoTorus.cxx:1086
 TGeoTorus.cxx:1087
 TGeoTorus.cxx:1088
 TGeoTorus.cxx:1089
 TGeoTorus.cxx:1090
 TGeoTorus.cxx:1091
 TGeoTorus.cxx:1092
 TGeoTorus.cxx:1093
 TGeoTorus.cxx:1094
 TGeoTorus.cxx:1095
 TGeoTorus.cxx:1096
 TGeoTorus.cxx:1097
 TGeoTorus.cxx:1098
 TGeoTorus.cxx:1099
 TGeoTorus.cxx:1100
 TGeoTorus.cxx:1101
 TGeoTorus.cxx:1102
 TGeoTorus.cxx:1103
 TGeoTorus.cxx:1104
 TGeoTorus.cxx:1105
 TGeoTorus.cxx:1106
 TGeoTorus.cxx:1107
 TGeoTorus.cxx:1108
 TGeoTorus.cxx:1109
 TGeoTorus.cxx:1110
 TGeoTorus.cxx:1111
 TGeoTorus.cxx:1112
 TGeoTorus.cxx:1113
 TGeoTorus.cxx:1114
 TGeoTorus.cxx:1115
 TGeoTorus.cxx:1116
 TGeoTorus.cxx:1117
 TGeoTorus.cxx:1118
 TGeoTorus.cxx:1119
 TGeoTorus.cxx:1120
 TGeoTorus.cxx:1121
 TGeoTorus.cxx:1122
 TGeoTorus.cxx:1123
 TGeoTorus.cxx:1124
 TGeoTorus.cxx:1125
 TGeoTorus.cxx:1126
 TGeoTorus.cxx:1127
 TGeoTorus.cxx:1128
 TGeoTorus.cxx:1129
 TGeoTorus.cxx:1130
 TGeoTorus.cxx:1131
 TGeoTorus.cxx:1132
 TGeoTorus.cxx:1133
 TGeoTorus.cxx:1134
 TGeoTorus.cxx:1135
 TGeoTorus.cxx:1136
 TGeoTorus.cxx:1137
 TGeoTorus.cxx:1138
 TGeoTorus.cxx:1139
 TGeoTorus.cxx:1140
 TGeoTorus.cxx:1141
 TGeoTorus.cxx:1142
 TGeoTorus.cxx:1143
 TGeoTorus.cxx:1144
 TGeoTorus.cxx:1145
 TGeoTorus.cxx:1146
 TGeoTorus.cxx:1147
 TGeoTorus.cxx:1148
 TGeoTorus.cxx:1149
 TGeoTorus.cxx:1150
 TGeoTorus.cxx:1151
 TGeoTorus.cxx:1152
 TGeoTorus.cxx:1153
 TGeoTorus.cxx:1154
 TGeoTorus.cxx:1155
 TGeoTorus.cxx:1156
 TGeoTorus.cxx:1157
 TGeoTorus.cxx:1158
 TGeoTorus.cxx:1159
 TGeoTorus.cxx:1160
 TGeoTorus.cxx:1161
 TGeoTorus.cxx:1162
 TGeoTorus.cxx:1163
 TGeoTorus.cxx:1164
 TGeoTorus.cxx:1165
 TGeoTorus.cxx:1166
 TGeoTorus.cxx:1167
 TGeoTorus.cxx:1168
 TGeoTorus.cxx:1169
 TGeoTorus.cxx:1170
 TGeoTorus.cxx:1171
 TGeoTorus.cxx:1172
 TGeoTorus.cxx:1173
 TGeoTorus.cxx:1174
 TGeoTorus.cxx:1175
 TGeoTorus.cxx:1176
 TGeoTorus.cxx:1177
 TGeoTorus.cxx:1178
 TGeoTorus.cxx:1179
 TGeoTorus.cxx:1180
 TGeoTorus.cxx:1181
 TGeoTorus.cxx:1182
 TGeoTorus.cxx:1183
 TGeoTorus.cxx:1184
 TGeoTorus.cxx:1185
 TGeoTorus.cxx:1186
 TGeoTorus.cxx:1187
 TGeoTorus.cxx:1188