74 ClassImp(TGeoPhysicalNode);
79 TGeoPhysicalNode::TGeoPhysicalNode() : TNamed()
86 SetVisibleFull(kFALSE);
94 TGeoPhysicalNode::TGeoPhysicalNode(
const char *path) : TNamed(path,
"")
97 Error(
"ctor",
"path not valid");
101 fMatrices =
new TObjArray(30);
102 fNodes =
new TObjArray(30);
105 SetVisibility(kTRUE);
106 SetVisibleFull(kFALSE);
114 TGeoPhysicalNode::TGeoPhysicalNode(
const TGeoPhysicalNode& gpn) :
118 fMatrices(gpn.fMatrices),
120 fMatrixOrig(gpn.fMatrixOrig)
127 TGeoPhysicalNode& TGeoPhysicalNode::operator=(
const TGeoPhysicalNode& gpn)
130 TNamed::operator=(gpn);
131 TAttLine::operator=(gpn);
133 fMatrices=gpn.fMatrices;
135 fMatrixOrig=gpn.fMatrixOrig;
143 TGeoPhysicalNode::~TGeoPhysicalNode()
149 if (fNodes)
delete fNodes;
150 if (fMatrixOrig)
delete fMatrixOrig;
164 Bool_t TGeoPhysicalNode::Align(TGeoMatrix *newmat, TGeoShape *newshape, Bool_t check, Double_t ovlp)
166 if (!newmat && !newshape)
return kFALSE;
167 if (TGeoManager::IsLocked()) {
168 Error(
"Align",
"Not performed. Geometry in LOCKED mode !");
171 if (newmat == gGeoIdentity) {
172 Error(
"Align",
"Cannot align using gGeoIdentity. Use some default matrix constructor to represent identities.");
175 TGeoNode *node = GetNode();
176 if (node->IsOffset()) {
177 Error(
"Align",
"Cannot align division nodes: %s\n",node->GetName());
183 TGeoVolume *vm = GetVolume(0);
187 Int_t *
id =
new Int_t[fLevel];
188 for (i=0; i<fLevel; i++) {
192 id[i] = vd->GetIndex(node);
194 Error(
"Align",
"%s cannot align node %s",GetName(), node->GetName());
199 for (i=0; i<fLevel; i++) {
203 if (node->IsCloned()) {
204 vd = node->GetVolume();
207 vd = node->GetVolume()->CloneVolume();
210 Fatal(
"Align",
"Cannot clone volume %s", node->GetVolume()->GetName());
213 nnode = node->MakeCopyNode();
216 Fatal(
"Align",
"Cannot make copy node for %s", node->GetName());
220 nnode->SetVolume(vd);
221 nnode->SetMotherVolume(vm);
223 if (vm->TestBit(TGeoVolume::kVolumeImportNodes)) {
224 gGeoManager->GetListOfGShapes()->Add(nnode);
226 vm->GetNodes()->RemoveAt(
id[i]);
227 vm->GetNodes()->AddAt(nnode,
id[i]);
228 fNodes->RemoveAt(i+1);
229 fNodes->AddAt(nnode,i+1);
240 TGeoNodeMatrix *aligned = (TGeoNodeMatrix*)nnode;
241 vm = nnode->GetMotherVolume();
242 vd = nnode->GetVolume();
245 Bool_t shared = kFALSE;
246 Int_t nd = vm->GetNdaughters();
247 TGeoCompositeShape *cs;
248 if (nnode->GetMatrix()->IsShared()) {
250 for (i=0; i<nd; i++) {
251 node = vm->GetNode(i);
252 if (node==nnode)
continue;
253 if (node->IsOffset())
continue;
254 if (!node->GetVolume()->GetShape()->IsComposite())
continue;
256 cs = (TGeoCompositeShape*)node->GetVolume()->GetShape();
257 if (cs->GetBoolNode()->GetRightMatrix() != nnode->GetMatrix())
continue;
259 TGeoCompositeShape *ncs =
new TGeoCompositeShape(cs->GetName(), cs->GetBoolNode()->MakeClone());
260 ncs->GetBoolNode()->ReplaceMatrix(nnode->GetMatrix(), newmat);
262 TGeoVolume *newvol = node->GetVolume()->CloneVolume();
264 Error(
"Align",
"Cannot clone volume %s", node->GetVolume()->GetName());
267 newvol->SetShape(ncs);
268 TGeoNode *newnode = node->MakeCopyNode();
270 Error(
"Align",
"Cannot clone node %s", node->GetName());
273 newnode->SetVolume(newvol);
274 newnode->SetMotherVolume(vm);
275 if (vm->TestBit(TGeoVolume::kVolumeImportNodes)) {
276 gGeoManager->GetListOfGShapes()->Add(newnode);
278 vm->GetNodes()->RemoveAt(i);
279 vm->GetNodes()->AddAt(newnode,i);
282 if (!shared) Error(
"Align",
"The matrix replaced for %s is not actually shared", GetName());
285 if (vd->GetShape()->IsComposite()) {
286 cs = (TGeoCompositeShape*)vd->GetShape();
287 if (cs->GetBoolNode()->GetRightMatrix()->IsShared()) {
288 if (!nnode->GetMatrix()->IsIdentity()) {
289 Error(
"Align",
"The composite shape having a shared matrix on the subtracted branch must be positioned using identity matrix.");
294 TGeoCompositeShape *ncs =
new TGeoCompositeShape(cs->GetName(), cs->GetBoolNode()->MakeClone());
295 TGeoMatrix *oldmat = ncs->GetBoolNode()->GetLeftMatrix();
296 TGeoHMatrix *newmat1 =
new TGeoHMatrix(*newmat);
297 newmat1->Multiply(oldmat);
298 ncs->GetBoolNode()->ReplaceMatrix(oldmat, newmat1);
306 if (!newmat->IsRegistered()) newmat->RegisterYourself();
308 aligned->SetMatrix(newmat);
310 TGeoHMatrix *global = GetMatrix();
311 TGeoHMatrix *up = GetMatrix(fLevel-1);
313 global->Multiply(newmat);
317 if (newshape) vd->SetShape(newshape);
320 for (i=fLevel-1; i>0; i--) {
321 Bool_t dassm = vd->IsAssembly();
324 Bool_t cassm = vd->IsAssembly();
325 if (cassm) ((TGeoShapeAssembly*)vd->GetShape())->NeedsBBoxRecompute();
326 if ((cassm || dassm) && vd->GetVoxels()) vd->GetVoxels()->SetNeedRebuild();
331 TGeoVoxelFinder *voxels = vm->GetVoxels();
332 if (voxels) voxels->SetNeedRebuild();
342 if (!node)
return kTRUE;
343 if (node->IsOverlapping()) {
344 Info(
"Align",
"The check for overlaps for node: \n%s\n cannot be performed since the node is declared possibly overlapping",
347 gGeoManager->SetCheckedNode(node);
349 while ((node=GetNode(--i))) {
350 if (!node->GetVolume()->IsAssembly())
break;
352 if (node && node->IsOverlapping()) {
353 Info(
"Align",
"The check for overlaps for assembly node: \n%s\n cannot be performed since the parent %s is declared possibly overlapping",
354 GetName(), node->GetName());
357 if (node) node->CheckOverlaps(ovlp);
358 gGeoManager->SetCheckedNode(0);
362 gGeoManager->CdTop();
369 void TGeoPhysicalNode::cd()
const
371 if (GetNode(0) != gGeoManager->GetTopNode())
return;
372 gGeoManager->cd(fName.Data());
378 void TGeoPhysicalNode::Draw(Option_t * )
385 TGeoNode *TGeoPhysicalNode::GetMother(Int_t levup)
const
387 Int_t ind = fLevel-levup;
389 return (TGeoNode*)fNodes->UncheckedAt(ind);
395 TGeoHMatrix *TGeoPhysicalNode::GetMatrix(Int_t level)
const
397 if (level<0)
return (TGeoHMatrix*)fMatrices->UncheckedAt(fLevel);
398 if (level>fLevel)
return 0;
399 return (TGeoHMatrix*)fMatrices->UncheckedAt(level);
405 TGeoNode *TGeoPhysicalNode::GetNode(Int_t level)
const
407 if (level<0)
return (TGeoNode*)fNodes->UncheckedAt(fLevel);
408 if (level>fLevel)
return 0;
409 return (TGeoNode*)fNodes->UncheckedAt(level);
415 TGeoVolume *TGeoPhysicalNode::GetVolume(Int_t level)
const
417 TGeoNode *node = GetNode(level);
418 if (node)
return node->GetVolume();
425 TGeoShape *TGeoPhysicalNode::GetShape(Int_t level)
const
427 TGeoVolume *vol = GetVolume(level);
428 if (vol)
return vol->GetShape();
435 void TGeoPhysicalNode::Paint(Option_t * )
437 TVirtualGeoPainter *painter = gGeoManager->GetGeomPainter();
438 if (!painter)
return;
445 void TGeoPhysicalNode::Print(Option_t * )
const
447 printf(
"TGeoPhysicalNode: %s level=%d aligned=%d\n", fName.Data(), fLevel, IsAligned());
448 for (Int_t i=0; i<=fLevel; i++) {
449 printf(
" level %d: node %s\n", i, GetNode(i)->GetName());
450 printf(
" local matrix:\n");
451 if (GetNode(i)->GetMatrix()->IsIdentity()) printf(
" IDENTITY\n");
452 else GetNode(i)->GetMatrix()->Print();
453 printf(
" global matrix:\n");
454 if (GetMatrix(i)->IsIdentity()) printf(
" IDENTITY\n");
455 else GetMatrix(i)->Print();
457 if (IsAligned() && fMatrixOrig) {
458 printf(
" original local matrix:\n");
459 fMatrixOrig->Print();
467 void TGeoPhysicalNode::Refresh()
469 SetPath(fName.Data());
475 void TGeoPhysicalNode::SetBranchAsState()
477 TGeoNodeCache *cache = gGeoManager->GetCache();
479 Error(
"SetBranchAsState",
"no state available");
482 if (!cache->IsDummy()) {
483 Error(
"SetBranchAsState",
"not implemented for full cache");
486 if (!fNodes) fNodes =
new TObjArray(30);
487 if (!fMatrices) fMatrices =
new TObjArray(30);
488 TGeoHMatrix **matrices = (TGeoHMatrix **) cache->GetMatrices();
489 TGeoNode **branch = (TGeoNode **) cache->GetBranch();
491 Bool_t refresh = (fLevel>0)?kTRUE:kFALSE;
493 TGeoHMatrix *current;
494 for (Int_t i=0; i<=fLevel; i++) {
495 fNodes->AddAtAndExpand(branch[i],i);
496 current = (TGeoHMatrix*)fMatrices->UncheckedAt(i);
497 *current = *matrices[i];
501 fLevel = gGeoManager->GetLevel();
502 for (Int_t i=0; i<=fLevel; i++) {
503 fNodes->AddAtAndExpand(branch[i],i);
504 fMatrices->AddAtAndExpand(
new TGeoHMatrix(*matrices[i]),i);
506 TGeoNode *node = (TGeoNode*)fNodes->UncheckedAt(fLevel);
507 if (!fMatrixOrig) fMatrixOrig =
new TGeoHMatrix();
508 *fMatrixOrig = node->GetMatrix();
515 void TGeoPhysicalNode::SetMatrixOrig(
const TGeoMatrix *local)
517 if (!fMatrixOrig) fMatrixOrig =
new TGeoHMatrix();
519 fMatrixOrig->Clear();
522 *fMatrixOrig = local;
528 Bool_t TGeoPhysicalNode::SetPath(
const char *path)
530 if (!gGeoManager->cd(path)) {
531 Error(
"SetPath",
"wrong path -> maybe RestoreMasterVolume");
541 Bool_t TGeoPhysicalNode::IsMatchingState(TGeoNavigator *nav)
const
543 TGeoNodeCache *cache = nav->GetCache();
545 Fatal(
"SetBranchAsState",
"no state available");
548 TGeoNode **branch = (TGeoNode **) cache->GetBranch();
549 for (Int_t i=1; i<=fLevel; i++)
550 if (fNodes->At(i) != branch[i])
return kFALSE;
554 ClassImp(TGeoPNEntry);
559 TGeoPNEntry::TGeoPNEntry()
569 TGeoPNEntry::TGeoPNEntry(
const char *name,
const char *path)
572 if (!gGeoManager || !gGeoManager->IsClosed() || !gGeoManager->CheckPath(path)) {
573 TString errmsg(
"Cannot define a physical node link without a closed geometry and a valid path !");
574 Error(
"ctor",
"%s", errmsg.Data());
578 gGeoManager->PushPath();
579 gGeoManager->cd(path);
580 fGlobalOrig =
new TGeoHMatrix();
581 *fGlobalOrig = gGeoManager->GetCurrentMatrix();
582 gGeoManager->PopPath();
590 TGeoPNEntry::~TGeoPNEntry()
592 if (fMatrix && !fMatrix->IsRegistered())
delete fMatrix;
599 void TGeoPNEntry::SetPhysicalNode(TGeoPhysicalNode *node)
602 Warning(
"SetPhysicalNode",
"Physical node changed for entry %s", GetName());
603 Warning(
"SetPhysicalNode",
"=== New path: %s", node->GetName());
612 void TGeoPNEntry::SetMatrix(
const TGeoHMatrix *mat)