#include "TList.h"
#include "TObjArray.h"
#include "TGeoManager.h"
#include "TGeoElement.h"
#include "TGeoMaterial.h"
#include "TGeoMedium.h"
#include "TGeoMatrix.h"
#include "TGeoPara.h"
#include "TGeoParaboloid.h"
#include "TGeoTube.h"
#include "TGeoEltu.h"
#include "TGeoHype.h"
#include "TGeoCone.h"
#include "TGeoSphere.h"
#include "TGeoArb8.h"
#include "TGeoPgon.h"
#include "TGeoTrd1.h"
#include "TGeoTrd2.h"
#include "TGeoTorus.h"
#include "TGeoXtru.h"
#include "TGeoNode.h"
#include "TGeoVolume.h"
#include "TGeoBuilder.h"
ClassImp(TGeoBuilder)
TGeoBuilder *TGeoBuilder::fgInstance = NULL;
TGeoBuilder::TGeoBuilder()
            :fGeometry(NULL)
{
   fgInstance = this;
} 
TGeoBuilder::TGeoBuilder(const TGeoBuilder& other)
            :TObject(other)
{
   Error("copy constructor","copying not allowed for TGeoBuilder");
} 
TGeoBuilder::~TGeoBuilder()
{
   fgInstance = NULL;
}   
TGeoBuilder &TGeoBuilder::operator=(const TGeoBuilder&)
{
   Error("Assignment","assignment not allowed for TGeoBuilder");
   return *this;
}
TGeoBuilder *TGeoBuilder::Instance(TGeoManager *geom) 
{
   if (!geom) {
      printf("ERROR: Cannot create geometry builder with NULL geometry\n");
      return NULL;
   }   
   if (!fgInstance) fgInstance = new TGeoBuilder();
   fgInstance->SetGeometry(geom);
   return fgInstance;
}   
Int_t TGeoBuilder::AddMaterial(TGeoMaterial *material)
{
   if (!material) return -1;
   TList *materials = fGeometry->GetListOfMaterials();
   if (materials->FindObject(material)) {
      Warning("AddMaterial", "Material %s already registered at index %d", 
              material->GetName(), material->GetIndex());
      return material->GetIndex();
   }   
   Int_t index = materials->GetSize();
   material->SetIndex(index);
   materials->Add(material);
   return index;
}
Int_t TGeoBuilder::AddTransformation(TGeoMatrix *matrix)
{
   Int_t index = -1;
   if (!matrix) return -1;
   TObjArray *matrices = fGeometry->GetListOfMatrices();
   index = matrices->IndexOf(matrix);
   if (index >= 0) {
      Warning("AddTransformation", "Matrix %s already registered at index %d", 
              matrix->GetName(), index);
      return index;
   }   
   index = matrices->GetEntriesFast();
   matrices->AddAtAndExpand(matrix,index);
   return index;
}
Int_t TGeoBuilder::AddShape(TGeoShape *shape)
{
   Int_t index = -1;
   if (!shape) return -1;
   TObjArray *shapes = fGeometry->GetListOfShapes();
   if (shape->IsRunTimeShape()) shapes =  fGeometry->GetListOfGShapes();
   index = shapes->IndexOf(shape);
   if (index >= 0) {
      Warning("AddShape", "Shape %s already registered at index %d", 
              shape->GetName(), index);
      return index;
   }   
   index = shapes->GetEntriesFast();
   shapes->AddAtAndExpand(shape,index);
   return index;
}
void TGeoBuilder::RegisterMatrix(TGeoMatrix *matrix)
{
   if (matrix->IsRegistered()) return;
   TObjArray *matrices = fGeometry->GetListOfMatrices();   
   Int_t nmat = matrices->GetEntriesFast();
   matrices->AddAtAndExpand(matrix, nmat);
}
TGeoVolume *TGeoBuilder::MakeArb8(const char *name, const TGeoMedium *medium,
                                  Double_t dz, Double_t *vertices)
{
   TGeoArb8 *arb = new TGeoArb8(dz, vertices);
   TGeoVolume *vol = new TGeoVolume(name, arb, medium);
   return vol;
}
TGeoVolume *TGeoBuilder::MakeBox(const char *name, const TGeoMedium *medium,
                                    Double_t dx, Double_t dy, Double_t dz)
{
   TGeoBBox *box = new TGeoBBox(dx, dy, dz);
   TGeoVolume *vol = 0;
   if (box->IsRunTimeShape()) {
      vol = fGeometry->MakeVolumeMulti(name, medium);
      vol->SetShape(box);
   } else {
      vol = new TGeoVolume(name, box, medium);
   }
   return vol;
}
TGeoVolume *TGeoBuilder::MakePara(const char *name, const TGeoMedium *medium,
                                    Double_t dx, Double_t dy, Double_t dz,
                                    Double_t alpha, Double_t theta, Double_t phi)
{
   if ((alpha==0) && (theta==0)) {
      Warning("MakePara","parallelipiped %s having alpha=0, theta=0 -> making box instead", name);
      return MakeBox(name, medium, dx, dy, dz);
   }
   TGeoPara *para=0;
   para = new TGeoPara(dx, dy, dz, alpha, theta, phi);
   TGeoVolume *vol = 0;
   if (para->IsRunTimeShape()) {
      vol = fGeometry->MakeVolumeMulti(name, medium);
      vol->SetShape(para);
   } else {
      vol = new TGeoVolume(name, para, medium);
   }
   return vol;
}
TGeoVolume *TGeoBuilder::MakeSphere(const char *name, const TGeoMedium *medium,
                                    Double_t rmin, Double_t rmax, Double_t themin, Double_t themax,
                                    Double_t phimin, Double_t phimax)
{
   TGeoSphere *sph = new TGeoSphere(rmin, rmax, themin, themax, phimin, phimax);
   TGeoVolume *vol = new TGeoVolume(name, sph, medium);
   return vol;
}
TGeoVolume *TGeoBuilder::MakeTorus(const char *name, const TGeoMedium *medium, Double_t r,
                                   Double_t rmin, Double_t rmax, Double_t phi1, Double_t dphi)
{
   TGeoTorus *tor = new TGeoTorus(name,r,rmin,rmax,phi1,dphi);
   TGeoVolume *vol = new TGeoVolume(name, tor, medium);
   return vol;
}
TGeoVolume *TGeoBuilder::MakeTube(const char *name, const TGeoMedium *medium,
                                     Double_t rmin, Double_t rmax, Double_t dz)
{
   if (rmin>rmax) {
      Error("MakeTube", "tube %s, Rmin=%g greater than Rmax=%g", name,rmin,rmax);
   }
   TGeoTube *tube = new TGeoTube(rmin, rmax, dz);
   TGeoVolume *vol = 0;
   if (tube->IsRunTimeShape()) {
      vol = fGeometry->MakeVolumeMulti(name, medium);
      vol->SetShape(tube);
   } else {
      vol = new TGeoVolume(name, tube, medium);
   }
   return vol;
}
TGeoVolume *TGeoBuilder::MakeTubs(const char *name, const TGeoMedium *medium,
                                     Double_t rmin, Double_t rmax, Double_t dz,
                                     Double_t phi1, Double_t phi2)
{
   TGeoTubeSeg *tubs = new TGeoTubeSeg(rmin, rmax, dz, phi1, phi2);
   TGeoVolume *vol = 0;
   if (tubs->IsRunTimeShape()) {
      vol = fGeometry->MakeVolumeMulti(name, medium);
      vol->SetShape(tubs);
   } else {
      vol = new TGeoVolume(name, tubs, medium);
   }
   return vol;
}
TGeoVolume *TGeoBuilder::MakeEltu(const char *name, const TGeoMedium *medium,
                                     Double_t a, Double_t b, Double_t dz)
{
   TGeoEltu *eltu = new TGeoEltu(a, b, dz);
   TGeoVolume *vol = 0;
   if (eltu->IsRunTimeShape()) {
      vol = fGeometry->MakeVolumeMulti(name, medium);
      vol->SetShape(eltu);
   } else {
      vol = new TGeoVolume(name, eltu, medium);
   }
   return vol;
}
TGeoVolume *TGeoBuilder::MakeHype(const char *name, const TGeoMedium *medium,
                                        Double_t rin, Double_t stin, Double_t rout, Double_t stout, Double_t dz)
{
   TGeoHype * hype =  new TGeoHype(name, rin,stin,rout,stout,dz);
   TGeoVolume *vol = 0;
   if (hype->IsRunTimeShape()) {
      vol = fGeometry->MakeVolumeMulti(name, medium);
      vol->SetShape(hype);
   } else {
      vol = new TGeoVolume(name, hype, medium);
   }
   return vol;
}
TGeoVolume *TGeoBuilder::MakeParaboloid(const char *name, const TGeoMedium *medium,
                                        Double_t rlo, Double_t rhi, Double_t dz)
{
   TGeoParaboloid *parab = new TGeoParaboloid(rlo, rhi, dz);
   TGeoVolume *vol = 0;
   if (parab->IsRunTimeShape()) {
      vol = fGeometry->MakeVolumeMulti(name, medium);
      vol->SetShape(parab);
   } else {
      vol = new TGeoVolume(name, parab, medium);
   }
   return vol;
}
TGeoVolume *TGeoBuilder::MakeCtub(const char *name, const TGeoMedium *medium,
                                     Double_t rmin, Double_t rmax, Double_t dz, Double_t phi1, Double_t phi2,
                                     Double_t lx, Double_t ly, Double_t lz, Double_t tx, Double_t ty, Double_t tz)
{
   TGeoCtub *ctub = new TGeoCtub(rmin, rmax, dz, phi1, phi2, lx, ly, lz, tx, ty, tz);
   TGeoVolume *vol = new TGeoVolume(name, ctub, medium);
   return vol;
}
TGeoVolume *TGeoBuilder::MakeCone(const char *name, const TGeoMedium *medium,
                                     Double_t dz, Double_t rmin1, Double_t rmax1,
                                     Double_t rmin2, Double_t rmax2)
{
   TGeoCone *cone = new TGeoCone(dz, rmin1, rmax1, rmin2, rmax2);
   TGeoVolume *vol = 0;
   if (cone->IsRunTimeShape()) {
      vol = fGeometry->MakeVolumeMulti(name, medium);
      vol->SetShape(cone);
   } else {
      vol = new TGeoVolume(name, cone, medium);
   }
   return vol;
}
TGeoVolume *TGeoBuilder::MakeCons(const char *name, const TGeoMedium *medium,
                                     Double_t dz, Double_t rmin1, Double_t rmax1,
                                     Double_t rmin2, Double_t rmax2,
                                     Double_t phi1, Double_t phi2)
{
   TGeoConeSeg *cons = new TGeoConeSeg(dz, rmin1, rmax1, rmin2, rmax2, phi1, phi2);
   TGeoVolume *vol = 0;
   if (cons->IsRunTimeShape()) {
      vol = fGeometry->MakeVolumeMulti(name, medium);
      vol->SetShape(cons);
   } else {
      vol = new TGeoVolume(name, cons, medium);
   }
   return vol;
}
TGeoVolume *TGeoBuilder::MakePcon(const char *name, const TGeoMedium *medium,
                                     Double_t phi, Double_t dphi, Int_t nz)
{
   TGeoPcon *pcon = new TGeoPcon(phi, dphi, nz);
   TGeoVolume *vol = new TGeoVolume(name, pcon, medium);
   return vol;
}
TGeoVolume *TGeoBuilder::MakePgon(const char *name, const TGeoMedium *medium,
                                     Double_t phi, Double_t dphi, Int_t nedges, Int_t nz)
{
   TGeoPgon *pgon = new TGeoPgon(phi, dphi, nedges, nz);
   TGeoVolume *vol = new TGeoVolume(name, pgon, medium);
   return vol;
}
TGeoVolume *TGeoBuilder::MakeTrd1(const char *name, const TGeoMedium *medium,
                                  Double_t dx1, Double_t dx2, Double_t dy, Double_t dz)
{
   TGeoTrd1 *trd1 = new TGeoTrd1(dx1, dx2, dy, dz);
   TGeoVolume *vol = 0;
   if (trd1->IsRunTimeShape()) {
      vol = fGeometry->MakeVolumeMulti(name, medium);
      vol->SetShape(trd1);
   } else {
      vol = new TGeoVolume(name, trd1, medium);
   }
   return vol;
}
TGeoVolume *TGeoBuilder::MakeTrd2(const char *name, const TGeoMedium *medium,
                                  Double_t dx1, Double_t dx2, Double_t dy1, Double_t dy2,
                                  Double_t dz)
{
   TGeoTrd2 *trd2 = new TGeoTrd2(dx1, dx2, dy1, dy2, dz);
   TGeoVolume *vol = 0;
   if (trd2->IsRunTimeShape()) {
      vol = fGeometry->MakeVolumeMulti(name, medium);
      vol->SetShape(trd2);
   } else {
      vol = new TGeoVolume(name, trd2, medium);
   }
   return vol;
}
TGeoVolume *TGeoBuilder::MakeTrap(const char *name, const TGeoMedium *medium,
                                  Double_t dz, Double_t theta, Double_t phi, Double_t h1,
                                  Double_t bl1, Double_t tl1, Double_t alpha1, Double_t h2, Double_t bl2,
                                  Double_t tl2, Double_t alpha2)
{
   TGeoTrap *trap = new TGeoTrap(dz, theta, phi, h1, bl1, tl1, alpha1, h2, bl2,
                                 tl2, alpha2);
   TGeoVolume *vol = new TGeoVolume(name, trap, medium);
   return vol;
}
TGeoVolume *TGeoBuilder::MakeGtra(const char *name, const TGeoMedium *medium,
                                  Double_t dz, Double_t theta, Double_t phi, Double_t twist, Double_t h1,
                                  Double_t bl1, Double_t tl1, Double_t alpha1, Double_t h2, Double_t bl2,
                                  Double_t tl2, Double_t alpha2)
{
   TGeoGtra *gtra = new TGeoGtra(dz, theta, phi, twist, h1, bl1, tl1, alpha1, h2, bl2,
                                 tl2, alpha2);
   TGeoVolume *vol = new TGeoVolume(name, gtra, medium);
   return vol;
}
TGeoVolume *TGeoBuilder::MakeXtru(const char *name, const TGeoMedium *medium, Int_t nz)
{
   TGeoXtru *xtru = new TGeoXtru(nz);
   TGeoVolume *vol = new TGeoVolume(name, xtru, medium);
   return vol;
}
TGeoVolumeAssembly *TGeoBuilder::MakeVolumeAssembly(const char *name)
{
   return (new TGeoVolumeAssembly(name));
}
TGeoVolumeMulti *TGeoBuilder::MakeVolumeMulti(const char *name, const TGeoMedium *medium)
{
   return (new TGeoVolumeMulti(name, medium));
}
TGeoVolume *TGeoBuilder::Division(const char *name, const char *mother, Int_t iaxis,
                                  Int_t ndiv, Double_t start, Double_t step, Int_t numed, Option_t *option)
{
   TGeoVolume *amother;
   TString sname = name;
   sname = sname.Strip();
   const char *vname = sname.Data();
   TString smname = mother;
   smname = smname.Strip();
   const char *mname = smname.Data();
   
   amother = (TGeoVolume*)fGeometry->GetListOfGVolumes()->FindObject(mname);
   if (!amother) amother = fGeometry->GetVolume(mname);
   if (amother) return amother->Divide(vname,iaxis,ndiv,start,step,numed, option);
   Error("Division","VOLUME: \"%s\" not defined",mname);
   return 0;
}
void TGeoBuilder::Matrix(Int_t index, Double_t theta1, Double_t phi1,
                         Double_t theta2, Double_t phi2,
                         Double_t theta3, Double_t phi3)
{
   TGeoRotation * rot = new TGeoRotation("",theta1,phi1,theta2,phi2,theta3,phi3);
   rot->SetUniqueID(index);
   rot->RegisterYourself();
}
TGeoMaterial *TGeoBuilder::Material(const char *name, Double_t a, Double_t z, Double_t dens, Int_t uid,Double_t radlen, Double_t intlen)
{
   TGeoMaterial *material = new TGeoMaterial(name,a,z,dens,radlen,intlen);
   material->SetUniqueID(uid);
   return material;
}
TGeoMaterial *TGeoBuilder::Mixture(const char *name, Float_t *a, Float_t *z, Double_t dens,
                                   Int_t nelem, Float_t *wmat, Int_t uid)
{
   TGeoMixture *mix = new TGeoMixture(name,nelem,dens);
   mix->SetUniqueID(uid);
   Int_t i;
   for (i=0;i<nelem;i++) {
      mix->DefineElement(i,a[i],z[i],wmat[i]);
   }
   return (TGeoMaterial*)mix;
}
TGeoMaterial *TGeoBuilder::Mixture(const char *name, Double_t *a, Double_t *z, Double_t dens,
                                   Int_t nelem, Double_t *wmat, Int_t uid)
{
   TGeoMixture *mix = new TGeoMixture(name,nelem,dens);
   mix->SetUniqueID(uid);
   Int_t i;
   for (i=0;i<nelem;i++) {
      mix->DefineElement(i,a[i],z[i],wmat[i]);
   }
   return (TGeoMaterial*)mix;
}
TGeoMedium *TGeoBuilder::Medium(const char *name, Int_t numed, Int_t nmat, Int_t isvol,
                                Int_t ifield, Double_t fieldm, Double_t tmaxfd,
                                Double_t stemax, Double_t deemax, Double_t epsil,
                                Double_t stmin)
{
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
   return new TGeoMedium(name,numed,nmat,isvol,ifield,fieldm,tmaxfd,stemax,deemax,epsil,stmin);
}
void TGeoBuilder::Node(const char *name, Int_t nr, const char *mother,
                       Double_t x, Double_t y, Double_t z, Int_t irot,
                       Bool_t isOnly, Float_t *upar, Int_t npar)
{
   TGeoVolume *amother= 0;
   TGeoVolume *volume = 0;
   
   
   amother = fGeometry->FindVolumeFast(mother,kTRUE);
   if (!amother) amother = fGeometry->FindVolumeFast(mother);
   if (!amother) {
      TString mname = mother;
      mname = mname.Strip();
      Error("Node","Mother VOLUME \"%s\" not defined",mname.Data());
      return;
   }
   Int_t i;
   if (npar<=0) {
   
      if (gDebug > 0) Info("Node","Calling gspos, mother=%s, name=%s, nr=%d, x=%g, y=%g, z=%g, irot=%d, konly=%i",mother,name,nr,x,y,z,irot,(Int_t)isOnly);
      
      volume  = fGeometry->FindVolumeFast(name,kTRUE);
      if (!volume) volume = fGeometry->FindVolumeFast(name);
      if (!volume) {
         TString vname = name;
         vname = vname.Strip();
         Error("Node","VOLUME: \"%s\" not defined",vname.Data());
         return;
      }
      if (((TObject*)volume)->TestBit(TGeoVolume::kVolumeMulti) && !volume->GetShape()) {
         Error("Node", "cannot add multiple-volume object %s as node", volume->GetName());
         return;
      }
   } else {
   
      TGeoVolumeMulti *vmulti  = (TGeoVolumeMulti*)fGeometry->FindVolumeFast(name, kTRUE);
      if (!vmulti) {
         volume = fGeometry->FindVolumeFast(name);
         if (volume) {
            Warning("Node", "volume: %s is defined as single -> ignoring shape parameters", volume->GetName());
            Node(name,nr,mother,x,y,z,irot,isOnly, upar);
            return;
         }
         TString vname = name;
         vname = vname.Strip();         
         Error("Node","VOLUME: \"%s\" not defined ",vname.Data());
         return;
      }
      TGeoMedium *medium = vmulti->GetMedium();
      TString sh    = vmulti->GetTitle();
      sh.ToLower();
      if (sh.Contains("box")) {
         volume = MakeBox(name,medium,upar[0],upar[1],upar[2]);
      } else if (sh.Contains("trd1")) {
         volume = MakeTrd1(name,medium,upar[0],upar[1],upar[2],upar[3]);
      } else if (sh.Contains("trd2")) {
         volume = MakeTrd2(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4]);
      } else if (sh.Contains("trap")) {
         volume = MakeTrap(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5],upar[6],upar[7],upar[8],upar[9],upar[10]);
      } else if (sh.Contains("gtra")) {
         volume = MakeGtra(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5],upar[6],upar[7],upar[8],upar[9],upar[10],upar[11]);
      } else if (sh.Contains("tube")) {
         volume = MakeTube(name,medium,upar[0],upar[1],upar[2]);
      } else if (sh.Contains("tubs")) {
         volume = MakeTubs(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4]);
      } else if (sh.Contains("cone")) {
         volume = MakeCone(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4]);
      } else if (sh.Contains("cons")) {
         volume = MakeCons(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5],upar[6]);
      } else if (sh.Contains("pgon")) {
         volume = MakePgon(name,medium,upar[0],upar[1],(Int_t)upar[2],(Int_t)upar[3]);
         Int_t nz = (Int_t)upar[3];
         for (i=0;i<nz;i++) {
            ((TGeoPgon*)volume->GetShape())->DefineSection(i,upar[3*i+4],upar[3*i+5],upar[3*i+6]);
         }
      } else if (sh.Contains("pcon")) {
         volume = MakePcon(name,medium,upar[0],upar[1],(Int_t)upar[2]);
         Int_t nz = (Int_t)upar[2];
         for (i=0;i<nz;i++) {
            ((TGeoPcon*)volume->GetShape())->DefineSection(i,upar[3*i+3],upar[3*i+4],upar[3*i+5]);
         }
      } else if (sh.Contains("eltu")) {
         volume = MakeEltu(name,medium,upar[0],upar[1],upar[2]);
      } else if (sh.Contains("sphe")) {
         volume = MakeSphere(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5]);
      } else if (sh.Contains("ctub")) {
         volume = MakeCtub(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5],upar[6],upar[7],upar[8],upar[9],upar[10]);
      } else if (sh.Contains("para")) {
         volume = MakePara(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5]);
      } else {
         Error("Node","cannot create shape %s",sh.Data());
      }
      if (!volume) return;
      vmulti->AddVolume(volume);
   }
   if (irot) {
      TGeoRotation *matrix = 0;
      TGeoMatrix *mat;
      TIter next(fGeometry->GetListOfMatrices());
      while ((mat=(TGeoMatrix*)next())) {
         if (mat->GetUniqueID()==UInt_t(irot)) {
            matrix = dynamic_cast<TGeoRotation*>(mat);
            break;
         }
      }
      if (!matrix) {
         Error("Node", "rotation %i not found", irot);
         return;
      }
      if (isOnly) amother->AddNode(volume,nr,new TGeoCombiTrans(x,y,z,matrix));
      else        amother->AddNodeOverlap(volume,nr,new TGeoCombiTrans(x,y,z,matrix));
   } else {
      if (x == 0 && y== 0 && z == 0) {
         if (isOnly) amother->AddNode(volume,nr);
         else        amother->AddNodeOverlap(volume,nr);
      } else {
         if (isOnly) amother->AddNode(volume,nr,new TGeoTranslation(x,y,z));
         else        amother->AddNodeOverlap(volume,nr,new TGeoTranslation(x,y,z));
      }
   }
}
void TGeoBuilder::Node(const char *name, Int_t nr, const char *mother,
                       Double_t x, Double_t y, Double_t z, Int_t irot,
                       Bool_t isOnly, Double_t *upar, Int_t npar)
{
   TGeoVolume *amother= 0;
   TGeoVolume *volume = 0;
   
   
   amother = fGeometry->FindVolumeFast(mother,kTRUE);
   if (!amother) amother = fGeometry->FindVolumeFast(mother);
   if (!amother) {
      TString mname = mother;
      mname = mname.Strip();
      Error("Node","Mother VOLUME \"%s\" not defined",mname.Data());
      return;
   }
   Int_t i;
   if (npar<=0) {
   
      if (gDebug > 0) Info("Node","Calling gspos, mother=%s, name=%s, nr=%d, x=%g, y=%g, z=%g, irot=%d, konly=%i",mother,name,nr,x,y,z,irot,(Int_t)isOnly);
      
      volume  = fGeometry->FindVolumeFast(name,kTRUE);
      if (!volume) volume = fGeometry->FindVolumeFast(name);
      if (!volume) {
         TString vname = name;
         vname = vname.Strip();
         Error("Node","VOLUME: \"%s\" not defined",vname.Data());
         return;
      }
      if (((TObject*)volume)->TestBit(TGeoVolume::kVolumeMulti) && !volume->GetShape()) {
         Error("Node", "cannot add multiple-volume object %s as node", volume->GetName());
         return;
      }
   } else {
   
      TGeoVolumeMulti *vmulti  = (TGeoVolumeMulti*)fGeometry->FindVolumeFast(name, kTRUE);
      if (!vmulti) {
         volume = fGeometry->FindVolumeFast(name);
         if (volume) {
            Warning("Node", "volume: %s is defined as single -> ignoring shape parameters", volume->GetName());
            Node(name,nr,mother,x,y,z,irot,isOnly, upar);
            return;
         }
         TString vname = name;
         vname = vname.Strip();         
         Error("Node","VOLUME: \"%s\" not defined ",vname.Data());
         return;
      }
      TGeoMedium *medium = vmulti->GetMedium();
      TString sh    = vmulti->GetTitle();
      sh.ToLower();
      if (sh.Contains("box")) {
         volume = MakeBox(name,medium,upar[0],upar[1],upar[2]);
      } else if (sh.Contains("trd1")) {
         volume = MakeTrd1(name,medium,upar[0],upar[1],upar[2],upar[3]);
      } else if (sh.Contains("trd2")) {
         volume = MakeTrd2(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4]);
      } else if (sh.Contains("trap")) {
         volume = MakeTrap(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5],upar[6],upar[7],upar[8],upar[9],upar[10]);
      } else if (sh.Contains("gtra")) {
         volume = MakeGtra(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5],upar[6],upar[7],upar[8],upar[9],upar[10],upar[11]);
      } else if (sh.Contains("tube")) {
         volume = MakeTube(name,medium,upar[0],upar[1],upar[2]);
      } else if (sh.Contains("tubs")) {
         volume = MakeTubs(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4]);
      } else if (sh.Contains("cone")) {
         volume = MakeCone(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4]);
      } else if (sh.Contains("cons")) {
         volume = MakeCons(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5],upar[6]);
      } else if (sh.Contains("pgon")) {
         volume = MakePgon(name,medium,upar[0],upar[1],(Int_t)upar[2],(Int_t)upar[3]);
         Int_t nz = (Int_t)upar[3];
         for (i=0;i<nz;i++) {
            ((TGeoPgon*)volume->GetShape())->DefineSection(i,upar[3*i+4],upar[3*i+5],upar[3*i+6]);
         }
      } else if (sh.Contains("pcon")) {
         volume = MakePcon(name,medium,upar[0],upar[1],(Int_t)upar[2]);
         Int_t nz = (Int_t)upar[2];
         for (i=0;i<nz;i++) {
            ((TGeoPcon*)volume->GetShape())->DefineSection(i,upar[3*i+3],upar[3*i+4],upar[3*i+5]);
         }
      } else if (sh.Contains("eltu")) {
         volume = MakeEltu(name,medium,upar[0],upar[1],upar[2]);
      } else if (sh.Contains("sphe")) {
         volume = MakeSphere(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5]);
      } else if (sh.Contains("ctub")) {
         volume = MakeCtub(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5],upar[6],upar[7],upar[8],upar[9],upar[10]);
      } else if (sh.Contains("para")) {
         volume = MakePara(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5]);
      } else {
         Error("Node","cannot create shape %s",sh.Data());
      }
      if (!volume) return;
      vmulti->AddVolume(volume);
   }
   if (irot) {
      TGeoRotation *matrix = 0;
      TGeoMatrix *mat;
      TIter next(fGeometry->GetListOfMatrices());
      while ((mat=(TGeoMatrix*)next())) {
         if (mat->GetUniqueID()==UInt_t(irot)) {
            matrix = dynamic_cast<TGeoRotation*>(mat);
            break;
         }
      }
      if (!matrix) {
         Error("Node", "rotation %i not found", irot);
         return;
      }
      if (isOnly) amother->AddNode(volume,nr,new TGeoCombiTrans(x,y,z,matrix));
      else        amother->AddNodeOverlap(volume,nr,new TGeoCombiTrans(x,y,z,matrix));
   } else {
      if (x == 0 && y== 0 && z == 0) {
         if (isOnly) amother->AddNode(volume,nr);
         else        amother->AddNodeOverlap(volume,nr);
      } else {
         if (isOnly) amother->AddNode(volume,nr,new TGeoTranslation(x,y,z));
         else        amother->AddNodeOverlap(volume,nr,new TGeoTranslation(x,y,z));
      }
   }
}
TGeoVolume *TGeoBuilder::Volume(const char *name, const char *shape, Int_t nmed,
                                Float_t *upar, Int_t npar)
{
   Int_t i;
   TGeoVolume *volume = 0;
   TGeoMedium *medium = fGeometry->GetMedium(nmed);
   if (!medium) {
      Error("Volume","cannot create volume: %s, medium: %d is unknown",name,nmed);
      return 0;
   }
   TString sh = shape;
   TString sname = name;
   sname = sname.Strip();
   const char *vname = sname.Data();
   if (npar <= 0) {
      
      volume = MakeVolumeMulti(vname,medium);
      volume->SetTitle(shape);
      TGeoVolumeMulti *vmulti  = (TGeoVolumeMulti*)fGeometry->GetListOfGVolumes()->FindObject(vname);
      if (!vmulti) {
         Error("Volume","volume multi: %s not created",vname);
         return 0;
      }
      return vmulti;
   }
   
   sh.ToLower();
   if (sh.Contains("box")) {
      volume = MakeBox(vname,medium,upar[0],upar[1],upar[2]);
   } else if (sh.Contains("trd1")) {
      volume = MakeTrd1(vname,medium,upar[0],upar[1],upar[2],upar[3]);
   } else if (sh.Contains("trd2")) {
      volume = MakeTrd2(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4]);
   } else if (sh.Contains("trap")) {
      volume = MakeTrap(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5],upar[6],upar[7],upar[8],upar[9],upar[10]);
   } else if (sh.Contains("gtra")) {
      volume = MakeGtra(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5],upar[6],upar[7],upar[8],upar[9],upar[10],upar[11]);
   } else if (sh.Contains("tube")) {
      volume = MakeTube(vname,medium,upar[0],upar[1],upar[2]);
   } else if (sh.Contains("tubs")) {
      volume = MakeTubs(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4]);
   } else if (sh.Contains("cone")) {
      volume = MakeCone(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4]);
   } else if (sh.Contains("cons")) {
      volume = MakeCons(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5],upar[6]);
   } else if (sh.Contains("pgon")) {
      volume = MakePgon(vname,medium,upar[0],upar[1],(Int_t)upar[2],(Int_t)upar[3]);
      Int_t nz = (Int_t)upar[3];
      for (i=0;i<nz;i++) {
         ((TGeoPgon*)volume->GetShape())->DefineSection(i,upar[3*i+4],upar[3*i+5],upar[3*i+6]);
      }
   } else if (sh.Contains("pcon")) {
      volume = MakePcon(vname,medium,upar[0],upar[1],(Int_t)upar[2]);
      Int_t nz = (Int_t)upar[2];
      for (i=0;i<nz;i++) {
         ((TGeoPcon*)volume->GetShape())->DefineSection(i,upar[3*i+3],upar[3*i+4],upar[3*i+5]);
      }
   } else if (sh.Contains("eltu")) {
      volume = MakeEltu(vname,medium,upar[0],upar[1],upar[2]);
   } else if (sh.Contains("sphe")) {
      volume = MakeSphere(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5]);
   } else if (sh.Contains("ctub")) {
      volume = MakeCtub(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5],upar[6],upar[7],upar[8],upar[9],upar[10]);
   } else if (sh.Contains("para")) {
      volume = MakePara(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5]);
   } else if (sh.Contains("tor")) {
      volume = MakeTorus(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4]);
   }
   if (!volume) {
      Error("Volume","volume: %s not created",vname);
      return 0;
   }
   return volume;
}
TGeoVolume *TGeoBuilder::Volume(const char *name, const char *shape, Int_t nmed,
                                Double_t *upar, Int_t npar)
{
   Int_t i;
   TGeoVolume *volume = 0;
   TGeoMedium *medium = fGeometry->GetMedium(nmed);
   if (!medium) {
      Error("Volume","cannot create volume: %s, medium: %d is unknown",name,nmed);
      return 0;
   }
   TString sh = shape;
   TString sname = name;
   sname = sname.Strip();
   const char *vname = sname.Data();
   if (npar <= 0) {
      
      volume = MakeVolumeMulti(vname,medium);
      volume->SetTitle(shape);
      TGeoVolumeMulti *vmulti  = (TGeoVolumeMulti*)fGeometry->GetListOfGVolumes()->FindObject(vname);
      if (!vmulti) {
         Error("Volume","volume multi: %s not created",vname);
         return 0;
      }
      return vmulti;
   }
   
   sh.ToLower();
   if (sh.Contains("box")) {
      volume = MakeBox(vname,medium,upar[0],upar[1],upar[2]);
   } else if (sh.Contains("trd1")) {
      volume = MakeTrd1(vname,medium,upar[0],upar[1],upar[2],upar[3]);
   } else if (sh.Contains("trd2")) {
      volume = MakeTrd2(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4]);
   } else if (sh.Contains("trap")) {
      volume = MakeTrap(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5],upar[6],upar[7],upar[8],upar[9],upar[10]);
   } else if (sh.Contains("gtra")) {
      volume = MakeGtra(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5],upar[6],upar[7],upar[8],upar[9],upar[10],upar[11]);
   } else if (sh.Contains("tube")) {
      volume = MakeTube(vname,medium,upar[0],upar[1],upar[2]);
   } else if (sh.Contains("tubs")) {
      volume = MakeTubs(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4]);
   } else if (sh.Contains("cone")) {
      volume = MakeCone(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4]);
   } else if (sh.Contains("cons")) {
      volume = MakeCons(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5],upar[6]);
   } else if (sh.Contains("pgon")) {
      volume = MakePgon(vname,medium,upar[0],upar[1],(Int_t)upar[2],(Int_t)upar[3]);
      Int_t nz = (Int_t)upar[3];
      for (i=0;i<nz;i++) {
         ((TGeoPgon*)volume->GetShape())->DefineSection(i,upar[3*i+4],upar[3*i+5],upar[3*i+6]);
      }
   } else if (sh.Contains("pcon")) {
      volume = MakePcon(vname,medium,upar[0],upar[1],(Int_t)upar[2]);
      Int_t nz = (Int_t)upar[2];
      for (i=0;i<nz;i++) {
         ((TGeoPcon*)volume->GetShape())->DefineSection(i,upar[3*i+3],upar[3*i+4],upar[3*i+5]);
      }
   } else if (sh.Contains("eltu")) {
      volume = MakeEltu(vname,medium,upar[0],upar[1],upar[2]);
   } else if (sh.Contains("sphe")) {
      volume = MakeSphere(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5]);
   } else if (sh.Contains("ctub")) {
      volume = MakeCtub(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5],upar[6],upar[7],upar[8],upar[9],upar[10]);
   } else if (sh.Contains("para")) {
      volume = MakePara(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5]);
   } else if (sh.Contains("tor")) {
      volume = MakeTorus(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4]);
   }
   if (!volume) {
      Error("Volume","volume: %s not created",vname);
      return 0;
   }
   return volume;
}
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.