#include "TGeoParallelWorld.h"
#include "TObjString.h"
#include "TGeoManager.h"
#include "TGeoVolume.h"
#include "TGeoVoxelFinder.h"
#include "TGeoMatrix.h"
#include "TGeoPhysicalNode.h"
#include "TGeoNavigator.h"
ClassImp(TGeoParallelWorld)
TGeoParallelWorld::TGeoParallelWorld(const char *name, TGeoManager *mgr)
: TNamed(name,""),
fGeoManager(mgr),
fPaths(new TObjArray(256)),
fUseOverlaps(kFALSE),
fIsClosed(kFALSE),
fVolume(0),
fLastState(0),
fPhysical(new TObjArray(256))
{
}
TGeoParallelWorld::~TGeoParallelWorld()
{
if (fPhysical) {fPhysical->Delete(); delete fPhysical;}
if (fPaths) {fPaths->Delete(); delete fPaths;}
delete fVolume;
}
void TGeoParallelWorld::AddNode(const char *path)
{
if (fIsClosed) Fatal("AddNode", "Cannot add nodes to a closed parallel geometry");
if (!fGeoManager->CheckPath(path)) {
Error("AddNode", "Path %s not valid.\nCannot add to parallel world!", path);
return;
}
fPaths->Add(new TObjString(path));
}
void TGeoParallelWorld::AddOverlap(TGeoVolume *vol, Bool_t activate)
{
if (activate) fUseOverlaps = kTRUE;
vol->SetOverlappingCandidate(kTRUE);
}
void TGeoParallelWorld::AddOverlap(const char *volname, Bool_t activate)
{
if (activate) fUseOverlaps = kTRUE;
TIter next(fGeoManager->GetListOfVolumes());
TGeoVolume *vol;
while ((vol=(TGeoVolume*)next())) {
if (!strcmp(vol->GetName(), volname)) vol->SetOverlappingCandidate(kTRUE);
}
}
Int_t TGeoParallelWorld::PrintDetectedOverlaps() const
{
TIter next(fGeoManager->GetListOfVolumes());
TGeoVolume *vol;
Int_t noverlaps = 0;
while ((vol=(TGeoVolume*)next())) {
if (vol->IsOverlappingCandidate()) {
if (noverlaps==0) Info("PrintDetectedOverlaps", "List of detected volumes overlapping with the PW");
noverlaps++;
printf("volume: %s at index: %d\n", vol->GetName(), vol->GetNumber());
}
}
return noverlaps;
}
void TGeoParallelWorld::ResetOverlaps() const
{
TIter next(fGeoManager->GetListOfVolumes());
TGeoVolume *vol;
while ((vol=(TGeoVolume*)next())) vol->SetOverlappingCandidate(kFALSE);
}
Bool_t TGeoParallelWorld::CloseGeometry()
{
if (fIsClosed) return kTRUE;
if (!fGeoManager->IsClosed()) Fatal("CloseGeometry", "Main geometry must be closed first");
if (!fPaths || !fPaths->GetEntriesFast()) {
Error("CloseGeometry", "List of paths is empty");
return kFALSE;
}
RefreshPhysicalNodes();
fIsClosed = kTRUE;
Info("CloseGeometry", "Parallel world %s contains %d prioritised objects", GetName(), fPaths->GetEntriesFast());
Int_t novlp = 0;
TIter next(fGeoManager->GetListOfVolumes());
TGeoVolume *vol;
while ((vol=(TGeoVolume*)next())) if (vol->IsOverlappingCandidate()) novlp++;
Info("CloseGeometry", "Number of declared overlaps: %d", novlp);
if (fUseOverlaps) Info("CloseGeometry", "Parallel world will use declared overlaps");
else Info("CloseGeometry", "Parallel world will detect overlaps with other volumes");
return kTRUE;
}
void TGeoParallelWorld::RefreshPhysicalNodes()
{
delete fVolume;
fVolume = new TGeoVolumeAssembly(GetName());
fGeoManager->GetListOfVolumes()->Remove(fVolume);
if (fPhysical) {fPhysical->Delete(); delete fPhysical;}
fPhysical = new TObjArray(fPaths->GetEntriesFast());
TGeoPhysicalNode *pnode;
TObjString *objs;
TIter next(fPaths);
Int_t copy = 0;
while ((objs = (TObjString*)next())) {
pnode = new TGeoPhysicalNode(objs->GetName());
fPhysical->AddAt(pnode, copy);
fVolume->AddNode(pnode->GetVolume(), copy++, new TGeoHMatrix(*pnode->GetMatrix()));
}
fVolume->GetShape()->ComputeBBox();
fVolume->Voxelize("ALL");
}
TGeoPhysicalNode *TGeoParallelWorld::FindNode(Double_t point[3])
{
if (!fIsClosed) Fatal("FindNode", "Parallel geometry must be closed first");
TGeoNavigator *nav = fGeoManager->GetCurrentNavigator();
TGeoVoxelFinder *voxels = fVolume->GetVoxels();
Int_t id;
Int_t ncheck = 0;
Int_t nd = fVolume->GetNdaughters();
TGeoNodeCache *cache = nav->GetCache();
TGeoStateInfo &info = *cache->GetMakePWInfo(nd);
Int_t *check_list = voxels->GetCheckList(point, ncheck, info);
if (!check_list) return 0;
TGeoNode *node;
Double_t local[3];
for (id=0; id<ncheck; id++) {
node = fVolume->GetNode(check_list[id]);
node->MasterToLocal(point, local);
if (node->GetVolume()->Contains(local)) {
fLastState = (TGeoPhysicalNode*)fPhysical->At(node->GetNumber());
return fLastState;
}
}
return 0;
}
TGeoPhysicalNode *TGeoParallelWorld::FindNextBoundary(Double_t point[3], Double_t dir[3],
Double_t &step, Double_t stepmax)
{
if (!fIsClosed) Fatal("FindNextBoundary", "Parallel geometry must be closed first");
TGeoPhysicalNode *pnode = 0;
TGeoNavigator *nav = fGeoManager->GetCurrentNavigator();
if (fUseOverlaps && !nav->GetCurrentVolume()->IsOverlappingCandidate()) return 0;
if (fLastState && fLastState->IsMatchingState(nav)) return 0;
Double_t snext = TGeoShape::Big();
step = stepmax;
TGeoVoxelFinder *voxels = fVolume->GetVoxels();
Int_t idaughter = -1;
Int_t nd = fVolume->GetNdaughters();
Int_t i;
TGeoNode *current;
Double_t lpoint[3], ldir[3];
if (nd<5) {
for (i=0; i<nd; i++) {
current = fVolume->GetNode(i);
if (voxels->IsSafeVoxel(point, i, stepmax)) continue;
current->MasterToLocal(point, lpoint);
current->MasterToLocalVect(dir, ldir);
snext = current->GetVolume()->GetShape()->DistFromOutside(lpoint, ldir, 3, step);
if (snext < step) {
step = snext;
idaughter = i;
}
}
if (idaughter>=0) {
pnode = (TGeoPhysicalNode*)fPhysical->At(idaughter);
return pnode;
}
step = TGeoShape::Big();
return 0;
}
Int_t ncheck = 0;
Int_t sumchecked = 0;
Int_t *vlist = 0;
TGeoNodeCache *cache = nav->GetCache();
TGeoStateInfo &info = *cache->GetMakePWInfo(nd);
voxels->SortCrossedVoxels(point, dir, info);
while ((sumchecked<nd) && (vlist=voxels->GetNextVoxel(point, dir, ncheck, info))) {
for (i=0; i<ncheck; i++) {
pnode = (TGeoPhysicalNode*)fPhysical->At(vlist[i]);
if (pnode->IsMatchingState(nav)) {
step = TGeoShape::Big();
return 0;
}
current = fVolume->GetNode(vlist[i]);
current->MasterToLocal(point, lpoint);
current->MasterToLocalVect(dir, ldir);
snext = current->GetVolume()->GetShape()->DistFromOutside(lpoint, ldir, 3, step);
if (snext < step - 1.E-8) {
step = snext;
idaughter = vlist[i];
}
}
if (idaughter>=0) {
pnode = (TGeoPhysicalNode*)fPhysical->At(idaughter);
if (!fUseOverlaps && !nav->GetCurrentVolume()->IsOverlappingCandidate()) {
AddOverlap(nav->GetCurrentVolume(),kFALSE);
}
return pnode;
}
}
step = TGeoShape::Big();
return 0;
}
Double_t TGeoParallelWorld::Safety(Double_t point[3], Double_t safmax)
{
TGeoNavigator *nav = fGeoManager->GetCurrentNavigator();
if (fLastState && fLastState->IsMatchingState(nav)) return TGeoShape::Big();
if (fUseOverlaps && !nav->GetCurrentVolume()->IsOverlappingCandidate()) return TGeoShape::Big();
Double_t local[3];
Double_t safe = safmax;
Double_t safnext;
TGeoPhysicalNode *pnode = 0;
const Double_t tolerance = TGeoShape::Tolerance();
Int_t nd = fVolume->GetNdaughters();
TGeoNode *current;
TGeoVoxelFinder *voxels = fVolume->GetVoxels();
Double_t *boxes = voxels->GetBoxes();
for (Int_t id=0; id<nd; id++) {
Int_t ist = 6*id;
Double_t dxyz = 0.;
Double_t dxyz0 = TMath::Abs(point[0]-boxes[ist+3])-boxes[ist];
if (dxyz0 > safe) continue;
Double_t dxyz1 = TMath::Abs(point[1]-boxes[ist+4])-boxes[ist+1];
if (dxyz1 > safe) continue;
Double_t dxyz2 = TMath::Abs(point[2]-boxes[ist+5])-boxes[ist+2];
if (dxyz2 > safe) continue;
if (dxyz0>0) dxyz+=dxyz0*dxyz0;
if (dxyz1>0) dxyz+=dxyz1*dxyz1;
if (dxyz2>0) dxyz+=dxyz2*dxyz2;
if (dxyz >= safe*safe) continue;
pnode = (TGeoPhysicalNode*)fPhysical->At(id);
if (pnode->IsMatchingState(nav)) return TGeoShape::Big();
current = fVolume->GetNode(id);
current->MasterToLocal(point, local);
safnext = current->Safety(local, kFALSE);
if (safnext < tolerance) return 0.;
if (safnext < safe) safe = safnext;
}
return safe;
}
void TGeoParallelWorld::CheckOverlaps(Double_t ovlp)
{
fVolume->CheckOverlaps(ovlp);
}
void TGeoParallelWorld::Draw(Option_t *option)
{
fVolume->Draw(option);
}
TGeoParallelWorld.cxx:100 TGeoParallelWorld.cxx:101 TGeoParallelWorld.cxx:102 TGeoParallelWorld.cxx:103 TGeoParallelWorld.cxx:104 TGeoParallelWorld.cxx:105 TGeoParallelWorld.cxx:106 TGeoParallelWorld.cxx:107 TGeoParallelWorld.cxx:108 TGeoParallelWorld.cxx:109 TGeoParallelWorld.cxx:110 TGeoParallelWorld.cxx:111 TGeoParallelWorld.cxx:112 TGeoParallelWorld.cxx:113 TGeoParallelWorld.cxx:114 TGeoParallelWorld.cxx:115 TGeoParallelWorld.cxx:116 TGeoParallelWorld.cxx:117 TGeoParallelWorld.cxx:118 TGeoParallelWorld.cxx:119 TGeoParallelWorld.cxx:120 TGeoParallelWorld.cxx:121 TGeoParallelWorld.cxx:122 TGeoParallelWorld.cxx:123 TGeoParallelWorld.cxx:124 TGeoParallelWorld.cxx:125 TGeoParallelWorld.cxx:126 TGeoParallelWorld.cxx:127 TGeoParallelWorld.cxx:128 TGeoParallelWorld.cxx:129 TGeoParallelWorld.cxx:130 TGeoParallelWorld.cxx:131 TGeoParallelWorld.cxx:132 TGeoParallelWorld.cxx:133 TGeoParallelWorld.cxx:134 TGeoParallelWorld.cxx:135 TGeoParallelWorld.cxx:136 TGeoParallelWorld.cxx:137 TGeoParallelWorld.cxx:138 TGeoParallelWorld.cxx:139 TGeoParallelWorld.cxx:140 TGeoParallelWorld.cxx:141 TGeoParallelWorld.cxx:142 TGeoParallelWorld.cxx:143 TGeoParallelWorld.cxx:144 TGeoParallelWorld.cxx:145 TGeoParallelWorld.cxx:146 TGeoParallelWorld.cxx:147 TGeoParallelWorld.cxx:148 TGeoParallelWorld.cxx:149 TGeoParallelWorld.cxx:150 TGeoParallelWorld.cxx:151 TGeoParallelWorld.cxx:152 TGeoParallelWorld.cxx:153 TGeoParallelWorld.cxx:154 TGeoParallelWorld.cxx:155 TGeoParallelWorld.cxx:156 TGeoParallelWorld.cxx:157 TGeoParallelWorld.cxx:158 TGeoParallelWorld.cxx:159 TGeoParallelWorld.cxx:160 TGeoParallelWorld.cxx:161 TGeoParallelWorld.cxx:162 TGeoParallelWorld.cxx:163 TGeoParallelWorld.cxx:164 TGeoParallelWorld.cxx:165 TGeoParallelWorld.cxx:166 TGeoParallelWorld.cxx:167 TGeoParallelWorld.cxx:168 TGeoParallelWorld.cxx:169 TGeoParallelWorld.cxx:170 TGeoParallelWorld.cxx:171 TGeoParallelWorld.cxx:172 TGeoParallelWorld.cxx:173 TGeoParallelWorld.cxx:174 TGeoParallelWorld.cxx:175 TGeoParallelWorld.cxx:176 TGeoParallelWorld.cxx:177 TGeoParallelWorld.cxx:178 TGeoParallelWorld.cxx:179 TGeoParallelWorld.cxx:180 TGeoParallelWorld.cxx:181 TGeoParallelWorld.cxx:182 TGeoParallelWorld.cxx:183 TGeoParallelWorld.cxx:184 TGeoParallelWorld.cxx:185 TGeoParallelWorld.cxx:186 TGeoParallelWorld.cxx:187 TGeoParallelWorld.cxx:188 TGeoParallelWorld.cxx:189 TGeoParallelWorld.cxx:190 TGeoParallelWorld.cxx:191 TGeoParallelWorld.cxx:192 TGeoParallelWorld.cxx:193 TGeoParallelWorld.cxx:194 TGeoParallelWorld.cxx:195 TGeoParallelWorld.cxx:196 TGeoParallelWorld.cxx:197 TGeoParallelWorld.cxx:198 TGeoParallelWorld.cxx:199 TGeoParallelWorld.cxx:200 TGeoParallelWorld.cxx:201 TGeoParallelWorld.cxx:202 TGeoParallelWorld.cxx:203 TGeoParallelWorld.cxx:204 TGeoParallelWorld.cxx:205 TGeoParallelWorld.cxx:206 TGeoParallelWorld.cxx:207 TGeoParallelWorld.cxx:208 TGeoParallelWorld.cxx:209 TGeoParallelWorld.cxx:210 TGeoParallelWorld.cxx:211 TGeoParallelWorld.cxx:212 TGeoParallelWorld.cxx:213 TGeoParallelWorld.cxx:214 TGeoParallelWorld.cxx:215 TGeoParallelWorld.cxx:216 TGeoParallelWorld.cxx:217 TGeoParallelWorld.cxx:218 TGeoParallelWorld.cxx:219 TGeoParallelWorld.cxx:220 TGeoParallelWorld.cxx:221 TGeoParallelWorld.cxx:222 TGeoParallelWorld.cxx:223 TGeoParallelWorld.cxx:224 TGeoParallelWorld.cxx:225 TGeoParallelWorld.cxx:226 TGeoParallelWorld.cxx:227 TGeoParallelWorld.cxx:228 TGeoParallelWorld.cxx:229 TGeoParallelWorld.cxx:230 TGeoParallelWorld.cxx:231 TGeoParallelWorld.cxx:232 TGeoParallelWorld.cxx:233 TGeoParallelWorld.cxx:234 TGeoParallelWorld.cxx:235 TGeoParallelWorld.cxx:236 TGeoParallelWorld.cxx:237 TGeoParallelWorld.cxx:238 TGeoParallelWorld.cxx:239 TGeoParallelWorld.cxx:240 TGeoParallelWorld.cxx:241 TGeoParallelWorld.cxx:242 TGeoParallelWorld.cxx:243 TGeoParallelWorld.cxx:244 TGeoParallelWorld.cxx:245 TGeoParallelWorld.cxx:246 TGeoParallelWorld.cxx:247 TGeoParallelWorld.cxx:248 TGeoParallelWorld.cxx:249 TGeoParallelWorld.cxx:250 TGeoParallelWorld.cxx:251 TGeoParallelWorld.cxx:252 TGeoParallelWorld.cxx:253 TGeoParallelWorld.cxx:254 TGeoParallelWorld.cxx:255 TGeoParallelWorld.cxx:256 TGeoParallelWorld.cxx:257 TGeoParallelWorld.cxx:258 TGeoParallelWorld.cxx:259 TGeoParallelWorld.cxx:260 TGeoParallelWorld.cxx:261 TGeoParallelWorld.cxx:262 TGeoParallelWorld.cxx:263 TGeoParallelWorld.cxx:264 TGeoParallelWorld.cxx:265 TGeoParallelWorld.cxx:266 TGeoParallelWorld.cxx:267 TGeoParallelWorld.cxx:268 TGeoParallelWorld.cxx:269 TGeoParallelWorld.cxx:270 TGeoParallelWorld.cxx:271 TGeoParallelWorld.cxx:272 TGeoParallelWorld.cxx:273 TGeoParallelWorld.cxx:274 TGeoParallelWorld.cxx:275 TGeoParallelWorld.cxx:276 TGeoParallelWorld.cxx:277 TGeoParallelWorld.cxx:278 TGeoParallelWorld.cxx:279 TGeoParallelWorld.cxx:280 TGeoParallelWorld.cxx:281 TGeoParallelWorld.cxx:282 TGeoParallelWorld.cxx:283 TGeoParallelWorld.cxx:284 TGeoParallelWorld.cxx:285 TGeoParallelWorld.cxx:286 TGeoParallelWorld.cxx:287 TGeoParallelWorld.cxx:288 TGeoParallelWorld.cxx:289 TGeoParallelWorld.cxx:290 TGeoParallelWorld.cxx:291 TGeoParallelWorld.cxx:292 TGeoParallelWorld.cxx:293 TGeoParallelWorld.cxx:294 TGeoParallelWorld.cxx:295 TGeoParallelWorld.cxx:296 TGeoParallelWorld.cxx:297 TGeoParallelWorld.cxx:298 TGeoParallelWorld.cxx:299 TGeoParallelWorld.cxx:300 TGeoParallelWorld.cxx:301 TGeoParallelWorld.cxx:302 TGeoParallelWorld.cxx:303 TGeoParallelWorld.cxx:304 TGeoParallelWorld.cxx:305 TGeoParallelWorld.cxx:306 TGeoParallelWorld.cxx:307 TGeoParallelWorld.cxx:308 TGeoParallelWorld.cxx:309 TGeoParallelWorld.cxx:310 TGeoParallelWorld.cxx:311 TGeoParallelWorld.cxx:312 TGeoParallelWorld.cxx:313 TGeoParallelWorld.cxx:314 TGeoParallelWorld.cxx:315 TGeoParallelWorld.cxx:316 TGeoParallelWorld.cxx:317 TGeoParallelWorld.cxx:318 TGeoParallelWorld.cxx:319 TGeoParallelWorld.cxx:320 TGeoParallelWorld.cxx:321 TGeoParallelWorld.cxx:322 TGeoParallelWorld.cxx:323 TGeoParallelWorld.cxx:324 TGeoParallelWorld.cxx:325 TGeoParallelWorld.cxx:326 TGeoParallelWorld.cxx:327 TGeoParallelWorld.cxx:328 TGeoParallelWorld.cxx:329 TGeoParallelWorld.cxx:330 TGeoParallelWorld.cxx:331 TGeoParallelWorld.cxx:332 TGeoParallelWorld.cxx:333 TGeoParallelWorld.cxx:334 TGeoParallelWorld.cxx:335 TGeoParallelWorld.cxx:336 TGeoParallelWorld.cxx:337 TGeoParallelWorld.cxx:338 TGeoParallelWorld.cxx:339 TGeoParallelWorld.cxx:340 TGeoParallelWorld.cxx:341 TGeoParallelWorld.cxx:342 TGeoParallelWorld.cxx:343 TGeoParallelWorld.cxx:344