#include "Riostream.h"
#include "TCernLib.h"
#include "TVolumePosition.h"
#include "TVolume.h"
#include "TROOT.h"
#include "TClass.h"
#include "TVirtualPad.h"
#include "TGeometry.h"
#include "TRotMatrix.h"
#include "TBrowser.h"
#include "X3DBuffer.h"
#include "TTablePadView3D.h"
ClassImp(TVolumePosition)
TVolumePosition::TVolumePosition(TVolume *node,Double_t x, Double_t y, Double_t z, const char *matrixname)
: fMatrix(0),fNode(node),fId(0)
{
SetMatrixOwner(kFALSE);
fX[0] = x; fX[1] =y; fX[2] = z;
if (!node) return;
static Int_t counter = 0;
counter++;
if(!(counter%1000))cout<<"TVolumePosition count="<<counter<<" name="<<node->GetName()<<endl;
if (!gGeometry) new TGeometry;
if (matrixname && strlen(matrixname)) fMatrix = gGeometry->GetRotMatrix(matrixname);
if (!fMatrix) fMatrix = TVolume::GetIdentity();
}
TVolumePosition::TVolumePosition(TVolume *node,Double_t x, Double_t y, Double_t z, TRotMatrix *matrix)
: fMatrix(matrix),fNode(node),fId(0)
{
SetMatrixOwner(kFALSE);
if (!gGeometry) new TGeometry;
fX[0] = x; fX[1] = y; fX[2] = z;
if (!fMatrix) fMatrix = TVolume::GetIdentity();
}
TVolumePosition::TVolumePosition(const TVolumePosition* oldPosition, const TVolumePosition* curPosition){
fMatrix = 0;
SetMatrixOwner(kFALSE);
TVolume *curNode = 0;
UInt_t curPositionId = 0;
TRotMatrix *curMatrix = 0;
if (curPosition) {
curNode = curPosition->GetNode();
curPositionId = curPosition->GetId();
curMatrix = (TRotMatrix *) curPosition->GetMatrix();
}
TRotMatrix *oldMatrix = 0;
fX[0] = 0; fX[1] = 0; fX[2] = 0;
Double_t oldTranslation[] = { 0, 0, 0 };
if (oldPosition) {
oldMatrix = (TRotMatrix *) oldPosition->GetMatrix();
oldTranslation[0] = oldPosition->GetX();
oldTranslation[1] = oldPosition->GetY();
oldTranslation[2] = oldPosition->GetZ();
}
Double_t newMatrix[9];
if(oldMatrix && curMatrix && curPosition) {
TGeometry::UpdateTempMatrix(oldTranslation,oldMatrix->GetMatrix(),
curPosition->GetX(),curPosition->GetY(),curPosition->GetZ(),
curMatrix->GetMatrix(),
fX,newMatrix);
Int_t num = gGeometry->GetListOfMatrices()->GetSize();
Char_t anum[100];
snprintf(anum,100,"%d",num+1);
fMatrix = new TRotMatrix(anum,"NodeView",newMatrix);
SetMatrixOwner(kTRUE);
} else {
if (curPosition) {
fX[0] = oldTranslation[0] + curPosition->GetX();
fX[1] = oldTranslation[1] + curPosition->GetY();
fX[2] = oldTranslation[2] + curPosition->GetZ();
fMatrix = curMatrix;
}
}
fId = curPositionId;
fNode = curNode;
}
TVolumePosition::TVolumePosition(const TVolumePosition&pos): TObject()
, fMatrix(((TVolumePosition &)pos).GetMatrix()),fNode(pos.GetNode()),fId(pos.GetId())
{
for (int i=0;i<3;i++) fX[i] = pos.GetX(i);
SetMatrixOwner(pos.IsMatrixOwner());
((TVolumePosition &)pos).SetMatrixOwner(kFALSE);
}
TVolumePosition::~TVolumePosition()
{
DeleteOwnMatrix();
}
void TVolumePosition::Browse(TBrowser *b)
{
if (GetNode()) {
TShape *shape = GetNode()->GetShape();
b->Add(GetNode(),shape?shape->GetName():GetNode()->GetName());
} else {
Draw();
gPad->Update();
}
}
Int_t TVolumePosition::DistancetoPrimitive(Int_t, Int_t)
{
return 99999;
}
void TVolumePosition::Draw(Option_t *option)
{
TVolume *node = GetNode();
if (node) node->Draw(option);
}
void TVolumePosition::ExecuteEvent(Int_t, Int_t, Int_t)
{
gPad->SetCursor(kHand);
}
const Char_t *TVolumePosition::GetName() const
{
return GetNode()?GetNode()->GetName():IsA()->GetName();
}
char *TVolumePosition::GetObjectInfo(Int_t, Int_t) const
{
if (!gPad) return 0;
if (!GetNode()) return 0;
static char info[64];
snprintf(info,64,"%s/%s, shape=%s/%s",GetNode()->GetName(),GetNode()->GetTitle(),GetNode()->GetShape()->GetName(),GetNode()->GetShape()->ClassName());
return info;
}
Double_t *TVolumePosition::Errmx2Master(const Double_t *localError, Double_t *masterError) const
{
Double_t error[6];
TCL::vzero(&error[1],4);
error[0] = localError[0]; error[2] = localError[1]; error[5] = localError[2];
return Cormx2Master(error, masterError);
}
Float_t *TVolumePosition::Errmx2Master(const Float_t *localError, Float_t *masterError) const
{
Float_t error[6];
TCL::vzero(&error[1],4);
error[0] = localError[0]; error[2] = localError[1]; error[5] = localError[2];
return Cormx2Master(error, masterError);
}
Double_t *TVolumePosition::Cormx2Master(const Double_t *localCorr, Double_t *masterCorr)const
{
Double_t *res = 0;
const TRotMatrix *rm = GetMatrix();
double *m = 0;
if (rm && ( m = ((TRotMatrix *)rm)->GetMatrix()) )
res = TCL::trasat(m,(Double_t *)localCorr,masterCorr,3,3);
else
res = TCL::ucopy(localCorr,masterCorr,6);
return res;
}
Float_t *TVolumePosition::Cormx2Master(const Float_t *localCorr, Float_t *masterCorr) const
{
Float_t *res = 0;
const TRotMatrix *rm = GetMatrix();
Double_t *m = 0;
if (rm && (m = ((TRotMatrix *)rm)->GetMatrix()) ) {
double corLocal[6], corGlobal[6];
TCL::ucopy(localCorr,corLocal,6);
TCL::trasat(m,corLocal,corGlobal,3,3);
res = TCL::ucopy(corGlobal,masterCorr,6);
} else
res = TCL::ucopy(localCorr,masterCorr,6);
return res;
}
Double_t *TVolumePosition::Errmx2Local(const Double_t *masterError, Double_t *localError) const
{
Double_t error[6];
TCL::vzero(&error[1],4);
error[0] = masterError[0]; error[2] = masterError[1]; error[5] = masterError[2];
return Cormx2Local(error, localError);
}
Float_t *TVolumePosition::Errmx2Local(const Float_t *masterError, Float_t *localError) const
{
Float_t error[6];
TCL::vzero(&error[1],4);
error[0] = masterError[0]; error[2] = masterError[1]; error[5] = masterError[2];
return Cormx2Local(error, localError);
}
Double_t *TVolumePosition::Cormx2Local(const Double_t *localCorr, Double_t *masterCorr) const
{
Double_t *res = 0;
TRotMatrix *rm = (TRotMatrix *) GetMatrix();
double *m = 0;
if (rm && ( m = rm->GetMatrix()) )
res = TCL::tratsa(m,(Double_t *)localCorr,masterCorr,3,3);
else
res = TCL::ucopy(localCorr,masterCorr,6);
return res;
}
Float_t *TVolumePosition::Cormx2Local(const Float_t *localCorr, Float_t *masterCorr) const
{
Float_t *res = 0;
TRotMatrix *rm = (TRotMatrix *) GetMatrix();
Double_t *m = 0;
if (rm && (m = rm->GetMatrix()) ) {
double corLocal[6], corGlobal[6];
TCL::ucopy(localCorr,corLocal,6);
TCL::tratsa(m,corLocal,corGlobal,3,3);
res = TCL::ucopy(corGlobal,masterCorr,6);
}
else
res = TCL::ucopy(localCorr,masterCorr,6);
return res;
}
Double_t *TVolumePosition::Local2Master(const Double_t *local, Double_t *master, Int_t nPoints) const
{
Double_t *matrix = 0;
Double_t *trans = 0;
if (!fMatrix || fMatrix == TVolume::GetIdentity() || !(matrix = ((TRotMatrix *)fMatrix)->GetMatrix()) ) {
trans = master;
for (int i =0; i < nPoints; i++,local += 3, master += 3) TCL::vadd(local,fX,master,3);
} else {
trans = master;
for (int i =0; i < nPoints; i++, local += 3, master += 3) {
TCL::mxmpy2(matrix,local,master,3,3,1);
TCL::vadd(master,fX,master,3);
}
}
return trans;
}
Float_t *TVolumePosition::Local2Master(const Float_t *local, Float_t *master, Int_t nPoints) const
{
Double_t *matrix = 0;
Float_t *trans = 0;
if (!fMatrix || fMatrix == TVolume::GetIdentity() || !(matrix = ((TRotMatrix *)fMatrix)->GetMatrix()) )
{
trans = master;
for (int i =0; i < nPoints; i++,local += 3, master += 3) TCL::vadd(local,fX,master,3);
} else {
trans = master;
for (int i =0; i < nPoints; i++, local += 3, master += 3) {
Double_t dlocal[3]; Double_t dmaster[3];
TCL::ucopy(local,dlocal,3);
TCL::mxmpy2(matrix,dlocal,dmaster,3,3,1);
TCL::vadd(dmaster,fX,dmaster,3);
TCL::ucopy(dmaster,master,3);
}
}
return trans;
}
Double_t *TVolumePosition::Master2Local(const Double_t *master, Double_t *local, Int_t nPoints) const
{
Double_t *matrix = 0;
Double_t *trans = 0;
if (!fMatrix || fMatrix == TVolume::GetIdentity() || !(matrix = ((TRotMatrix *)fMatrix)->GetMatrix()) ){
trans = local;
for (int i =0; i < nPoints; i++,master += 3, local += 3) TCL::vsub(master,fX,local,3);
} else {
trans = local;
for (int i =0; i < nPoints; i++, master += 3, local += 3) {
Double_t dlocal[3];
TCL::vsub(master,fX,dlocal,3);
TCL::mxmpy(matrix,dlocal,local,3,3,1);
}
}
return trans;
}
Float_t *TVolumePosition::Master2Local(const Float_t *master, Float_t *local, Int_t nPoints) const
{
Double_t *matrix = 0;
Float_t *trans = 0;
if (!fMatrix || fMatrix == TVolume::GetIdentity() || !(matrix = ((TRotMatrix *)fMatrix)->GetMatrix()) ){
trans = local;
for (int i =0; i < nPoints; i++,master += 3, local += 3) TCL::vsub(master,fX,local,3);
} else {
trans = local;
for (int i =0; i < nPoints; i++, master += 3, local += 3) {
Double_t dmaster[3]; Double_t dlocal[3];
TCL::ucopy(master,dmaster,3);
TCL::vsub(dmaster,fX,dmaster,3);
TCL::mxmpy(matrix,dmaster,dlocal,3,3,1);
TCL::ucopy(dlocal,local,3);
}
}
return trans;
}
void TVolumePosition::Paint(Option_t *)
{
Error("Paint","Position can not be painted");
}
void TVolumePosition::Print(Option_t *) const
{
cout << *this << endl;
}
TVolumePosition *TVolumePosition::Reset(TVolume *node,Double_t x, Double_t y, Double_t z, TRotMatrix *matrix)
{
fNode = node;
SetPosition(x,y,z);
SetMatrix(matrix);
if (!fMatrix) fMatrix = TVolume::GetIdentity();
return this;
}
void TVolumePosition::SavePrimitive(ostream &, Option_t * )
{
#if 0
out << "TVolumePosition *CreatePosition() { " << endl;
out << " TVolumePosition *myPosition = 0; " << endl;
Double_t x = GetX();
Double_t y = GetY();
Double_t z = GetZ();
TRotMatrix *matrix =
myPosition = new TVolumePosition(TVolume *node,Double_t x, Double_t y, Double_t z, const char *matrixname)
: fNode(node),fX(x),fY(y),fZ(z),fMatrix(0)
{
/
out << " return myPosition; " << endl;
out << "} " << endl;
#endif
}
void TVolumePosition::SetLineAttributes()
{
TVolume *thisNode = GetNode();
if (thisNode) thisNode->SetLineAttributes();
}
void TVolumePosition::SetMatrix(TRotMatrix *matrix)
{
if (matrix != fMatrix) {
DeleteOwnMatrix();
fMatrix = matrix;
}
}
void TVolumePosition::UpdatePosition(Option_t *)
{
TTablePadView3D *view3D=(TTablePadView3D *)gPad->GetView3D();
if (gGeometry->GeomLevel() && fMatrix) {
gGeometry->UpdateTempMatrix(fX[0],fX[1],fX[2]
,((TRotMatrix *)fMatrix)->GetMatrix()
,fMatrix->IsReflection());
if (view3D)
view3D->UpdatePosition(fX[0],fX[1],fX[2],((TRotMatrix *)fMatrix));
}
}
void TVolumePosition::SetVisibility(Int_t vis)
{
TVolume *node = GetNode();
if (node) node->SetVisibility(TVolume::ENodeSEEN(vis));
}
TVolumePosition &TVolumePosition::Mult(const TVolumePosition &curPosition) {
TVolume *curNode = 0;
curNode = curPosition.GetNode();
const TRotMatrix *oldMatrix = 0;
Double_t oldTranslation[] = { 0, 0, 0 };
oldMatrix = GetMatrix();
oldTranslation[0] = GetX();
oldTranslation[1] = GetY();
oldTranslation[2] = GetZ();
const TRotMatrix *curMatrix = curPosition.GetMatrix();
Double_t newTranslation[3];
Double_t newMatrix[9];
if(oldMatrix){
TGeometry::UpdateTempMatrix(oldTranslation,((TRotMatrix *)oldMatrix)->GetMatrix()
,curPosition.GetX(),curPosition.GetY(),curPosition.GetZ(),
((TRotMatrix *)curMatrix)->GetMatrix()
,newTranslation,newMatrix);
Int_t num = gGeometry->GetListOfMatrices()->GetSize();
Char_t anum[100];
snprintf(anum,100,"%d",num+1);
SetMatrixOwner();
Reset(curNode
,newTranslation[0],newTranslation[1],newTranslation[2]
,new TRotMatrix(anum,"NodeView",newMatrix));
SetMatrixOwner(kTRUE);
} else {
newTranslation[0] = oldTranslation[0] + curPosition.GetX();
newTranslation[1] = oldTranslation[1] + curPosition.GetY();
newTranslation[2] = oldTranslation[2] + curPosition.GetZ();
Reset(curNode,newTranslation[0],newTranslation[1],newTranslation[2]);
}
return *this;
}
void TVolumePosition::SetXYZ(Double_t *xyz)
{
if (xyz) memcpy(fX,xyz,sizeof(fX));
else memset(fX,0,sizeof(fX));
}
void TVolumePosition::Streamer(TBuffer &R__b)
{
TRotMatrix *save = fMatrix;
if (R__b.IsReading()) {
fMatrix = 0;
R__b.ReadClassBuffer(TVolumePosition::Class(), this);
if (!fMatrix) fMatrix = save;
} else {
if (save == TVolume::GetIdentity() ) fMatrix = 0;
R__b.WriteClassBuffer(TVolumePosition::Class(), this);
fMatrix = save;
}
}
ostream& operator<<(ostream& s,const TVolumePosition &target)
{
s << " Node: ";
if (target.GetNode()) s << target.GetNode()->GetName() << endl;
else s << "NILL" << endl;
s << Form(" Position: x=%10.5f : y=%10.5f : z=%10.5f\n", target.GetX(), target.GetY(), target.GetZ());
TRotMatrix *rot = (TRotMatrix *) target.GetMatrix();
if (rot){
s << rot->IsA()->GetName() << "\t" << rot->GetName() << "\t" << rot->GetTitle() << endl;
Double_t *matrix = rot->GetMatrix();
Int_t i = 0;
for (i=0;i<3;i++) {
for (Int_t j=0;j<3;j++) s << Form("%10.5f:", *matrix++);
s << endl;
}
}
return s;
}