TNode.cxx

Go to the documentation of this file.
00001 // @(#)root/g3d:$Id: TNode.cxx 35111 2010-09-01 16:12:27Z matevz $
00002 // Author: Rene Brun   14/09/95
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 #include "Riostream.h"
00013 #include "TROOT.h"
00014 #include "TClass.h"
00015 #include "TVirtualPad.h"
00016 #include "TView.h"
00017 #include "TGeometry.h"
00018 #include "TRotMatrix.h"
00019 #include "TShape.h"
00020 #include "TNode.h"
00021 #include "TBrowser.h"
00022 #include "X3DBuffer.h"
00023 #include "TVirtualViewer3D.h"
00024 #include "TBuffer3D.h"
00025 
00026 #if 0
00027 const Int_t kMAXLEVELS = 20;
00028 const Int_t kVectorSize = 3;
00029 const Int_t kMatrixSize = kVectorSize*kVectorSize;
00030 #endif
00031 
00032 static Double_t gTranslation[kMAXLEVELS][kVectorSize];
00033 static Double_t gRotMatrix[kMAXLEVELS][kMatrixSize];
00034 static Int_t gGeomLevel = 0;
00035 
00036 TNode *gNode;
00037 
00038 
00039 ClassImp(TNode)
00040 
00041 
00042 //______________________________________________________________________________
00043 //                    T N O D E  description
00044 //                    ======================
00045 //
00046 //    A TNode object is used to build the geometry hierarchy (see TGeometry).
00047 //    A node may contain other nodes.
00048 //
00049 //    A geometry node has attributes:
00050 //      - name and title
00051 //      - pointer to the referenced shape (see TShape).
00052 //      - x,y,z offset with respect to the mother node.
00053 //      - pointer to the rotation matrix (see TRotMatrix).
00054 //
00055 //    A node can be drawn.
00056 
00057 
00058 //______________________________________________________________________________
00059 TNode::TNode()
00060 {
00061    // Node default constructor.
00062 
00063    fMatrix = 0;
00064    fParent = 0;
00065    fShape  = 0;
00066    fNodes  = 0;
00067    fVisibility = 1;
00068    fX = fY = fZ = 0;
00069 }
00070 
00071 
00072 //______________________________________________________________________________
00073 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)
00074        :TNamed(name,title),TAttLine(), TAttFill()
00075 {
00076    // Node normal constructor.
00077    //
00078    //    name    is the name of the node
00079    //    title   is title
00080    //    shapename is the name of the referenced shape
00081    //    x,y,z   are the offsets of the volume with respect to his mother
00082    //    matrixname  is the name of the rotation matrix
00083    //
00084    //    This new node is added into the list of sons of the current node
00085 
00086 #ifdef WIN32
00087    // The color "1" - default produces a very bad 3D image with OpenGL
00088    Color_t lcolor = 16;
00089    SetLineColor(lcolor);
00090 #endif
00091    static Int_t counter = 0;
00092    counter++;
00093    fX      = x;
00094    fY      = y;
00095    fZ      = z;
00096    fNodes  = 0;
00097    fShape  = gGeometry->GetShape(shapename);
00098    fParent = gGeometry->GetCurrentNode();
00099    fOption = option;
00100    fVisibility = 1;
00101 
00102    if (strlen(matrixname)) fMatrix = gGeometry->GetRotMatrix(matrixname);
00103    else {
00104       fMatrix = gGeometry->GetRotMatrix("Identity");
00105       if (!fMatrix)
00106          fMatrix  = new TRotMatrix("Identity","Identity matrix",90,0,90,90,0,0);
00107    }
00108 
00109    if (!fShape) {
00110       Printf("Error Referenced shape does not exist: %s",shapename);
00111       return;
00112    }
00113 
00114    ImportShapeAttributes();
00115    if (fParent) {
00116       fParent->BuildListOfNodes();
00117       fParent->GetListOfNodes()->Add(this);
00118    } else {
00119       gGeometry->GetListOfNodes()->Add(this);
00120       cd();
00121    }
00122 }
00123 
00124 
00125 //______________________________________________________________________________
00126 TNode::TNode(const char *name, const char *title, TShape *shape, Double_t x, Double_t y, Double_t z, TRotMatrix *matrix, Option_t *option)
00127                 :TNamed(name,title),TAttLine(),TAttFill()
00128 {
00129    // Node normal constructor.
00130    //
00131    //    name    is the name of the node
00132    //    title   is title
00133    //    shape   is the pointer to the shape definition
00134    //    x,y,z   are the offsets of the volume with respect to his mother
00135    //    matrix  is the pointer to the rotation matrix
00136    //
00137    //    This new node is added into the list of sons of the current node
00138 
00139 #ifdef WIN32
00140 //*-* The color "1" - default produces a very bad 3D image with OpenGL
00141    Color_t lcolor = 16;
00142    SetLineColor(lcolor);
00143 #endif
00144 
00145    fX      = x;
00146    fY      = y;
00147    fZ      = z;
00148    fNodes  = 0;
00149    fShape  = shape;
00150    fMatrix = matrix;
00151    fOption = option;
00152    fVisibility = 1;
00153    fParent = gGeometry->GetCurrentNode();
00154    if(!fMatrix) {
00155       fMatrix =gGeometry->GetRotMatrix("Identity");
00156       if (!fMatrix)
00157          fMatrix  = new TRotMatrix("Identity","Identity matrix",90,0,90,90,0,0);
00158    }
00159 
00160    if(!shape) {Printf("Illegal referenced shape"); return;}
00161 
00162    if (fParent) {
00163       fParent->BuildListOfNodes();
00164       fParent->GetListOfNodes()->Add(this);
00165       ImportShapeAttributes();
00166    } else {
00167       gGeometry->GetListOfNodes()->Add(this);
00168       cd();
00169    }
00170 
00171 }
00172 
00173 //______________________________________________________________________________
00174 TNode::TNode(const TNode& no) :
00175   TNamed(no),
00176   TAttLine(no),
00177   TAttFill(no),
00178   TAtt3D(no),
00179   fX(no.fX),
00180   fY(no.fY),
00181   fZ(no.fZ),
00182   fMatrix(no.fMatrix),
00183   fShape(no.fShape),
00184   fParent(no.fParent),
00185   fNodes(no.fNodes),
00186   fOption(no.fOption),
00187   fVisibility(no.fVisibility)
00188 { 
00189 //copy constructor
00190 }
00191 
00192 //______________________________________________________________________________
00193 TNode& TNode::operator=(const TNode& no)
00194 {
00195    //assignement operator
00196    if(this!=&no) {
00197       TNamed::operator=(no);
00198       TAttLine::operator=(no);
00199       TAttFill::operator=(no);
00200       TAtt3D::operator=(no);
00201       fX=no.fX;
00202       fY=no.fY;
00203       fZ=no.fZ;
00204       fMatrix=no.fMatrix;
00205       fShape=no.fShape;
00206       fParent=no.fParent;
00207       fNodes=no.fNodes;
00208       fOption=no.fOption;
00209       fVisibility=no.fVisibility;
00210    }
00211    return *this;
00212 }
00213 
00214 //______________________________________________________________________________
00215 TNode::~TNode()
00216 {
00217    // Node default destructor.
00218 
00219    if (fParent)     fParent->GetListOfNodes()->Remove(this);
00220    else    {if (gGeometry) gGeometry->GetListOfNodes()->Remove(this);}
00221    if (fNodes) fNodes->Delete();
00222    if (gGeometry && gGeometry->GetCurrentNode() == this) gGeometry->SetCurrentNode(0);
00223    delete fNodes;
00224    fNodes = 0;
00225 }
00226 
00227 
00228 //______________________________________________________________________________
00229 void TNode::Browse(TBrowser *b)
00230 {
00231    // Browse.
00232 
00233    if( fNodes ) {
00234       fNodes->Browse( b );
00235    } else {
00236       Draw();
00237       gPad->Update();
00238    }
00239 }
00240 
00241 
00242 //______________________________________________________________________________
00243 void TNode::BuildListOfNodes()
00244 {
00245    // Create the list to support sons of this node.
00246 
00247    if (!fNodes) fNodes   = new TList;
00248 }
00249 
00250 
00251 //______________________________________________________________________________
00252 void TNode::cd(const char *)
00253 {
00254    // Change Current Reference node to this.
00255 
00256    gGeometry->SetCurrentNode(this);
00257 }
00258 
00259 
00260 //______________________________________________________________________________
00261 Int_t TNode::DistancetoPrimitive(Int_t px, Int_t py)
00262 {
00263    // Compute distance from point px,py to a Node.
00264    //
00265    //  Compute the closest distance of approach from point px,py to this node.
00266    //  The distance is computed in pixels units.
00267 
00268    const Int_t big = 9999;
00269    const Int_t inaxis = 7;
00270    const Int_t maxdist = 5;
00271 
00272    Int_t puxmin = gPad->XtoAbsPixel(gPad->GetUxmin());
00273    Int_t puymin = gPad->YtoAbsPixel(gPad->GetUymin());
00274    Int_t puxmax = gPad->XtoAbsPixel(gPad->GetUxmax());
00275    Int_t puymax = gPad->YtoAbsPixel(gPad->GetUymax());
00276 
00277    // return if point is not in the user area
00278    if (px < puxmin - inaxis) return big;
00279    if (py > puymin + inaxis) return big;
00280    if (px > puxmax + inaxis) return big;
00281    if (py < puymax - inaxis) return big;
00282 
00283    TView *view =gPad->GetView();
00284    if (!view) return big;
00285 
00286    // Update translation vector and rotation matrix for new level
00287    if (fMatrix && gGeometry) {
00288       gGeometry->UpdateTempMatrix(fX,fY,fZ,fMatrix->GetMatrix(),fMatrix->IsReflection());
00289    }
00290 
00291    // Paint Referenced shape
00292    Int_t dist = big;
00293    if (fVisibility && fShape->GetVisibility()) {
00294       gNode = this;
00295       dist = fShape->DistancetoPrimitive(px,py);
00296       if (dist < maxdist) {
00297          gPad->SetSelected(this);
00298          return 0;
00299       }
00300    }
00301    if ( TestBit(kSonsInvisible) ) return dist;
00302    if (!gGeometry) return dist;
00303 
00304    // Loop on all sons
00305    Int_t nsons = 0;
00306    if (fNodes) nsons = fNodes->GetSize();
00307    Int_t dnode = dist;
00308    if (nsons) {
00309       gGeometry->PushLevel();
00310       TNode *node;
00311       TObject *obj;
00312       TIter  next(fNodes);
00313       while ((obj = next())) {
00314          node = (TNode*)obj;
00315          dnode = node->DistancetoPrimitive(px,py);
00316          if (dnode <= 0) break;
00317          if (dnode < dist) dist = dnode;
00318       }
00319       gGeometry->PopLevel();
00320    }
00321 
00322    return dnode;
00323 }
00324 
00325 
00326 //______________________________________________________________________________
00327 void TNode::Draw(Option_t *option)
00328 {
00329    // Draw Referenced node with current parameters.
00330 
00331    TString opt = option;
00332    opt.ToLower();
00333 
00334    // Clear pad if option "same" not given
00335    if (!gPad) {
00336       gROOT->MakeDefCanvas();
00337    }
00338    if (!opt.Contains("same")) gPad->Clear();
00339 
00340    // Draw Referenced node
00341    if (!gGeometry) new TGeometry;
00342    gGeometry->SetGeomLevel();
00343    gGeometry->UpdateTempMatrix();
00344 
00345    AppendPad(option);
00346 
00347    // Create a 3-D view
00348    TView *view = gPad->GetView();
00349    if (!view) {
00350       view = TView::CreateView(11,0,0);
00351       // Set the view to perform a first autorange (frame) draw. 
00352       // TViewer3DPad will revert view to normal painting after this
00353       view->SetAutoRange(kTRUE);
00354    }
00355    
00356    // Create a 3D viewer to draw us
00357    gPad->GetViewer3D(option);
00358 }
00359 
00360 
00361 //______________________________________________________________________________
00362 void TNode::DrawOnly(Option_t *option)
00363 {
00364    // Draw only Sons of this node.
00365 
00366    SetVisibility(2);
00367    Draw(option);
00368 }
00369 
00370 
00371 //______________________________________________________________________________
00372 void TNode::ExecuteEvent(Int_t, Int_t, Int_t)
00373 {
00374    // Execute action corresponding to one event.
00375    //
00376    //  This member function must be implemented to realize the action
00377    //  corresponding to the mouse click on the object in the window
00378 
00379    gPad->SetCursor(kHand);
00380 }
00381 
00382 
00383 //______________________________________________________________________________
00384 TNode *TNode::GetNode(const char *name) const
00385 {
00386    // Return pointer to node with name in the node tree.
00387 
00388    if (!strcmp(name, GetName())) return (TNode*)this;
00389    TNode *node, *nodefound;
00390    if (!fNodes) return 0;
00391    TObjLink *lnk = fNodes->FirstLink();
00392    while (lnk) {
00393       node = (TNode *)lnk->GetObject();
00394       if (node->TestBit(kNotDeleted)) {
00395          nodefound = node->GetNode(name);
00396          if (nodefound) return nodefound;
00397       }
00398       lnk = lnk->Next();
00399    }
00400    return 0;
00401 }
00402 
00403 
00404 //______________________________________________________________________________
00405 char *TNode::GetObjectInfo(Int_t, Int_t) const
00406 {
00407    // Get object info.
00408 
00409    const char *snull = "";
00410    if (!gPad) return (char*)snull;
00411    static TString info;
00412    info.Form("%s/%s, shape=%s/%s",GetName(),GetTitle(),fShape->GetName(),fShape->ClassName());
00413    return const_cast<char*>(info.Data());
00414 }
00415 
00416 
00417 //______________________________________________________________________________
00418 void TNode::ImportShapeAttributes()
00419 {
00420    // Copy shape attributes as node attributes.
00421 
00422    SetLineColor(fShape->GetLineColor());
00423    SetLineStyle(fShape->GetLineStyle());
00424    SetLineWidth(fShape->GetLineWidth());
00425    SetFillColor(fShape->GetFillColor());
00426    SetFillStyle(fShape->GetFillStyle());
00427 
00428    if (!fNodes) return;
00429    TNode *node;
00430 
00431    TObjLink *lnk = fNodes->FirstLink();
00432    while (lnk) {
00433       node = (TNode *)lnk->GetObject();
00434       node->ImportShapeAttributes();
00435       lnk = lnk->Next();
00436    }
00437 }
00438 
00439 
00440 //______________________________________________________________________________
00441 Bool_t TNode::IsFolder() const
00442 {
00443    // Return TRUE if node contains nodes, FALSE otherwise.
00444 
00445    if (fNodes) return kTRUE;
00446    else        return kFALSE;
00447 }
00448 
00449 
00450 //______________________________________________________________________________
00451 void TNode::Local2Master(const Double_t *local, Double_t *master)
00452 {
00453    // Convert one point from local system to master reference system.
00454    //
00455    //  Note that before invoking this function, the global rotation matrix
00456    //  and translation vector for this node must have been computed.
00457    //  This is automatically done by the Paint functions.
00458    //  Otherwise TNode::UpdateMatrix should be called before.
00459 
00460    Double_t x,y,z;
00461    Float_t bomb = gGeometry->GetBomb();
00462 
00463    Double_t *matrix      = &gRotMatrix[gGeomLevel][0];
00464    Double_t *translation = &gTranslation[gGeomLevel][0];
00465 
00466    x = bomb*translation[0]
00467      + local[0]*matrix[0]
00468      + local[1]*matrix[3]
00469      + local[2]*matrix[6];
00470 
00471    y = bomb*translation[1]
00472      + local[0]*matrix[1]
00473      + local[1]*matrix[4]
00474      + local[2]*matrix[7];
00475 
00476    z = bomb*translation[2]
00477      + local[0]*matrix[2]
00478      + local[1]*matrix[5]
00479      + local[2]*matrix[8];
00480 
00481    master[0] = x; master[1] = y; master[2] = z;
00482 }
00483 
00484 
00485 //______________________________________________________________________________
00486 void TNode::Local2Master(const Float_t *local, Float_t *master)
00487 {
00488    // Convert one point from local system to master reference system.
00489    //
00490    //  Note that before invoking this function, the global rotation matrix
00491    //  and translation vector for this node must have been computed.
00492    //  This is automatically done by the Paint functions.
00493    //  Otherwise TNode::UpdateMatrix should be called before.
00494 
00495    Float_t x,y,z;
00496    Float_t bomb = gGeometry->GetBomb();
00497 
00498    Double_t *matrix      = &gRotMatrix[gGeomLevel][0];
00499    Double_t *translation = &gTranslation[gGeomLevel][0];
00500 
00501    x = bomb*translation[0]
00502      + local[0]*matrix[0]
00503      + local[1]*matrix[3]
00504      + local[2]*matrix[6];
00505 
00506    y = bomb*translation[1]
00507      + local[0]*matrix[1]
00508      + local[1]*matrix[4]
00509      + local[2]*matrix[7];
00510 
00511    z = bomb*translation[2]
00512      + local[0]*matrix[2]
00513      + local[1]*matrix[5]
00514      + local[2]*matrix[8];
00515 
00516    master[0] = x; master[1] = y; master[2] = z;
00517 }
00518 
00519 
00520 //______________________________________________________________________________
00521 void TNode::ls(Option_t *option) const
00522 {
00523    // List Referenced object with current parameters.
00524 
00525    Int_t sizeX3D = 0;
00526    TString opt = option;
00527    opt.ToLower();
00528 
00529    if (!gGeometry) new TGeometry;
00530 
00531    Int_t maxlevel = 15;
00532    if (opt.Contains("1")) maxlevel = 1;
00533    if (opt.Contains("2")) maxlevel = 2;
00534    if (opt.Contains("3")) maxlevel = 3;
00535    if (opt.Contains("4")) maxlevel = 4;
00536    if (opt.Contains("5")) maxlevel = 5;
00537    if (opt.Contains("x")) sizeX3D  = 1;
00538 
00539    TROOT::IndentLevel();
00540 
00541    Int_t nsons = 0;
00542    if (fNodes) nsons = fNodes->GetSize();
00543    const char *shapename, *matrixname;
00544    if (fShape) shapename = fShape->IsA()->GetName();
00545    else        shapename = "????";
00546    cout<<GetName()<<":"<<GetTitle()<<" is a "<<shapename;
00547    if (sizeX3D) {
00548       gSize3D.numPoints = 0;
00549       gSize3D.numSegs   = 0;
00550       gSize3D.numPolys  = 0;
00551       Sizeof3D();
00552       cout<<" NumPoints="<<gSize3D.numPoints;
00553       cout<<" NumSegs  ="<<gSize3D.numSegs;
00554       cout<<" NumPolys ="<<gSize3D.numPolys;
00555    } else {
00556       cout<<" X="<<fX<<" Y="<<fY<<" Z="<<fZ;
00557       if (nsons) cout<<" Sons="<<nsons;
00558       if (fMatrix) matrixname   = fMatrix->GetName();
00559       else         matrixname   = "Identity";
00560       if(strcmp(matrixname,"Identity")) cout<<" Rot="<<matrixname;
00561    }
00562    cout<<endl;
00563    if(!nsons) return;
00564    if (gGeomLevel >= maxlevel) return;
00565 
00566    TROOT::IncreaseDirLevel();
00567    gGeomLevel++;
00568    fNodes->ls(option);
00569    gGeomLevel--;
00570    TROOT::DecreaseDirLevel();
00571 
00572 }
00573 
00574 
00575 //______________________________________________________________________________
00576 void TNode::Master2Local(const Double_t *master, Double_t *local)
00577 {
00578    // Convert one point from master system to local reference system.
00579    //
00580    //  Note that before invoking this function, the global rotation matrix
00581    //  and translation vector for this node must have been computed.
00582    //  This is automatically done by the Paint functions.
00583    //  Otherwise TNode::UpdateMatrix should be called before.
00584 
00585    Double_t x,y,z;
00586    Float_t bomb = gGeometry->GetBomb();
00587 
00588    Double_t *matrix      = &gRotMatrix[gGeomLevel][0];
00589    Double_t *translation = &gTranslation[gGeomLevel][0];
00590 
00591    Double_t xms = master[0] - bomb*translation[0];
00592    Double_t yms = master[1] - bomb*translation[1];
00593    Double_t zms = master[2] - bomb*translation[2];
00594 
00595    x = xms*matrix[0] + yms*matrix[1] + zms*matrix[2];
00596    y = xms*matrix[3] + yms*matrix[4] + zms*matrix[5];
00597    z = xms*matrix[6] + yms*matrix[7] + zms*matrix[8];
00598 
00599    local[0] = x; local[1] = y; local[2] = z;
00600 }
00601 
00602 
00603 //______________________________________________________________________________
00604 void TNode::Master2Local(const Float_t *master, Float_t *local)
00605 {
00606    // Convert one point from master system to local reference system.
00607    //
00608    //  Note that before invoking this function, the global rotation matrix
00609    //  and translation vector for this node must have been computed.
00610    //  This is automatically done by the Paint functions.
00611    //  Otherwise TNode::UpdateMatrix should be called before.
00612 
00613    Float_t x,y,z;
00614    Float_t bomb = gGeometry->GetBomb();
00615 
00616    Double_t *matrix      = &gRotMatrix[gGeomLevel][0];
00617    Double_t *translation = &gTranslation[gGeomLevel][0];
00618 
00619    Double_t xms = master[0] - bomb*translation[0];
00620    Double_t yms = master[1] - bomb*translation[1];
00621    Double_t zms = master[2] - bomb*translation[2];
00622 
00623    x = xms*matrix[0] + yms*matrix[1] + zms*matrix[2];
00624    y = xms*matrix[3] + yms*matrix[4] + zms*matrix[5];
00625    z = xms*matrix[6] + yms*matrix[7] + zms*matrix[8];
00626 
00627    local[0] = x; local[1] = y; local[2] = z;
00628 }
00629 
00630 
00631 //______________________________________________________________________________
00632 void TNode::Paint(Option_t *option)
00633 {
00634    // Paint Referenced node with current parameters.
00635    // 
00636    //  vis = 1  (default) shape is drawn
00637    //  vis = 0  shape is not drawn but its sons may be not drawn
00638    //  vis = -1 shape is not drawn. Its sons are not drawn
00639    //  vis = -2 shape is drawn. Its sons are not drawn
00640 
00641    Int_t level = 0;
00642    if (gGeometry) level = gGeometry->GeomLevel();
00643 
00644    // Update translation vector and rotation matrix for new level
00645    if (level) {
00646       gGeometry->UpdateTempMatrix(fX,fY,fZ,fMatrix->GetMatrix(),fMatrix->IsReflection());
00647    }
00648 
00649    // Paint Referenced shape
00650    Int_t nsons = 0;
00651    if (fNodes) nsons = fNodes->GetSize();
00652 
00653    TAttLine::Modify();
00654    TAttFill::Modify();
00655 
00656    Bool_t viewerWantsSons = kTRUE;
00657 
00658    if (fVisibility && fShape->GetVisibility()) {
00659       gNode = this;
00660       fShape->SetLineColor(GetLineColor());
00661       fShape->SetLineStyle(GetLineStyle());
00662       fShape->SetLineWidth(GetLineWidth());
00663       fShape->SetFillColor(GetFillColor());
00664       fShape->SetFillStyle(GetFillStyle());
00665 
00666       TVirtualViewer3D * viewer3D = gPad->GetViewer3D();
00667       if (viewer3D) {
00668          // We only provide master frame positions in these shapes
00669          // so don't ask viewer preference
00670 
00671          // Ask all shapes for kCore/kBoundingBox/kShapeSpecific
00672          // Not all will support the last two - which is fine
00673          const TBuffer3D & buffer = 
00674             fShape->GetBuffer3D(TBuffer3D::kCore|TBuffer3D::kBoundingBox|TBuffer3D::kShapeSpecific);
00675 
00676          Int_t reqSections = viewer3D->AddObject(buffer, &viewerWantsSons);
00677          if (reqSections != TBuffer3D::kNone)
00678          {
00679             fShape->GetBuffer3D(reqSections);
00680             viewer3D->AddObject(buffer, &viewerWantsSons);
00681          }
00682       }
00683    }
00684    if ( TestBit(kSonsInvisible) ) return;
00685 
00686    // Paint all sons
00687    if(!nsons || !viewerWantsSons) return;
00688 
00689    gGeometry->PushLevel();
00690    TNode *node;
00691    TObject *obj;
00692    TIter  next(fNodes);
00693    while ((obj = next())) {
00694       node = (TNode*)obj;
00695       node->Paint(option);
00696    }
00697    gGeometry->PopLevel();
00698 }
00699 
00700 
00701 //______________________________________________________________________________
00702 void TNode::RecursiveRemove(TObject *obj)
00703 {
00704    // Recursively remove object from the list of nodes of this node.
00705 
00706    if (fNodes && dynamic_cast<TNode*>(obj) ) fNodes->RecursiveRemove(obj);
00707 }
00708 
00709 
00710 //______________________________________________________________________________
00711 void TNode::SetName(const char *name)
00712 {
00713    // Change the name of this Node
00714 
00715    if (gPad) gPad->Modified();
00716 
00717    //  Nodes are named objects in a THashList.
00718    //  We must update the hashlist if we change the name
00719    if (fParent) fParent->GetListOfNodes()->Remove(this);
00720    fName = name;
00721    if (fParent) fParent->GetListOfNodes()->Add(this);
00722 }
00723 
00724 
00725 //______________________________________________________________________________
00726 void TNode::SetNameTitle(const char *name, const char *title)
00727 {
00728    // Change the name and title of this Node
00729 
00730    if (gPad) gPad->Modified();
00731 
00732    //  Nodes are named objects in a THashList.
00733    //  We must update the hashlist if we change the name
00734    if (fParent) fParent->GetListOfNodes()->Remove(this);
00735    fName  = name;
00736    fTitle = title;
00737    if (fParent) fParent->GetListOfNodes()->Add(this);
00738 }
00739 
00740 
00741 //______________________________________________________________________________
00742 void TNode::SetParent(TNode *parent)
00743 {
00744    // Set the pointer to the parent, keep parents informed about who they have
00745 
00746    TNode *pp = parent;
00747    while(pp) {
00748       if (pp == this) {
00749          printf("Error: Cannot set parent node to be a child node:%s\n",GetName());
00750          printf("       Operation not performed!\n");
00751          return;
00752       }
00753       pp = pp->GetParent();
00754    }
00755 
00756    if (fParent)   fParent->GetListOfNodes()->Remove(this);
00757    else         gGeometry->GetListOfNodes()->Remove(this);
00758 
00759    fParent = parent;
00760 
00761    if (fParent) {
00762       fParent->BuildListOfNodes(); // new parent might not have list
00763       fParent->GetListOfNodes()->Add(this);
00764    }
00765    else gGeometry->GetListOfNodes()->Add(this);
00766 }
00767 
00768 
00769 //______________________________________________________________________________
00770 void TNode::SetVisibility(Int_t vis)
00771 {
00772    // Set visibility for this node and its sons.
00773    //
00774    //  vis = 3  node is drawn and its sons are drawn
00775    //  vis = 2  node is not drawn but its sons are drawn
00776    //  vis = 1  (default) node is drawn
00777    //  vis = 0  node is not drawn
00778    //  vis = -1 node is not drawn. Its sons are not drawn
00779    //  vis = -2 node is drawn. Its sons are not drawn
00780    //  vis = -3 Only node leaves are drawn
00781    //  vis = -4 Node is not drawn. Its immediate sons are drawn
00782 
00783    ResetBit(kSonsInvisible);
00784    TNode *node;
00785    if (vis == -4 ) {         //Node is not drawn. Its immediate sons are drawn
00786       fVisibility = 0;
00787       if (!fNodes) { fVisibility = 1; return;}
00788       TIter  next(fNodes); while ((node = (TNode*)next())) { node->SetVisibility(-2); }
00789    } else if (vis == -3 ) {  //Only node leaves are drawn
00790       fVisibility = 0;
00791       if (!fNodes) { fVisibility = 1; return;}
00792       TIter  next(fNodes); while ((node = (TNode*)next())) { node->SetVisibility(-3); }
00793 
00794    } else if (vis == -2) {  //node is drawn. Its sons are not drawn
00795       fVisibility = 1; SetBit(kSonsInvisible); if (!fNodes) return;
00796       TIter  next(fNodes); while ((node = (TNode*)next())) { node->SetVisibility(-1); }
00797 
00798    } else if (vis == -1) {  //node is not drawn. Its sons are not drawn
00799       fVisibility = 0; SetBit(kSonsInvisible); if (!fNodes) return;
00800       TIter  next(fNodes); while ((node = (TNode*)next())) { node->SetVisibility(-1); }
00801 
00802    } else if (vis ==  0) {  //node is not drawn
00803       fVisibility = 0;
00804 
00805    } else if (vis ==  1) {  //node is drawn
00806       fVisibility = 1;
00807 
00808    } else if (vis ==  2) {  //node is not drawn but its sons are drawn
00809       fVisibility = 0; if (!fNodes) return;
00810       TIter  next(fNodes); while ((node = (TNode*)next())) { node->SetVisibility(3); }
00811 
00812    } else if (vis ==  3) {  //node is drawn and its sons are drawn
00813       fVisibility = 1; if (!fNodes) return;
00814       TIter  next(fNodes); while ((node = (TNode*)next())) { node->SetVisibility(3); }
00815    }
00816 }
00817 
00818 
00819 //______________________________________________________________________________
00820 void TNode::Sizeof3D() const
00821 {
00822    // Return total size of this 3-D Node with its attributes.
00823 
00824    if (fVisibility && fShape && fShape->GetVisibility()) {
00825       fShape->Sizeof3D();
00826    }
00827    if ( TestBit(kSonsInvisible) ) return;
00828 
00829    if (!fNodes) return;
00830    TNode *node;
00831    TObject *obj;
00832    TIter  next(fNodes);
00833    while ((obj = next())) {
00834       node = (TNode*)obj;
00835       node->Sizeof3D();
00836    }
00837 }
00838 
00839 
00840 //_______________________________________________________________________
00841 void TNode::Streamer(TBuffer &b)
00842 {
00843    // Stream a class object.
00844 
00845    if (b.IsReading()) {
00846       UInt_t R__s, R__c;
00847       Version_t R__v = b.ReadVersion(&R__s, &R__c);
00848       if (R__v > 2) {
00849          b.ReadClassBuffer(TNode::Class(), this, R__v, R__s, R__c);
00850          return;
00851       }
00852       //====process old versions before automatic schema evolution
00853       TNamed::Streamer(b);
00854       TAttLine::Streamer(b);
00855       TAttFill::Streamer(b);
00856       b >> fX;
00857       b >> fY;
00858       b >> fZ;
00859       b >> fMatrix;
00860       b >> fShape;
00861       b >> fParent;
00862       b >> fNodes;
00863       fOption.Streamer(b);
00864       if (R__v > 1) b >> fVisibility;
00865       else  fVisibility = fShape->GetVisibility();
00866       b.CheckByteCount(R__s, R__c, TNode::IsA());
00867       //====end of old versions
00868 
00869    } else {
00870       b.WriteClassBuffer(TNode::Class(),this);
00871    }
00872 }
00873 
00874 
00875 //______________________________________________________________________________
00876 void TNode::UpdateMatrix()
00877 {
00878    // Update global rotation matrix/translation vector for this node
00879    // this function must be called before invoking Local2Master
00880 
00881    TNode *nodes[kMAXLEVELS], *node;
00882    Int_t i;
00883    for (i=0;i<kVectorSize;i++) gTranslation[0][i] = 0;
00884    for (i=0;i<kMatrixSize;i++) gRotMatrix[0][i] = 0;
00885    gRotMatrix[0][0] = 1;   gRotMatrix[0][4] = 1;   gRotMatrix[0][8] = 1;
00886 
00887    node     = this;
00888    gGeomLevel  = 0;
00889    //build array of parent nodes
00890    while (node) {
00891       nodes[gGeomLevel] = node;
00892       node = node->GetParent();
00893       gGeomLevel++;
00894    }
00895    gGeomLevel--;
00896    //Update matrices in the hierarchy
00897    for (i=1;i<=gGeomLevel;i++) {
00898       node = nodes[gGeomLevel-i];
00899       UpdateTempMatrix(&(gTranslation[i-1][0]),&gRotMatrix[i-1][0]
00900                       ,node->GetX(),node->GetY(),node->GetZ(),node->GetMatrix()->GetMatrix()
00901                       ,&gTranslation[i][0],&gRotMatrix[i][0]);
00902    }
00903 }
00904 
00905 
00906 //______________________________________________________________________________
00907 void TNode::UpdateTempMatrix(const Double_t *dx,const Double_t *rmat
00908                          , Double_t x, Double_t y, Double_t z, Double_t *matrix
00909                          , Double_t *dxnew, Double_t *rmatnew)
00910 {
00911    // Compute new translation vector and global matrix.
00912    //
00913    //  dx      old translation vector
00914    //  rmat    old global matrix
00915    //  x,y,z   offset of new local system with respect to mother
00916    //  dxnew   new translation vector
00917    //  rmatnew new global rotation matrix
00918 
00919    dxnew[0] = dx[0] + x*rmat[0] + y*rmat[3] + z*rmat[6];
00920    dxnew[1] = dx[1] + x*rmat[1] + y*rmat[4] + z*rmat[7];
00921    dxnew[2] = dx[2] + x*rmat[2] + y*rmat[5] + z*rmat[8];
00922 
00923    rmatnew[0] = rmat[0]*matrix[0] + rmat[3]*matrix[1] + rmat[6]*matrix[2];
00924    rmatnew[1] = rmat[1]*matrix[0] + rmat[4]*matrix[1] + rmat[7]*matrix[2];
00925    rmatnew[2] = rmat[2]*matrix[0] + rmat[5]*matrix[1] + rmat[8]*matrix[2];
00926    rmatnew[3] = rmat[0]*matrix[3] + rmat[3]*matrix[4] + rmat[6]*matrix[5];
00927    rmatnew[4] = rmat[1]*matrix[3] + rmat[4]*matrix[4] + rmat[7]*matrix[5];
00928    rmatnew[5] = rmat[2]*matrix[3] + rmat[5]*matrix[4] + rmat[8]*matrix[5];
00929    rmatnew[6] = rmat[0]*matrix[6] + rmat[3]*matrix[7] + rmat[6]*matrix[8];
00930    rmatnew[7] = rmat[1]*matrix[6] + rmat[4]*matrix[7] + rmat[7]*matrix[8];
00931    rmatnew[8] = rmat[2]*matrix[6] + rmat[5]*matrix[7] + rmat[8]*matrix[8];
00932 }

Generated on Tue Jul 5 14:16:41 2011 for ROOT_528-00b_version by  doxygen 1.5.1