00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "Riostream.h"
00014
00015 #include "TCernLib.h"
00016 #include "TVolumePosition.h"
00017 #include "TVolume.h"
00018
00019 #include "TROOT.h"
00020 #include "TClass.h"
00021 #include "TVirtualPad.h"
00022 #include "TGeometry.h"
00023 #include "TRotMatrix.h"
00024 #include "TBrowser.h"
00025 #include "X3DBuffer.h"
00026
00027 #include "TTablePadView3D.h"
00028
00029
00030
00031 ClassImp(TVolumePosition)
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 TVolumePosition::TVolumePosition(TVolume *node,Double_t x, Double_t y, Double_t z, const char *matrixname)
00053 : fMatrix(0),fNode(node),fId(0)
00054 {
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 SetMatrixOwner(kFALSE);
00066 fX[0] = x; fX[1] =y; fX[2] = z;
00067 if (!node) return;
00068 static Int_t counter = 0;
00069 counter++;
00070 if(!(counter%1000))cout<<"TVolumePosition count="<<counter<<" name="<<node->GetName()<<endl;
00071
00072 if (!gGeometry) new TGeometry;
00073 if (matrixname && strlen(matrixname)) fMatrix = gGeometry->GetRotMatrix(matrixname);
00074 if (!fMatrix) fMatrix = TVolume::GetIdentity();
00075 }
00076
00077
00078
00079 TVolumePosition::TVolumePosition(TVolume *node,Double_t x, Double_t y, Double_t z, TRotMatrix *matrix)
00080 : fMatrix(matrix),fNode(node),fId(0)
00081 {
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 SetMatrixOwner(kFALSE);
00093 if (!gGeometry) new TGeometry;
00094 fX[0] = x; fX[1] = y; fX[2] = z;
00095 if (!fMatrix) fMatrix = TVolume::GetIdentity();
00096 }
00097
00098 TVolumePosition::TVolumePosition(const TVolumePosition* oldPosition, const TVolumePosition* curPosition){
00099
00100 fMatrix = 0;
00101 SetMatrixOwner(kFALSE);
00102 TVolume *curNode = 0;
00103 UInt_t curPositionId = 0;
00104 TRotMatrix *curMatrix = 0;
00105 if (curPosition) {
00106 curNode = curPosition->GetNode();
00107 curPositionId = curPosition->GetId();
00108 curMatrix = (TRotMatrix *) curPosition->GetMatrix();
00109 }
00110 TRotMatrix *oldMatrix = 0;
00111 fX[0] = 0; fX[1] = 0; fX[2] = 0;
00112 Double_t oldTranslation[] = { 0, 0, 0 };
00113 if (oldPosition) {
00114 oldMatrix = (TRotMatrix *) oldPosition->GetMatrix();
00115 oldTranslation[0] = oldPosition->GetX();
00116 oldTranslation[1] = oldPosition->GetY();
00117 oldTranslation[2] = oldPosition->GetZ();
00118 }
00119
00120
00121
00122
00123 Double_t newMatrix[9];
00124
00125 if(oldMatrix && curMatrix && curPosition) {
00126 TGeometry::UpdateTempMatrix(oldTranslation,oldMatrix->GetMatrix(),
00127 curPosition->GetX(),curPosition->GetY(),curPosition->GetZ(),
00128 curMatrix->GetMatrix(),
00129 fX,newMatrix);
00130 Int_t num = gGeometry->GetListOfMatrices()->GetSize();
00131 Char_t anum[100];
00132 snprintf(anum,100,"%d",num+1);
00133 fMatrix = new TRotMatrix(anum,"NodeView",newMatrix);
00134 SetMatrixOwner(kTRUE);
00135 } else {
00136 if (curPosition) {
00137 fX[0] = oldTranslation[0] + curPosition->GetX();
00138 fX[1] = oldTranslation[1] + curPosition->GetY();
00139 fX[2] = oldTranslation[2] + curPosition->GetZ();
00140 fMatrix = curMatrix;
00141 }
00142 }
00143 fId = curPositionId;
00144 fNode = curNode;
00145 }
00146
00147
00148 TVolumePosition::TVolumePosition(const TVolumePosition&pos): TObject()
00149 , fMatrix(((TVolumePosition &)pos).GetMatrix()),fNode(pos.GetNode()),fId(pos.GetId())
00150 {
00151
00152 for (int i=0;i<3;i++) fX[i] = pos.GetX(i);
00153
00154
00155
00156
00157 SetMatrixOwner(pos.IsMatrixOwner());
00158
00159 ((TVolumePosition &)pos).SetMatrixOwner(kFALSE);
00160 }
00161
00162
00163 TVolumePosition::~TVolumePosition()
00164 {
00165
00166 DeleteOwnMatrix();
00167 }
00168
00169 void TVolumePosition::Browse(TBrowser *b)
00170 {
00171
00172 if (GetNode()) {
00173 TShape *shape = GetNode()->GetShape();
00174 b->Add(GetNode(),shape?shape->GetName():GetNode()->GetName());
00175 } else {
00176 Draw();
00177 gPad->Update();
00178 }
00179 }
00180
00181
00182 Int_t TVolumePosition::DistancetoPrimitive(Int_t, Int_t)
00183 {
00184
00185
00186
00187
00188
00189
00190
00191 return 99999;
00192 }
00193
00194
00195 void TVolumePosition::Draw(Option_t *option)
00196 {
00197
00198
00199 TVolume *node = GetNode();
00200 if (node) node->Draw(option);
00201 }
00202
00203
00204
00205 void TVolumePosition::ExecuteEvent(Int_t, Int_t, Int_t)
00206 {
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 gPad->SetCursor(kHand);
00218 }
00219
00220
00221 const Char_t *TVolumePosition::GetName() const
00222 {
00223
00224 return GetNode()?GetNode()->GetName():IsA()->GetName();
00225 }
00226
00227
00228 char *TVolumePosition::GetObjectInfo(Int_t, Int_t) const
00229 {
00230
00231 if (!gPad) return 0;
00232 if (!GetNode()) return 0;
00233 static char info[64];
00234 snprintf(info,64,"%s/%s, shape=%s/%s",GetNode()->GetName(),GetNode()->GetTitle(),GetNode()->GetShape()->GetName(),GetNode()->GetShape()->ClassName());
00235 return info;
00236 }
00237
00238
00239 Double_t *TVolumePosition::Errmx2Master(const Double_t *localError, Double_t *masterError) const
00240 {
00241
00242 Double_t error[6];
00243 TCL::vzero(&error[1],4);
00244 error[0] = localError[0]; error[2] = localError[1]; error[5] = localError[2];
00245 return Cormx2Master(error, masterError);
00246 }
00247
00248
00249 Float_t *TVolumePosition::Errmx2Master(const Float_t *localError, Float_t *masterError) const
00250 {
00251
00252 Float_t error[6];
00253 TCL::vzero(&error[1],4);
00254 error[0] = localError[0]; error[2] = localError[1]; error[5] = localError[2];
00255 return Cormx2Master(error, masterError);
00256 }
00257
00258
00259 Double_t *TVolumePosition::Cormx2Master(const Double_t *localCorr, Double_t *masterCorr)const
00260 {
00261
00262 Double_t *res = 0;
00263 const TRotMatrix *rm = GetMatrix();
00264 double *m = 0;
00265 if (rm && ( m = ((TRotMatrix *)rm)->GetMatrix()) )
00266 res = TCL::trasat(m,(Double_t *)localCorr,masterCorr,3,3);
00267 else
00268 res = TCL::ucopy(localCorr,masterCorr,6);
00269 return res;
00270 }
00271
00272
00273 Float_t *TVolumePosition::Cormx2Master(const Float_t *localCorr, Float_t *masterCorr) const
00274 {
00275
00276 Float_t *res = 0;
00277 const TRotMatrix *rm = GetMatrix();
00278 Double_t *m = 0;
00279 if (rm && (m = ((TRotMatrix *)rm)->GetMatrix()) ) {
00280 double corLocal[6], corGlobal[6];
00281 TCL::ucopy(localCorr,corLocal,6);
00282 TCL::trasat(m,corLocal,corGlobal,3,3);
00283 res = TCL::ucopy(corGlobal,masterCorr,6);
00284 } else
00285 res = TCL::ucopy(localCorr,masterCorr,6);
00286 return res;
00287 }
00288
00289 Double_t *TVolumePosition::Errmx2Local(const Double_t *masterError, Double_t *localError) const
00290 {
00291
00292 Double_t error[6];
00293 TCL::vzero(&error[1],4);
00294 error[0] = masterError[0]; error[2] = masterError[1]; error[5] = masterError[2];
00295 return Cormx2Local(error, localError);
00296 }
00297
00298 Float_t *TVolumePosition::Errmx2Local(const Float_t *masterError, Float_t *localError) const
00299 {
00300
00301 Float_t error[6];
00302 TCL::vzero(&error[1],4);
00303 error[0] = masterError[0]; error[2] = masterError[1]; error[5] = masterError[2];
00304 return Cormx2Local(error, localError);
00305 }
00306
00307 Double_t *TVolumePosition::Cormx2Local(const Double_t *localCorr, Double_t *masterCorr) const
00308 {
00309
00310 Double_t *res = 0;
00311 TRotMatrix *rm = (TRotMatrix *) GetMatrix();
00312 double *m = 0;
00313 if (rm && ( m = rm->GetMatrix()) )
00314 res = TCL::tratsa(m,(Double_t *)localCorr,masterCorr,3,3);
00315 else
00316 res = TCL::ucopy(localCorr,masterCorr,6);
00317 return res;
00318 }
00319
00320
00321 Float_t *TVolumePosition::Cormx2Local(const Float_t *localCorr, Float_t *masterCorr) const
00322 {
00323
00324 Float_t *res = 0;
00325 TRotMatrix *rm = (TRotMatrix *) GetMatrix();
00326 Double_t *m = 0;
00327 if (rm && (m = rm->GetMatrix()) ) {
00328 double corLocal[6], corGlobal[6];
00329 TCL::ucopy(localCorr,corLocal,6);
00330 TCL::tratsa(m,corLocal,corGlobal,3,3);
00331 res = TCL::ucopy(corGlobal,masterCorr,6);
00332 }
00333 else
00334 res = TCL::ucopy(localCorr,masterCorr,6);
00335 return res;
00336 }
00337
00338
00339 Double_t *TVolumePosition::Local2Master(const Double_t *local, Double_t *master, Int_t nPoints) const
00340 {
00341
00342
00343
00344
00345
00346
00347
00348 Double_t *matrix = 0;
00349 Double_t *trans = 0;
00350 if (!fMatrix || fMatrix == TVolume::GetIdentity() || !(matrix = ((TRotMatrix *)fMatrix)->GetMatrix()) ) {
00351 trans = master;
00352 for (int i =0; i < nPoints; i++,local += 3, master += 3) TCL::vadd(local,fX,master,3);
00353 } else {
00354 trans = master;
00355 for (int i =0; i < nPoints; i++, local += 3, master += 3) {
00356 TCL::mxmpy2(matrix,local,master,3,3,1);
00357 TCL::vadd(master,fX,master,3);
00358 }
00359 }
00360 return trans;
00361 }
00362
00363
00364 Float_t *TVolumePosition::Local2Master(const Float_t *local, Float_t *master, Int_t nPoints) const
00365 {
00366
00367
00368
00369
00370
00371
00372
00373
00374 Double_t *matrix = 0;
00375 Float_t *trans = 0;
00376 if (!fMatrix || fMatrix == TVolume::GetIdentity() || !(matrix = ((TRotMatrix *)fMatrix)->GetMatrix()) )
00377 {
00378 trans = master;
00379 for (int i =0; i < nPoints; i++,local += 3, master += 3) TCL::vadd(local,fX,master,3);
00380 } else {
00381 trans = master;
00382 for (int i =0; i < nPoints; i++, local += 3, master += 3) {
00383 Double_t dlocal[3]; Double_t dmaster[3];
00384 TCL::ucopy(local,dlocal,3);
00385 TCL::mxmpy2(matrix,dlocal,dmaster,3,3,1);
00386 TCL::vadd(dmaster,fX,dmaster,3);
00387 TCL::ucopy(dmaster,master,3);
00388 }
00389 }
00390 return trans;
00391 }
00392
00393 Double_t *TVolumePosition::Master2Local(const Double_t *master, Double_t *local, Int_t nPoints) const
00394 {
00395
00396
00397
00398
00399
00400
00401
00402 Double_t *matrix = 0;
00403 Double_t *trans = 0;
00404 if (!fMatrix || fMatrix == TVolume::GetIdentity() || !(matrix = ((TRotMatrix *)fMatrix)->GetMatrix()) ){
00405 trans = local;
00406 for (int i =0; i < nPoints; i++,master += 3, local += 3) TCL::vsub(master,fX,local,3);
00407 } else {
00408 trans = local;
00409 for (int i =0; i < nPoints; i++, master += 3, local += 3) {
00410 Double_t dlocal[3];
00411 TCL::vsub(master,fX,dlocal,3);
00412 TCL::mxmpy(matrix,dlocal,local,3,3,1);
00413 }
00414 }
00415 return trans;
00416 }
00417
00418
00419 Float_t *TVolumePosition::Master2Local(const Float_t *master, Float_t *local, Int_t nPoints) const
00420 {
00421
00422
00423
00424
00425
00426
00427
00428
00429 Double_t *matrix = 0;
00430 Float_t *trans = 0;
00431 if (!fMatrix || fMatrix == TVolume::GetIdentity() || !(matrix = ((TRotMatrix *)fMatrix)->GetMatrix()) ){
00432 trans = local;
00433 for (int i =0; i < nPoints; i++,master += 3, local += 3) TCL::vsub(master,fX,local,3);
00434 } else {
00435 trans = local;
00436 for (int i =0; i < nPoints; i++, master += 3, local += 3) {
00437 Double_t dmaster[3]; Double_t dlocal[3];
00438 TCL::ucopy(master,dmaster,3);
00439 TCL::vsub(dmaster,fX,dmaster,3);
00440 TCL::mxmpy(matrix,dmaster,dlocal,3,3,1);
00441 TCL::ucopy(dlocal,local,3);
00442 }
00443 }
00444 return trans;
00445 }
00446
00447 void TVolumePosition::Paint(Option_t *)
00448 {
00449
00450
00451
00452 Error("Paint","Position can not be painted");
00453 }
00454
00455
00456 void TVolumePosition::Print(Option_t *) const
00457 {
00458
00459 cout << *this << endl;
00460 }
00461
00462
00463 TVolumePosition *TVolumePosition::Reset(TVolume *node,Double_t x, Double_t y, Double_t z, TRotMatrix *matrix)
00464 {
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475 fNode = node;
00476 SetPosition(x,y,z);
00477 SetMatrix(matrix);
00478 if (!fMatrix) fMatrix = TVolume::GetIdentity();
00479 return this;
00480 }
00481
00482
00483 void TVolumePosition::SavePrimitive(ostream &, Option_t * )
00484 {
00485
00486 #if 0
00487 out << "TVolumePosition *CreatePosition() { " << endl;
00488 out << " TVolumePosition *myPosition = 0; " << endl;
00489 Double_t x = GetX();
00490 Double_t y = GetY();
00491 Double_t z = GetZ();
00492 TRotMatrix *matrix =
00493 myPosition = new TVolumePosition(TVolume *node,Double_t x, Double_t y, Double_t z, const char *matrixname)
00494 : fNode(node),fX(x),fY(y),fZ(z),fMatrix(0)
00495 {
00496 /
00497 out << " return myPosition; " << endl;
00498 out << "} " << endl;
00499 #endif
00500
00501 }
00502
00503 void TVolumePosition::SetLineAttributes()
00504 {
00505
00506 TVolume *thisNode = GetNode();
00507 if (thisNode) thisNode->SetLineAttributes();
00508 }
00509
00510 void TVolumePosition::SetMatrix(TRotMatrix *matrix)
00511 {
00512
00513 if (matrix != fMatrix) {
00514 DeleteOwnMatrix();
00515 fMatrix = matrix;
00516 }
00517 }
00518
00519 void TVolumePosition::UpdatePosition(Option_t *)
00520 {
00521
00522 TTablePadView3D *view3D=(TTablePadView3D *)gPad->GetView3D();
00523
00524 if (gGeometry->GeomLevel() && fMatrix) {
00525 gGeometry->UpdateTempMatrix(fX[0],fX[1],fX[2]
00526 ,((TRotMatrix *)fMatrix)->GetMatrix()
00527 ,fMatrix->IsReflection());
00528 if (view3D)
00529 view3D->UpdatePosition(fX[0],fX[1],fX[2],((TRotMatrix *)fMatrix));
00530 }
00531 }
00532
00533
00534 void TVolumePosition::SetVisibility(Int_t vis)
00535 {
00536
00537 TVolume *node = GetNode();
00538 if (node) node->SetVisibility(TVolume::ENodeSEEN(vis));
00539 }
00540
00541 TVolumePosition &TVolumePosition::Mult(const TVolumePosition &curPosition) {
00542
00543
00544
00545
00546
00547
00548
00549 TVolume *curNode = 0;
00550
00551 curNode = curPosition.GetNode();
00552
00553 const TRotMatrix *oldMatrix = 0;
00554 Double_t oldTranslation[] = { 0, 0, 0 };
00555 oldMatrix = GetMatrix();
00556 oldTranslation[0] = GetX();
00557 oldTranslation[1] = GetY();
00558 oldTranslation[2] = GetZ();
00559
00560
00561 const TRotMatrix *curMatrix = curPosition.GetMatrix();
00562
00563
00564 Double_t newTranslation[3];
00565 Double_t newMatrix[9];
00566 if(oldMatrix){
00567 TGeometry::UpdateTempMatrix(oldTranslation,((TRotMatrix *)oldMatrix)->GetMatrix()
00568 ,curPosition.GetX(),curPosition.GetY(),curPosition.GetZ(),
00569 ((TRotMatrix *)curMatrix)->GetMatrix()
00570 ,newTranslation,newMatrix);
00571 Int_t num = gGeometry->GetListOfMatrices()->GetSize();
00572 Char_t anum[100];
00573 snprintf(anum,100,"%d",num+1);
00574 SetMatrixOwner();
00575 Reset(curNode
00576 ,newTranslation[0],newTranslation[1],newTranslation[2]
00577 ,new TRotMatrix(anum,"NodeView",newMatrix));
00578 SetMatrixOwner(kTRUE);
00579 } else {
00580 newTranslation[0] = oldTranslation[0] + curPosition.GetX();
00581 newTranslation[1] = oldTranslation[1] + curPosition.GetY();
00582 newTranslation[2] = oldTranslation[2] + curPosition.GetZ();
00583 Reset(curNode,newTranslation[0],newTranslation[1],newTranslation[2]);
00584 }
00585
00586 return *this;
00587 }
00588
00589
00590 void TVolumePosition::SetXYZ(Double_t *xyz)
00591 {
00592
00593 if (xyz) memcpy(fX,xyz,sizeof(fX));
00594 else memset(fX,0,sizeof(fX));
00595 }
00596
00597
00598 void TVolumePosition::Streamer(TBuffer &R__b)
00599 {
00600
00601 TRotMatrix *save = fMatrix;
00602 if (R__b.IsReading()) {
00603 fMatrix = 0;
00604 R__b.ReadClassBuffer(TVolumePosition::Class(), this);
00605 if (!fMatrix) fMatrix = save;
00606 } else {
00607 if (save == TVolume::GetIdentity() ) fMatrix = 0;
00608 R__b.WriteClassBuffer(TVolumePosition::Class(), this);
00609 fMatrix = save;
00610 }
00611 }
00612
00613 ostream& operator<<(ostream& s,const TVolumePosition &target)
00614 {
00615
00616 s << " Node: ";
00617 if (target.GetNode()) s << target.GetNode()->GetName() << endl;
00618 else s << "NILL" << endl;
00619 s << Form(" Position: x=%10.5f : y=%10.5f : z=%10.5f\n", target.GetX(), target.GetY(), target.GetZ());
00620 TRotMatrix *rot = (TRotMatrix *) target.GetMatrix();
00621 if (rot){
00622 s << rot->IsA()->GetName() << "\t" << rot->GetName() << "\t" << rot->GetTitle() << endl;
00623 Double_t *matrix = rot->GetMatrix();
00624 Int_t i = 0;
00625 for (i=0;i<3;i++) {
00626 for (Int_t j=0;j<3;j++) s << Form("%10.5f:", *matrix++);
00627 s << endl;
00628 }
00629 }
00630 return s;
00631 }