ROOT logo
// @(#)root/table:$Id: TVolumeView.cxx 27157 2009-01-15 14:05:12Z brun $
// Author: Valery Fine(fine@bnl.gov)   25/12/98

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


#include "Riostream.h"
#include <assert.h>
#include <stdlib.h>

#include "TCanvas.h"
#include "TPad.h"
#include "TCernLib.h"
#include "TBrowser.h"
#include "TVolumeView.h"
#include "TVolumeViewIter.h"
#include "TVolumePosition.h"
#include "TROOT.h"
#include "TView.h"
#include "TTablePadView3D.h"
#include "TGeometry.h"
#include "TVirtualPad.h"
#include "TObjArray.h"
#include "TVirtualViewer3D.h"
#include "TBuffer3D.h"

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TVolumeView                                                          //
//                                                                      //
// TVolumeView class is a special kind of TDataSet with one extra       //
// pointer to wrap any TObject onto TDataSet object                     //
//                                                                      //
//  BE CAREFUL !!!                                                      //
//  One has to use it carefully no control over that extra object       //
//  is performed. This means: the object m_Obj data-member points to can//
//  be destroyed with no this kbject notifying.                         //
//  There is no tool /protection to check whether m_Obj is till alive.  //
//  It is one's  code responsilitiy                                     //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

ClassImp(TVolumeView)

//_____________________________________________________________________________
TVolumeView::TVolumeView(TVolumeView *viewNode,TVolumePosition *nodePosition)
            : TObjectSet(viewNode->GetName(),(TObject *)nodePosition),fListOfShapes(0)
            //             ,fListOfAttributes(0)
{
  //
  // This ctor creates a TVolumeView structure from the "marked" nodes
  // of the "viewNode" input structure
  // It re-calculates all positions according of the new topology
  // All new TVolume became UNMARKED though
  //
   if (!gGeometry) new TGeometry;
   if (viewNode) {
      SetTitle(viewNode->GetTitle());
      EDataSetPass mode = kContinue;
      TVolumeViewIter next(viewNode,0);
      TVolumeView *nextView = 0;
      while ( (nextView = (TVolumeView *)next(mode)) ){
         mode = kContinue;
         if (nextView->IsMarked()) {
            TVolumePosition *position =next[0];
            if (!position->GetNode()) {
               Error("TVolumeView ctor","%s %s ",GetName(),nextView->GetName());
            }
            Add(new TVolumeView(nextView,position));
            mode = kPrune;
         }
      }
   }
}

//_____________________________________________________________________________
TVolumeView::TVolumeView(TVolumeView *viewNode,TVolumeView *topNode)
            : TObjectSet(viewNode->GetName(),(TObject *)0),fListOfShapes(0)
            //             ,fListOfAttributes(0)
{
  //
  // This ctor creates a TVolumeView structure containing:
  //
  //   - viewNode on the top
  //   - skip ALL node from the original viewNode untill topNode found
  //   - include all "marked" node below "topNode" if any
  //     topNode is always included
  //
  // It re-calculates all positions according of the new topology
  //
   if (!gGeometry) new TGeometry;
   if (viewNode && topNode) {
      SetTitle(viewNode->GetTitle());
      // define the depth of the "top" Node
      EDataSetPass mode = kContinue;
      TVolumeViewIter next(viewNode,0);
      TVolumeView *nextView = 0;
      while ( (nextView = (TVolumeView *)next(mode)) ){
         mode = kContinue;
         // Skip till  "top Node" found
         if (topNode != nextView) continue;
         TVolumePosition *position = next[0];
         if (!position->GetNode()) {
            Error("TVolumeView ctor","%s %s ",GetName(),nextView->GetName());
         }
         Add(new TVolumeView(nextView,position));
         break;
      }
   }
}

//_____________________________________________________________________________
TVolumeView::TVolumeView(TVolumeView *viewNode,const Char_t *nodeName1,const Char_t *nodeName2)
            : TObjectSet(viewNode->GetName(),(TObject *)0),fListOfShapes(0)
            //             ,fListOfAttributes(0)
{
  //
  // This ctor creates a TVolumeView structure containing:
  //
  //   - viewNode on the top
  //   - skip ALL node from the original viewNode untill topNodeName found
  //   - include all "marked" node below "topNodename" if any
  //     topNodeName is always included
  //
  // It re-calculates all positions according of the new topology
  //
   const Char_t *foundName[2] = {nodeName1, nodeName2};
   Bool_t found = kFALSE;
   if (!gGeometry) new TGeometry;
   if (viewNode && nodeName1 && nodeName1[0]) {
      SetTitle(viewNode->GetTitle());
      // define the depth of the "top" Node
      EDataSetPass mode = kContinue;
      TVolumeViewIter next(viewNode,0);
      TVolumeView *nextView = 0;
      while ( (nextView = (TVolumeView *)next(mode)) ){
         mode = kContinue;
         // Skip till  "top Node" found
         Int_t i = 0;
         found = kFALSE;
         for (i=0;i<2;i++) {
            if (foundName[i]) {
               if (strcmp(nextView->GetName(),foundName[i])) continue;
               foundName[i] = 0;
               found = kTRUE;
               break;
            }
         }
         if (!found) continue;
         TVolumePosition *position = next[0];
         if (!position->GetNode()) {
            Error("TVolumeView ctor","%s %s ",GetName(),nextView->GetName());
         }
         Add(new TVolumeView(nextView,position));
         mode = kPrune;
      }
   }
}

//_____________________________________________________________________________
TVolumeView::TVolumeView(TVolumeView *viewNode,const TVolumeView *node1,const TVolumeView *node2)
            : TObjectSet(viewNode->GetName(),(TObject *)0),fListOfShapes(0)
            //             ,fListOfAttributes(0)
{
  //
  // This ctor creates a TVolumeView structure containing:
  //
  //   - viewNode on the top
  //   - skip ALL node from the original viewNode untill topNodeName found
  //   - include all "marked" node below "topNodename" if any
  //     topNodeName is always included
  //
  // It re-calculates all positions according of the new topology
  //
   const TVolumeView *foundView[2] = {node1, node2};
   const Int_t nViews = sizeof(foundView)/sizeof(const TVolumeView *);
   Bool_t found = kFALSE;
   if (!gGeometry) new TGeometry;
   if (viewNode) {
      SetTitle(viewNode->GetTitle());
      // define the depth of the "top" Node
      EDataSetPass mode = kContinue;
      TVolumeViewIter next(viewNode,0);
      TVolumeView *nextView = 0;
      while ( (nextView = (TVolumeView *)next(mode)) ){
         mode = kContinue;
         // Skip till  "top Node" found
         Int_t i = 0;
         found = kFALSE;
         for (i=0;i<nViews;i++) {
            if (foundView[i]) {
               if (nextView != foundView[i]) continue;
               foundView[i] = 0;
               found = kTRUE;
               break;
            }
         }
         if (!found) continue;
         TVolumePosition *position = next[0];
         if (!position->GetNode()) {
            Error("TVolumeView ctor","%s %s ",GetName(),nextView->GetName());
         }
         Add(new TVolumeView(nextView,position));
         mode = kPrune;
      }
   }
}

//_____________________________________________________________________________
TVolumeView::TVolumeView(TVolume &pattern,Int_t maxDepLevel,
             const TVolumePosition *nodePosition,EDataSetPass iopt, TVolumeView *rootVolume)
            : TObjectSet(pattern.GetName(),(TObject *)nodePosition),fListOfShapes(0)
{
  //
  // Creates TVolumeView (view) with a topology similar with TVolume *pattern
  //
  //  Parameters:
  //  -----------
  //  pattern        - the pattern dataset
  //  iopt = kStruct - clone only my structural links
  //         kAll    - clone all links
  //         kRefs   - clone only refs
  //         kMarked - clone marked (not implemented yet) only
  //
  //   All new-created sets become the structural ones anyway.
  //
  //  cout << "ctor for " << GetName() << " - " << GetTitle() << endl;
   if (!gGeometry) new TGeometry;
   if (!nodePosition) {
      // Create the trivial position if any
      nodePosition = new TVolumePosition(&pattern);
      SetObject((TObject*)nodePosition);
   }
   if (!rootVolume) {
      rootVolume   = this;
      nodePosition = 0;
   }
   SetTitle(pattern.GetTitle());
   if ( pattern.IsMarked() ) Mark();
   TVolumePosition *position = 0;
   const TList *list = pattern.GetListOfPositions();
   if (!list || maxDepLevel == 1 || maxDepLevel < 0) return;

   TIter nextPosition(list);
   Bool_t optSel    = (iopt == kStruct);
//  Bool_t optAll    = (iopt == kAll);
   Bool_t optMarked = (iopt == kMarked);

   const TRotMatrix *thisMatrix = 0;
   Double_t thisTranslation[3] = {0,0,0};
   if (nodePosition ) {
      thisMatrix = nodePosition->GetMatrix();
      for (int i =0; i< 3; i++) thisTranslation[i]= nodePosition->GetX(i);
   }
   while ( (position = (TVolumePosition *)nextPosition()) ) {
      // define the the related TVolume
      TVolume *node     = position->GetNode();
      Double_t *positionMatrix = ((TRotMatrix *)position->GetMatrix())->GetMatrix();
      if (node) {
         UInt_t positionId = position->GetId();
         Double_t newTranslation[3] = {position->GetX(),position->GetY(),position->GetZ()};
         Double_t newMatrix[9];
         TRotMatrix currentMatrix;

         if (nodePosition) {
            if (positionMatrix) {
               TGeometry::UpdateTempMatrix(thisTranslation,thisMatrix?((TRotMatrix *)thisMatrix)->GetMatrix():0
                         ,position->GetX(),position->GetY(),position->GetZ(),positionMatrix
                         ,newTranslation,newMatrix);
               currentMatrix.SetMatrix(newMatrix);
            } else {
               TCL::vadd(thisTranslation, newTranslation,newTranslation,3);
               currentMatrix.SetMatrix(((TRotMatrix *)thisMatrix)->GetMatrix());
            }
         } else {
            if (positionMatrix)
               currentMatrix.SetMatrix(positionMatrix);
            else {
               TCL::ucopy(thisTranslation,newTranslation,3);
               currentMatrix.SetMatrix(TVolume::GetIdentity()->GetMatrix());
            }
         }
         TVolumePosition nextPos(node,newTranslation[0],newTranslation[1],
                                      newTranslation[2], &currentMatrix);
         nextPos.SetId(positionId);
         if (optMarked && !node->IsMarked()) {
            TVolumeView fakeView(*node,maxDepLevel,&nextPos,iopt,rootVolume);
            fakeView.DoOwner(kFALSE);
            continue;
         }

         if (optSel) {
            TDataSet *parent = node->GetParent();
            if ( parent && (parent != (TDataSet *)&pattern) ) continue;
         }
         TRotMatrix *newRotation = new TRotMatrix();
         newRotation->SetMatrix(currentMatrix.GetMatrix());
         TVolumePosition *nP = new TVolumePosition(node,newTranslation[0],newTranslation[1],
                                     newTranslation[2], newRotation);
         nP->SetId(positionId);
         rootVolume->Add(new TVolumeView(*node,maxDepLevel?maxDepLevel-1:0,nP,iopt));
      } else
         Error("TVolumeView ctor","Position with NO node attached has been supplied");

   }
}
//_____________________________________________________________________________
TVolumeView::TVolumeView(TVolumeView &viewNode):
             TObjectSet(viewNode.GetName(),(TObject *)viewNode.GetPosition())
            ,TAtt3D()
            ,fListOfShapes(viewNode.GetListOfShapes())
{
   //to be documented
   if (viewNode.IsOwner()) {
      viewNode.DoOwner(kFALSE); DoOwner();
   }
}

//_____________________________________________________________________________
TVolumeView::TVolumeView(Double_t *translate, Double_t *rotate, UInt_t positionId, TVolume *topNode,
                         const Char_t *thisNodePath, const Char_t *matrixName, Int_t matrixType)
            // : fListOfAttributes(0)
{
   // Special ctor to back TVolumeView::SavePrimitive() method
   if (!gGeometry) new TGeometry;
   fListOfShapes     = 0;
   TVolume *thisNode = 0;
   Double_t thisX  = translate[0];
   Double_t thisY  = translate[1];
   Double_t thisZ  = translate[2];

   // Find TVolume by path;
   if (topNode) {
      thisNode =  (TVolume *)topNode->Find(thisNodePath);
      if (!thisNode->InheritsFrom("TVolume")) {
         thisNode = 0;
         Error("TVolumeView","wrong node <%s> on path: \"%s\"",thisNode->GetName(),thisNodePath);
      }
   }

   TRotMatrix *thisRotMatrix =  0;
   if (matrixName && strlen(matrixName)) thisRotMatrix = gGeometry->GetRotMatrix(matrixName);
   TVolumePosition *thisPosition = 0;
   if (thisRotMatrix)
      thisPosition = new TVolumePosition(thisNode,thisX, thisY, thisZ, matrixName);
   else if (matrixType==2)
      thisPosition = new TVolumePosition(thisNode,thisX, thisY, thisZ);
   else if (rotate) {
      const Char_t *title = "rotation";
      thisRotMatrix = new TRotMatrix((char *)matrixName,(char *)title,rotate);
      thisPosition  = new TVolumePosition(thisNode,thisX, thisY, thisZ, thisRotMatrix);
   } else
      Error("TVolumeView"," No rotation matrix is defined");
   thisPosition->SetId(positionId);
   SetObject(thisPosition);
   if (thisNode) {
      SetName(thisNode->GetName());
      SetTitle(thisNode->GetTitle());
   }
}

//_____________________________________________________________________________
TVolumeView::TVolumeView(TVolume *thisNode,TVolumePosition *nodePosition)
            : TObjectSet(thisNode?thisNode->GetName():"",(TObject *)nodePosition),fListOfShapes(0)
{
   //to be documented
   if (!gGeometry) new TGeometry;
   SafeDelete(fListOfShapes);
   if (thisNode)
      SetTitle(thisNode->GetTitle());
}

//______________________________________________________________________________
TVolumeView::~TVolumeView()
{
// default dtor (empty for this class)
}

//_____________________________________________________________________________
TVolume *TVolumeView::AddNode(TVolume *node)
{
  // Add the TVolume in the Tnode data-structure refered
  // by this TVolumeView object
  // Return TVolume * the input TVolume * was attached to

   TVolume *closedNode = 0;
   TVolumePosition *pos ;
   if ( node && (pos = GetPosition() )  && (closedNode = pos->GetNode()) )
      closedNode->Add(node);
   return closedNode;
}

//______________________________________________________________________________
void TVolumeView::Add(TShape *shape, Bool_t IsMaster)
{
   //to be documented
   if (!shape) return;
   if (!fListOfShapes) fListOfShapes = new TList;
   if (IsMaster)
      fListOfShapes->AddFirst(shape);
   else
      fListOfShapes->Add(shape);
}

//_____________________________________________________________________________
void TVolumeView::Browse(TBrowser *b)
{
   //to be documented
   TObjectSet::Browse(b);
//  TVolumePosition *pos = GetPosition();
//  if (pos) pos->Browse(b);
//    b->Add(pos);
}

//______________________________________________________________________________
Int_t TVolumeView::DistancetoPrimitive(Int_t px, Int_t py)
{
//*-*-*-*-*-*-*-*-*Compute distance from point px,py to a TVolumeView*-*-*-*-*-*
//*-*                  ===========================================
//*-*  Compute the closest distance of approach from point px,py to the position of
//*-*  this node.
//*-*  The distance is computed in pixels units.
//*-*
//*-*  It is restricted by 2 levels of TVolumes
//*-*
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*

   const Int_t big = 9999;
   const Int_t inaxis = 7;
   const Int_t maxdist = 5;

   Int_t dist = big;

   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());

//*-*- return if point is not in the user area
   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;

   TVolumePosition *position = GetPosition();
   TVolume *thisNode  = 0;
   TShape  *thisShape = 0;
   if (position) {
      thisNode = position->GetNode();
      position->UpdatePosition();
      if (thisNode) {
         thisShape    = thisNode->GetShape();
         if (!(thisNode->GetVisibility() & TVolume::kThisUnvisible) &&
            thisShape && thisShape->GetVisibility()) {
            dist = thisShape->DistancetoPrimitive(px,py);
            if (dist < maxdist) {
               gPad->SetSelected(this);
               return 0;
            }
         }
      }
   }

//   if ( TestBit(kSonsInvisible) ) return dist;

//*-*- Loop on all sons
   TSeqCollection *fNodes =  GetCollection();
   Int_t nsons = fNodes?fNodes->GetSize():0;
   Int_t dnode = dist;
   if (nsons) {
      gGeometry->PushLevel();
      TVolume *node;
      TIter  next(fNodes);
      while ((node  = (TVolume *)next())) {
         dnode = node->DistancetoPrimitive(px,py);
         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 TVolumeView::Draw(Option_t *option)
{
//*-*-*-*-*-*-*-*-*-*-*-*Draw Referenced node with current parameters*-*-*-*
//*-*                   =============================================

   TString opt = option;
   opt.ToLower();
//*-*- Clear pad if option "same" not given
   if (!gPad) {
      gROOT->MakeDefCanvas();
   }
   if (!opt.Contains("same")) gPad->Clear();

//*-*- Draw Referenced node
   gGeometry->SetGeomLevel();
   gGeometry->UpdateTempMatrix();

   // Check geometry level

   Int_t iopt = atoi(option);
   TDataSet *parent = 0;
   char buffer[10];
   if (iopt < 0) {
      sprintf(buffer,"%d",-iopt);
      option = buffer;
      // select parent to draw
      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)
   // the new (4.03/05) way to active 3D viewer
   // Create a 3-D view
   TView *view = gPad->GetView();
   if (!view) {
      view = TView::CreateView(1,0,0);
      // Set the view to perform a first autorange (frame) draw.
      // TViewer3DPad will revert view to normal painting after this
      view->SetAutoRange(kTRUE);
   }

   // Create a 3D viewer to draw us
   gPad->GetViewer3D(option);
#else
    Paint(option);
#endif
}

//_____________________________________________________________________________
TVolume *TVolumeView::GetNode() const
{
   //to be documented
   TVolumePosition *pos = GetPosition();
   if (pos)
      return pos->GetNode();
   return 0;
}

//_____________________________________________________________________________
Int_t TVolumeView::GetGlobalRange(const TVolumeView *rootNode,Float_t *globalMin,Float_t *globalMax)
{
   //
   // Calculate the position of the vertrex of the outlined cube in repect
   // of the given TVolumeView object
   //
   if (rootNode) {
      SetTitle(rootNode->GetTitle());
      EDataSetPass mode = kContinue;
      TVolumeViewIter next((TVolumeView *)rootNode,0);
      TVolumeView *nextView = 0;
      // Find itself.
      while ( (nextView = (TVolumeView *)next(mode)) && nextView != this ){}
      if (nextView == this) {
         TVolumePosition *position = next[0];
         if (!position->GetNode()) {
            Error("TVolumeView ctor","%s %s ",GetName(),nextView->GetName());
         }
         // Calculate the range of the outlined cube verteces.
         GetLocalRange(globalMin,globalMax);
         Float_t offSet[3] = {position->GetX(),position->GetY(),position->GetZ()};
         for (Int_t i=0;i<3;i++) {
            globalMin[i] += offSet[i];
            globalMax[i] += offSet[i];
         }
      }
      return next.GetDepth();
   }
   else return -1;
}

//______________________________________________________________________________
void TVolumeView::GetLocalRange(Float_t *min, Float_t *max)
{
  //  GetRange
  //
  //  Calculates the size of 3 box the node occupies.
  //  Return:
  //    two floating point arrays with the bound of box
  //     surroundind all shapes of this TModeView
  //

   TVirtualPad *savePad = gPad;
   //  Create a dummy TPad;
   TCanvas dummyPad("--Dumm--","dum",1,1);
   // Assing 3D TView
   TView *view = TView::CreateView(1,0,0);

   gGeometry->SetGeomLevel();
   gGeometry->UpdateTempMatrix();
   view->SetAutoRange(kTRUE);
   Paint("range");
   view->GetRange(&min[0],&max[0]);
   delete view;
   // restore "current pad"
   if (savePad) savePad->cd();
}

//______________________________________________________________________________
char *TVolumeView::GetObjectInfo(Int_t px, Int_t py) const
{
   //to be documented
   if (!gPad) return 0;
   static char info[512];
   Double_t x[3] = {0,0,0.5};
   ((TPad *)gPad)->AbsPixeltoXY(px,py,x[0],x[1]);
   TView *view =gPad->GetView();
   if (view) {
      Double_t min[3], max[3];
      view->GetRange(min,max);
      for (int i =0; i<3;i++) min[i] = (max[i]+min[i])/2;
      view->WCtoNDC(min,max);
      min[0] = x[0]; min[1] = x[1];
      min[2] = max[2];
      view->NDCtoWC(min, x);
   }
   TShape *shape = GetShape();
   if (shape)
      sprintf(info,"%6.2f/%6.2f/%6.2f: %s/%s, shape=%s/%s",x[0],x[1],x[2],GetName(),GetTitle(),shape->GetName(),shape->ClassName());
   else
      sprintf(info,"%6.2f/%6.2f/%6.2f: %s/%s",x[0],x[1],x[2],GetName(),GetTitle());
   return info;
}

//______________________________________________________________________________
TVolumePosition  *TVolumeView::Local2Master(const Char_t *localName, const Char_t *masterName)
{
   //to be documented
   TVolumeView *masterNode = this;
   TVolumePosition *position = 0;
   if (masterName && masterName[0]) masterNode = (TVolumeView *)Find(masterName);
   if (masterNode) {
      TVolumeViewIter transform(masterNode,0);
      if (transform(localName)) position = transform[0];
   }
   return position;
}

//______________________________________________________________________________
TVolumePosition *TVolumeView::Local2Master(const TVolumeView *localNode,const TVolumeView *masterNode)
{
   //to be documented
   TVolumePosition *position = 0;
   if (!masterNode) masterNode = this;
   if (masterNode && localNode) {
      TVolumeViewIter transform((TVolumeView *)masterNode,0);
      TVolumeView *nextNode = 0;
      while ((nextNode = (TVolumeView *)transform()) && nextNode != localNode) { }
      if (nextNode) position = transform[0];
   }
   return position;
}

//______________________________________________________________________________
Float_t *TVolumeView::Local2Master(const Float_t *local, Float_t *master,
                                   const Char_t *localName, const Char_t *masterName, Int_t nVector)
{
  //
  // calculate  transformation  master = (M-local->master )*local + (T-local->master )
  //  where
  //     M-local->master - rotation matrix 3 x 3 from the master node to the local node
  //     T-local->master - trasport vector 3 from the master node to the local node
  //
  // returns a "master" pointer if transformation has been found
  //        otherwise 0;
  //
   Float_t *trans = 0;
   TVolumePosition *position = 0;
   TVolumeView *masterNode = this;
   if (masterName && masterName[0]) masterNode = (TVolumeView *)Find(masterName);
   if (masterNode) {
      TVolumeViewIter transform(masterNode,0);
      if (transform(localName) && (position = (TVolumePosition *) transform.GetPosition()) )
         trans = position->Local2Master(local,master,nVector);
   }
   return trans;
}

//______________________________________________________________________________
Float_t *TVolumeView::Local2Master(const Float_t *local, Float_t *master,
                                   const TVolumeView *localNode,
                                   const TVolumeView *masterNode, Int_t nVector)
{
  //
  // calculate  transformation  master = (M-local->master )*local + (T-local->master )
  //  where
  //     M-local->master - rotation matrix 3 x 3 from the master node to the local node
  //     T-local->master - trasport vector 3 from the master node to the local node
  //
  // returns a "master" pointer if transformation has been found
  //        otherwise 0;
  //
   Float_t *trans = 0;
   TVolumePosition *position = 0;
   if (!masterNode) masterNode = this;
   if (masterNode && localNode) {
      TVolumeViewIter transform((TVolumeView *)masterNode,0);
      TVolumeView *nextNode = 0;
      while ((nextNode = (TVolumeView *)transform()) && nextNode != localNode) { }
      if (nextNode && (position = (TVolumePosition *) transform.GetPosition()) )
         trans = position->Local2Master(local,master,nVector);
   }
   return trans;
}

//______________________________________________________________________________
void TVolumeView::Paint(Option_t *option)
{
//*-*-*-*-*-*-*-*-*-*-*-*Paint Referenced node with current parameters*-*-*-*
//*-*                   ==============================================
//*-*
//*-*  vis = 1  (default) shape is drawn
//*-*  vis = 0  shape is not drawn but its sons may be not drawn
//*-*  vis = -1 shape is not drawn. Its sons are not drawn
//*-*  vis = -2 shape is drawn. Its sons are not drawn
//*-*
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//
// It draw the TVolumeView layers from the iFirst one (form the zero) till
// iLast one reached.
//
// restrict the levels for "range" option
   Int_t level = gGeometry->GeomLevel();
   if (option && option[0]=='r' && level > 3 ) return;

   Int_t iFirst =  atoi(option);
   Int_t iLast = 0;
   const char *delim = strpbrk( option,":-,");
   if (delim)  iLast = atoi(delim+1);
   if (iLast < iFirst) {
      iLast = iFirst-1;
      iFirst = 0;
   }

   if ( (0 < iLast) && (iLast < level) )  return;

   TTablePadView3D *view3D = (TTablePadView3D*)gPad->GetView3D();

   TVolume *thisNode  = 0;
   TVolumePosition *position = GetPosition();

   // UpdatePosition does change the current matrix and it MUST be called FIRST !!!
   if (position) {
      thisNode  = position->GetNode();
      position->UpdatePosition(option);
   }

   // if (option[0] !='r' ) printf(" Level %d first = %d  iLast %d \n",level, iFirst, iLast);
   if (level >= iFirst) {
      PaintShape(option);
      if (thisNode)  thisNode->PaintShape(option);
   }
////---   if ( thisNode->TestBit(kSonsInvisible) ) return;

//*-*- Paint all sons
   TSeqCollection *nodes =  GetCollection();
   Int_t nsons = nodes?nodes->GetSize():0;

   if(!nsons) return;

   gGeometry->PushLevel();
   TVolumeView *node;
   TIter  next(nodes);
   while ((node = (TVolumeView *)next())) {
      if (view3D)  view3D->PushMatrix();

      node->Paint(option);

      if (view3D)  view3D->PopMatrix();
   }
   gGeometry->PopLevel();
}

//______________________________________________________________________________
void TVolumeView::PaintShape(Option_t *option)
{
   // Paint shape of the node
   // To be called from the TObject::Paint method only
   Bool_t rangeView = option && option[0]=='r';

   TIter nextShape(fListOfShapes);
   TShape *shape = 0;
   while( (shape = (TShape *)nextShape()) ) {
      if (!shape->GetVisibility())   continue;
      if (!rangeView) {
         TTablePadView3D *view3D = (TTablePadView3D*)gPad->GetView3D();
         if (view3D)
            view3D->SetLineAttr(shape->GetLineColor(),shape->GetLineWidth(),option);
      }
#if ROOT_VERSION_CODE >= ROOT_VERSION(4,03,05)
      // It MUST be the TShape::PAint method:
      Bool_t viewerWantsSons = kTRUE;
      TVirtualViewer3D * viewer3D = gPad->GetViewer3D();
      if (viewer3D) {
         // We only provide master frame positions in these shapes
         // so don't ask viewer preference

         // Ask all shapes for kCore/kBoundingBox/kShapeSpecific
         // Not all will support the last two - which is fine
         const TBuffer3D & buffer =
            shape->GetBuffer3D(TBuffer3D::kCore|TBuffer3D::kBoundingBox|TBuffer3D::kShapeSpecific);

         // TShape sets buffer id based on TNode * gNode
         // As we not using TNode we need to override this
         const_cast<TBuffer3D &>(buffer).fID = this;

         Int_t reqSections = viewer3D->AddObject(buffer, &viewerWantsSons);
         if (reqSections != TBuffer3D::kNone) {
            shape->GetBuffer3D(reqSections);
            viewer3D->AddObject(buffer);
         }
      }
#else
      shape->Paint(option);
#endif
   }
}

//______________________________________________________________________________
TString TVolumeView::PathP() const
{
   // return the full path of this data set
   TString str;
   TVolumeView *parent = (TVolumeView *)GetParent();
   if (parent) {
      str = parent->PathP();
      str += "/";
   }
   str +=  GetName();
   UInt_t positionId = 0;
   TVolumePosition *p = GetPosition();
   if (p) {
      char buffer[10];
      positionId = p->GetId();
      sprintf(buffer,";%d",p->GetId());
      str +=  buffer;
   }
   return str;
}

//_______________________________________________________________________
void TVolumeView::SavePrimitive(ostream &out, Option_t * /*= ""*/)
{
   //to be documented
   const Char_t *sceleton[] = {
      "TVolumeView *CreateNodeView(TVolume *topNode) {"
     ,"  TString     thisNodePath   = "
     ,"  UInt_t      thisPositionId = "
     ,"  Double_t thisTranslate[3]  = "
     ," "
     ,"  TString        matrixName  = "
     ,"  Int_t          matrixType  = "
     ,"  Double_t     thisMatrix[]  = {  "
     ,"                                  "
     ,"                                  "
     ,"                               };"
     ,"  return = new TVolumeView(thisTranslate, thisMatrix, thisPositionId, topNode,"
     ,"                          thisNodePath.Data(),matrixName.Data(), matrixType);"
     ,"}"
   };
//------------------- end of sceleton ---------------------
   Int_t sceletonSize = sizeof(sceleton)/4;
   TVolumePosition *thisPosition = GetPosition();
   TVolume *thisFullNode = GetNode();
   TString thisNodePath = thisFullNode ? thisFullNode->Path() : TString("");
   // Define position
   UInt_t thisPositionId = thisPosition ? thisPosition->GetId():0;
   Double_t thisX  = thisPosition ? thisPosition->GetX():0;
   Double_t thisY  = thisPosition ? thisPosition->GetY():0;
   Double_t thisZ  = thisPosition ? thisPosition->GetZ():0;

   const TRotMatrix *matrix = thisPosition ? thisPosition->GetMatrix():0;
   Int_t matrixType = 2;
   TString matrixName = " ";
   Double_t thisMatrix[] = { 0,0,0, 0,0,0, 0,0,0 };
   if (matrix) {
      matrixName = matrix->GetName();
      memcpy(thisMatrix,((TRotMatrix *)matrix)->GetMatrix(),9*sizeof(Double_t));
      matrixType = matrix->GetType();
   }
   Int_t im = 0;
   for (Int_t lineNumber =0; lineNumber < sceletonSize; lineNumber++) {
      out << sceleton[lineNumber];                             // cout << lineNumber << ". " << sceleton[lineNumber];
      switch (lineNumber) {
         case  1:  out  << "\"" << thisNodePath.Data() << "\";" ; // cout  << "\"" << thisNodePath.Data() << "\";" ;
            break;
         case  2:  out   << thisPositionId << ";" ; // cout  << "\"" << thisNodePath.Data() << "\";" ;
            break;
         case  3:  out << "{" << thisX << ", " << thisY << ", "<< thisZ << "};";  // cout << thisX << ";" ;
            break;
         case  5:  out << "\"" << matrixName << "\";" ;           // cout << "\"" << matrixName << "\";" ;
            break;
         case  6:  out <<  matrixType << ";" ;                    // cout <<  matrixType << ";" ;
            break;
         case  7:  out << thisMatrix[im++] << ", "; out << thisMatrix[im++] << ", "; out << thisMatrix[im++] << ", ";
            break;
         case  8:  out << thisMatrix[im++] << ", "; out << thisMatrix[im++] << ", "; out << thisMatrix[im++] << ", ";
            break;
         case  9:  out << thisMatrix[im++] << ", "; out << thisMatrix[im++] << ", "; out << thisMatrix[im++];
            break;
         default:
            break;
      };
//   cout << " " << endl;
      out << " " << endl;
   }
}

//______________________________________________________________________________
void  TVolumeView::SetLineAttributes()
{
   //to be documented
   TVolume *thisNode = GetNode();
   if (thisNode) thisNode->SetLineAttributes();
}

//______________________________________________________________________________
void TVolumeView::SetVisibility(Int_t vis)
{
   //to be documented
   TVolume *node = GetNode();
   if (node) node->SetVisibility(TVolume::ENodeSEEN(vis));
}

//______________________________________________________________________________
void TVolumeView::Sizeof3D() const
{
//*-*-*-*-*-*-*Return total size of this 3-D Node with its attributes*-*-*
//*-*          ==========================================================

   if (GetListOfShapes()) {
      TIter nextShape(GetListOfShapes());
      TShape *shape = 0;
      while( (shape = (TShape *)nextShape()) ) {
         if (shape->GetVisibility())  shape->Sizeof3D();
      }
   }

   TVolume *thisNode  = GetNode();
   if (thisNode && !(thisNode->GetVisibility()&TVolume::kThisUnvisible) ) {
      TIter nextShape(thisNode->GetListOfShapes());
      TShape *shape = 0;
      while( (shape = (TShape *)nextShape()) ) {
         if (shape->GetVisibility())  shape->Sizeof3D();
      }
   }

//   if ( TestBit(kSonsInvisible) ) return;

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