27 const Int_t kMAXLEVELS = 20;
 
   28 const Int_t kVectorSize = 3;
 
   29 const Int_t kMatrixSize = kVectorSize*kVectorSize;
 
   32 static Double_t gTranslation[kMAXLEVELS][kVectorSize];
 
   33 static Double_t gRotMatrix[kMAXLEVELS][kMatrixSize];
 
   34 static Int_t gGeomLevel = 0;
 
   81 TNode::TNode(
const char *name, 
const char *title, 
const char *shapename, Double_t x, Double_t y, Double_t z, 
const char *matrixname, Option_t *option)
 
   82        :TNamed(name,title),TAttLine(), TAttFill()
 
   89    static Int_t counter = 0;
 
   95    fShape  = gGeometry->GetShape(shapename);
 
   96    fParent = gGeometry->GetCurrentNode();
 
  100    if (strlen(matrixname)) fMatrix = gGeometry->GetRotMatrix(matrixname);
 
  102       fMatrix = gGeometry->GetRotMatrix(
"Identity");
 
  104          fMatrix  = 
new TRotMatrix(
"Identity",
"Identity matrix",90,0,90,90,0,0);
 
  108       Printf(
"Error Referenced shape does not exist: %s",shapename);
 
  112    ImportShapeAttributes();
 
  114       fParent->BuildListOfNodes();
 
  115       fParent->GetListOfNodes()->Add(
this);
 
  117       gGeometry->GetListOfNodes()->Add(
this);
 
  133 TNode::TNode(
const char *name, 
const char *title, TShape *shape, Double_t x, Double_t y, Double_t z, TRotMatrix *matrix, Option_t *option)
 
  134                 :TNamed(name,title),TAttLine(),TAttFill()
 
  139    SetLineColor(lcolor);
 
  150    fParent = gGeometry->GetCurrentNode();
 
  152       fMatrix =gGeometry->GetRotMatrix(
"Identity");
 
  154          fMatrix  = 
new TRotMatrix(
"Identity",
"Identity matrix",90,0,90,90,0,0);
 
  157    if(!shape) {Printf(
"Illegal referenced shape"); 
return;}
 
  160       fParent->BuildListOfNodes();
 
  161       fParent->GetListOfNodes()->Add(
this);
 
  162       ImportShapeAttributes();
 
  164       gGeometry->GetListOfNodes()->Add(
this);
 
  173 TNode::TNode(
const TNode& no) :
 
  186   fVisibility(no.fVisibility)
 
  193 TNode& TNode::operator=(
const TNode& no)
 
  196       TNamed::operator=(no);
 
  197       TAttLine::operator=(no);
 
  198       TAttFill::operator=(no);
 
  199       TAtt3D::operator=(no);
 
  208       fVisibility=no.fVisibility;
 
  218    if (fParent)     fParent->GetListOfNodes()->Remove(
this);
 
  219    else    {
if (gGeometry) gGeometry->GetListOfNodes()->Remove(
this);}
 
  220    if (fNodes) fNodes->Delete();
 
  221    if (gGeometry && gGeometry->GetCurrentNode() == 
this) gGeometry->SetCurrentNode(0);
 
  229 void TNode::Browse(TBrowser *b)
 
  242 void TNode::BuildListOfNodes()
 
  244    if (!fNodes) fNodes   = 
new TList;
 
  250 void TNode::cd(
const char *)
 
  252    gGeometry->SetCurrentNode(
this);
 
  261 Int_t TNode::DistancetoPrimitive(Int_t px, Int_t py)
 
  263    const Int_t big = 9999;
 
  264    const Int_t inaxis = 7;
 
  265    const Int_t maxdist = 5;
 
  267    Int_t puxmin = gPad->XtoAbsPixel(gPad->GetUxmin());
 
  268    Int_t puymin = gPad->YtoAbsPixel(gPad->GetUymin());
 
  269    Int_t puxmax = gPad->XtoAbsPixel(gPad->GetUxmax());
 
  270    Int_t puymax = gPad->YtoAbsPixel(gPad->GetUymax());
 
  273    if (px < puxmin - inaxis) 
return big;
 
  274    if (py > puymin + inaxis) 
return big;
 
  275    if (px > puxmax + inaxis) 
return big;
 
  276    if (py < puymax - inaxis) 
return big;
 
  278    TView *view =gPad->GetView();
 
  279    if (!view) 
return big;
 
  282    if (fMatrix && gGeometry) {
 
  283       gGeometry->UpdateTempMatrix(fX,fY,fZ,fMatrix->GetMatrix(),fMatrix->IsReflection());
 
  288    if (fVisibility && fShape->GetVisibility()) {
 
  290       dist = fShape->DistancetoPrimitive(px,py);
 
  291       if (dist < maxdist) {
 
  292          gPad->SetSelected(
this);
 
  296    if ( TestBit(kSonsInvisible) ) 
return dist;
 
  297    if (!gGeometry) 
return dist;
 
  301    if (fNodes) nsons = fNodes->GetSize();
 
  304       gGeometry->PushLevel();
 
  308       while ((obj = next())) {
 
  310          dnode = node->DistancetoPrimitive(px,py);
 
  311          if (dnode <= 0) 
break;
 
  312          if (dnode < dist) dist = dnode;
 
  314       gGeometry->PopLevel();
 
  323 void TNode::Draw(Option_t *option)
 
  325    TString opt = option;
 
  330       gROOT->MakeDefCanvas();
 
  332    if (!opt.Contains(
"same")) gPad->Clear();
 
  335    if (!gGeometry) 
new TGeometry;
 
  336    gGeometry->SetGeomLevel();
 
  337    gGeometry->UpdateTempMatrix();
 
  342    TView *view = gPad->GetView();
 
  344       view = TView::CreateView(11,0,0);
 
  347       if (view) view->SetAutoRange(kTRUE);
 
  351    gPad->GetViewer3D(option);
 
  357 void TNode::DrawOnly(Option_t *option)
 
  369 void TNode::ExecuteEvent(Int_t, Int_t, Int_t)
 
  372    gPad->SetCursor(kHand);
 
  378 TNode *TNode::GetNode(
const char *name)
 const 
  380    if (!strcmp(name, GetName())) 
return (TNode*)
this;
 
  381    TNode *node, *nodefound;
 
  382    if (!fNodes) 
return 0;
 
  383    TObjLink *lnk = fNodes->FirstLink();
 
  385       node = (TNode *)lnk->GetObject();
 
  386       if (node->TestBit(kNotDeleted)) {
 
  387          nodefound = node->GetNode(name);
 
  388          if (nodefound) 
return nodefound;
 
  398 char *TNode::GetObjectInfo(Int_t, Int_t)
 const 
  400    const char *snull = 
"";
 
  401    if (!gPad) 
return (
char*)snull;
 
  403    info.Form(
"%s/%s, shape=%s/%s",GetName(),GetTitle(),fShape->GetName(),fShape->ClassName());
 
  404    return const_cast<char*
>(info.Data());
 
  410 void TNode::ImportShapeAttributes()
 
  412    SetLineColor(fShape->GetLineColor());
 
  413    SetLineStyle(fShape->GetLineStyle());
 
  414    SetLineWidth(fShape->GetLineWidth());
 
  415    SetFillColor(fShape->GetFillColor());
 
  416    SetFillStyle(fShape->GetFillStyle());
 
  421    TObjLink *lnk = fNodes->FirstLink();
 
  423       node = (TNode *)lnk->GetObject();
 
  424       node->ImportShapeAttributes();
 
  432 Bool_t TNode::IsFolder()
 const 
  434    if (fNodes) 
return kTRUE;
 
  446 void TNode::Local2Master(
const Double_t *local, Double_t *master)
 
  449    Float_t bomb = gGeometry->GetBomb();
 
  451    Double_t *matrix      = &gRotMatrix[gGeomLevel][0];
 
  452    Double_t *translation = &gTranslation[gGeomLevel][0];
 
  454    x = bomb*translation[0]
 
  457      + local[2]*matrix[6];
 
  459    y = bomb*translation[1]
 
  462      + local[2]*matrix[7];
 
  464    z = bomb*translation[2]
 
  467      + local[2]*matrix[8];
 
  469    master[0] = x; master[1] = y; master[2] = z;
 
  480 void TNode::Local2Master(
const Float_t *local, Float_t *master)
 
  483    Float_t bomb = gGeometry->GetBomb();
 
  485    Double_t *matrix      = &gRotMatrix[gGeomLevel][0];
 
  486    Double_t *translation = &gTranslation[gGeomLevel][0];
 
  488    x = bomb*translation[0]
 
  491      + local[2]*matrix[6];
 
  493    y = bomb*translation[1]
 
  496      + local[2]*matrix[7];
 
  498    z = bomb*translation[2]
 
  501      + local[2]*matrix[8];
 
  503    master[0] = x; master[1] = y; master[2] = z;
 
  509 void TNode::ls(Option_t *option)
 const 
  512    TString opt = option;
 
  515    if (!gGeometry) 
new TGeometry;
 
  518    if (opt.Contains(
"1")) maxlevel = 1;
 
  519    if (opt.Contains(
"2")) maxlevel = 2;
 
  520    if (opt.Contains(
"3")) maxlevel = 3;
 
  521    if (opt.Contains(
"4")) maxlevel = 4;
 
  522    if (opt.Contains(
"5")) maxlevel = 5;
 
  523    if (opt.Contains(
"x")) sizeX3D  = 1;
 
  525    TROOT::IndentLevel();
 
  528    if (fNodes) nsons = fNodes->GetSize();
 
  529    const char *shapename, *matrixname;
 
  530    if (fShape) shapename = fShape->IsA()->GetName();
 
  531    else        shapename = 
"????";
 
  532    std::cout<<GetName()<<
":"<<GetTitle()<<
" is a "<<shapename;
 
  534       gSize3D.numPoints = 0;
 
  536       gSize3D.numPolys  = 0;
 
  538       std::cout<<
" NumPoints="<<gSize3D.numPoints;
 
  539       std::cout<<
" NumSegs  ="<<gSize3D.numSegs;
 
  540       std::cout<<
" NumPolys ="<<gSize3D.numPolys;
 
  542       std::cout<<
" X="<<fX<<
" Y="<<fY<<
" Z="<<fZ;
 
  543       if (nsons) std::cout<<
" Sons="<<nsons;
 
  544       if (fMatrix) matrixname   = fMatrix->GetName();
 
  545       else         matrixname   = 
"Identity";
 
  546       if(strcmp(matrixname,
"Identity")) std::cout<<
" Rot="<<matrixname;
 
  548    std::cout<<std::endl;
 
  550    if (gGeomLevel >= maxlevel) 
return;
 
  552    TROOT::IncreaseDirLevel();
 
  556    TROOT::DecreaseDirLevel();
 
  568 void TNode::Master2Local(
const Double_t *master, Double_t *local)
 
  571    Float_t bomb = gGeometry->GetBomb();
 
  573    Double_t *matrix      = &gRotMatrix[gGeomLevel][0];
 
  574    Double_t *translation = &gTranslation[gGeomLevel][0];
 
  576    Double_t xms = master[0] - bomb*translation[0];
 
  577    Double_t yms = master[1] - bomb*translation[1];
 
  578    Double_t zms = master[2] - bomb*translation[2];
 
  580    x = xms*matrix[0] + yms*matrix[1] + zms*matrix[2];
 
  581    y = xms*matrix[3] + yms*matrix[4] + zms*matrix[5];
 
  582    z = xms*matrix[6] + yms*matrix[7] + zms*matrix[8];
 
  584    local[0] = x; local[1] = y; local[2] = z;
 
  595 void TNode::Master2Local(
const Float_t *master, Float_t *local)
 
  598    Float_t bomb = gGeometry->GetBomb();
 
  600    Double_t *matrix      = &gRotMatrix[gGeomLevel][0];
 
  601    Double_t *translation = &gTranslation[gGeomLevel][0];
 
  603    Double_t xms = master[0] - bomb*translation[0];
 
  604    Double_t yms = master[1] - bomb*translation[1];
 
  605    Double_t zms = master[2] - bomb*translation[2];
 
  607    x = xms*matrix[0] + yms*matrix[1] + zms*matrix[2];
 
  608    y = xms*matrix[3] + yms*matrix[4] + zms*matrix[5];
 
  609    z = xms*matrix[6] + yms*matrix[7] + zms*matrix[8];
 
  611    local[0] = x; local[1] = y; local[2] = z;
 
  622 void TNode::Paint(Option_t *option)
 
  625    if (gGeometry) level = gGeometry->GeomLevel();
 
  629       gGeometry->UpdateTempMatrix(fX,fY,fZ,fMatrix->GetMatrix(),fMatrix->IsReflection());
 
  634    if (fNodes) nsons = fNodes->GetSize();
 
  639    Bool_t viewerWantsSons = kTRUE;
 
  641    if (fVisibility && fShape->GetVisibility()) {
 
  643       fShape->SetLineColor(GetLineColor());
 
  644       fShape->SetLineStyle(GetLineStyle());
 
  645       fShape->SetLineWidth(GetLineWidth());
 
  646       fShape->SetFillColor(GetFillColor());
 
  647       fShape->SetFillStyle(GetFillStyle());
 
  649       TVirtualViewer3D * viewer3D = gPad->GetViewer3D();
 
  656          const TBuffer3D & buffer =
 
  657             fShape->GetBuffer3D(TBuffer3D::kCore|TBuffer3D::kBoundingBox|TBuffer3D::kShapeSpecific);
 
  659          Int_t reqSections = viewer3D->AddObject(buffer, &viewerWantsSons);
 
  660          if (reqSections != TBuffer3D::kNone)
 
  662             fShape->GetBuffer3D(reqSections);
 
  663             viewer3D->AddObject(buffer, &viewerWantsSons);
 
  667    if ( TestBit(kSonsInvisible) ) 
return;
 
  670    if(!nsons || !viewerWantsSons) 
return;
 
  672    gGeometry->PushLevel();
 
  676    while ((obj = next())) {
 
  680    gGeometry->PopLevel();
 
  686 void TNode::RecursiveRemove(TObject *obj)
 
  688    if (fNodes && dynamic_cast<TNode*>(obj) ) fNodes->RecursiveRemove(obj);
 
  694 void TNode::SetName(
const char *name)
 
  696    if (gPad) gPad->Modified();
 
  700    if (fParent) fParent->GetListOfNodes()->Remove(
this);
 
  702    if (fParent) fParent->GetListOfNodes()->Add(
this);
 
  708 void TNode::SetNameTitle(
const char *name, 
const char *title)
 
  710    if (gPad) gPad->Modified();
 
  714    if (fParent) fParent->GetListOfNodes()->Remove(
this);
 
  717    if (fParent) fParent->GetListOfNodes()->Add(
this);
 
  723 void TNode::SetParent(TNode *parent)
 
  728          printf(
"Error: Cannot set parent node to be a child node:%s\n",GetName());
 
  729          printf(
"       Operation not performed!\n");
 
  732       pp = pp->GetParent();
 
  735    if (fParent)   fParent->GetListOfNodes()->Remove(
this);
 
  736    else         gGeometry->GetListOfNodes()->Remove(
this);
 
  741       fParent->BuildListOfNodes(); 
 
  742       fParent->GetListOfNodes()->Add(
this);
 
  744    else gGeometry->GetListOfNodes()->Add(
this);
 
  759 void TNode::SetVisibility(Int_t vis)
 
  761    ResetBit(kSonsInvisible);
 
  765       if (!fNodes) { fVisibility = 1; 
return;}
 
  766       TIter  next(fNodes); 
while ((node = (TNode*)next())) { node->SetVisibility(-2); }
 
  767    } 
else if (vis == -3 ) {  
 
  769       if (!fNodes) { fVisibility = 1; 
return;}
 
  770       TIter  next(fNodes); 
while ((node = (TNode*)next())) { node->SetVisibility(-3); }
 
  772    } 
else if (vis == -2) {  
 
  773       fVisibility = 1; SetBit(kSonsInvisible); 
if (!fNodes) 
return;
 
  774       TIter  next(fNodes); 
while ((node = (TNode*)next())) { node->SetVisibility(-1); }
 
  776    } 
else if (vis == -1) {  
 
  777       fVisibility = 0; SetBit(kSonsInvisible); 
if (!fNodes) 
return;
 
  778       TIter  next(fNodes); 
while ((node = (TNode*)next())) { node->SetVisibility(-1); }
 
  780    } 
else if (vis ==  0) {  
 
  783    } 
else if (vis ==  1) {  
 
  786    } 
else if (vis ==  2) {  
 
  787       fVisibility = 0; 
if (!fNodes) 
return;
 
  788       TIter  next(fNodes); 
while ((node = (TNode*)next())) { node->SetVisibility(3); }
 
  790    } 
else if (vis ==  3) {  
 
  791       fVisibility = 1; 
if (!fNodes) 
return;
 
  792       TIter  next(fNodes); 
while ((node = (TNode*)next())) { node->SetVisibility(3); }
 
  799 void TNode::Sizeof3D()
 const 
  801    if (fVisibility && fShape && fShape->GetVisibility()) {
 
  804    if ( TestBit(kSonsInvisible) ) 
return;
 
  810    while ((obj = next())) {
 
  819 void TNode::Streamer(TBuffer &b)
 
  823       Version_t R__v = b.ReadVersion(&R__s, &R__c);
 
  825          b.ReadClassBuffer(TNode::Class(), 
this, R__v, R__s, R__c);
 
  830       TAttLine::Streamer(b);
 
  831       TAttFill::Streamer(b);
 
  840       if (R__v > 1) b >> fVisibility;
 
  841       else  fVisibility = fShape->GetVisibility();
 
  842       b.CheckByteCount(R__s, R__c, TNode::IsA());
 
  846       b.WriteClassBuffer(TNode::Class(),
this);
 
  854 void TNode::UpdateMatrix()
 
  856    TNode *nodes[kMAXLEVELS], *node;
 
  858    for (i=0;i<kVectorSize;i++) gTranslation[0][i] = 0;
 
  859    for (i=0;i<kMatrixSize;i++) gRotMatrix[0][i] = 0;
 
  860    gRotMatrix[0][0] = 1;   gRotMatrix[0][4] = 1;   gRotMatrix[0][8] = 1;
 
  866       nodes[gGeomLevel] = node;
 
  867       node = node->GetParent();
 
  872    for (i=1;i<=gGeomLevel;i++) {
 
  873       node = nodes[gGeomLevel-i];
 
  874       UpdateTempMatrix(&(gTranslation[i-1][0]),&gRotMatrix[i-1][0]
 
  875                       ,node->GetX(),node->GetY(),node->GetZ(),node->GetMatrix()->GetMatrix()
 
  876                       ,&gTranslation[i][0],&gRotMatrix[i][0]);
 
  889 void TNode::UpdateTempMatrix(
const Double_t *dx,
const Double_t *rmat
 
  890                          , Double_t x, Double_t y, Double_t z, Double_t *matrix
 
  891                          , Double_t *dxnew, Double_t *rmatnew)
 
  893    dxnew[0] = dx[0] + x*rmat[0] + y*rmat[3] + z*rmat[6];
 
  894    dxnew[1] = dx[1] + x*rmat[1] + y*rmat[4] + z*rmat[7];
 
  895    dxnew[2] = dx[2] + x*rmat[2] + y*rmat[5] + z*rmat[8];
 
  897    rmatnew[0] = rmat[0]*matrix[0] + rmat[3]*matrix[1] + rmat[6]*matrix[2];
 
  898    rmatnew[1] = rmat[1]*matrix[0] + rmat[4]*matrix[1] + rmat[7]*matrix[2];
 
  899    rmatnew[2] = rmat[2]*matrix[0] + rmat[5]*matrix[1] + rmat[8]*matrix[2];
 
  900    rmatnew[3] = rmat[0]*matrix[3] + rmat[3]*matrix[4] + rmat[6]*matrix[5];
 
  901    rmatnew[4] = rmat[1]*matrix[3] + rmat[4]*matrix[4] + rmat[7]*matrix[5];
 
  902    rmatnew[5] = rmat[2]*matrix[3] + rmat[5]*matrix[4] + rmat[8]*matrix[5];
 
  903    rmatnew[6] = rmat[0]*matrix[6] + rmat[3]*matrix[7] + rmat[6]*matrix[8];
 
  904    rmatnew[7] = rmat[1]*matrix[6] + rmat[4]*matrix[7] + rmat[7]*matrix[8];
 
  905    rmatnew[8] = rmat[2]*matrix[6] + rmat[5]*matrix[7] + rmat[8]*matrix[8];