#include "TGeoParallelWorld.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),
fPhysical(0),
fVolume(new TGeoVolumeAssembly(name)),
fIsClosed(kFALSE),
fUseOverlaps(kFALSE)
{
}
TGeoParallelWorld::~TGeoParallelWorld()
{
delete fPhysical;
}
void TGeoParallelWorld::AddNode(TGeoPhysicalNode *pnode)
{
if (fIsClosed) Fatal("AddNode", "Cannot add nodes to a closed parallel geometry");
if (!fPhysical) fPhysical = new TObjArray(256);
fPhysical->Add(pnode);
}
void TGeoParallelWorld::AddOverlap(TGeoVolume *vol)
{
fUseOverlaps = kTRUE;
vol->SetOverlappingCandidate(kTRUE);
}
Bool_t TGeoParallelWorld::CloseGeometry()
{
if (fIsClosed) return kTRUE;
if (!fGeoManager->IsClosed()) Fatal("CloseGeometry", "Main geometry must be closed first");
if (!fPhysical || !fPhysical->GetEntriesFast()) {
Error("CloseGeometry", "List of physical nodes is empty");
return kFALSE;
}
RefreshPhysicalNodes();
fIsClosed = kTRUE;
return kTRUE;
}
void TGeoParallelWorld::RefreshPhysicalNodes()
{
if (fIsClosed) {
delete fVolume;
fVolume = new TGeoVolume();
}
TGeoPhysicalNode *pnode;
TIter next(fPhysical);
Int_t copy = 0;
while ((pnode = (TGeoPhysicalNode*)next())) {
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();
if (fUseOverlaps && !nav->GetCurrentVolume()->IsOverlappingCandidate()) return 0;
TGeoVoxelFinder *voxels = fVolume->GetVoxels();
Int_t id;
Int_t ncheck = 0;
TGeoNodeCache *cache = nav->GetCache();
TGeoStateInfo &info = *cache->GetInfo();
Int_t *check_list = voxels->GetCheckList(point, ncheck, info);
cache->ReleaseInfo();
if (!check_list) return 0;
TGeoNode *node;
TGeoPhysicalNode *pnode;
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)) {
pnode = (TGeoPhysicalNode*)fPhysical->At(node->GetNumber());
return pnode;
}
}
return 0;
}
TGeoPhysicalNode *TGeoParallelWorld::FindNextBoundary(Double_t point[3], Double_t dir[3],
Double_t &step, Double_t stepmax)
{
if (!fIsClosed) Fatal("FindNode", "Parallel geometry must be closed first");
TGeoPhysicalNode *pnode = 0;
TGeoNavigator *nav = fGeoManager->GetCurrentNavigator();
if (fUseOverlaps && !nav->GetCurrentVolume()->IsOverlappingCandidate()) return 0;
TIter next(fPhysical);
while ((pnode = (TGeoPhysicalNode*)next())) {
if (pnode->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];
const Double_t tolerance = TGeoShape::Tolerance();
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-tolerance) {
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->GetInfo();
cache->ReleaseInfo();
voxels->SortCrossedVoxels(point, dir, info);
while ((sumchecked<nd) && (vlist=voxels->GetNextVoxel(point, dir, ncheck, info))) {
for (i=0; i<ncheck; i++) {
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-tolerance) {
step = snext;
idaughter = vlist[i];
}
}
if (idaughter>=0) {
pnode = (TGeoPhysicalNode*)fPhysical->At(idaughter);
return pnode;
}
}
step = TGeoShape::Big();
return 0;
}
Double_t TGeoParallelWorld::Safety(Double_t point[3], Double_t safmax)
{
TGeoNavigator *nav = fGeoManager->GetCurrentNavigator();
if (fUseOverlaps && !nav->GetCurrentVolume()->IsOverlappingCandidate()) return TGeoShape::Big();
Double_t local[3];
Double_t safe = safmax;
Double_t safnext;
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;
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