00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 #include "TClass.h"
00049 #include "TGeoManager.h"
00050 #include "TGeoVoxelFinder.h"
00051 #include "TGeoCache.h"
00052 #include "TGeoMatrix.h"
00053 #include "TGeoShapeAssembly.h"
00054 #include "TGeoVolume.h"
00055 #include "TVirtualGeoPainter.h"
00056
00057 #include "TGeoPhysicalNode.h"
00058
00059
00060
00061 ClassImp(TGeoPhysicalNode)
00062
00063
00064 TGeoPhysicalNode::TGeoPhysicalNode() : TNamed()
00065 {
00066
00067 fLevel = 0;
00068 fMatrices = 0;
00069 fNodes = 0;
00070 fMatrixOrig = 0;
00071 SetVisibility(kTRUE);
00072 SetVisibleFull(kFALSE);
00073 SetIsVolAtt(kTRUE);
00074 SetAligned(kFALSE);
00075 }
00076
00077
00078 TGeoPhysicalNode::TGeoPhysicalNode(const char *path) : TNamed(path,"")
00079 {
00080
00081 if (!strlen(path)) {
00082 Error("ctor", "path not valid");
00083 return;
00084 }
00085 fLevel = 0;
00086 fMatrices = new TObjArray(30);
00087 fNodes = new TObjArray(30);
00088 fMatrixOrig = 0;
00089 SetPath(path);
00090 SetVisibility(kTRUE);
00091 SetVisibleFull(kFALSE);
00092 SetIsVolAtt(kTRUE);
00093 SetAligned(kFALSE);
00094 }
00095
00096
00097 TGeoPhysicalNode::TGeoPhysicalNode(const TGeoPhysicalNode& gpn) :
00098 TNamed(gpn),
00099 TAttLine(gpn),
00100 fLevel(gpn.fLevel),
00101 fMatrices(gpn.fMatrices),
00102 fNodes(gpn.fNodes),
00103 fMatrixOrig(gpn.fMatrixOrig)
00104 {
00105
00106 }
00107
00108
00109 TGeoPhysicalNode& TGeoPhysicalNode::operator=(const TGeoPhysicalNode& gpn)
00110 {
00111
00112 if(this!=&gpn) {
00113 TNamed::operator=(gpn);
00114 TAttLine::operator=(gpn);
00115 fLevel=gpn.fLevel;
00116 fMatrices=gpn.fMatrices;
00117 fNodes=gpn.fNodes;
00118 fMatrixOrig=gpn.fMatrixOrig;
00119 }
00120 return *this;
00121 }
00122
00123
00124 TGeoPhysicalNode::~TGeoPhysicalNode()
00125 {
00126
00127 if (fMatrices) {
00128 fMatrices->Delete();
00129 delete fMatrices;
00130 }
00131 if (fNodes) delete fNodes;
00132 if (fMatrixOrig) delete fMatrixOrig;
00133 }
00134
00135
00136 void TGeoPhysicalNode::Align(TGeoMatrix *newmat, TGeoShape *newshape, Bool_t check, Double_t ovlp)
00137 {
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 if (!newmat && !newshape) return;
00148 if (TGeoManager::IsLocked()) {
00149 Error("Align", "Not performed. Geometry in LOCKED mode !");
00150 return;
00151 }
00152 TGeoNode *node = GetNode();
00153 if (node->IsOffset()) {
00154 Error("Align", "Cannot align division nodes: %s\n",node->GetName());
00155 return;
00156 }
00157 TGeoNode *nnode = 0;
00158 TGeoVolume *vm = GetVolume(0);
00159 TGeoVolume *vd = 0;
00160 Int_t i;
00161 if (!IsAligned()) {
00162 Int_t *id = new Int_t[fLevel];
00163 for (i=0; i<fLevel; i++) {
00164
00165 vd = GetVolume(i);
00166 node = GetNode(i+1);
00167 id[i] = vd->GetIndex(node);
00168 if (id[i]<0) {
00169 Error("Align","%s cannot align node %s",GetName(), node->GetName());
00170 delete [] id;
00171 return;
00172 }
00173 }
00174 for (i=0; i<fLevel; i++) {
00175
00176 node = GetNode(i+1);
00177
00178 vd = node->GetVolume()->CloneVolume();
00179 nnode = node->MakeCopyNode();
00180
00181 nnode->SetVolume(vd);
00182 nnode->SetMotherVolume(vm);
00183
00184 if (vm->TestBit(TGeoVolume::kVolumeImportNodes)) {
00185 gGeoManager->GetListOfGShapes()->Add(nnode);
00186 }
00187 vm->GetNodes()->RemoveAt(id[i]);
00188 vm->GetNodes()->AddAt(nnode,id[i]);
00189 fNodes->RemoveAt(i+1);
00190 fNodes->AddAt(nnode,i+1);
00191
00192 vm = vd;
00193 }
00194 delete [] id;
00195 } else {
00196 nnode = GetNode();
00197 }
00198
00199 TGeoNodeMatrix *aligned = (TGeoNodeMatrix*)nnode;
00200 vm = nnode->GetMotherVolume();
00201 vd = nnode->GetVolume();
00202 if (newmat) {
00203
00204 if (!newmat->IsRegistered()) newmat->RegisterYourself();
00205 aligned->SetMatrix(newmat);
00206
00207 TGeoHMatrix *global = GetMatrix();
00208 TGeoHMatrix *up = GetMatrix(fLevel-1);
00209 *global = up;
00210 global->Multiply(newmat);
00211 }
00212
00213 if (newshape) vd->SetShape(newshape);
00214
00215
00216 for (i=fLevel-1; i>0; i--) {
00217 Bool_t dassm = vd->IsAssembly();
00218 vd = GetVolume(i);
00219 Bool_t cassm = vd->IsAssembly();
00220 if (cassm) ((TGeoShapeAssembly*)vd->GetShape())->NeedsBBoxRecompute();
00221 if ((cassm || dassm) && vd->GetVoxels()) vd->GetVoxels()->SetNeedRebuild();
00222 if (!cassm) break;
00223 }
00224
00225
00226 TGeoVoxelFinder *voxels = vm->GetVoxels();
00227 if (voxels) voxels->SetNeedRebuild();
00228
00229 if (check) {
00230 if (voxels) {
00231 voxels->Voxelize();
00232 vm->FindOverlaps();
00233 }
00234
00235 i = fLevel;
00236 node = GetNode(i);
00237 if (node->IsOverlapping()) {
00238 Info("Align", "The check for overlaps for node: \n%s\n cannot be performed since the node is declared possibly overlapping",
00239 GetName());
00240 } else {
00241 gGeoManager->SetCheckedNode(node);
00242
00243 while ((node=GetNode(--i))) {
00244 if (!node->GetVolume()->IsAssembly()) break;
00245 }
00246 if (node && node->IsOverlapping()) {
00247 Info("Align", "The check for overlaps for assembly node: \n%s\n cannot be performed since the parent %s is declared possibly overlapping",
00248 GetName(), node->GetName());
00249 node = 0;
00250 }
00251 if (node) node->CheckOverlaps(ovlp);
00252 gGeoManager->SetCheckedNode(0);
00253 }
00254 }
00255
00256 gGeoManager->CdTop();
00257 SetAligned(kTRUE);
00258 }
00259
00260
00261 void TGeoPhysicalNode::cd() const
00262 {
00263 gGeoManager->cd(fName.Data());
00264 }
00265
00266
00267 void TGeoPhysicalNode::Draw(Option_t * )
00268 {
00269
00270 }
00271
00272
00273 TGeoNode *TGeoPhysicalNode::GetMother(Int_t levup) const
00274 {
00275
00276 Int_t ind = fLevel-levup;
00277 if (ind<0) return 0;
00278 return (TGeoNode*)fNodes->UncheckedAt(ind);
00279 }
00280
00281
00282 TGeoHMatrix *TGeoPhysicalNode::GetMatrix(Int_t level) const
00283 {
00284
00285 if (level<0) return (TGeoHMatrix*)fMatrices->UncheckedAt(fLevel);
00286 if (level>fLevel) return 0;
00287 return (TGeoHMatrix*)fMatrices->UncheckedAt(level);
00288 }
00289
00290
00291 TGeoNode *TGeoPhysicalNode::GetNode(Int_t level) const
00292 {
00293
00294 if (level<0) return (TGeoNode*)fNodes->UncheckedAt(fLevel);
00295 if (level>fLevel) return 0;
00296 return (TGeoNode*)fNodes->UncheckedAt(level);
00297 }
00298
00299
00300 TGeoVolume *TGeoPhysicalNode::GetVolume(Int_t level) const
00301 {
00302
00303 TGeoNode *node = GetNode(level);
00304 if (node) return node->GetVolume();
00305 return 0;
00306 }
00307
00308
00309 TGeoShape *TGeoPhysicalNode::GetShape(Int_t level) const
00310 {
00311
00312 TGeoVolume *vol = GetVolume(level);
00313 if (vol) return vol->GetShape();
00314 return 0;
00315 }
00316
00317
00318 void TGeoPhysicalNode::Paint(Option_t * )
00319 {
00320
00321 TVirtualGeoPainter *painter = gGeoManager->GetGeomPainter();
00322 if (!painter) return;
00323
00324 }
00325
00326
00327 void TGeoPhysicalNode::Print(Option_t * ) const
00328 {
00329
00330 printf("TGeoPhysicalNode: %s level=%d aligned=%d\n", fName.Data(), fLevel, IsAligned());
00331 for (Int_t i=0; i<=fLevel; i++) {
00332 printf(" level %d: node %s\n", i, GetNode(i)->GetName());
00333 printf(" local matrix:\n");
00334 if (GetNode(i)->GetMatrix()->IsIdentity()) printf(" IDENTITY\n");
00335 else GetNode(i)->GetMatrix()->Print();
00336 printf(" global matrix:\n");
00337 if (GetMatrix(i)->IsIdentity()) printf(" IDENTITY\n");
00338 else GetMatrix(i)->Print();
00339 }
00340 if (IsAligned() && fMatrixOrig) {
00341 printf(" original local matrix:\n");
00342 fMatrixOrig->Print();
00343 }
00344 }
00345
00346
00347 void TGeoPhysicalNode::Refresh()
00348 {
00349
00350
00351 SetPath(fName.Data());
00352 }
00353
00354
00355 void TGeoPhysicalNode::SetBranchAsState()
00356 {
00357
00358 TGeoNodeCache *cache = gGeoManager->GetCache();
00359 if (!cache) {
00360 Error("SetBranchAsState","no state available");
00361 return;
00362 }
00363 if (!cache->IsDummy()) {
00364 Error("SetBranchAsState", "not implemented for full cache");
00365 return;
00366 }
00367 if (!fNodes) fNodes = new TObjArray(30);
00368 if (!fMatrices) fMatrices = new TObjArray(30);
00369 TGeoHMatrix **matrices = (TGeoHMatrix **) cache->GetMatrices();
00370 TGeoNode **branch = (TGeoNode **) cache->GetBranch();
00371
00372 Bool_t refresh = (fLevel>0)?kTRUE:kFALSE;
00373 if (refresh) {
00374 TGeoHMatrix *current;
00375 for (Int_t i=0; i<=fLevel; i++) {
00376 fNodes->AddAtAndExpand(branch[i],i);
00377 current = (TGeoHMatrix*)fMatrices->UncheckedAt(i);
00378 *current = *matrices[i];
00379 }
00380 return;
00381 }
00382 fLevel = gGeoManager->GetLevel();
00383 for (Int_t i=0; i<=fLevel; i++) {
00384 fNodes->AddAtAndExpand(branch[i],i);
00385 fMatrices->AddAtAndExpand(new TGeoHMatrix(*matrices[i]),i);
00386 }
00387 TGeoNode *node = (TGeoNode*)fNodes->UncheckedAt(fLevel);
00388 if (!fMatrixOrig) fMatrixOrig = new TGeoHMatrix();
00389 *fMatrixOrig = node->GetMatrix();
00390 }
00391
00392
00393 void TGeoPhysicalNode::SetMatrixOrig(const TGeoMatrix *local)
00394 {
00395
00396
00397 if (!fMatrixOrig) fMatrixOrig = new TGeoHMatrix();
00398 if (!local) fMatrixOrig->Clear();
00399 *fMatrixOrig = local;
00400 }
00401
00402
00403 Bool_t TGeoPhysicalNode::SetPath(const char *path)
00404 {
00405
00406 if (!gGeoManager->cd(path)) {
00407 Error("SetPath","wrong path -> maybe RestoreMasterVolume");
00408 return kFALSE;
00409 }
00410 SetBranchAsState();
00411 return kTRUE;
00412 }
00413
00414 ClassImp(TGeoPNEntry)
00415
00416
00417 TGeoPNEntry::TGeoPNEntry()
00418 {
00419
00420 fNode = 0;
00421 fMatrix = 0;
00422 fGlobalOrig = 0;
00423 }
00424
00425
00426 TGeoPNEntry::TGeoPNEntry(const char *name, const char *path)
00427 :TNamed(name, path)
00428 {
00429
00430 if (!gGeoManager || !gGeoManager->IsClosed() || !gGeoManager->CheckPath(path)) {
00431 TString errmsg("Cannot define a physical node link without a closed geometry and a valid path !");
00432 Error("ctor", "%s", errmsg.Data());
00433 throw errmsg;
00434 return;
00435 }
00436 gGeoManager->PushPath();
00437 gGeoManager->cd(path);
00438 fGlobalOrig = new TGeoHMatrix();
00439 *fGlobalOrig = gGeoManager->GetCurrentMatrix();
00440 gGeoManager->PopPath();
00441 fNode = 0;
00442 fMatrix = 0;
00443 }
00444
00445
00446 TGeoPNEntry::~TGeoPNEntry()
00447 {
00448
00449 if (fMatrix && !fMatrix->IsRegistered()) delete fMatrix;
00450 delete fGlobalOrig;
00451 }
00452
00453
00454 void TGeoPNEntry::SetPhysicalNode(TGeoPhysicalNode *node)
00455 {
00456
00457 if (fNode && node) {
00458 Warning("SetPhysicalNode", "Physical node changed for entry %s", GetName());
00459 Warning("SetPhysicalNode", "=== New path: %s", node->GetName());
00460 }
00461 fNode = node;
00462 }
00463
00464
00465 void TGeoPNEntry::SetMatrix(const TGeoHMatrix *mat)
00466 {
00467
00468
00469 fMatrix = mat;
00470 }