#include "Riostream.h"
#include <stdlib.h>
#include "TROOT.h"
#include "TClass.h"
#include "TVirtualPad.h"
#include "TView.h"
#include "TGeometry.h"
#include "TRotMatrix.h"
#include "TShape.h"
#include "TVolume.h"
#include "TBrowser.h"
#include "X3DBuffer.h"
#include "TTablePadView3D.h"
#include "TCanvas.h"
#include "TRotMatrix.h"
#include "TVolumePosition.h"
#include "TVirtualViewer3D.h"
#include "TBuffer3D.h"
const Int_t kSonsInvisible = BIT(17);
#if 0
const Int_t kVectorSize = 3;
const Int_t kMatrixSize = kVectorSize*kVectorSize;
static Double_t gTranslation[kMAXLEVELS][kVectorSize];
static Double_t gRotMatrix[kMAXLEVELS][kMatrixSize];
static Int_t gGeomLevel = 0;
TVolume *gNode;
#endif
static TRotMatrix *gIdentity = 0;
ClassImp(TVolume)
TVolume::TVolume()
{
   fShape        = 0;
   fListOfShapes = 0;
   fVisibility   = kBothVisible;
   if (!gGeometry) new TGeometry;
}
TVolume::TVolume(const Text_t *name, const Text_t *title, const Text_t *shapename, Option_t *option)
       :TObjectSet(name),TAttLine(), TAttFill(),fShape(0),fListOfShapes(0)
{
#ifdef WIN32
   Color_t lcolor = 16;
   SetLineColor(lcolor);
#endif
   static Int_t counter = 0;
   counter++;
   SetTitle(title);
   if(!(counter%1000))cout<<"TVolume count="<<counter<<" name="<<name<<endl;
   if (!gGeometry) new TGeometry;
   Add(gGeometry->GetShape(shapename),kTRUE);
   fOption = option;
   fVisibility = kBothVisible;
   if(fShape) ImportShapeAttributes();
}
TVolume::TVolume(const Text_t *name, const Text_t *title, TShape *shape, Option_t *option)
                :TObjectSet(name),TAttLine(),TAttFill(),fShape(0),fListOfShapes(0)
{
#ifdef WIN32
   Color_t lcolor = 16;
   SetLineColor(lcolor);
#endif
   if (!gGeometry) new TGeometry;
   Add(shape,kTRUE);
   fOption = option;
   fVisibility = kBothVisible;
   SetTitle(title);
   if(shape) ImportShapeAttributes();
}
Int_t TVolume::MapStNode2GEANTVis(ENodeSEEN  vis)
{
   const Int_t mapVis[4] = {1, -2, 0, -1 };
   return mapVis[vis];
}
Int_t TVolume::MapGEANT2StNodeVis(Int_t vis)
{
   const Int_t mapVis[4] = {1, -2, 0, -1 };
   Int_t i;
   for (i =0; i<3;i++) if (mapVis[i] == vis) return i;
   return kBothVisible;
}
TVolume::TVolume(TNode &rootNode):fShape(0),fListOfShapes(0)
{
  
   SetName(rootNode.GetName());
   SetTitle(rootNode.GetTitle());
   fVisibility = ENodeSEEN(MapGEANT2StNodeVis(rootNode.GetVisibility()));
   fOption     = rootNode.GetOption();
   Add(rootNode.GetShape(),kTRUE);
   SetLineColor(rootNode.GetLineColor());
   SetLineStyle(rootNode.GetLineStyle());
   SetLineWidth(rootNode.GetLineWidth());
   SetFillColor(rootNode.GetFillColor());
   SetFillStyle(rootNode.GetFillStyle());
   TList *nodes = rootNode.GetListOfNodes();
   if (nodes) {
      TIter next(nodes);
      TNode *node = 0;
      while ( (node = (TNode *) next()) ){
         TVolume *nextNode = new TVolume(*node);
         Add(nextNode,node->GetX(),node->GetY(),node->GetZ(),node->GetMatrix());
      }
   }
}
void TVolume::Add(TShape *shape, Bool_t IsMaster)
{
   
   if (!shape) return;
   if (!fListOfShapes) fListOfShapes = new TList;
   fListOfShapes->Add(shape);
   if (IsMaster) fShape = shape;
}
TNode *TVolume::CreateTNode(const TVolumePosition *position)
{
   
   Double_t x=0;
   Double_t y=0;
   Double_t z=0;
   const TRotMatrix* matrix = 0;
   if (position) {
      x=position->GetX();
      y=position->GetY();
      z=position->GetZ();
      matrix = position->GetMatrix();
   }
   TNode *newNode  = new TNode(GetName(),GetTitle(),GetShape(),x,y,z,(TRotMatrix* )matrix,GetOption());
   newNode->SetVisibility(MapStNode2GEANTVis(GetVisibility()));
   newNode->SetLineColor(GetLineColor());
   newNode->SetLineStyle(GetLineStyle());
   newNode->SetLineWidth(GetLineWidth());
   newNode->SetFillColor(GetFillColor());
   newNode->SetFillStyle(GetFillStyle());
   TList *positions = GetListOfPositions();
   if (positions) {
      TIter next(positions);
      TVolumePosition *pos = 0;
      while ( (pos = (TVolumePosition *) next()) ){
         TVolume *node = pos->GetNode();
         if (node) {
            newNode->cd();
            node->CreateTNode(pos);
         }
      }
   }
   newNode->ImportShapeAttributes();
   return newNode;
}
TVolume::~TVolume()
{
   
   
   if (GetListOfPositions()) {
      GetListOfPositions()->Delete();
      SetPositionsList();
   }
   SafeDelete(fListOfShapes);
}
void TVolume::Add(TVolumePosition *position)
{
   
   if (!GetListOfPositions()) SetPositionsList(new TList);
   if ( GetListOfPositions()) GetListOfPositions()->Add(position);
   else Error("Add","Can not create list of positions for the current node <%s>:<%s>",GetName(),GetTitle());
}
TVolumePosition *TVolume::Add(TVolume *node, TVolumePosition *nodePosition)
{
   
   TVolumePosition *position = nodePosition;
   if (!node) return 0;
   if (!position) position = new TVolumePosition(node);  
   
   if (!(GetCollection() && GetCollection()->FindObject(node)) ) TDataSet::Add(node);
   Add(position);
   return position;
}
TVolumePosition *TVolume::Add(TVolume *volume, Double_t x, Double_t y, Double_t z,
                              TRotMatrix *matrix,  UInt_t id, Option_t *)
{
   if (!volume) return 0;
   TRotMatrix *rotation = matrix;
   if(!rotation) rotation = GetIdentity();
   TVolumePosition *position = new TVolumePosition(volume,x,y,z,rotation);
   position->SetId(id);
   return Add(volume,position);
}
TVolumePosition *TVolume::Add(TVolume *volume, Double_t x, Double_t y, Double_t z,
                              const Text_t *matrixname,  UInt_t id, Option_t *)
{
   if (!volume) return 0;
   TRotMatrix *rotation = 0;
   if (matrixname && strlen(matrixname)) rotation = gGeometry->GetRotMatrix(matrixname);
   if (!rotation)                        rotation = GetIdentity();
   TVolumePosition *position = new TVolumePosition(volume,x,y,z,rotation);
   position->SetId(id);
   return Add(volume,position);
}
void TVolume::Browse(TBrowser *b)
{
   
   if (GetListOfPositions()){
      TVolumePosition *nodePosition = 0;
      TIter next(GetListOfPositions());
      Int_t posNumber = 0;
      while ( (nodePosition = (TVolumePosition *)next()) ) {
         posNumber       = nodePosition->GetId();
         TString posName = "*";
         posName += nodePosition->GetNode()->GetTitle();
         char num[10];
         posName += ";";
         sprintf(num,"%d",posNumber);
         posName += num;
         b->Add(nodePosition,posName.Data());
      }
   }
}
Int_t TVolume::DistancetoPrimitive(Int_t px, Int_t py)
{
   
   return DistancetoNodePrimitive(px,py);
}
Int_t TVolume::DistancetoNodePrimitive(Int_t px, Int_t py,TVolumePosition *pos)
{
   const Int_t big = 9999;
   if ( GetVisibility() == kNoneVisible )  return big;
   const Int_t inaxis = 7;
   const Int_t maxdist = 5;
   Int_t puxmin = gPad->XtoAbsPixel(gPad->GetUxmin());
   Int_t puymin = gPad->YtoAbsPixel(gPad->GetUymin());
   Int_t puxmax = gPad->XtoAbsPixel(gPad->GetUxmax());
   Int_t puymax = gPad->YtoAbsPixel(gPad->GetUymax());
   if (px < puxmin - inaxis) return big;
   if (py > puymin + inaxis) return big;
   if (px > puxmax + inaxis) return big;
   if (py < puymax - inaxis) return big;
   TView *view =gPad->GetView();
   if (!view) return big;
   static TVolumePosition nullPosition;
   TVolumePosition *position = pos;
   if (!position) position = &nullPosition;
   if (pos) position->UpdatePosition();
   Int_t dist = big;
   if ( !(GetVisibility() & kThisUnvisible ) ) {
      TShape  *shape = 0;
      TIter nextShape(fListOfShapes);
      while ((shape = (TShape *)nextShape())) {
         
         if (shape->GetVisibility()) {
            Int_t dshape = shape->DistancetoPrimitive(px,py);
            if (dshape < maxdist) {
               gPad->SetSelected(this);
               return 0;
            }
            if (dshape < dist) dist = dshape;
         }
      }
   }
   if ( (GetVisibility() & kSonUnvisible) ) return dist;
   TList *posList = GetListOfPositions();
   Int_t dnode = dist;
   if (posList && posList->GetSize()) {
      gGeometry->PushLevel();
      TVolumePosition *thisPosition;
      TObject *obj;
      TIter  next(posList);
      while ((obj = next())) {
         thisPosition = (TVolumePosition*)obj;
         TVolume *node = thisPosition->GetNode();
         dnode = node->DistancetoNodePrimitive(px,py,thisPosition);
         if (dnode <= 0)  break;
         if (dnode < dist) dist = dnode;
         if (gGeometry->GeomLevel() > 2) break;
      }
      gGeometry->PopLevel();
   }
   if (gGeometry->GeomLevel()==0 && dnode > maxdist) {
      gPad->SetSelected(view);
      return 0;
   } else
      return dnode;
}
void TVolume::Draw(Option_t *option)
{
   TString opt = option;
   opt.ToLower();
   if (!gPad) {
      gROOT->MakeDefCanvas();
   }
   if (!opt.Contains("same")) gPad->Clear();
    
   Int_t iopt = atoi(option);
   TDataSet *parent = 0;
   char buffer[10];
   if (iopt < 0) {
      
      sprintf(buffer,"%d",-iopt);
      option = buffer;
      
      parent = this;
      do parent = parent->GetParent();
      while (parent && ++iopt);
   }
   if (parent) parent->AppendPad(option);
   else        AppendPad(option);
#if ROOT_VERSION_CODE >= ROOT_VERSION(4,03,05)
   
   
   TView *view = gPad->GetView();
   if (!view) {
      view = TView::CreateView(1,0,0);
      
      
      view->SetAutoRange(kTRUE);
   }
   
   gPad->GetViewer3D();
#else
    Paint(option);
#endif
}
void TVolume::DrawOnly(Option_t *option)
{
   SetVisibility(kThisUnvisible);
   Draw(option);
}
void TVolume::ExecuteEvent(Int_t, Int_t, Int_t)
{
   gPad->SetCursor(kHand);
}
TRotMatrix *TVolume::GetIdentity()
{
   
   Double_t *identityMatrix = 0;
   if (!gIdentity) {
      gIdentity = gGeometry->GetRotMatrix("Identity");
      if (!gIdentity) {
         gIdentity  =  new TRotMatrix();
         gIdentity->SetName("Identity");
         gIdentity->SetTitle("Identity matrix");
         gIdentity->SetMatrix((Double_t *)0);
         identityMatrix = gIdentity->GetMatrix();
         memset(identityMatrix,0,9*sizeof(Double_t));
                                *identityMatrix = 1;
         identityMatrix += 4;   *identityMatrix = 1;
         identityMatrix += 4;   *identityMatrix = 1;
         gGeometry->GetListOfMatrices()->AddFirst(gIdentity);
      }
   }
   return gIdentity;
}
Text_t *TVolume::GetObjectInfo(Int_t px, Int_t py) const
{
   
   if (!gPad) return 0;
   static char info[512];
   sprintf(info,"%s/%s",GetName(),GetTitle());
   Double_t x[3];
   ((TPad *)gPad)->AbsPixeltoXY(px,py,x[0],x[1]);
   x[2] = 0;
   TView *view =gPad->GetView();
   if (view) view->NDCtoWC(x, x);
   TIter nextShape(fListOfShapes);
   TShape *shape = 0;
   while( (shape = (TShape *)nextShape()) )
      sprintf(&info[strlen(info)]," %6.2f/%6.2f: shape=%s/%s",x[0],x[1],shape->GetName(),shape->ClassName());
   return info;
}
void TVolume::ImportShapeAttributes()
{
   if (fShape) {
      SetLineColor(fShape->GetLineColor());
      SetLineStyle(fShape->GetLineStyle());
      SetLineWidth(fShape->GetLineWidth());
      SetFillColor(fShape->GetFillColor());
      SetFillStyle(fShape->GetFillStyle());
   }
   if (!GetCollection()) return;
   TVolume *volume;
   TIter  next(GetCollection());
   while ( (volume = (TVolume *)next()) )
      volume->ImportShapeAttributes();
}
void TVolume::Paint(Option_t *opt)
{
   gGeometry->SetGeomLevel();
   gGeometry->UpdateTempMatrix();
   PaintNodePosition(opt);
   return;
}
void TVolume::PaintNodePosition(Option_t *option,TVolumePosition *pos)
{
   if ( GetVisibility() == kNoneVisible )  return;
   static TVolumePosition nullPosition;
   Int_t level = gGeometry->GeomLevel();
   if ((!(GetVisibility() & kThisUnvisible)) && option && option[0]=='r' && level > 3 ) return;
   Int_t iopt = atoi(option);
   if ( (0 < iopt) && (iopt <= level) )  return;
   TTablePadView3D *view3D = (TTablePadView3D*)gPad->GetView3D();
   TVirtualViewer3D * viewer3D = gPad->GetViewer3D();
   TVolumePosition *position = pos;
   if (!position)   position   = &nullPosition;
   
   position->UpdatePosition(option);
   if ( viewer3D && !(GetVisibility() & kThisUnvisible))  PaintShape(option);
   if (GetVisibility() & kSonUnvisible) return;
   TList *posList = GetListOfPositions();
   if (posList && posList->GetSize()) {
      gGeometry->PushLevel();
      TVolumePosition *thisPosition;
      TIter  next(posList);
      while ((thisPosition = (TVolumePosition *)next())) {
         if (view3D)  view3D->PushMatrix();
         TVolume *volume = thisPosition->GetNode();
         if (volume) volume->PaintNodePosition(option,thisPosition);
         if (view3D) view3D->PopMatrix();
      }
      gGeometry->PopLevel();
   }
}
void TVolume::PaintShape(Option_t *option)
{
   
   
   Bool_t rangeView = option && option[0]=='r';
   if (!rangeView) {
      TAttLine::Modify();
      TAttFill::Modify();
   }
   if ( (GetVisibility() & kThisUnvisible) ) return;
   TIter nextShape(fListOfShapes);
   TShape *shape = 0;
   while( (shape = (TShape *)nextShape()) ) {
      if (!rangeView) {
         shape->SetLineColor(GetLineColor());
         shape->SetLineStyle(GetLineStyle());
         shape->SetLineWidth(GetLineWidth());
         shape->SetFillColor(GetFillColor());
         shape->SetFillStyle(GetFillStyle());
         TTablePadView3D *view3D = (TTablePadView3D*)gPad->GetView3D();
         gPad->GetViewer3D();
         if (view3D)
            view3D->SetLineAttr(GetLineColor(),GetLineWidth(),option);
      }
#if ROOT_VERSION_CODE >= ROOT_VERSION(4,03,05)
      
      Bool_t viewerWantsSons = kTRUE;
      TVirtualViewer3D * viewer3D = gPad->GetViewer3D();
      if (viewer3D) {
         
         
         
         
         const TBuffer3D & buffer =
            fShape->GetBuffer3D(TBuffer3D::kCore|TBuffer3D::kBoundingBox|TBuffer3D::kShapeSpecific);
         
         
         const_cast<TBuffer3D &>(buffer).fID = this;
         Int_t reqSections = viewer3D->AddObject(buffer, &viewerWantsSons);
         if (reqSections != TBuffer3D::kNone) {
            fShape->GetBuffer3D(reqSections);
            viewer3D->AddObject(buffer);
         }
      }
#else
    shape->Paint(option);
#endif
   }
}
void TVolume::DeletePosition(TVolumePosition *position)
{
  
  
   if (!position) return;
   if (GetListOfPositions()) {
      TObjLink *lnk = GetListOfPositions()->FirstLink();
      while (lnk) {
         TVolumePosition *nextPosition = (TVolumePosition *)(lnk->GetObject());
         if (nextPosition && nextPosition == position) {
            TVolume *node = nextPosition->GetNode();
            GetListOfPositions()->Remove(lnk);
            delete nextPosition;
            Remove(node);
            break;
         }
         lnk = lnk->Next();
      }
   }
}
void TVolume::GetLocalRange(Float_t *min, Float_t *max)
{
  
  
  
  
  
  
  
   TVirtualPad *savePad = gPad;
   
   TCanvas dummyPad("--Dumm--","dum",1,1);
   
   TView *view = TView::CreateView(1,0,0);
   gGeometry->SetGeomLevel();
   gGeometry->UpdateTempMatrix();
   view->SetAutoRange(kTRUE);
   Paint("range");
   view->GetRange(&min[0],&max[0]);
   delete view;
   
   if (savePad) savePad->cd();
}
void TVolume::SetVisibility(ENodeSEEN vis)
{
   fVisibility = vis;
}
void TVolume::Sizeof3D() const
{
   if (!(GetVisibility() & kThisUnvisible) ) {
      TIter nextShape(fListOfShapes);
      TShape *shape = 0;
      while( (shape = (TShape *)nextShape()) ) {
         if (shape->GetVisibility())  shape->Sizeof3D();
      }
   }
   if ( GetVisibility() & kSonUnvisible ) return;
   if (!Nodes()) return;
   TVolume *node;
   TObject *obj;
   TIter  next(Nodes());
   while ((obj = next())) {
      node = (TVolume*)obj;
      node->Sizeof3D();
   }
}
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.