// @(#)root/g3d:$Name: $:$Id: TNode.cxx,v 1.19 2003/04/14 20:06:01 brun Exp $
// Author: Rene Brun 14/09/95
/*************************************************************************
* 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 "TROOT.h"
#include "TClass.h"
#include "TVirtualPad.h"
#include "TView.h"
#include "TGeometry.h"
#include "TRotMatrix.h"
#include "TShape.h"
#include "TNode.h"
#include "TBrowser.h"
#include "X3DBuffer.h"
#include "TPadView3D.h"
#if 0
const Int_t kMAXLEVELS = 20;
const Int_t kVectorSize = 3;
const Int_t kMatrixSize = kVectorSize*kVectorSize;
#endif
static Double_t gTranslation[kMAXLEVELS][kVectorSize];
static Double_t gRotMatrix[kMAXLEVELS][kMatrixSize];
static Int_t gGeomLevel = 0;
TNode *gNode;
ClassImp(TNode)
//______________________________________________________________________________
//*-*-*-*-*-*-*-*-*-*-*-* T N O D E description *-*-*-*-*-*-*-*-*-*-*-*-*
//*-* =======================
//*-*
//*-* A TNode object is used to build the geometry hierarchy (see TGeometry).
//*-* A node may contain other nodes.
//*-*
//*-* A geometry node has attributes:
//*-* - name and title
//*-* - pointer to the referenced shape (see TShape).
//*-* - x,y,z offset with respect to the mother node.
//*-* - pointer to the rotation matrix (see TRotMatrix).
//*-*
//*-* A node can be drawn.
//*-*
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//______________________________________________________________________________
TNode::TNode()
{
//*-*-*-*-*-*-*-*-*-*-*Node default constructor*-*-*-*-*-*-*-*-*-*-*-*-*
//*-* ========================
fMatrix = 0;
fParent = 0;
fShape = 0;
fNodes = 0;
fVisibility = 1;
}
//______________________________________________________________________________
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)
:TNamed(name,title),TAttLine(), TAttFill()
{
//*-*-*-*-*-*-*-*-*-*-*Node normal constructor*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-* ======================
//*-*
//*-* name is the name of the node
//*-* title is title
//*-* shapename is the name of the referenced shape
//*-* x,y,z are the offsets of the volume with respect to his mother
//*-* matrixname is the name of the rotation matrix
//*-*
//*-* This new node is added into the list of sons of the current node
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
#ifdef WIN32
//*-* The color "1" - default produces a very bad 3D image with OpenGL
Color_t lcolor = 16;
SetLineColor(lcolor);
#endif
static Int_t counter = 0;
counter++;
// if(!(counter%1000))cout<<"TNode count="<<counter<<" name="<<name<<endl;
fX = x;
fY = y;
fZ = z;
fNodes = 0;
fShape = gGeometry->GetShape(shapename);
fParent = gGeometry->GetCurrentNode();
fOption = option;
fVisibility = 1;
if (strlen(matrixname)) fMatrix = gGeometry->GetRotMatrix(matrixname);
else {
fMatrix = gGeometry->GetRotMatrix("Identity");
if (!fMatrix)
fMatrix = new TRotMatrix("Identity","Identity matrix",90,0,90,90,0,0);
}
if (!fShape) {
Printf("Error Referenced shape does not exist: %s",shapename);
return;
}
ImportShapeAttributes();
if (fParent) {
fParent->BuildListOfNodes();
fParent->GetListOfNodes()->Add(this);
} else {
gGeometry->GetListOfNodes()->Add(this);
cd();
}
}
//______________________________________________________________________________
TNode::TNode(const char *name, const char *title, TShape *shape, Double_t x, Double_t y, Double_t z, TRotMatrix *matrix, Option_t *option)
:TNamed(name,title),TAttLine(),TAttFill()
{
//*-*-*-*-*-*-*-*-*-*-*Node normal constructor*-*-*-*-*-*-*-*-*-*-*
//*-* ================================
//*-*
//*-* name is the name of the node
//*-* title is title
//*-* shape is the pointer to the shape definition
//*-* x,y,z are the offsets of the volume with respect to his mother
//*-* matrix is the pointer to the rotation matrix
//*-*
//*-* This new node is added into the list of sons of the current node
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
#ifdef WIN32
//*-* The color "1" - default produces a very bad 3D image with OpenGL
Color_t lcolor = 16;
SetLineColor(lcolor);
#endif
fX = x;
fY = y;
fZ = z;
fNodes = 0;
fShape = shape;
fMatrix = matrix;
fOption = option;
fVisibility = 1;
fParent = gGeometry->GetCurrentNode();
if(!fMatrix) {
fMatrix =gGeometry->GetRotMatrix("Identity");
if (!fMatrix)
fMatrix = new TRotMatrix("Identity","Identity matrix",90,0,90,90,0,0);
}
if(!shape) {Printf("Illegal referenced shape"); return;}
if (fParent) {
fParent->BuildListOfNodes();
fParent->GetListOfNodes()->Add(this);
ImportShapeAttributes();
} else {
gGeometry->GetListOfNodes()->Add(this);
cd();
}
}
//______________________________________________________________________________
TNode::~TNode()
{
//*-*-*-*-*-*-*-*-*-*-*Node default destructor*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-* ======================
//if (!gGeometry) return;
if (fParent) fParent->GetListOfNodes()->Remove(this);
else {if (gGeometry) gGeometry->GetListOfNodes()->Remove(this);}
if (fNodes) fNodes->Delete();
if (gGeometry && gGeometry->GetCurrentNode() == this) gGeometry->SetCurrentNode(0);
delete fNodes;
fNodes = 0;
}
//______________________________________________________________________________
void TNode::Browse(TBrowser *b)
{
if( fNodes ) {
fNodes->Browse( b );
} else {
Draw();
gPad->Update();
}
}
//______________________________________________________________________________
void TNode::BuildListOfNodes()
{
//*-*-*-*-*-*Create the list to support sons of this node*-*-*-*-*-*-*-*-*-*-*
//*-* ============================================
if (!fNodes) fNodes = new TList;
}
//______________________________________________________________________________
void TNode::cd(const char *)
{
//*-*-*-*-*-*Change Current Reference node to this*-*-*-*-*-*-*-*-*-*-*-*-*
//*-* =====================================
gGeometry->SetCurrentNode(this);
}
//______________________________________________________________________________
Int_t TNode::DistancetoPrimitive(Int_t px, Int_t py)
{
//*-*-*-*-*-*-*-*-*-*-*Compute distance from point px,py to a Node*-*-*-*-*-*
//*-* ===========================================
//*-* Compute the closest distance of approach from point px,py to this node.
//*-* The distance is computed in pixels units.
//*-*
//*-*
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
const Int_t big = 9999;
const Int_t inaxis = 7;
const Int_t maxdist = 5;
Int_t puxmin = gPad->XtoAbsPixel(gPad->GetUxmin());
Int_t puymin = gPad->YtoAbsPixel(gPad->GetUymin());
Int_t puxmax = gPad->XtoAbsPixel(gPad->GetUxmax());
Int_t puymax = gPad->YtoAbsPixel(gPad->GetUymax());
//*-*- 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;
//*-*- Update translation vector and rotation matrix for new level
if (fMatrix && gGeometry) {
gGeometry->UpdateTempMatrix(fX,fY,fZ,fMatrix->GetMatrix(),fMatrix->IsReflection());
}
//*-*- Paint Referenced shape
Int_t dist = big;
if (fVisibility && fShape->GetVisibility()) {
gNode = this;
dist = fShape->DistancetoPrimitive(px,py);
if (dist < maxdist) {
gPad->SetSelected(this);
return 0;
}
}
if ( TestBit(kSonsInvisible) ) return dist;
if (!gGeometry) return dist;
//*-*- Loop on all sons
Int_t nsons = 0;
if (fNodes) nsons = fNodes->GetSize();
Int_t dnode = dist;
if (nsons) {
gGeometry->PushLevel();
TNode *node;
TObject *obj;
TIter next(fNodes);
while ((obj = next())) {
node = (TNode*)obj;
dnode = node->DistancetoPrimitive(px,py);
if (dnode <= 0) break;
if (dnode < dist) dist = dnode;
}
gGeometry->PopLevel();
}
return dnode;
}
//______________________________________________________________________________
void TNode::Draw(Option_t *option)
{
//*-*-*-*-*-*-*-*-*-*-*-*Draw Referenced node with current parameters*-*-*-*
//*-* =============================================
TString opt = option;
opt.ToLower();
//*-*- Clear pad if option "same" not given
if (!gPad) {
if (!gROOT->GetMakeDefCanvas()) return;
(gROOT->GetMakeDefCanvas())();
}
if (!opt.Contains("same")) gPad->Clear();
//*-*- Draw Referenced node
if (!gGeometry) new TGeometry;
gGeometry->SetGeomLevel();
gGeometry->UpdateTempMatrix();
AppendPad(option);
//*-*- Create a 3-D View
TView *view = gPad->GetView();
if (!view) {
view = new TView(1);
view->SetAutoRange(kTRUE);
Paint("range");
view->SetAutoRange(kFALSE);
}
}
//______________________________________________________________________________
void TNode::DrawOnly(Option_t *option)
{
//*-*-*-*-*-*-*-*-*-*Draw only Sons of this node*-*-*-*-*-*-*-*-*-*-*-*-*
//*-* ===========================
SetVisibility(2);
Draw(option);
}
//______________________________________________________________________________
void TNode::ExecuteEvent(Int_t, Int_t, Int_t)
{
//*-*-*-*-*-*-*-*-*-*-*Execute action corresponding to one event*-*-*-*
//*-* =========================================
//*-* This member function must be implemented to realize the action
//*-* corresponding to the mouse click on the object in the window
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
// if (gPad->GetView())
// gPad->GetView()->ExecuteRotateView(event, px, py);
// if (!gPad->GetListOfPrimitives()->FindObject(this)) gPad->SetCursor(kCross);
gPad->SetCursor(kHand);
}
//______________________________________________________________________________
TNode *TNode::GetNode(const char *name) const
{
//*-*-*-*-*-*-*Return pointer to node with name in the node tree*-*-*-*-*
//*-* =================================================
if (!strcmp(name, GetName())) return (TNode*)this;
TNode *node, *nodefound;
if (!fNodes) return 0;
TObjLink *lnk = fNodes->FirstLink();
while (lnk) {
node = (TNode *)lnk->GetObject();
if (node->TestBit(kNotDeleted)) {
nodefound = node->GetNode(name);
if (nodefound) return nodefound;
}
lnk = lnk->Next();
}
return 0;
}
//______________________________________________________________________________
char *TNode::GetObjectInfo(Int_t, Int_t) const
{
const char *snull = "";
if (!gPad) return (char*)snull;
static char info[64];
sprintf(info,"%s/%s, shape=%s/%s",GetName(),GetTitle(),fShape->GetName(),fShape->ClassName());
return info;
}
//______________________________________________________________________________
void TNode::ImportShapeAttributes()
{
//*-*-*-*-*-*-*Copy shape attributes as node attributes*-*-*-*-*--*-*-*-*-*-*
//*-* ========================================
SetLineColor(fShape->GetLineColor());
SetLineStyle(fShape->GetLineStyle());
SetLineWidth(fShape->GetLineWidth());
SetFillColor(fShape->GetFillColor());
SetFillStyle(fShape->GetFillStyle());
if (!fNodes) return;
TNode *node;
TObjLink *lnk = fNodes->FirstLink();
while (lnk) {
node = (TNode *)lnk->GetObject();
node->ImportShapeAttributes();
lnk = lnk->Next();
}
}
//______________________________________________________________________________
Bool_t TNode::IsFolder() const
{
//*-*-*-*-*Return TRUE if node contains nodes, FALSE otherwise*-*
//*-* ======================================================
if (fNodes) return kTRUE;
else return kFALSE;
}
//______________________________________________________________________________
void TNode::Local2Master(const Double_t *local, Double_t *master)
{
//*-*-*-*-*Convert one point from local system to master reference system*-*-*
//*-* ==============================================================
//
// Note that before invoking this function, the global rotation matrix
// and translation vector for this node must have been computed.
// This is automatically done by the Paint functions.
// Otherwise TNode::UpdateMatrix should be called before.
Double_t x,y,z;
Float_t bomb = gGeometry->GetBomb();
Double_t *matrix = &gRotMatrix[gGeomLevel][0];
Double_t *translation = &gTranslation[gGeomLevel][0];
x = bomb*translation[0]
+ local[0]*matrix[0]
+ local[1]*matrix[3]
+ local[2]*matrix[6];
y = bomb*translation[1]
+ local[0]*matrix[1]
+ local[1]*matrix[4]
+ local[2]*matrix[7];
z = bomb*translation[2]
+ local[0]*matrix[2]
+ local[1]*matrix[5]
+ local[2]*matrix[8];
master[0] = x; master[1] = y; master[2] = z;
}
//______________________________________________________________________________
void TNode::Local2Master(const Float_t *local, Float_t *master)
{
//*-*-*-*-*Convert one point from local system to master reference system*-*-*
//*-* ==============================================================
//
// Note that before invoking this function, the global rotation matrix
// and translation vector for this node must have been computed.
// This is automatically done by the Paint functions.
// Otherwise TNode::UpdateMatrix should be called before.
Float_t x,y,z;
Float_t bomb = gGeometry->GetBomb();
Double_t *matrix = &gRotMatrix[gGeomLevel][0];
Double_t *translation = &gTranslation[gGeomLevel][0];
x = bomb*translation[0]
+ local[0]*matrix[0]
+ local[1]*matrix[3]
+ local[2]*matrix[6];
y = bomb*translation[1]
+ local[0]*matrix[1]
+ local[1]*matrix[4]
+ local[2]*matrix[7];
z = bomb*translation[2]
+ local[0]*matrix[2]
+ local[1]*matrix[5]
+ local[2]*matrix[8];
master[0] = x; master[1] = y; master[2] = z;
}
//______________________________________________________________________________
void TNode::ls(Option_t *option) const
{
//*-*-*-*-*-*-*-*-*-*-*-*List Referenced object with current parameters*-*-*-*
//*-* ===============================================
Int_t sizeX3D = 0;
TString opt = option;
opt.ToLower();
if (!gGeometry) new TGeometry;
Int_t maxlevel = 15;
if (opt.Contains("1")) maxlevel = 1;
if (opt.Contains("2")) maxlevel = 2;
if (opt.Contains("3")) maxlevel = 3;
if (opt.Contains("4")) maxlevel = 4;
if (opt.Contains("5")) maxlevel = 5;
if (opt.Contains("x")) sizeX3D = 1;
TROOT::IndentLevel();
Int_t nsons = 0;
if (fNodes) nsons = fNodes->GetSize();
const char *shapename, *matrixname;
if (fShape) shapename = fShape->IsA()->GetName();
else shapename = "????";
cout<<GetName()<<":"<<GetTitle()<<" is a "<<shapename;
if (sizeX3D) {
gSize3D.numPoints = 0;
gSize3D.numSegs = 0;
gSize3D.numPolys = 0;
Sizeof3D();
cout<<" NumPoints="<<gSize3D.numPoints;
cout<<" NumSegs ="<<gSize3D.numSegs;
cout<<" NumPolys ="<<gSize3D.numPolys;
} else {
cout<<" X="<<fX<<" Y="<<fY<<" Z="<<fZ;
if (nsons) cout<<" Sons="<<nsons;
if (fMatrix) matrixname = fMatrix->GetName();
else matrixname = "Identity";
if(strcmp(matrixname,"Identity")) cout<<" Rot="<<matrixname;
}
cout<<endl;
if(!nsons) return;
if (gGeomLevel >= maxlevel) return;
TROOT::IncreaseDirLevel();
gGeomLevel++;
fNodes->ls(option);
gGeomLevel--;
TROOT::DecreaseDirLevel();
}
//______________________________________________________________________________
void TNode::Master2Local(const Double_t *master, Double_t *local)
{
//*-*-*-*-*Convert one point from master system to local reference system*-*-*
//*-* ==============================================================
//
// Note that before invoking this function, the global rotation matrix
// and translation vector for this node must have been computed.
// This is automatically done by the Paint functions.
// Otherwise TNode::UpdateMatrix should be called before.
Double_t x,y,z;
Float_t bomb = gGeometry->GetBomb();
Double_t *matrix = &gRotMatrix[gGeomLevel][0];
Double_t *translation = &gTranslation[gGeomLevel][0];
Double_t xms = master[0] - bomb*translation[0];
Double_t yms = master[1] - bomb*translation[1];
Double_t zms = master[2] - bomb*translation[2];
x = xms*matrix[0] + yms*matrix[1] + zms*matrix[2];
y = xms*matrix[3] + yms*matrix[4] + zms*matrix[5];
z = xms*matrix[6] + yms*matrix[7] + zms*matrix[8];
local[0] = x; local[1] = y; local[2] = z;
}
//______________________________________________________________________________
void TNode::Master2Local(const Float_t *master, Float_t *local)
{
//*-*-*-*-*Convert one point from master system to local reference system*-*-*
//*-* ==============================================================
//
// Note that before invoking this function, the global rotation matrix
// and translation vector for this node must have been computed.
// This is automatically done by the Paint functions.
// Otherwise TNode::UpdateMatrix should be called before.
Float_t x,y,z;
Float_t bomb = gGeometry->GetBomb();
Double_t *matrix = &gRotMatrix[gGeomLevel][0];
Double_t *translation = &gTranslation[gGeomLevel][0];
Double_t xms = master[0] - bomb*translation[0];
Double_t yms = master[1] - bomb*translation[1];
Double_t zms = master[2] - bomb*translation[2];
x = xms*matrix[0] + yms*matrix[1] + zms*matrix[2];
y = xms*matrix[3] + yms*matrix[4] + zms*matrix[5];
z = xms*matrix[6] + yms*matrix[7] + zms*matrix[8];
local[0] = x; local[1] = y; local[2] = z;
}
//______________________________________________________________________________
void TNode::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
//*-*
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
TPadView3D *view3D = (TPadView3D*)gPad->GetView3D();
Int_t level = 0;
if (gGeometry) level = gGeometry->GeomLevel();
// restrict the levels for "range" option
if (level > 3 && option && strlen(option) && strcmp(option,"range") == 0) return;
//*-*- Update translation vector and rotation matrix for new level
if (level) {
gGeometry->UpdateTempMatrix(fX,fY,fZ,fMatrix->GetMatrix(),fMatrix->IsReflection());
if (view3D)
view3D->UpdateNodeMatrix(this,option);
}
//*-*- Paint Referenced shape
// Int_t vis = fShape->GetVisibility();
// if ( vis == -1) return;
Int_t nsons = 0;
if (fNodes) nsons = fNodes->GetSize();
// if (vis == -3) {
// if (nsons == 0) vis = 1;
// else vis = 0;
// }
TAttLine::Modify();
TAttFill::Modify();
if (fVisibility && fShape->GetVisibility()) {
gNode = this;
fShape->SetLineColor(GetLineColor());
fShape->SetLineStyle(GetLineStyle());
fShape->SetLineWidth(GetLineWidth());
fShape->SetFillColor(GetFillColor());
fShape->SetFillStyle(GetFillStyle());
if (view3D)
view3D->SetAttNode(this,option);
fShape->Paint(option);
}
if ( TestBit(kSonsInvisible) ) return;
//*-*- Paint all sons
if(!nsons) return;
gGeometry->PushLevel();
TNode *node;
TObject *obj;
TIter next(fNodes);
while ((obj = next())) {
if (view3D)
view3D->PushMatrix();
node = (TNode*)obj;
node->Paint(option);
if (view3D)
view3D->PopMatrix();
}
gGeometry->PopLevel();
}
//______________________________________________________________________________
void TNode::RecursiveRemove(TObject *obj)
{
//*-*-*-*-*Recursively remove object from the list of nodes of this node*-*-*-*
//*-* =============================================================
if (fNodes) fNodes->RecursiveRemove(obj);
}
//______________________________________________________________________________
void TNode::SetName(const char *name)
{
// Change the name of this Node
//
if (gPad) gPad->Modified();
// Nodes are named objects in a THashList.
// We must update the hashlist if we change the name
if (fParent) fParent->GetListOfNodes()->Remove(this);
fName = name;
if (fParent) fParent->GetListOfNodes()->Add(this);
}
//______________________________________________________________________________
void TNode::SetNameTitle(const char *name, const char *title)
{
// Change the name and title of this Node
//
if (gPad) gPad->Modified();
// Nodes are named objects in a THashList.
// We must update the hashlist if we change the name
if (fParent) fParent->GetListOfNodes()->Remove(this);
fName = name;
fTitle = title;
if (fParent) fParent->GetListOfNodes()->Add(this);
}
//______________________________________________________________________________
void TNode::SetParent(TNode *parent)
{
// set the pointer to the parent, keep parents informed about who they have
TNode *pp = parent;
while(pp) {
if (pp == this) {
printf("Error: Cannot set parent node to be a child node:%sn",GetName());
printf(" Operation not performed!n");
return;
}
pp = pp->GetParent();
}
if (fParent) fParent->GetListOfNodes()->Remove(this);
else gGeometry->GetListOfNodes()->Remove(this);
fParent = parent;
if (fParent) {
fParent->BuildListOfNodes(); // new parent might not have list
fParent->GetListOfNodes()->Add(this);
}
else gGeometry->GetListOfNodes()->Add(this);
}
//______________________________________________________________________________
void TNode::SetVisibility(Int_t vis)
{
//*-*-*-*-*-*-*Set visibility for this node and its sons*-*-*-*-*--*-*-*-*-*-*
//*-* =========================================
//*-* vis = 3 node is drawn and its sons are drawn
//*-* vis = 2 node is not drawn but its sons are drawn
//*-* vis = 1 (default) node is drawn
//*-* vis = 0 node is not drawn
//*-* vis = -1 node is not drawn. Its sons are not drawn
//*-* vis = -2 node is drawn. Its sons are not drawn
//*-* vis = -3 Only node leaves are drawn
//*-* vis = -4 Node is not drawn. Its immediate sons are drawn
//*-*
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
ResetBit(kSonsInvisible);
TNode *node;
if (vis == -4 ) { //Node is not drawn. Its immediate sons are drawn
fVisibility = 0;
if (!fNodes) { fVisibility = 1; return;}
TIter next(fNodes); while ((node = (TNode*)next())) { node->SetVisibility(-2); }
} else if (vis == -3 ) { //Only node leaves are drawn
fVisibility = 0;
if (!fNodes) { fVisibility = 1; return;}
TIter next(fNodes); while ((node = (TNode*)next())) { node->SetVisibility(-3); }
} else if (vis == -2) { //node is drawn. Its sons are not drawn
fVisibility = 1; SetBit(kSonsInvisible); if (!fNodes) return;
TIter next(fNodes); while ((node = (TNode*)next())) { node->SetVisibility(-1); }
} else if (vis == -1) { //node is not drawn. Its sons are not drawn
fVisibility = 0; SetBit(kSonsInvisible); if (!fNodes) return;
TIter next(fNodes); while ((node = (TNode*)next())) { node->SetVisibility(-1); }
} else if (vis == 0) { //node is not drawn
fVisibility = 0;
} else if (vis == 1) { //node is drawn
fVisibility = 1;
} else if (vis == 2) { //node is not drawn but its sons are drawn
fVisibility = 0; if (!fNodes) return;
TIter next(fNodes); while ((node = (TNode*)next())) { node->SetVisibility(3); }
} else if (vis == 3) { //node is drawn and its sons are drawn
fVisibility = 1; if (!fNodes) return;
TIter next(fNodes); while ((node = (TNode*)next())) { node->SetVisibility(3); }
}
}
//______________________________________________________________________________
void TNode::Sizeof3D() const
{
//*-*-*-*-*-*-*Return total size of this 3-D Node with its attributes*-*-*
//*-* ==========================================================
if (fVisibility && fShape->GetVisibility()) {
fShape->Sizeof3D();
}
if ( TestBit(kSonsInvisible) ) return;
if (!fNodes) return;
TNode *node;
TObject *obj;
TIter next(fNodes);
while ((obj = next())) {
node = (TNode*)obj;
node->Sizeof3D();
}
}
//_______________________________________________________________________
void TNode::Streamer(TBuffer &b)
{
//*-*-*-*-*-*-*-*-*Stream a class object*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-* =========================================
if (b.IsReading()) {
UInt_t R__s, R__c;
Version_t R__v = b.ReadVersion(&R__s, &R__c);
if (R__v > 2) {
TNode::Class()->ReadBuffer(b, this, R__v, R__s, R__c);
return;
}
//====process old versions before automatic schema evolution
TNamed::Streamer(b);
TAttLine::Streamer(b);
TAttFill::Streamer(b);
b >> fX;
b >> fY;
b >> fZ;
b >> fMatrix;
b >> fShape;
b >> fParent;
b >> fNodes;
fOption.Streamer(b);
if (R__v > 1) b >> fVisibility;
else fVisibility = fShape->GetVisibility();
b.CheckByteCount(R__s, R__c, TNode::IsA());
//====end of old versions
} else {
TNode::Class()->WriteBuffer(b,this);
}
}
//______________________________________________________________________________
void TNode::UpdateMatrix()
{
// Update global rotation matrix/translation vector for this node
// this function must be called before invoking Local2Master
TNode *nodes[kMAXLEVELS], *node;
Int_t i;
for (i=0;i<kVectorSize;i++) gTranslation[0][i] = 0;
for (i=0;i<kMatrixSize;i++) gRotMatrix[0][i] = 0;
gRotMatrix[0][0] = 1; gRotMatrix[0][4] = 1; gRotMatrix[0][8] = 1;
node = this;
gGeomLevel = 0;
//build array of parent nodes
while (node) {
nodes[gGeomLevel] = node;
node = node->GetParent();
gGeomLevel++;
}
gGeomLevel--;
//Update matrices in the hierarchy
for (i=1;i<=gGeomLevel;i++) {
node = nodes[gGeomLevel-i];
UpdateTempMatrix(&(gTranslation[i-1][0]),&gRotMatrix[i-1][0]
,node->GetX(),node->GetY(),node->GetZ(),node->GetMatrix()->GetMatrix()
,&gTranslation[i][0],&gRotMatrix[i][0]);
}
}
//______________________________________________________________________________
void TNode::UpdateTempMatrix(const Double_t *dx,const Double_t *rmat
, Double_t x, Double_t y, Double_t z, Double_t *matrix
, Double_t *dxnew, Double_t *rmatnew)
{
//*-*-*-*-*-*-*Compute new translation vector and global matrix*-*-*-*-*-*-*-*
//*-* ================================================
//*-*
//*-* dx old translation vector
//*-* rmat old global matrix
//*-* x,y,z offset of new local system with respect to mother
//*-* dxnew new translation vector
//*-* rmatnew new global rotation matrix
//*-*
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
dxnew[0] = dx[0] + x*rmat[0] + y*rmat[3] + z*rmat[6];
dxnew[1] = dx[1] + x*rmat[1] + y*rmat[4] + z*rmat[7];
dxnew[2] = dx[2] + x*rmat[2] + y*rmat[5] + z*rmat[8];
rmatnew[0] = rmat[0]*matrix[0] + rmat[3]*matrix[1] + rmat[6]*matrix[2];
rmatnew[1] = rmat[1]*matrix[0] + rmat[4]*matrix[1] + rmat[7]*matrix[2];
rmatnew[2] = rmat[2]*matrix[0] + rmat[5]*matrix[1] + rmat[8]*matrix[2];
rmatnew[3] = rmat[0]*matrix[3] + rmat[3]*matrix[4] + rmat[6]*matrix[5];
rmatnew[4] = rmat[1]*matrix[3] + rmat[4]*matrix[4] + rmat[7]*matrix[5];
rmatnew[5] = rmat[2]*matrix[3] + rmat[5]*matrix[4] + rmat[8]*matrix[5];
rmatnew[6] = rmat[0]*matrix[6] + rmat[3]*matrix[7] + rmat[6]*matrix[8];
rmatnew[7] = rmat[1]*matrix[6] + rmat[4]*matrix[7] + rmat[7]*matrix[8];
rmatnew[8] = rmat[2]*matrix[6] + rmat[5]*matrix[7] + rmat[8]*matrix[8];
}
ROOT page - Class index - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.