// @(#)root/g3d:$Name: $:$Id: TGeometry.cxx,v 1.3 2000/09/08 16:05:21 rdm Exp $
// Author: Rene Brun 22/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 "TROOT.h"
#include "THashList.h"
#include "TObjArray.h"
#include "TGeometry.h"
#include "TNode.h"
#include "TMaterial.h"
#include "TBrowser.h"
TGeometry *gGeometry = 0;
ClassImp(TGeometry)
//______________________________________________________________________________
//*-*-*-*-*-*-*-*-*-*-*-* T G E O M E T R Y description *-*-*-*-*-*-*-*-*-*-*
//*-* ===============================
//*-*
//*-* The Geometry class describes the geometry of a detector.
//*-* The current implementation supports the GEANT3 style description.
//*-* A special program provided in the ROOT utilities (toroot) can be used
//*-* to automatically translate a GEANT detector geometry into a ROOT geometry.
//*-*
//*-* a Geometry object is entered into the list of geometries into the
//*-* ROOT main object (see TROOT description) when the TGeometry
//*-* constructor is invoked.
//*-* Several geometries may coexist in memory.
//*-*
//*-* A Geometry object consist of the following linked lists:
//*-* - the TMaterial list (material definition only).
//*-* - the TRotmatrix list (Rotation matrices definition only).
//*-* - the TShape list (volume definition only).
//*-* - the TNode list assembling all detector elements.
//*-*
//*-* Only the Build and Draw functions for a geometry are currently supported.
//*-*
//*-*---------------------------------------------------------------------------
//*-*- The conversion program from Geant to Root has been added in the list
//*-* of utilities in utils directory.(see g2root)
//*-* The executable module of g2root can be found in $ROOTSYS/bin/g2root.
//*-*
//*-* To use this conversion program, type the shell command:
//*-* g2root geant_rzfile macro_name
//*-*
//*-* for example
//*-* g2root na49.geom na49.C
//*-* will convert the GEANT RZ file na49.geom into a ROOT macro na49.C
//*-*
//*-* To generate the Geometry structure within Root, do:
//*-* Root > .x na49.C
//*-* Root > na49.Draw()
//*-* Root > wh.x3d() (this invokes the 3-d Root viewver)
//*-* Root > TFile gna49("na49.root","NEW") //open a new root file
//*-* Root > na49.Write() //Write the na49 geometry structure
//*-* Root > gna49.Write() //Write all keys (in this case only one)
//*-* Note: all keys are also written on closing of the file, gna49.Close or
//*-* when the program exits, Root closes all open files correctly.
//*-* Once this file has been written, in a subsequent session, simply do:
//*-* Root > TFile gna49("na49.root")
//*-* Root > na49.Draw()
//*-*
//*-* The figure below shows the geometry above using the x3d viewer.
//*-* This x3d viewver is invoked by selecting "View x3d" in the View menu
//*-* of a canvas (See example of this tool bar in TCanvas).
//
/*
*/
//
//*-*
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//______________________________________________________________________________
TGeometry::TGeometry()
{
//*-*-*-*-*-*-*-*-*-*-*-*-*Geometry default constructor*-*-*-*-*-*-*-*-*-*-*-*
fMaterials = new THashList(100,3);
fMatrices = new THashList(100,3);
fShapes = new THashList(500,3);
fNodes = new TList;
fCurrentNode = 0;
fMaterialPointer = 0;
fMatrixPointer = 0;
fShapePointer = 0;
gGeometry = this;
fBomb = 1;
fMatrix = 0;
fX=fY=fZ =0.0;
fGeomLevel =0;
fIsReflection[fGeomLevel] = kFALSE;
}
//______________________________________________________________________________
TGeometry::TGeometry(const char *name,const char *title ) : TNamed (name, title)
{
//*-*-*-*-*-*-*-*-*-*-*-*-*Geometry normal constructor*-*-*-*-*-*-*-*-*-*-*-*
//*-* ===========================
fMaterials = new THashList(1000,3);
fMatrices = new THashList(1000,3);
fShapes = new THashList(5000,3);
fNodes = new TList;
fCurrentNode = 0;
fMaterialPointer = 0;
fMatrixPointer = 0;
fShapePointer = 0;
gGeometry = this;
fBomb = 1;
fMatrix = 0;
fX=fY=fZ =0.0;
gROOT->GetListOfGeometries()->Add(this);
fGeomLevel =0;
fIsReflection[fGeomLevel] = kFALSE;
}
//______________________________________________________________________________
TGeometry::~TGeometry()
{
//*-*-*-*-*-*-*-*-*-*-*-*-*Geometry default destructor*-*-*-*-*-*-*-*-*-*-*-*
//*-* ========================
if (!fMaterials) return;
fMaterials->Delete();
fMatrices->Delete();
fShapes->Delete();
fNodes->Delete();
delete fMaterials;
delete fMatrices;
delete fShapes;
delete fNodes;
delete [] fMaterialPointer;
delete [] fMatrixPointer;
delete [] fShapePointer;
fMaterials = 0;
fMatrices = 0;
fShapes = 0;
fNodes = 0;
fMaterialPointer = 0;
fMatrixPointer = 0;
fShapePointer = 0;
if (gGeometry == this) {
gGeometry = (TGeometry*) gROOT->GetListOfGeometries()->First();
if (gGeometry == this)
gGeometry = (TGeometry*) gROOT->GetListOfGeometries()->After(gGeometry);
}
gROOT->GetListOfGeometries()->Remove(this);
}
//______________________________________________________________________________
void TGeometry::Browse(TBrowser *b)
{
if( b ) {
b->Add( fMaterials, "Materials" );
b->Add( fMatrices, "Rotation Matrices" );
b->Add( fShapes, "Shapes" );
b->Add( fNodes, "Nodes" );
}
}
//______________________________________________________________________________
void TGeometry::cd(const char *)
{
//*-*-*-*-*-*Change Current Geometry to this*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-* ===============================
gGeometry = this;
}
//______________________________________________________________________________
void TGeometry::Draw(Option_t *option)
{
//*-*-*-*-*-*-*-*-*-*-*-*-*Draw this Geometry*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-* ==================
TNode *node1 = (TNode*)fNodes->First();
if (node1) node1->Draw(option);
}
//______________________________________________________________________________
TObject *TGeometry::FindObject(TObject *) const
{
// find object in a geometry node, material, etc
Error("FindObject","Not yet implemented");
return 0;
}
//______________________________________________________________________________
TObject *TGeometry::FindObject(const char *name) const
{
// search object identified by name in the geometry tree
TObjArray *loc = TGeometry::Get(name);
if (loc) return loc->At(0);
return 0;
}
//______________________________________________________________________________
TObjArray *TGeometry::Get(const char *name)
{
//
// Static function called by TROOT to search name in the geometry.
// Returns a TObjArray containing a pointer to the found object
// and a pointer to the container where the object was found.
//
static TObjArray *locs = 0;
if (!locs) locs = new TObjArray(2);
TObjArray &loc = *locs;
loc[0] = 0;
loc[1] = 0;
if (!gGeometry) return &loc;
TObject *temp;
TObject *where;
temp = gGeometry->GetListOfMaterials()->FindObject(name);
where = gGeometry->GetListOfMaterials();
if (!temp) {
temp = gGeometry->GetListOfShapes()->FindObject(name);
where = gGeometry->GetListOfShapes();
}
if (!temp) {
temp = gGeometry->GetListOfMatrices()->FindObject(name);
where = gGeometry->GetListOfMatrices();
}
if (!temp) {
temp = gGeometry->GetNode(name);
where = gGeometry;
}
loc[0] = temp;
loc[1] = where;
return &loc;
}
//______________________________________________________________________________
TMaterial *TGeometry::GetMaterial(const char *name)
{
//*-*-*-*-*-*-*-*-*Return pointer to Material with name*-*-*-*-*-*-*-*-*
//*-* ====================================
return (TMaterial*)fMaterials->FindObject(name);
}
//______________________________________________________________________________
TMaterial *TGeometry::GetMaterialByNumber(Int_t number)
{
//*-*-*-*-*-*-*-*-*Return pointer to Material with number*-*-*-*-*-*-*-*-*
//*-* ======================================
TMaterial *mat;
if (number < 0 || number >= fMaterials->GetSize()) return 0;
if (fMaterialPointer) return fMaterialPointer[number];
TIter next(fMaterials);
while ((mat = (TMaterial*) next())) {
if (mat->GetNumber() == number) return mat;
}
return 0;
}
//______________________________________________________________________________
TNode *TGeometry::GetNode(const char *name)
{
//*-*-*-*-*-*-*Return pointer to node with name in the geometry tree*-*-*-*-*
//*-* =====================================================
TNode *node= (TNode*)GetListOfNodes()->First();
if (!node) return 0;
if (node->TestBit(kNotDeleted)) return node->GetNode(name);
return 0;
}
//______________________________________________________________________________
TRotMatrix *TGeometry::GetRotMatrix(const char *name)
{
//*-*-*-*-*-*-*-*-*Return pointer to RotMatrix with name*-*-*-*-*-*-*-*-*-*
//*-* =====================================
return (TRotMatrix*)fMatrices->FindObject(name);
}
//______________________________________________________________________________
TRotMatrix *TGeometry::GetRotMatrixByNumber(Int_t number)
{
//*-*-*-*-*-*-*-*-*Return pointer to RotMatrix with number*-*-*-*-*-*-*-*-*-*
//*-* =======================================
TRotMatrix *matrix;
if (number < 0 || number >= fMatrices->GetSize()) return 0;
if (fMatrixPointer) return fMatrixPointer[number];
TIter next(fMatrices);
while ((matrix = (TRotMatrix*) next())) {
if (matrix->GetNumber() == number) return matrix;
}
return 0;
}
//______________________________________________________________________________
TShape *TGeometry::GetShape(const char *name)
{
//*-*-*-*-*-*-*-*-*Return pointer to Shape with name*-*-*-*-*-*-*-*-*-*
//*-* =================================
return (TShape*)fShapes->FindObject(name);
}
//______________________________________________________________________________
TShape *TGeometry::GetShapeByNumber(Int_t number)
{
//*-*-*-*-*-*-*-*-*Return pointer to Shape with number*-*-*-*-*-*-*-*-*-*
//*-* ===================================
TShape *shape;
if (number < 0 || number >= fShapes->GetSize()) return 0;
if (fShapePointer) return fShapePointer[number];
TIter next(fShapes);
while ((shape = (TShape*) next())) {
if (shape->GetNumber() == number) return shape;
}
return 0;
}
//______________________________________________________________________________
void TGeometry::Local2Master(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.
if (GeomLevel()) {
Double_t x,y,z;
Double_t bomb = GetBomb();
// Double_t *matrix = fMatrix->GetMatrix();
Double_t *matrix = &fRotMatrix[GeomLevel()][0];
x = bomb*fX
+ local[0]*matrix[0]
+ local[1]*matrix[3]
+ local[2]*matrix[6];
y = bomb*fY
+ local[0]*matrix[1]
+ local[1]*matrix[4]
+ local[2]*matrix[7];
z = bomb*fZ
+ local[0]*matrix[2]
+ local[1]*matrix[5]
+ local[2]*matrix[8];
master[0] = x; master[1] = y; master[2] = z;
}
else
memcpy(master,local,sizeof(Double_t)* kVectorSize);
}
//______________________________________________________________________________
void TGeometry::Local2Master(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.
if (GeomLevel()) {
Float_t x,y,z;
Float_t bomb = GetBomb();
// Double_t *matrix = fMatrix->GetMatrix();
Double_t *matrix = &fRotMatrix[GeomLevel()][0];
x = bomb*fX
+ local[0]*matrix[0]
+ local[1]*matrix[3]
+ local[2]*matrix[6];
y = bomb*fY
+ local[0]*matrix[1]
+ local[1]*matrix[4]
+ local[2]*matrix[7];
z = bomb*fZ
+ local[0]*matrix[2]
+ local[1]*matrix[5]
+ local[2]*matrix[8];
master[0] = x; master[1] = y; master[2] = z;
}
else
memcpy(master,local,sizeof(Float_t)* kVectorSize);
}
//______________________________________________________________________________
void TGeometry::ls(Option_t *option)
{
//*-*-*-*-*-*-*-*-*-*-*-*List this geometry*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-* ===================
TString opt = option;
opt.ToLower();
if (opt.Contains("m")) {
Printf("=================List of Materials================");
fMaterials->ls(option);
}
if (opt.Contains("r")) {
Printf("=================List of RotationMatrices================");
fMatrices->ls(option);
}
if (opt.Contains("s")) {
Printf("=================List of Shapes==========================");
fShapes->ls(option);
}
if (opt.Contains("n")) {
Printf("=================List of Nodes===========================");
fNodes->ls(option);
}
}
//______________________________________________________________________________
void TGeometry::Master2Local(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.
if (GeomLevel()) {
Double_t x,y,z;
Double_t bomb = GetBomb();
// Double_t *matrix = fMatrix->GetMatrix();
Double_t *matrix = &fRotMatrix[GeomLevel()][0];
Double_t xms = master[0] - bomb*fX;
Double_t yms = master[1] - bomb*fY;
Double_t zms = master[2] - bomb*fZ;
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;
}
else
memcpy(local,master,sizeof(Double_t)* kVectorSize);
}
//______________________________________________________________________________
void TGeometry::Master2Local(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.
if (GeomLevel()) {
Float_t x,y,z;
Float_t bomb = GetBomb();
// Double_t *matrix = fMatrix->GetMatrix();
Double_t *matrix = &fRotMatrix[GeomLevel()][0];
Double_t xms = master[0] - bomb*fX;
Double_t yms = master[1] - bomb*fY;
Double_t zms = master[2] - bomb*fZ;
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;
}
else
memcpy(local,master,sizeof(Float_t)* kVectorSize);
}
//______________________________________________________________________________
void TGeometry::Node(const char *name, const char *title, const char *shapename, Double_t x, Double_t y, Double_t z, const char *matrixname, Option_t *option)
{
//*-*-*-*-*-*-*-*Add a node to the current node in this geometry*-*-*-*-*-*-*
//*-* ===============================================
new TNode(name,title,shapename,x,y,z,matrixname,option);
}
//______________________________________________________________________________
void TGeometry::RecursiveRemove(TObject *obj)
{
//*-*-*-*-*-*-*-*Recursively remove object from a Geometry list*-*-*-*-*-*-*-*
//*-* =========================================
if (fNodes) fNodes->RecursiveRemove(obj);
}
//_______________________________________________________________________
void TGeometry::Streamer(TBuffer &b)
{
//*-*-*-*-*-*-*-*-*Stream a class object*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-* =========================================
Int_t i;
TMaterial *onemat;
TRotMatrix *onematrix;
TShape *oneshape;
UInt_t R__s, R__c;
if (b.IsReading()) {
b.ReadVersion(&R__s, &R__c);
TNamed::Streamer(b);
fMaterials->Streamer(b);
fMatrices->Streamer(b);
fShapes->Streamer(b);
//*-*- Build direct access pointers to individual materials,matrices and shapes
Int_t nmat = fMaterials->GetSize();
if (nmat) fMaterialPointer = new TMaterial* [nmat];
TIter nextmat(fMaterials);
i = 0;
while ((onemat = (TMaterial*) nextmat())) {
fMaterialPointer[i] = onemat;
i++;
}
Int_t nrot = fMatrices->GetSize();
if (nrot) fMatrixPointer = new TRotMatrix* [nrot];
TIter nextmatrix(fMatrices);
i = 0;
while ((onematrix = (TRotMatrix*) nextmatrix())) {
fMatrixPointer[i] = onematrix;
i++;
}
Int_t nsha = fShapes->GetSize();
if (nsha) fShapePointer = new TShape* [nsha];
TIter nextshape(fShapes);
i = 0;
while ((oneshape = (TShape*) nextshape())) {
fShapePointer[i] = oneshape;
i++;
}
fNodes->Streamer(b);
b >> fBomb;
//*-*- If geometry already exists, delete old version
TGeometry *oldgeom = (TGeometry*)gROOT->GetGeometry(GetName());
delete oldgeom;
gROOT->GetListOfGeometries()->Add(this);
fCurrentNode = (TNode*)GetListOfNodes()->First();
b.CheckByteCount(R__s, R__c, TGeometry::IsA());
} else {
R__c = b.WriteVersion(TGeometry::IsA(), kTRUE);
TNamed::Streamer(b);
fMaterials->Streamer(b);
fMatrices->Streamer(b);
fShapes->Streamer(b);
fNodes->Streamer(b);
b << fBomb;
b.SetByteCount(R__c, kTRUE);
}
}
//______________________________________________________________________________
void TGeometry::UpdateMatrix(TNode *node)
{
// Update global rotation matrix/translation vector for this node
// this function must be called before invoking Local2Master
TNode *nodes[kMAXLEVELS];
Int_t i;
for (i=0;i<kVectorSize;i++) fTranslation[0][i] = 0;
for (i=0;i<kMatrixSize;i++) fRotMatrix[0][i] = 0;
fRotMatrix[0][0] = 1; fRotMatrix[0][4] = 1; fRotMatrix[0][8] = 1;
fGeomLevel = 0;
//build array of parent nodes
while (node) {
nodes[fGeomLevel] = node;
node = node->GetParent();
fGeomLevel++;
}
fGeomLevel--;
Int_t saveGeomLevel = fGeomLevel;
//Update matrices in the hierarchy
for (fGeomLevel=1;i<=saveGeomLevel;fGeomLevel++) {
node = nodes[i-i];
UpdateTempMatrix(node->GetX(),node->GetY(),node->GetZ(),node->GetMatrix());
}
}
//______________________________________________________________________________
void TGeometry::UpdateTempMatrix(Double_t x, Double_t y, Double_t z, TRotMatrix *rotMatrix)
{
Double_t *matrix = 0;
Bool_t isReflection = kFALSE;
if (rotMatrix && rotMatrix->GetType()) {
matrix = rotMatrix->GetMatrix();
isReflection = rotMatrix->IsReflection();
}
UpdateTempMatrix( x,y,z, matrix,isReflection);
}
//______________________________________________________________________________
void TGeometry::UpdateTempMatrix(Double_t x, Double_t y, Double_t z, Double_t *matrix,Bool_t isReflection)
{
Int_t i=GeomLevel();
if (i) {
if(matrix)
{
UpdateTempMatrix(&(fTranslation[i-1][0]),&fRotMatrix[i-1][0]
,x,y,z,matrix
,&fTranslation[i][0],&fRotMatrix[i][0]);
fX = fTranslation[i][0];
fY = fTranslation[i][1];
fZ = fTranslation[i][2];
fIsReflection[i] = fIsReflection[i-1] ^ isReflection;
}
else {
fX = fTranslation[i][0] = fTranslation[i-1][0] + x;
fY = fTranslation[i][1] = fTranslation[i-1][1] + y;
fZ = fTranslation[i][2] = fTranslation[i-1][2] + z;
}
}
else {
fX=fY=fZ=0;
fIsReflection[0] = kFALSE;
for (i=0;i<kVectorSize;i++) fTranslation[0][i] = 0;
for (i=0;i<kMatrixSize;i++) fRotMatrix[0][i] = 0;
fRotMatrix[0][0] = 1; fRotMatrix[0][4] = 1; fRotMatrix[0][8] = 1;
}
}
//______________________________________________________________________________
void TGeometry::UpdateTempMatrix(Double_t *dx,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.