109 TGeoNode::TGeoNode(
const TGeoVolume *vol)
112 Error(
"ctor",
"volume not specified");
115 fVolume = (TGeoVolume*)vol;
116 if (fVolume->IsAdded()) fVolume->SetReplicated();
129 TGeoNode::~TGeoNode()
131 if (fOverlaps)
delete [] fOverlaps;
132 if (fUserExtension) {fUserExtension->Release(); fUserExtension=0;}
133 if (fFWExtension) {fFWExtension->Release(); fFWExtension=0;}
139 void TGeoNode::Browse(TBrowser *b)
142 if (!GetNdaughters())
return;
145 for (Int_t i=0; i<GetNdaughters(); i++) {
146 daughter = GetDaughter(i);
147 b->Add(daughter, daughter->GetName(), daughter->IsVisible());
155 Int_t TGeoNode::CountDaughters(Bool_t unique_volumes)
157 static Int_t icall = 0;
160 if (unique_volumes) {
161 if (!fVolume->IsSelected()) {
163 fVolume->SelectVolume(kFALSE);
167 Int_t nd = fVolume->GetNdaughters();
169 for (Int_t i=0; i<nd; i++) counter += GetDaughter(i)->CountDaughters(unique_volumes);
172 if (icall == 0) fVolume->SelectVolume(kTRUE);
179 void TGeoNode::CheckOverlaps(Double_t ovlp, Option_t *option)
185 Bool_t sampling = kFALSE;
188 if (opt.Contains(
"s")) sampling = kTRUE;
190 TGeoManager *geom = fVolume->GetGeoManager();
191 ncheck = CountDaughters(kFALSE);
192 timer =
new TStopwatch();
193 geom->ClearOverlaps();
194 geom->SetCheckingOverlaps(kTRUE);
195 Info(
"CheckOverlaps",
"Checking overlaps for %s and daughters within %g", fVolume->GetName(),ovlp);
197 Info(
"CheckOverlaps",
"Checking overlaps by sampling <%s> for %s and daughters", option, fVolume->GetName());
198 Info(
"CheckOverlaps",
"=== NOTE: Extrusions NOT checked with sampling option ! ===");
201 geom->GetGeomPainter()->OpProgress(fVolume->GetName(),icheck,ncheck,timer,kFALSE);
202 fVolume->CheckOverlaps(ovlp,option);
204 TGeoIterator next(fVolume);
207 TObjArray *overlaps = geom->GetListOfOverlaps();
210 while ((node=next())) {
213 if (!node->GetVolume()->IsSelected()) {
214 msg = TString::Format(
"found %d overlaps", overlaps->GetEntriesFast());
215 geom->GetGeomPainter()->OpProgress(node->GetVolume()->GetName(),icheck,ncheck,timer,kFALSE, msg);
216 node->GetVolume()->SelectVolume(kFALSE);
217 node->GetVolume()->CheckOverlaps(ovlp,option);
220 fVolume->SelectVolume(kTRUE);
221 geom->SetCheckingOverlaps(kFALSE);
222 geom->SortOverlaps();
223 novlps = overlaps->GetEntriesFast();
225 for (i=0; i<novlps; i++) {
226 obj = (TNamed*)overlaps->At(i);
227 obj->SetName(TString::Format(
"ov%05d",i));
229 geom->GetGeomPainter()->OpProgress(
"Check overlaps:",icheck,ncheck,timer,kTRUE);
230 Info(
"CheckOverlaps",
"Number of illegal overlaps/extrusions : %d\n", novlps);
237 Int_t TGeoNode::DistancetoPrimitive(Int_t px, Int_t py)
240 if (!fVolume)
return dist;
241 if (gGeoManager != fVolume->GetGeoManager()) gGeoManager = fVolume->GetGeoManager();
242 TVirtualGeoPainter *painter = gGeoManager->GetPainter();
243 if (!painter)
return dist;
244 dist = painter->DistanceToPrimitiveVol(fVolume, px, py);
251 void TGeoNode::ExecuteEvent(Int_t event, Int_t px, Int_t py)
253 if (!fVolume)
return;
254 TVirtualGeoPainter *painter = fVolume->GetGeoManager()->GetPainter();
255 if (!painter)
return;
256 painter->ExecuteVolumeEvent(fVolume, event, px, py);
262 char *TGeoNode::GetObjectInfo(Int_t px, Int_t py)
const
264 if (!fVolume)
return 0;
265 TVirtualGeoPainter *painter = fVolume->GetGeoManager()->GetPainter();
266 if (!painter)
return 0;
267 return (
char*)painter->GetVolumeInfo(fVolume, px, py);
273 Bool_t TGeoNode::IsOnScreen()
const
275 if (fVolume->TestAttBit(TGeoAtt::kVisOnScreen))
return kTRUE;
282 void TGeoNode::InspectNode()
const
284 printf(
"== Inspecting node %s ", GetName());
285 if (fMother) printf(
"mother volume %s. ", fMother->GetName());
286 if (IsOverlapping()) printf(
"(Node is MANY)\n");
288 if (fOverlaps && fMother) {
289 printf(
" possibly overlapping with : ");
290 for (Int_t i=0; i<fNovlp; i++)
291 printf(
" %s ", fMother->GetNode(fOverlaps[i])->GetName());
294 printf(
"Transformation matrix:\n");
295 TGeoMatrix *matrix = GetMatrix();
296 if (GetMatrix()) matrix->Print();
303 void TGeoNode::CheckShapes()
305 fVolume->CheckShapes();
306 Int_t nd = GetNdaughters();
308 for (Int_t i=0; i<nd; i++) fVolume->GetNode(i)->CheckShapes();
314 void TGeoNode::DrawOnly(Option_t *option)
316 fVolume->DrawOnly(option);
322 void TGeoNode::Draw(Option_t *option)
324 gGeoManager->FindNode();
327 gGeoManager->MasterToLocal(gGeoManager->GetCurrentPoint(), &point[0]);
328 gGeoManager->SetCurrentPoint(&point[0]);
329 gGeoManager->GetCurrentVolume()->Draw(option);
335 void TGeoNode::DrawOverlaps()
337 if (!fNovlp) {printf(
"node %s is ONLY\n", GetName());
return;}
338 if (!fOverlaps) {printf(
"node %s no overlaps\n", GetName());
return;}
341 Int_t nd = fMother->GetNdaughters();
342 for (i=0; i<nd; i++) {
343 node = fMother->GetNode(i);
344 node->GetVolume()->SetVisibility(kFALSE);
346 fVolume->SetVisibility(kTRUE);
347 for (i=0; i<fNovlp; i++) {
348 node = fMother->GetNode(fOverlaps[i]);
349 node->GetVolume()->SetVisibility(kTRUE);
351 gGeoManager->SetVisLevel(1);
358 void TGeoNode::FillIdArray(Int_t &ifree, Int_t &nodeid, Int_t *array)
const
360 Int_t nd = GetNdaughters();
363 Int_t istart = ifree;
365 for (Int_t
id=0;
id<nd;
id++) {
366 daughter = GetDaughter(
id);
367 array[istart+id] = ifree;
368 array[ifree++] = ++nodeid;
369 daughter->FillIdArray(ifree, nodeid, array);
377 Int_t TGeoNode::FindNode(
const TGeoNode *node, Int_t level)
379 Int_t nd = GetNdaughters();
381 TIter next(fVolume->GetNodes());
383 while ((daughter=(TGeoNode*)next())) {
384 if (daughter==node) {
385 gGeoManager->GetListOfNodes()->AddAt(daughter,level+1);
391 while ((daughter=(TGeoNode*)next())) {
392 new_level = daughter->FindNode(node, level+1);
394 gGeoManager->GetListOfNodes()->AddAt(daughter, level+1);
404 void TGeoNode::SaveAttributes(std::ostream &out)
406 if (IsVisStreamed())
return;
407 SetVisStreamed(kTRUE);
409 Bool_t voldef = kFALSE;
410 if ((fVolume->IsVisTouched()) && (!fVolume->IsVisStreamed())) {
411 fVolume->SetVisStreamed(kTRUE);
412 out <<
" vol = gGeoManager->GetVolume("<<quote<<fVolume->GetName()<<quote<<
");"<<std::endl;
414 if (!fVolume->IsVisDaughters())
415 out <<
" vol->SetVisDaughters(kFALSE);"<<std::endl;
416 if (fVolume->IsVisible()) {
426 out <<
" vol->SetVisibility(kFALSE);"<<std::endl;
429 if (!IsVisDaughters())
return;
430 Int_t nd = GetNdaughters();
433 for (Int_t i=0; i<nd; i++) {
434 node = GetDaughter(i);
435 if (node->IsVisStreamed())
continue;
436 if (node->IsVisTouched()) {
438 out <<
" vol = gGeoManager->GetVolume("<<quote<<fVolume->GetName()<<quote<<
");"<<std::endl;
439 out<<
" node = vol->GetNode("<<i<<
");"<<std::endl;
440 if (!node->IsVisDaughters()) {
441 out<<
" node->VisibleDaughters(kFALSE);"<<std::endl;
442 node->SetVisStreamed(kTRUE);
445 if (!node->IsVisible())
446 out<<
" node->SetVisibility(kFALSE);"<<std::endl;
448 node->SaveAttributes(out);
449 node->SetVisStreamed(kTRUE);
461 void TGeoNode::SetUserExtension(TGeoExtension *ext)
463 if (fUserExtension) fUserExtension->Release();
465 if (ext) fUserExtension = ext->Grab();
476 void TGeoNode::SetFWExtension(TGeoExtension *ext)
478 if (fFWExtension) fFWExtension->Release();
480 if (ext) fFWExtension = ext->Grab();
488 TGeoExtension *TGeoNode::GrabUserExtension()
const
490 if (fUserExtension)
return fUserExtension->Grab();
499 TGeoExtension *TGeoNode::GrabFWExtension()
const
501 if (fFWExtension)
return fFWExtension->Grab();
508 Bool_t TGeoNode::MayOverlap(Int_t iother)
const
510 if (!fOverlaps)
return kFALSE;
511 for (Int_t i=0; i<fNovlp; i++)
if (fOverlaps[i]==iother)
return kTRUE;
518 void TGeoNode::MasterToLocal(
const Double_t *master, Double_t *local)
const
520 GetMatrix()->MasterToLocal(master, local);
526 void TGeoNode::MasterToLocalVect(
const Double_t *master, Double_t *local)
const
528 GetMatrix()->MasterToLocalVect(master, local);
534 void TGeoNode::LocalToMaster(
const Double_t *local, Double_t *master)
const
536 GetMatrix()->LocalToMaster(local, master);
542 void TGeoNode::LocalToMasterVect(
const Double_t *local, Double_t *master)
const
544 GetMatrix()->LocalToMasterVect(local, master);
550 void TGeoNode::ls(Option_t * )
const
557 void TGeoNode::Paint(Option_t *option)
559 TVirtualGeoPainter *painter = gGeoManager->GetGeomPainter();
560 if (!painter)
return;
561 painter->PaintNode(
this, option);
567 void TGeoNode::PrintCandidates()
const
570 gGeoManager->MasterToLocal(gGeoManager->GetCurrentPoint(), &point[0]);
571 printf(
" Local : %g, %g, %g\n", point[0], point[1], point[2]);
572 if (!fVolume->Contains(&point[0])) {
573 printf(
"current point not inside this\n");
576 TGeoPatternFinder *finder = fVolume->GetFinder();
579 printf(
"current node divided\n");
580 node = finder->FindNode(&point[0]);
582 printf(
"point not inside division element\n");
585 printf(
"inside division element %s\n", node->GetName());
588 TGeoVoxelFinder *voxels = fVolume->GetVoxels();
590 printf(
"volume not voxelized\n");
594 TGeoNavigator *nav = gGeoManager->GetCurrentNavigator();
595 TGeoStateInfo &info = *nav->GetCache()->GetInfo();
596 Int_t *check_list = voxels->GetCheckList(&point[0], ncheck, info);
597 nav->GetCache()->ReleaseInfo();
598 voxels->PrintVoxelLimits(&point[0]);
600 printf(
"no candidates for current point\n");
603 TString overlap =
"ONLY";
604 for (Int_t
id=0;
id<ncheck;
id++) {
605 node = fVolume->GetNode(check_list[
id]);
606 if (node->IsOverlapping()) overlap =
"MANY";
607 else overlap =
"ONLY";
608 printf(
"%i %s %s\n", check_list[
id], node->GetName(), overlap.Data());
616 void TGeoNode::PrintOverlaps()
const
618 if (!fOverlaps) {printf(
"node %s no overlaps\n", GetName());
return;}
619 printf(
"Overlaps for node %s :\n", GetName());
621 for (Int_t i=0; i<fNovlp; i++) {
622 node = fMother->GetNode(fOverlaps[i]);
623 printf(
" %s\n", node->GetName());
630 Double_t TGeoNode::Safety(
const Double_t *point, Bool_t in)
const
633 GetMatrix()->MasterToLocal(point,local);
634 return fVolume->GetShape()->Safety(local,in);
640 void TGeoNode::CopyOverlaps(Int_t *src, Int_t novlp)
642 Int_t *ovlps =
nullptr;
643 if (src && (novlp > 0)) {
644 ovlps =
new Int_t[novlp];
645 memcpy(ovlps, src, novlp*
sizeof(Int_t));
647 SetOverlaps(ovlps, novlp);
653 void TGeoNode::SetOverlaps(Int_t *ovlp, Int_t novlp)
655 if (fOverlaps)
delete [] fOverlaps;
663 void TGeoNode::SetVisibility(Bool_t vis)
665 if (gGeoManager->IsClosed()) SetVisTouched(kTRUE);
666 TGeoAtt::SetVisibility(vis);
667 if (vis && !fVolume->IsVisible()) fVolume->SetVisibility(vis);
668 gGeoManager->ModifiedPad();
674 void TGeoNode::VisibleDaughters(Bool_t vis)
676 if (gGeoManager->IsClosed()) SetVisTouched(kTRUE);
677 SetVisDaughters(vis);
678 gGeoManager->ModifiedPad();
686 ClassImp(TGeoNodeMatrix);
691 TGeoNodeMatrix::TGeoNodeMatrix()
699 TGeoNodeMatrix::TGeoNodeMatrix(
const TGeoVolume *vol,
const TGeoMatrix *matrix) :
702 fMatrix = (TGeoMatrix*)matrix;
703 if (!fMatrix) fMatrix = gGeoIdentity;
709 TGeoNodeMatrix::~TGeoNodeMatrix()
716 Int_t TGeoNodeMatrix::GetByteCount()
const
718 Int_t count = 40 + 4;
728 Int_t TGeoNodeMatrix::GetOptimalVoxels()
const
730 Bool_t type = fVolume->GetShape()->IsCylType();
732 if (!fMatrix->IsRotAboutZ())
return 0;
733 const Double_t *transl = fMatrix->GetTranslation();
734 if (TMath::Abs(transl[0])>1E-10)
return 0;
735 if (TMath::Abs(transl[1])>1E-10)
return 0;
742 TGeoNode *TGeoNodeMatrix::MakeCopyNode()
const
744 TGeoNodeMatrix *node =
new TGeoNodeMatrix(fVolume, fMatrix);
745 node->SetName(GetName());
747 node->SetMotherVolume(fMother);
749 node->SetNumber(fNumber);
751 node->CopyOverlaps(fOverlaps, fNovlp);
754 if (IsVirtual()) node->SetVirtual();
755 if (IsOverlapping()) node->SetOverlapping();
757 node->SetUserExtension(fUserExtension);
758 node->SetFWExtension(fFWExtension);
766 void TGeoNodeMatrix::SetMatrix(
const TGeoMatrix *matrix)
768 fMatrix = (TGeoMatrix*)matrix;
769 if (!fMatrix) fMatrix = gGeoIdentity;
777 ClassImp(TGeoNodeOffset);
782 TGeoNodeOffset::TGeoNodeOffset()
784 TObject::SetBit(kGeoNodeOffset);
793 TGeoNodeOffset::TGeoNodeOffset(
const TGeoVolume *vol, Int_t index, Double_t offset) :
796 TObject::SetBit(kGeoNodeOffset);
805 TGeoNodeOffset::~TGeoNodeOffset()
812 Int_t TGeoNodeOffset::GetIndex()
const
814 return (fIndex+fFinder->GetDivIndex());
820 TGeoNode *TGeoNodeOffset::MakeCopyNode()
const
822 TGeoNodeOffset *node =
new TGeoNodeOffset(fVolume, GetIndex(), fOffset);
823 node->SetName(GetName());
825 node->SetMotherVolume(fMother);
827 node->SetNumber(fNumber);
828 if (IsVirtual()) node->SetVirtual();
830 node->SetFinder(GetFinder());
832 node->SetUserExtension(fUserExtension);
833 node->SetFWExtension(fFWExtension);
922 ClassImp(TGeoIteratorPlugin);
923 ClassImp(TGeoIterator);
928 TGeoIterator::TGeoIterator(TGeoVolume *top)
932 fMustResume = kFALSE;
935 fArray =
new Int_t[30];
936 fMatrix =
new TGeoHMatrix();
937 fTopName = fTop->GetName();
939 fPluginAutoexec = kFALSE;
945 TGeoIterator::TGeoIterator(
const TGeoIterator &iter)
947 fTop = iter.GetTopVolume();
948 fLevel = iter.GetLevel();
949 fMustResume = kFALSE;
951 fType = iter.GetType();
952 fArray =
new Int_t[30+ 30*Int_t(fLevel/30)];
953 for (Int_t i=0; i<fLevel+1; i++) fArray[i] = iter.GetIndex(i);
954 fMatrix =
new TGeoHMatrix(*iter.GetCurrentMatrix());
955 fTopName = fTop->GetName();
956 fPlugin = iter.fPlugin;
957 fPluginAutoexec = iter.fPluginAutoexec;;
963 TGeoIterator::~TGeoIterator()
965 if (fArray)
delete [] fArray;
972 TGeoIterator &TGeoIterator::operator=(
const TGeoIterator &iter)
974 if (&iter ==
this)
return *
this;
975 fTop = iter.GetTopVolume();
976 fLevel = iter.GetLevel();
977 fMustResume = kFALSE;
979 fType = iter.GetType();
980 if (fArray)
delete [] fArray;
981 fArray =
new Int_t[30+ 30*Int_t(fLevel/30)];
982 for (Int_t i=0; i<fLevel+1; i++) fArray[i] = iter.GetIndex(i);
983 if (!fMatrix) fMatrix =
new TGeoHMatrix();
984 *fMatrix = *iter.GetCurrentMatrix();
985 fTopName = fTop->GetName();
986 fPlugin = iter.fPlugin;
987 fPluginAutoexec = iter.fPluginAutoexec;;
994 TGeoNode *TGeoIterator::Next()
996 if (fMustStop)
return 0;
997 TGeoNode *mother = 0;
1000 Int_t nd = fTop->GetNdaughters();
1006 fArray[++fLevel] = 0;
1007 next = fTop->GetNode(0);
1008 if (fPlugin && fPluginAutoexec) fPlugin->ProcessNode();
1011 next = fTop->GetNode(fArray[1]);
1013 for (i=2; i<fLevel+1; i++) {
1015 next = mother->GetDaughter(fArray[i]);
1018 fMustResume = kFALSE;
1019 if (fPlugin && fPluginAutoexec) fPlugin->ProcessNode();
1025 nd = next->GetNdaughters();
1029 if ((fLevel%30)==0) IncreaseArray();
1031 if (fPlugin && fPluginAutoexec) fPlugin->ProcessNode();
1032 return next->GetDaughter(0);
1036 next = GetNode(fLevel-1);
1038 nd = fTop->GetNdaughters();
1039 if (fArray[fLevel]<nd-1) {
1041 if (fPlugin && fPluginAutoexec) fPlugin->ProcessNode();
1042 return fTop->GetNode(fArray[fLevel]);
1047 nd = next->GetNdaughters();
1048 if (fArray[fLevel]<nd-1) {
1050 if (fPlugin && fPluginAutoexec) fPlugin->ProcessNode();
1051 return next->GetDaughter(fArray[fLevel]);
1058 if (mother) nd = mother->GetNdaughters();
1059 if (fArray[fLevel]<nd-1) {
1061 if (fPlugin && fPluginAutoexec) fPlugin->ProcessNode();
1062 if (!mother)
return fTop->GetNode(fArray[fLevel]);
1063 else return mother->GetDaughter(fArray[fLevel]);
1073 TGeoNode *TGeoIterator::operator()()
1081 const TGeoMatrix *TGeoIterator::GetCurrentMatrix()
const
1084 if (!fLevel)
return fMatrix;
1085 TGeoNode *node = fTop->GetNode(fArray[1]);
1086 fMatrix->Multiply(node->GetMatrix());
1087 for (Int_t i=2; i<fLevel+1; i++) {
1088 node = node->GetDaughter(fArray[i]);
1089 fMatrix->Multiply(node->GetMatrix());
1097 TGeoNode *TGeoIterator::GetNode(Int_t level)
const
1099 if (!level || level>fLevel)
return 0;
1100 TGeoNode *node = fTop->GetNode(fArray[1]);
1101 for (Int_t i=2; i<level+1; i++) node = node->GetDaughter(fArray[i]);
1108 void TGeoIterator::GetPath(TString &path)
const
1111 if (!fLevel)
return;
1112 TGeoNode *node = fTop->GetNode(fArray[1]);
1114 path += node->GetName();
1115 for (Int_t i=2; i<fLevel+1; i++) {
1116 node = node->GetDaughter(fArray[i]);
1118 path += node->GetName();
1125 void TGeoIterator::IncreaseArray()
1127 Int_t *array =
new Int_t[fLevel+30];
1128 memcpy(array, fArray, fLevel*
sizeof(Int_t));
1136 void TGeoIterator::Reset(TGeoVolume *top)
1138 if (top) fTop = top;
1140 fMustResume = kFALSE;
1147 void TGeoIterator::SetTopName(
const char *name)
1156 void TGeoIterator::Skip()
1158 fMustResume = kTRUE;
1159 TGeoNode *next = GetNode(fLevel);
1166 next = GetNode(fLevel-1);
1167 nd = (next==0)?fTop->GetNdaughters():next->GetNdaughters();
1168 if (fArray[fLevel]<nd-1) {
1180 next = GetNode(fLevel-1);
1181 nd = (next==0)?fTop->GetNdaughters():next->GetNdaughters();
1182 if (fArray[fLevel]<nd-1) {
1194 void TGeoIterator::SetUserPlugin(TGeoIteratorPlugin *plugin)
1197 if (plugin) plugin->SetIterator(
this);