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 #include "TObject.h"
00026 #include "TGeoMatrix.h"
00027 #include "TGeoBBox.h"
00028 #include "TGeoNode.h"
00029 #include "TGeoManager.h"
00030 #include "TMath.h"
00031
00032 #include "TGeoVoxelFinder.h"
00033
00034
00035
00036
00037
00038
00039 ClassImp(TGeoVoxelFinder)
00040
00041
00042
00043 TGeoVoxelFinder::TGeoVoxelFinder()
00044 {
00045
00046 fVolume = 0;
00047 fNboxes = 0;
00048 fIbx = 0;
00049 fIby = 0;
00050 fIbz = 0;
00051 fNox = 0;
00052 fNoy = 0;
00053 fNoz = 0;
00054 fNex = 0;
00055 fNey = 0;
00056 fNez = 0;
00057 fNx = 0;
00058 fNy = 0;
00059 fNz = 0;
00060 fBoxes = 0;
00061 fXb = 0;
00062 fYb = 0;
00063 fZb = 0;
00064 fOBx = 0;
00065 fOBy = 0;
00066 fOBz = 0;
00067 fOEx = 0;
00068 fOEy = 0;
00069 fOEz = 0;
00070 fIndcX = 0;
00071 fIndcY = 0;
00072 fIndcZ = 0;
00073 fExtraX = 0;
00074 fExtraY = 0;
00075 fExtraZ = 0;
00076 fNsliceX = 0;
00077 fNsliceY = 0;
00078 fNsliceZ = 0;
00079 fCheckList = 0;
00080 fNcandidates = 0;
00081 fCurrentVoxel = 0;
00082 fBits1 = 0;
00083 for (Int_t i=0; i<3; i++) {
00084 fPriority[i] = 0;
00085 fSlices[i] = 0;
00086 fInc[i] = 0;
00087 fInvdir[i] = 0.;
00088 fLimits[i] = 0.;
00089 }
00090 SetInvalid(kFALSE);
00091 }
00092
00093 TGeoVoxelFinder::TGeoVoxelFinder(TGeoVolume *vol)
00094 {
00095
00096 if (!vol) {
00097 Fatal("TGeoVoxelFinder", "Null pointer for volume");
00098 return;
00099 }
00100 fVolume = vol;
00101 fVolume->SetCylVoxels(kFALSE);
00102 fNboxes = 0;
00103 fIbx = 0;
00104 fIby = 0;
00105 fIbz = 0;
00106 fNox = 0;
00107 fNoy = 0;
00108 fNoz = 0;
00109 fNex = 0;
00110 fNey = 0;
00111 fNez = 0;
00112 fNx = 0;
00113 fNy = 0;
00114 fNz = 0;
00115 fBoxes = 0;
00116 fXb = 0;
00117 fYb = 0;
00118 fZb = 0;
00119 fOBx = 0;
00120 fOBy = 0;
00121 fOBz = 0;
00122 fOEx = 0;
00123 fOEy = 0;
00124 fOEz = 0;
00125 fIndcX = 0;
00126 fIndcY = 0;
00127 fIndcZ = 0;
00128 fExtraX = 0;
00129 fExtraY = 0;
00130 fExtraZ = 0;
00131 fNsliceX = 0;
00132 fNsliceY = 0;
00133 fNsliceZ = 0;
00134 fCheckList = 0;
00135 fNcandidates = 0;
00136 fCurrentVoxel = 0;
00137 fBits1 = 0;
00138 for (Int_t i=0; i<3; i++) {
00139 fPriority[i] = 0;
00140 fSlices[i] = 0;
00141 fInc[i] = 0;
00142 fInvdir[i] = 0.;
00143 fLimits[i] = 0.;
00144 }
00145 SetNeedRebuild();
00146 }
00147
00148
00149 TGeoVoxelFinder::TGeoVoxelFinder(const TGeoVoxelFinder& vf) :
00150 TObject(vf),
00151 fVolume(vf.fVolume),
00152 fNcandidates(vf.fNcandidates),
00153 fCurrentVoxel(vf.fCurrentVoxel),
00154 fIbx(vf.fIbx),
00155 fIby(vf.fIby),
00156 fIbz(vf.fIbz),
00157 fNboxes(vf.fNboxes),
00158 fNox(vf.fNox),
00159 fNoy(vf.fNoy),
00160 fNoz(vf.fNoz),
00161 fNex(vf.fNex),
00162 fNey(vf.fNey),
00163 fNez(vf.fNez),
00164 fNx(vf.fNx),
00165 fNy(vf.fNy),
00166 fNz(vf.fNz),
00167 fBoxes(vf.fBoxes),
00168 fXb(vf.fXb),
00169 fYb(vf.fYb),
00170 fZb(vf.fZb),
00171 fOBx(vf.fOBx),
00172 fOBy(vf.fOBy),
00173 fOBz(vf.fOBz),
00174 fOEx(vf.fOEx),
00175 fOEy(vf.fOEy),
00176 fOEz(vf.fOEz),
00177 fExtraX(vf.fExtraX),
00178 fExtraY(vf.fExtraY),
00179 fExtraZ(vf.fExtraZ),
00180 fNsliceX(vf.fNsliceX),
00181 fNsliceY(vf.fNsliceY),
00182 fNsliceZ(vf.fNsliceZ),
00183 fIndcX(vf.fIndcX),
00184 fIndcY(vf.fIndcY),
00185 fIndcZ(vf.fIndcZ),
00186 fCheckList(vf.fCheckList),
00187 fBits1(vf.fBits1)
00188 {
00189
00190 for(Int_t i=0; i<3; i++) {
00191 fPriority[i]=vf.fPriority[i];
00192 fSlices[i]=vf.fSlices[i];
00193 fInc[i]=vf.fInc[i];
00194 fInvdir[i]=vf.fInvdir[i];
00195 fLimits[i]=vf.fLimits[i];
00196 }
00197 }
00198
00199
00200 TGeoVoxelFinder& TGeoVoxelFinder::operator=(const TGeoVoxelFinder& vf)
00201 {
00202
00203 if(this!=&vf) {
00204 TObject::operator=(vf);
00205 fVolume=vf.fVolume;
00206 fNcandidates=vf.fNcandidates;
00207 fCurrentVoxel=vf.fCurrentVoxel;
00208 fIbx=vf.fIbx;
00209 fIby=vf.fIby;
00210 fIbz=vf.fIbz;
00211 fNboxes=vf.fNboxes;
00212 fNox=vf.fNox;
00213 fNoy=vf.fNoy;
00214 fNoz=vf.fNoz;
00215 fNex=vf.fNex;
00216 fNey=vf.fNey;
00217 fNez=vf.fNez;
00218 fNx=vf.fNx;
00219 fNy=vf.fNy;
00220 fNz=vf.fNz;
00221 for(Int_t i=0; i<3; i++) {
00222 fPriority[i]=vf.fPriority[i];
00223 fSlices[i]=vf.fSlices[i];
00224 fInc[i]=vf.fInc[i];
00225 fInvdir[i]=vf.fInvdir[i];
00226 fLimits[i]=vf.fLimits[i];
00227 }
00228 fBoxes=vf.fBoxes;
00229 fXb=vf.fXb;
00230 fYb=vf.fYb;
00231 fZb=vf.fZb;
00232 fOBx=vf.fOBx;
00233 fOBy=vf.fOBy;
00234 fOBz=vf.fOBz;
00235 fOEx=vf.fOEx;
00236 fOEy=vf.fOEy;
00237 fOEz=vf.fOEz;
00238 fNsliceX=vf.fNsliceX;
00239 fNsliceY=vf.fNsliceY;
00240 fNsliceZ=vf.fNsliceZ;
00241 fIndcX=vf.fIndcX;
00242 fIndcY=vf.fIndcY;
00243 fIndcZ=vf.fIndcZ;
00244 fExtraX=vf.fExtraX;
00245 fExtraY=vf.fExtraY;
00246 fExtraZ=vf.fExtraZ;
00247 fCheckList=vf.fCheckList;
00248 fBits1=vf.fBits1;
00249 }
00250 return *this;
00251 }
00252
00253
00254 TGeoVoxelFinder::~TGeoVoxelFinder()
00255 {
00256
00257
00258 if (fOBx) delete [] fOBx;
00259 if (fOBy) delete [] fOBy;
00260 if (fOBz) delete [] fOBz;
00261 if (fOEx) delete [] fOEx;
00262 if (fOEy) delete [] fOEy;
00263 if (fOEz) delete [] fOEz;
00264
00265 if (fBoxes) delete [] fBoxes;
00266
00267 if (fXb) delete [] fXb;
00268 if (fYb) delete [] fYb;
00269 if (fZb) delete [] fZb;
00270
00271 if (fNsliceX) delete [] fNsliceX;
00272 if (fNsliceY) delete [] fNsliceY;
00273 if (fNsliceZ) delete [] fNsliceZ;
00274 if (fIndcX) delete [] fIndcX;
00275 if (fIndcY) delete [] fIndcY;
00276 if (fIndcZ) delete [] fIndcZ;
00277 if (fExtraX) delete [] fExtraX;
00278 if (fExtraY) delete [] fExtraY;
00279 if (fExtraZ) delete [] fExtraZ;
00280
00281 if (fCheckList) delete [] fCheckList;
00282 if (fBits1) delete [] fBits1;
00283
00284 }
00285
00286 void TGeoVoxelFinder::BuildVoxelLimits()
00287 {
00288
00289 Int_t nd = fVolume->GetNdaughters();
00290 if (!nd) return;
00291 Int_t id;
00292 TGeoNode *node;
00293 if (fBoxes) delete [] fBoxes;
00294 if (fBits1) delete [] fBits1;
00295 fBits1 = new UChar_t[1+((nd-1)>>3)];
00296 fNboxes = 6*nd;
00297 fBoxes = new Double_t[fNboxes];
00298 if (fCheckList) delete [] fCheckList;
00299 fCheckList = new Int_t[nd];
00300 Double_t vert[24];
00301 Double_t pt[3];
00302 Double_t xyz[6];
00303
00304 TGeoBBox *box = 0;
00305 for (id=0; id<nd; id++) {
00306 node = fVolume->GetNode(id);
00307
00308 box = (TGeoBBox*)node->GetVolume()->GetShape();
00309 box->SetBoxPoints(&vert[0]);
00310 for (Int_t point=0; point<8; point++) {
00311 DaughterToMother(id, &vert[3*point], &pt[0]);
00312 if (!point) {
00313 xyz[0] = xyz[1] = pt[0];
00314 xyz[2] = xyz[3] = pt[1];
00315 xyz[4] = xyz[5] = pt[2];
00316 continue;
00317 }
00318 for (Int_t j=0; j<3; j++) {
00319 if (pt[j] < xyz[2*j]) xyz[2*j]=pt[j];
00320 if (pt[j] > xyz[2*j+1]) xyz[2*j+1]=pt[j];
00321 }
00322 }
00323 fBoxes[6*id] = 0.5*(xyz[1]-xyz[0]);
00324 fBoxes[6*id+1] = 0.5*(xyz[3]-xyz[2]);
00325 fBoxes[6*id+2] = 0.5*(xyz[5]-xyz[4]);
00326 fBoxes[6*id+3] = 0.5*(xyz[0]+xyz[1]);
00327 fBoxes[6*id+4] = 0.5*(xyz[2]+xyz[3]);
00328 fBoxes[6*id+5] = 0.5*(xyz[4]+xyz[5]);
00329 }
00330 }
00331
00332 void TGeoVoxelFinder::CreateCheckList()
00333 {
00334
00335 if (NeedRebuild()) {
00336 Voxelize();
00337 fVolume->FindOverlaps();
00338 }
00339 Int_t nd = fVolume->GetNdaughters();
00340 if (!nd) return;
00341 if (!fCheckList) fCheckList = new Int_t[nd];
00342 if (!fBits1) fBits1 = new UChar_t[1+((nd-1)>>3)];
00343 }
00344
00345 void TGeoVoxelFinder::DaughterToMother(Int_t id, Double_t *local, Double_t *master) const
00346 {
00347
00348
00349 TGeoMatrix *mat = fVolume->GetNode(id)->GetMatrix();
00350 if (!mat) memcpy(master,local,3*sizeof(Double_t));
00351 else mat->LocalToMaster(local, master);
00352 }
00353
00354 Bool_t TGeoVoxelFinder::IsSafeVoxel(Double_t *point, Int_t inode, Double_t minsafe) const
00355 {
00356
00357
00358 if (NeedRebuild()) {
00359 TGeoVoxelFinder *vox = (TGeoVoxelFinder*)this;
00360 vox->Voxelize();
00361 fVolume->FindOverlaps();
00362 }
00363 Double_t dxyz, minsafe2=minsafe*minsafe;
00364 Int_t ist = 6*inode;
00365 Int_t i;
00366 Double_t rsq = 0;
00367 for (i=0; i<3; i++) {
00368 dxyz = TMath::Abs(point[i]-fBoxes[ist+i+3])-fBoxes[ist+i];
00369 if (dxyz>-1E-6) rsq+=dxyz*dxyz;
00370 if (rsq > minsafe2*(1.+TGeoShape::Tolerance())) return kTRUE;
00371 }
00372 return kFALSE;
00373 }
00374
00375
00376 Double_t TGeoVoxelFinder::Efficiency()
00377 {
00378
00379 printf("Voxelization efficiency for %s\n", fVolume->GetName());
00380 if (NeedRebuild()) {
00381 Voxelize();
00382 fVolume->FindOverlaps();
00383 }
00384 Double_t nd = Double_t(fVolume->GetNdaughters());
00385 Double_t eff = 0;
00386 Double_t effslice = 0;
00387 Int_t id;
00388 if (fPriority[0]) {
00389 for (id=0; id<fIbx-1; id++) {
00390 effslice += fNsliceX[id];
00391 }
00392 if (!TGeoShape::IsSameWithinTolerance(effslice,0)) effslice = nd/effslice;
00393 else printf("Woops : slice X\n");
00394 }
00395 printf("X efficiency : %g\n", effslice);
00396 eff += effslice;
00397 effslice = 0;
00398 if (fPriority[1]) {
00399 for (id=0; id<fIby-1; id++) {
00400 effslice += fNsliceY[id];
00401 }
00402 if (!TGeoShape::IsSameWithinTolerance(effslice,0)) effslice = nd/effslice;
00403 else printf("Woops : slice X\n");
00404 }
00405 printf("Y efficiency : %g\n", effslice);
00406 eff += effslice;
00407 effslice = 0;
00408 if (fPriority[2]) {
00409 for (id=0; id<fIbz-1; id++) {
00410 effslice += fNsliceZ[id];
00411 }
00412 if (!TGeoShape::IsSameWithinTolerance(effslice,0)) effslice = nd/effslice;
00413 else printf("Woops : slice X\n");
00414 }
00415 printf("Z efficiency : %g\n", effslice);
00416 eff += effslice;
00417 eff /= 3.;
00418 printf("Total efficiency : %g\n", eff);
00419 return eff;
00420 }
00421
00422 void TGeoVoxelFinder::FindOverlaps(Int_t inode) const
00423 {
00424
00425 if (!fBoxes) return;
00426 Double_t xmin, xmax, ymin, ymax, zmin, zmax;
00427 Double_t xmin1, xmax1, ymin1, ymax1, zmin1, zmax1;
00428 Double_t ddx1, ddx2;
00429 Int_t nd = fVolume->GetNdaughters();
00430 Int_t *ovlps = 0;
00431 Int_t *otmp = new Int_t[nd-1];
00432 Int_t novlp = 0;
00433 TGeoNode *node = fVolume->GetNode(inode);
00434 xmin = fBoxes[6*inode+3] - fBoxes[6*inode];
00435 xmax = fBoxes[6*inode+3] + fBoxes[6*inode];
00436 ymin = fBoxes[6*inode+4] - fBoxes[6*inode+1];
00437 ymax = fBoxes[6*inode+4] + fBoxes[6*inode+1];
00438 zmin = fBoxes[6*inode+5] - fBoxes[6*inode+2];
00439 zmax = fBoxes[6*inode+5] + fBoxes[6*inode+2];
00440
00441 for (Int_t ib=0; ib<nd; ib++) {
00442 if (ib == inode) continue;
00443 xmin1 = fBoxes[6*ib+3] - fBoxes[6*ib];
00444 xmax1 = fBoxes[6*ib+3] + fBoxes[6*ib];
00445 ymin1 = fBoxes[6*ib+4] - fBoxes[6*ib+1];
00446 ymax1 = fBoxes[6*ib+4] + fBoxes[6*ib+1];
00447 zmin1 = fBoxes[6*ib+5] - fBoxes[6*ib+2];
00448 zmax1 = fBoxes[6*ib+5] + fBoxes[6*ib+2];
00449
00450 ddx1 = xmax-xmin1;
00451 ddx2 = xmax1-xmin;
00452 if (ddx1*ddx2 <= 0.) continue;
00453 ddx1 = ymax-ymin1;
00454 ddx2 = ymax1-ymin;
00455 if (ddx1*ddx2 <= 0.) continue;
00456 ddx1 = zmax-zmin1;
00457 ddx2 = zmax1-zmin;
00458 if (ddx1*ddx2 <= 0.) continue;
00459 otmp[novlp++] = ib;
00460 }
00461 if (!novlp) {
00462 delete [] otmp;
00463 node->SetOverlaps(ovlps, 0);
00464 return;
00465 }
00466 ovlps = new Int_t[novlp];
00467 memcpy(ovlps, otmp, novlp*sizeof(Int_t));
00468 delete [] otmp;
00469 node->SetOverlaps(ovlps, novlp);
00470 }
00471
00472
00473 Bool_t TGeoVoxelFinder::GetIndices(Double_t *point)
00474 {
00475
00476 fSlices[0] = -2;
00477 fSlices[1] = -2;
00478 fSlices[2] = -2;
00479 Bool_t flag=kTRUE;
00480 if (fPriority[0]) {
00481 fSlices[0] = TMath::BinarySearch(fIbx, fXb, point[0]);
00482 if ((fSlices[0]<0) || (fSlices[0]>=fIbx-1)) {
00483
00484 flag=kFALSE;
00485 } else {
00486 if (fPriority[0]==2) {
00487
00488 if (!fNsliceX[fSlices[0]]) flag = kFALSE;
00489 }
00490 }
00491 }
00492 if (fPriority[1]) {
00493 fSlices[1] = TMath::BinarySearch(fIby, fYb, point[1]);
00494 if ((fSlices[1]<0) || (fSlices[1]>=fIby-1)) {
00495
00496 flag=kFALSE;
00497 } else {
00498 if (fPriority[1]==2) {
00499
00500 if (!fNsliceY[fSlices[1]]) flag = kFALSE;
00501 }
00502 }
00503 }
00504 if (fPriority[2]) {
00505 fSlices[2] = TMath::BinarySearch(fIbz, fZb, point[2]);
00506 if ((fSlices[2]<0) || (fSlices[2]>=fIbz-1)) return kFALSE;
00507 if (fPriority[2]==2) {
00508
00509 if (!fNsliceZ[fSlices[2]]) return kFALSE;
00510 }
00511 }
00512 return flag;
00513 }
00514
00515
00516 Int_t *TGeoVoxelFinder::GetExtraX(Int_t islice, Bool_t left, Int_t &nextra) const
00517 {
00518
00519
00520 Int_t *list = 0;
00521 nextra = 0;
00522 if (fPriority[0]!=2) return list;
00523 if (left) {
00524 nextra = fExtraX[fOEx[islice]];
00525 list = &fExtraX[fOEx[islice]+2];
00526 } else {
00527 nextra = fExtraX[fOEx[islice]+1];
00528 list = &fExtraX[fOEx[islice]+2+fExtraX[fOEx[islice]]];
00529 }
00530 return list;
00531 }
00532
00533
00534 Int_t *TGeoVoxelFinder::GetExtraY(Int_t islice, Bool_t left, Int_t &nextra) const
00535 {
00536
00537
00538 Int_t *list = 0;
00539 nextra = 0;
00540 if (fPriority[1]!=2) return list;
00541 if (left) {
00542 nextra = fExtraY[fOEy[islice]];
00543 list = &fExtraY[fOEy[islice]+2];
00544 } else {
00545 nextra = fExtraY[fOEy[islice]+1];
00546 list = &fExtraY[fOEy[islice]+2+fExtraY[fOEy[islice]]];
00547 }
00548 return list;
00549 }
00550
00551
00552 Int_t *TGeoVoxelFinder::GetExtraZ(Int_t islice, Bool_t left, Int_t &nextra) const
00553 {
00554
00555
00556 Int_t *list = 0;
00557 nextra = 0;
00558 if (fPriority[2]!=2) return list;
00559 if (left) {
00560 nextra = fExtraZ[fOEz[islice]];
00561 list = &fExtraZ[fOEz[islice]+2];
00562 } else {
00563 nextra = fExtraZ[fOEz[islice]+1];
00564 list = &fExtraZ[fOEz[islice]+2+fExtraZ[fOEz[islice]]];
00565 }
00566 return list;
00567 }
00568
00569
00570 Int_t *TGeoVoxelFinder::GetValidExtra(Int_t *list, Int_t &ncheck)
00571 {
00572
00573
00574 fNcandidates = 0;
00575 Int_t icand;
00576 UInt_t bitnumber, loc;
00577 UChar_t bit, byte;
00578 for (icand=0; icand<ncheck; icand++) {
00579 bitnumber = (UInt_t)list[icand];
00580 loc = bitnumber>>3;
00581 bit = bitnumber%8;
00582 byte = (~fBits1[loc]) & (1<<bit);
00583 if (byte) fCheckList[fNcandidates++]=list[icand];
00584 }
00585 ncheck = fNcandidates;
00586 return fCheckList;
00587 }
00588
00589
00590 Int_t *TGeoVoxelFinder::GetValidExtra(Int_t , UChar_t *array1, Int_t *list, Int_t &ncheck)
00591 {
00592
00593
00594 fNcandidates = 0;
00595 Int_t icand;
00596 UInt_t bitnumber, loc;
00597 UChar_t bit, byte;
00598 for (icand=0; icand<ncheck; icand++) {
00599 bitnumber = (UInt_t)list[icand];
00600 loc = bitnumber>>3;
00601 bit = bitnumber%8;
00602 byte = (~fBits1[loc]) & array1[loc] & (1<<bit);
00603 if (byte) fCheckList[fNcandidates++]=list[icand];
00604 }
00605 ncheck = fNcandidates;
00606 return fCheckList;
00607 }
00608
00609
00610 Int_t *TGeoVoxelFinder::GetValidExtra(Int_t , UChar_t *array1, Int_t , UChar_t *array2, Int_t *list, Int_t &ncheck)
00611 {
00612
00613
00614 fNcandidates = 0;
00615 Int_t icand;
00616 UInt_t bitnumber, loc;
00617 UChar_t bit, byte;
00618 for (icand=0; icand<ncheck; icand++) {
00619 bitnumber = (UInt_t)list[icand];
00620 loc = bitnumber>>3;
00621 bit = bitnumber%8;
00622 byte = (~fBits1[loc]) & array1[loc] & array2[loc] & (1<<bit);
00623 if (byte) fCheckList[fNcandidates++]=list[icand];
00624 }
00625 ncheck = fNcandidates;
00626 return fCheckList;
00627 }
00628
00629
00630
00631 Int_t *TGeoVoxelFinder::GetNextCandidates(Double_t *point, Int_t &ncheck)
00632 {
00633
00634
00635 if (NeedRebuild()) {
00636 Voxelize();
00637 fVolume->FindOverlaps();
00638 }
00639 ncheck = 0;
00640 if (fLimits[0]<0) return 0;
00641 if (fLimits[1]<0) return 0;
00642 if (fLimits[2]<0) return 0;
00643 Int_t dind[3];
00644
00645 memcpy(&dind[0], &fSlices[0], 3*sizeof(Int_t));
00646 Double_t dmin[3];
00647 dmin[0] = dmin[1] = dmin[2] = TGeoShape::Big();
00648
00649 Double_t maxstep = TMath::Min(gGeoManager->GetStep(), fLimits[TMath::LocMin(3, fLimits)]);
00650
00651 Bool_t isXlimit=kFALSE, isYlimit=kFALSE, isZlimit=kFALSE;
00652 Bool_t isForcedX=kFALSE, isForcedY=kFALSE, isForcedZ=kFALSE;
00653 Double_t dforced[3];
00654 dforced[0] = dforced[1] = dforced[2] = TGeoShape::Big();
00655 Int_t iforced = 0;
00656
00657
00658 if (fPriority[0] && fInc[0]) {
00659
00660 dind[0] += fInc[0];
00661 if (fInc[0]==1) {
00662 if (dind[0]<0 || dind[0]>fIbx-1) return 0;
00663 dmin[0] = (fXb[dind[0]]-point[0])*fInvdir[0];
00664 } else {
00665 if (fSlices[0]<0 || fSlices[0]>fIbx-1) return 0;
00666 dmin[0] = (fXb[fSlices[0]]-point[0])*fInvdir[0];
00667 }
00668 isXlimit = (dmin[0]>maxstep)?kTRUE:kFALSE;
00669
00670
00671
00672
00673 if ((fSlices[0]==-1) || (fSlices[0]==fIbx-1)) {
00674 isForcedX = kTRUE;
00675 dforced[0] = dmin[0];
00676 iforced++;
00677
00678 if (isXlimit) return 0;
00679 } else {
00680 if (fPriority[0]==2) {
00681
00682 if (fNsliceX[fSlices[0]]==0) {
00683 isForcedX = kTRUE;
00684 dforced[0] = dmin[0];
00685 iforced++;
00686
00687 if (isXlimit) return 0;
00688 }
00689 }
00690 }
00691 } else {
00692
00693
00694 dmin[0] = fLimits[0];
00695 isXlimit = kTRUE;
00696 }
00697
00698 if (fPriority[1] && fInc[1]) {
00699
00700 dind[1] += fInc[1];
00701 if (fInc[1]==1) {
00702 if (dind[1]<0 || dind[1]>fIby-1) return 0;
00703 dmin[1] = (fYb[dind[1]]-point[1])*fInvdir[1];
00704 } else {
00705 if (fSlices[1]<0 || fSlices[1]>fIby-1) return 0;
00706 dmin[1] = (fYb[fSlices[1]]-point[1])*fInvdir[1];
00707 }
00708 isYlimit = (dmin[1]>maxstep)?kTRUE:kFALSE;
00709
00710
00711
00712
00713
00714 if ((fSlices[1]==-1) || (fSlices[1]==fIby-1)) {
00715 isForcedY = kTRUE;
00716 dforced[1] = dmin[1];
00717 iforced++;
00718
00719 if (isYlimit) return 0;
00720 } else {
00721 if (fPriority[1]==2) {
00722
00723 if (fNsliceY[fSlices[1]]==0) {
00724 isForcedY = kTRUE;
00725 dforced[1] = dmin[1];
00726 iforced++;
00727
00728 if (isYlimit) return 0;
00729 }
00730 }
00731 }
00732 } else {
00733
00734
00735 dmin[1] = fLimits[1];
00736 isYlimit = kTRUE;
00737 }
00738
00739 if (fPriority[2] && fInc[2]) {
00740
00741 dind[2] += fInc[2];
00742 if (fInc[2]==1) {
00743 if (dind[2]<0 || dind[2]>fIbz-1) return 0;
00744 dmin[2] = (fZb[dind[2]]-point[2])*fInvdir[2];
00745 } else {
00746 if (fSlices[2]<0 || fSlices[2]>fIbz-1) return 0;
00747 dmin[2] = (fZb[fSlices[2]]-point[2])*fInvdir[2];
00748 }
00749 isZlimit = (dmin[2]>maxstep)?kTRUE:kFALSE;
00750
00751
00752
00753
00754
00755 if ((fSlices[2]==-1) || (fSlices[2]==fIbz-1)) {
00756 isForcedZ = kTRUE;
00757 dforced[2] = dmin[2];
00758 iforced++;
00759
00760 if (isZlimit) return 0;
00761 } else {
00762 if (fPriority[2]==2) {
00763
00764 if (fNsliceZ[fSlices[2]]==0) {
00765 isForcedZ = kTRUE;
00766 dforced[2] = dmin[2];
00767 iforced++;
00768
00769 if (isZlimit) return 0;
00770 }
00771 }
00772 }
00773 } else {
00774
00775
00776 dmin[2] = fLimits[2];
00777 isZlimit = kTRUE;
00778 }
00779
00780
00781
00782 Double_t dslice = 0;
00783 Int_t islice = 0;
00784 if (iforced) {
00785
00786 if (isForcedX) {
00787
00788 dslice = dforced[0];
00789 islice = 0;
00790 if (isForcedY) {
00791
00792 if (dforced[1]>dslice) {
00793 dslice = dforced[1];
00794 islice = 1;
00795 }
00796 if (isForcedZ) {
00797
00798 if (dforced[2]>dslice) {
00799 dslice = dforced[2];
00800 islice = 2;
00801 }
00802 }
00803 } else {
00804
00805 if (isForcedZ) {
00806
00807 if (dforced[2]>dslice) {
00808 dslice = dforced[2];
00809 islice = 2;
00810 }
00811 }
00812 }
00813 } else {
00814 if (isForcedY) {
00815
00816 dslice = dforced[1];
00817 islice = 1;
00818 if (isForcedZ) {
00819
00820 if (dforced[2]>dslice) {
00821 dslice = dforced[2];
00822 islice = 2;
00823 }
00824 }
00825 } else {
00826
00827 dslice = dforced[2];
00828 islice = 2;
00829 }
00830 }
00831 } else {
00832
00833 islice = TMath::LocMin(3, dmin);
00834 dslice = dmin[islice];
00835 if (dslice>=maxstep) {
00836
00837 return 0;
00838 }
00839 }
00840
00841 Double_t xptnew;
00842 Int_t *new_list;
00843 UChar_t *slice1 = 0;
00844 UChar_t *slice2 = 0;
00845 Int_t ndd[2] = {0,0};
00846 Int_t islices = 0;
00847 Bool_t left;
00848 switch (islice) {
00849 case 0:
00850 if (isXlimit) return 0;
00851
00852 fSlices[0]=dind[0];
00853 if (iforced) {
00854
00855 if (dslice>fLimits[1]) return 0;
00856 if (dslice>fLimits[2]) return 0;
00857 if ((dslice>dmin[1]) && fInc[1]) {
00858 xptnew = point[1]+dslice/fInvdir[1];
00859
00860 while (1) {
00861 fSlices[1] += fInc[1];
00862 if (fInc[1]==1) {
00863 if (fSlices[1]<-1 || fSlices[1]>fIby-2) break;
00864 if (fYb[fSlices[1]+1]>=xptnew) break;
00865 } else {
00866 if (fSlices[1]<0 || fSlices[1]>fIby-1) break;
00867 if (fYb[fSlices[1]]<= xptnew) break;
00868 }
00869 }
00870
00871 }
00872 if ((dslice>dmin[2]) && fInc[2]) {
00873 xptnew = point[2]+dslice/fInvdir[2];
00874
00875 while (1) {
00876 fSlices[2] += fInc[2];
00877 if (fInc[2]==1) {
00878 if (fSlices[2]<-1 || fSlices[2]>fIbz-2) break;
00879 if (fZb[fSlices[2]+1]>=xptnew) break;
00880 } else {
00881 if (fSlices[2]<0 || fSlices[2]>fIbz-1) break;
00882 if (fZb[fSlices[2]]<= xptnew) break;
00883 }
00884 }
00885
00886 }
00887 }
00888
00889 if (fPriority[0]==1) {
00890
00891
00892 if (fPriority[1]==2) {
00893 if (fSlices[1]<0 || fSlices[1]>=fIby-1) return fCheckList;
00894 ndd[0] = fNsliceY[fSlices[1]];
00895 if (!ndd[0]) return fCheckList;
00896 slice1 = &fIndcY[fOBy[fSlices[1]]];
00897 islices++;
00898 }
00899 if (fPriority[2]==2) {
00900 if (fSlices[2]<0 || fSlices[2]>=fIbz-1) return fCheckList;
00901 ndd[1] = fNsliceZ[fSlices[2]];
00902 if (!ndd[1]) return fCheckList;
00903 islices++;
00904 if (slice1) {
00905 slice2 = &fIndcZ[fOBz[fSlices[2]]];
00906 } else {
00907 slice1 = &fIndcZ[fOBz[fSlices[2]]];
00908 ndd[0] = ndd[1];
00909 }
00910 }
00911 if (islices==1) {
00912 IntersectAndStore(ndd[0], slice1);
00913 } else {
00914 IntersectAndStore(ndd[0], slice1, ndd[1], slice2);
00915 }
00916 ncheck = fNcandidates;
00917 return fCheckList;
00918 }
00919
00920 left = (fInc[0]>0)?kTRUE:kFALSE;
00921 new_list = GetExtraX(fSlices[0], left, ncheck);
00922
00923 if (!ncheck) return fCheckList;
00924 if (fPriority[1]==2) {
00925 if (fSlices[1]<0 || fSlices[1]>=fIby-1) {
00926 ncheck = 0;
00927 return fCheckList;
00928 }
00929 ndd[0] = fNsliceY[fSlices[1]];
00930 if (!ndd[0]) {
00931 ncheck = 0;
00932 return fCheckList;
00933 }
00934 slice1 = &fIndcY[fOBy[fSlices[1]]];
00935 islices++;
00936 }
00937 if (fPriority[2]==2) {
00938 if (fSlices[2]<0 || fSlices[2]>=fIbz-1) {
00939 ncheck = 0;
00940 return fCheckList;
00941 }
00942 ndd[1] = fNsliceZ[fSlices[2]];
00943 if (!ndd[1]) {
00944 ncheck = 0;
00945 return fCheckList;
00946 }
00947 islices++;
00948 if (slice1) {
00949 slice2 = &fIndcZ[fOBz[fSlices[2]]];
00950 } else {
00951 slice1 = &fIndcZ[fOBz[fSlices[2]]];
00952 ndd[0] = ndd[1];
00953 }
00954 }
00955 if (!islices) return GetValidExtra(new_list, ncheck);
00956 if (islices==1) {
00957 return GetValidExtra(ndd[0], slice1, new_list, ncheck);
00958 } else {
00959 return GetValidExtra(ndd[0], slice1, ndd[1], slice2, new_list, ncheck);
00960 }
00961 case 1:
00962 if (isYlimit) return 0;
00963
00964 fSlices[1]=dind[1];
00965 if (iforced) {
00966
00967 if (dslice>fLimits[0]) return 0;
00968 if (dslice>fLimits[2]) return 0;
00969 if ((dslice>dmin[0]) && fInc[0]) {
00970 xptnew = point[0]+dslice/fInvdir[0];
00971
00972 while (1) {
00973 fSlices[0] += fInc[0];
00974 if (fInc[0]==1) {
00975 if (fSlices[0]<-1 || fSlices[0]>fIbx-2) break;
00976 if (fXb[fSlices[0]+1]>=xptnew) break;
00977 } else {
00978 if (fSlices[0]<0 || fSlices[0]>fIbx-1) break;
00979 if (fXb[fSlices[0]]<= xptnew) break;
00980 }
00981 }
00982
00983 }
00984 if ((dslice>dmin[2]) && fInc[2]) {
00985 xptnew = point[2]+dslice/fInvdir[2];
00986
00987 while (1) {
00988 fSlices[2] += fInc[2];
00989 if (fInc[2]==1) {
00990 if (fSlices[2]<-1 || fSlices[2]>fIbz-2) break;
00991 if (fZb[fSlices[2]+1]>=xptnew) break;
00992 } else {
00993 if (fSlices[2]<0 || fSlices[2]>fIbz-1) break;
00994 if (fZb[fSlices[2]]<= xptnew) break;
00995 }
00996 }
00997
00998 }
00999 }
01000
01001 if (fPriority[1]==1) {
01002
01003
01004 if (fPriority[0]==2) {
01005 if (fSlices[0]<0 || fSlices[0]>=fIbx-1) return fCheckList;
01006 ndd[0] = fNsliceX[fSlices[0]];
01007 if (!ndd[0]) return fCheckList;
01008 slice1 = &fIndcX[fOBx[fSlices[0]]];
01009 islices++;
01010 }
01011 if (fPriority[2]==2) {
01012 if (fSlices[2]<0 || fSlices[2]>=fIbz-1) return fCheckList;
01013 ndd[1] = fNsliceZ[fSlices[2]];
01014 if (!ndd[1]) return fCheckList;
01015 islices++;
01016 if (slice1) {
01017 slice2 = &fIndcZ[fOBz[fSlices[2]]];
01018 } else {
01019 slice1 = &fIndcZ[fOBz[fSlices[2]]];
01020 ndd[0] = ndd[1];
01021 }
01022 }
01023 if (islices==1) {
01024 IntersectAndStore(ndd[0], slice1);
01025 } else {
01026 IntersectAndStore(ndd[0], slice1, ndd[1], slice2);
01027 }
01028 ncheck = fNcandidates;
01029 return fCheckList;
01030 }
01031
01032 left = (fInc[1]>0)?kTRUE:kFALSE;
01033 new_list = GetExtraY(fSlices[1], left, ncheck);
01034
01035 if (!ncheck) return fCheckList;
01036 if (fPriority[0]==2) {
01037 if (fSlices[0]<0 || fSlices[0]>=fIbx-1) {
01038 ncheck = 0;
01039 return fCheckList;
01040 }
01041 ndd[0] = fNsliceX[fSlices[0]];
01042 if (!ndd[0]) {
01043 ncheck = 0;
01044 return fCheckList;
01045 }
01046 slice1 = &fIndcX[fOBx[fSlices[0]]];
01047 islices++;
01048 }
01049 if (fPriority[2]==2) {
01050 if (fSlices[2]<0 || fSlices[2]>=fIbz-1) {
01051 ncheck = 0;
01052 return fCheckList;
01053 }
01054 ndd[1] = fNsliceZ[fSlices[2]];
01055 if (!ndd[1]) {
01056 ncheck = 0;
01057 return fCheckList;
01058 }
01059 islices++;
01060 if (slice1) {
01061 slice2 = &fIndcZ[fOBz[fSlices[2]]];
01062 } else {
01063 slice1 = &fIndcZ[fOBz[fSlices[2]]];
01064 ndd[0] = ndd[1];
01065 }
01066 }
01067 if (!islices) return GetValidExtra(new_list, ncheck);
01068 if (islices==1) {
01069 return GetValidExtra(ndd[0], slice1, new_list, ncheck);
01070 } else {
01071 return GetValidExtra(ndd[0], slice1, ndd[1], slice2, new_list, ncheck);
01072 }
01073 case 2:
01074 if (isZlimit) return 0;
01075
01076 fSlices[2]=dind[2];
01077 if (iforced) {
01078
01079 if (dslice>fLimits[1]) return 0;
01080 if (dslice>fLimits[0]) return 0;
01081 if ((dslice>dmin[1]) && fInc[1]) {
01082 xptnew = point[1]+dslice/fInvdir[1];
01083
01084 while (1) {
01085 fSlices[1] += fInc[1];
01086 if (fInc[1]==1) {
01087 if (fSlices[1]<-1 || fSlices[1]>fIby-2) break;
01088 if (fYb[fSlices[1]+1]>=xptnew) break;
01089 } else {
01090 if (fSlices[1]<0 || fSlices[1]>fIby-1) break;
01091 if (fYb[fSlices[1]]<= xptnew) break;
01092 }
01093 }
01094
01095 }
01096 if ((dslice>dmin[0]) && fInc[0]) {
01097 xptnew = point[0]+dslice/fInvdir[0];
01098
01099 while (1) {
01100 fSlices[0] += fInc[0];
01101 if (fInc[0]==1) {
01102 if (fSlices[0]<-1 || fSlices[0]>fIbx-2) break;
01103 if (fXb[fSlices[0]+1]>=xptnew) break;
01104 } else {
01105 if (fSlices[0]<0 || fSlices[0]>fIbx-1) break;
01106 if (fXb[fSlices[0]]<= xptnew) break;
01107 }
01108 }
01109
01110 }
01111 }
01112
01113 if (fPriority[2]==1) {
01114
01115
01116 if (fPriority[1]==2) {
01117 if (fSlices[1]<0 || fSlices[1]>=fIby-1) return fCheckList;
01118 ndd[0] = fNsliceY[fSlices[1]];
01119 if (!ndd[0]) return fCheckList;
01120 slice1 = &fIndcY[fOBy[fSlices[1]]];
01121 islices++;
01122 }
01123 if (fPriority[0]==2) {
01124 if (fSlices[0]<0 || fSlices[0]>=fIbx-1) return fCheckList;
01125 ndd[1] = fNsliceX[fSlices[0]];
01126 if (!ndd[1]) return fCheckList;
01127 islices++;
01128 if (slice1) {
01129 slice2 = &fIndcX[fOBx[fSlices[0]]];
01130 } else {
01131 slice1 = &fIndcX[fOBx[fSlices[0]]];
01132 ndd[0] = ndd[1];
01133 }
01134 }
01135 if (islices==1) {
01136 IntersectAndStore(ndd[0], slice1);
01137 } else {
01138 IntersectAndStore(ndd[0], slice1, ndd[1], slice2);
01139 }
01140 ncheck = fNcandidates;
01141 return fCheckList;
01142 }
01143
01144 left = (fInc[2]>0)?kTRUE:kFALSE;
01145 new_list = GetExtraZ(fSlices[2], left, ncheck);
01146
01147 if (!ncheck) return fCheckList;
01148 if (fPriority[1]==2) {
01149 if (fSlices[1]<0 || fSlices[1]>=fIby-1) {
01150 ncheck = 0;
01151 return fCheckList;
01152 }
01153 ndd[0] = fNsliceY[fSlices[1]];
01154 if (!ndd[0]) {
01155 ncheck = 0;
01156 return fCheckList;
01157 }
01158 slice1 = &fIndcY[fOBy[fSlices[1]]];
01159 islices++;
01160 }
01161 if (fPriority[0]==2) {
01162 if (fSlices[0]<0 || fSlices[0]>=fIbx-1) {
01163 ncheck = 0;
01164 return fCheckList;
01165 }
01166 ndd[1] = fNsliceX[fSlices[0]];
01167 if (!ndd[1]) {
01168 ncheck = 0;
01169 return fCheckList;
01170 }
01171 islices++;
01172 if (slice1) {
01173 slice2 = &fIndcX[fOBx[fSlices[0]]];
01174 } else {
01175 slice1 = &fIndcX[fOBx[fSlices[0]]];
01176 ndd[0] = ndd[1];
01177 }
01178 }
01179 if (!islices) return GetValidExtra(new_list, ncheck);
01180 if (islices==1) {
01181 return GetValidExtra(ndd[0], slice1, new_list, ncheck);
01182 } else {
01183 return GetValidExtra(ndd[0], slice1, ndd[1], slice2, new_list, ncheck);
01184 }
01185 default:
01186 Error("GetNextCandidates", "Invalid islice=%i inside %s", islice, fVolume->GetName());
01187 }
01188 return 0;
01189 }
01190
01191
01192 void TGeoVoxelFinder::SortCrossedVoxels(Double_t *point, Double_t *dir)
01193 {
01194
01195 if (NeedRebuild()) {
01196 TGeoVoxelFinder *vox = (TGeoVoxelFinder*)this;
01197 vox->Voxelize();
01198 fVolume->FindOverlaps();
01199 }
01200 fCurrentVoxel = 0;
01201
01202 fNcandidates = 0;
01203 Int_t loc = 1+((fVolume->GetNdaughters()-1)>>3);
01204
01205
01206 memset(fBits1, 0, loc);
01207 memset(fInc, 0, 3*sizeof(Int_t));
01208 for (Int_t i=0; i<3; i++) {
01209 fInvdir[i] = TGeoShape::Big();
01210 if (TMath::Abs(dir[i])<1E-10) continue;
01211 fInc[i] = (dir[i]>0)?1:-1;
01212 fInvdir[i] = 1./dir[i];
01213 }
01214 Bool_t flag = GetIndices(point);
01215 TGeoBBox *box = (TGeoBBox*)(fVolume->GetShape());
01216 const Double_t *box_orig = box->GetOrigin();
01217 if (fInc[0]==0) {
01218 fLimits[0] = TGeoShape::Big();
01219 } else {
01220 if (fSlices[0]==-2) {
01221
01222 fLimits[0] = (box_orig[0]-point[0]+fInc[0]*box->GetDX())*fInvdir[0];
01223 } else {
01224 if (fInc[0]==1) {
01225 fLimits[0] = (fXb[fIbx-1]-point[0])*fInvdir[0];
01226 } else {
01227 fLimits[0] = (fXb[0]-point[0])*fInvdir[0];
01228 }
01229 }
01230 }
01231 if (fInc[1]==0) {
01232 fLimits[1] = TGeoShape::Big();
01233 } else {
01234 if (fSlices[1]==-2) {
01235
01236 fLimits[1] = (box_orig[1]-point[1]+fInc[1]*box->GetDY())*fInvdir[1];
01237 } else {
01238 if (fInc[1]==1) {
01239 fLimits[1] = (fYb[fIby-1]-point[1])*fInvdir[1];
01240 } else {
01241 fLimits[1] = (fYb[0]-point[1])*fInvdir[1];
01242 }
01243 }
01244 }
01245 if (fInc[2]==0) {
01246 fLimits[2] = TGeoShape::Big();
01247 } else {
01248 if (fSlices[2]==-2) {
01249
01250 fLimits[2] = (box_orig[2]-point[2]+fInc[2]*box->GetDZ())*fInvdir[2];
01251 } else {
01252 if (fInc[2]==1) {
01253 fLimits[2] = (fZb[fIbz-1]-point[2])*fInvdir[2];
01254 } else {
01255 fLimits[2] = (fZb[0]-point[2])*fInvdir[2];
01256 }
01257 }
01258 }
01259
01260 if (!flag) {
01261
01262
01263 return;
01264 }
01265
01266 Int_t nd[3];
01267 Int_t islices = 0;
01268 memset(&nd[0], 0, 3*sizeof(Int_t));
01269 UChar_t *slicex = 0;
01270 if (fPriority[0]==2) {
01271 nd[0] = fNsliceX[fSlices[0]];
01272 slicex=&fIndcX[fOBx[fSlices[0]]];
01273 islices++;
01274 }
01275 UChar_t *slicey = 0;
01276 if (fPriority[1]==2) {
01277 nd[1] = fNsliceY[fSlices[1]];
01278 islices++;
01279 if (slicex) {
01280 slicey=&fIndcY[fOBy[fSlices[1]]];
01281 } else {
01282 slicex=&fIndcY[fOBy[fSlices[1]]];
01283 nd[0] = nd[1];
01284 }
01285 }
01286 UChar_t *slicez = 0;
01287 if (fPriority[2]==2) {
01288 nd[2] = fNsliceZ[fSlices[2]];
01289 islices++;
01290 if (slicex && slicey) {
01291 slicez=&fIndcZ[fOBz[fSlices[2]]];
01292 } else {
01293 if (slicex) {
01294 slicey=&fIndcZ[fOBz[fSlices[2]]];
01295 nd[1] = nd[2];
01296 } else {
01297 slicex=&fIndcZ[fOBz[fSlices[2]]];
01298 nd[0] = nd[2];
01299 }
01300 }
01301 }
01302
01303 switch (islices) {
01304 case 0:
01305 Error("SortCrossedVoxels", "no slices for %s", fVolume->GetName());
01306
01307 return;
01308 case 1:
01309 IntersectAndStore(nd[0], slicex);
01310 break;
01311 case 2:
01312 IntersectAndStore(nd[0], slicex, nd[1], slicey);
01313 break;
01314 default:
01315 IntersectAndStore(nd[0], slicex, nd[1], slicey, nd[2], slicez);
01316 }
01317
01318
01319
01320
01321
01322 }
01323
01324 Int_t *TGeoVoxelFinder::GetCheckList(Double_t *point, Int_t &nelem)
01325 {
01326
01327 if (NeedRebuild()) {
01328 Voxelize();
01329 fVolume->FindOverlaps();
01330 }
01331 if (fVolume->GetNdaughters() == 1) {
01332 if (fXb) {
01333 if (point[0]<fXb[0] || point[0]>fXb[1]) return 0;
01334 }
01335 if (fYb) {
01336 if (point[1]<fYb[0] || point[1]>fYb[1]) return 0;
01337 }
01338
01339 if (fZb) {
01340 if (point[2]<fZb[0] || point[2]>fZb[1]) return 0;
01341 }
01342 fCheckList[0] = 0;
01343 nelem = 1;
01344 return fCheckList;
01345 }
01346 Int_t nslices = 0;
01347 UChar_t *slice1 = 0;
01348 UChar_t *slice2 = 0;
01349 UChar_t *slice3 = 0;
01350 Int_t nd[3] = {0,0,0};
01351 Int_t im;
01352 if (fPriority[0]) {
01353 im = TMath::BinarySearch(fIbx, fXb, point[0]);
01354 if ((im==-1) || (im==fIbx-1)) return 0;
01355 if (fPriority[0]==2) {
01356 nd[0] = fNsliceX[im];
01357 if (!nd[0]) return 0;
01358 nslices++;
01359 slice1 = &fIndcX[fOBx[im]];
01360 }
01361 }
01362
01363 if (fPriority[1]) {
01364 im = TMath::BinarySearch(fIby, fYb, point[1]);
01365 if ((im==-1) || (im==fIby-1)) return 0;
01366 if (fPriority[1]==2) {
01367 nd[1] = fNsliceY[im];
01368 if (!nd[1]) return 0;
01369 nslices++;
01370 if (slice1) {
01371 slice2 = &fIndcY[fOBy[im]];
01372 } else {
01373 slice1 = &fIndcY[fOBy[im]];
01374 nd[0] = nd[1];
01375 }
01376 }
01377 }
01378
01379 if (fPriority[2]) {
01380 im = TMath::BinarySearch(fIbz, fZb, point[2]);
01381 if ((im==-1) || (im==fIbz-1)) return 0;
01382 if (fPriority[2]==2) {
01383 nd[2] = fNsliceZ[im];
01384 if (!nd[2]) return 0;
01385 nslices++;
01386 if (slice1 && slice2) {
01387 slice3 = &fIndcZ[fOBz[im]];
01388 } else {
01389 if (slice1) {
01390 slice2 = &fIndcZ[fOBz[im]];
01391 nd[1] = nd[2];
01392 } else {
01393 slice1 = &fIndcZ[fOBz[im]];
01394 nd[0] = nd[2];
01395 }
01396 }
01397 }
01398 }
01399 nelem = 0;
01400
01401 Bool_t intersect = kFALSE;
01402 switch (nslices) {
01403 case 0:
01404 Error("GetCheckList", "No slices for %s", fVolume->GetName());
01405 return 0;
01406 case 1:
01407 intersect = Intersect(nd[0], slice1, nelem, fCheckList);
01408 break;
01409 case 2:
01410 intersect = Intersect(nd[0], slice1, nd[1], slice2, nelem, fCheckList);
01411 break;
01412 default:
01413 intersect = Intersect(nd[0], slice1, nd[1], slice2, nd[2], slice3, nelem, fCheckList);
01414 }
01415 if (intersect) return fCheckList;
01416 return 0;
01417 }
01418
01419
01420 Int_t *TGeoVoxelFinder::GetVoxelCandidates(Int_t i, Int_t j, Int_t k, Int_t &ncheck)
01421 {
01422
01423 UChar_t *slice1 = 0;
01424 UChar_t *slice2 = 0;
01425 UChar_t *slice3 = 0;
01426 Int_t nd[3] = {0,0,0};
01427 Int_t nslices = 0;
01428 if (fPriority[0]==2) {
01429 nd[0] = fNsliceX[i];
01430 if (!nd[0]) return 0;
01431 nslices++;
01432 slice1 = &fIndcX[fOBx[i]];
01433 }
01434
01435 if (fPriority[1]==2) {
01436 nd[1] = fNsliceY[j];
01437 if (!nd[1]) return 0;
01438 nslices++;
01439 if (slice1) {
01440 slice2 = &fIndcY[fOBy[j]];
01441 } else {
01442 slice1 = &fIndcY[fOBy[j]];
01443 nd[0] = nd[1];
01444 }
01445 }
01446
01447 if (fPriority[2]==2) {
01448 nd[2] = fNsliceZ[k];
01449 if (!nd[2]) return 0;
01450 nslices++;
01451 if (slice1 && slice2) {
01452 slice3 = &fIndcZ[fOBz[k]];
01453 } else {
01454 if (slice1) {
01455 slice2 = &fIndcZ[fOBz[k]];
01456 nd[1] = nd[2];
01457 } else {
01458 slice1 = &fIndcZ[fOBz[k]];
01459 nd[0] = nd[2];
01460 }
01461 }
01462 }
01463 Bool_t intersect = kFALSE;
01464 switch (nslices) {
01465 case 0:
01466 Error("GetCheckList", "No slices for %s", fVolume->GetName());
01467 return 0;
01468 case 1:
01469 intersect = Intersect(nd[0], slice1, ncheck, fCheckList);
01470 break;
01471 case 2:
01472 intersect = Intersect(nd[0], slice1, nd[1], slice2, ncheck, fCheckList);
01473 break;
01474 default:
01475 intersect = Intersect(nd[0], slice1, nd[1], slice2, nd[2], slice3, ncheck, fCheckList);
01476 }
01477 if (intersect) return fCheckList;
01478 return 0;
01479 }
01480
01481
01482 Int_t *TGeoVoxelFinder::GetNextVoxel(Double_t *point, Double_t * , Int_t &ncheck)
01483 {
01484
01485
01486 if (NeedRebuild()) {
01487 Voxelize();
01488 fVolume->FindOverlaps();
01489 }
01490 if (fCurrentVoxel==0) {
01491
01492
01493 fCurrentVoxel++;
01494 ncheck = fNcandidates;
01495 return fCheckList;
01496 }
01497 fCurrentVoxel++;
01498
01499
01500
01501 return GetNextCandidates(point, ncheck);
01502 }
01503
01504
01505 Bool_t TGeoVoxelFinder::Intersect(Int_t n1, UChar_t *array1, Int_t &nf, Int_t *result)
01506 {
01507
01508 Int_t nd = fVolume->GetNdaughters();
01509 nf = 0;
01510 Int_t nbytes = 1+((nd-1)>>3);
01511 Int_t current_byte;
01512 Int_t current_bit;
01513 UChar_t byte;
01514 Bool_t ibreak = kFALSE;
01515 for (current_byte=0; current_byte<nbytes; current_byte++) {
01516 byte = array1[current_byte];
01517 if (!byte) continue;
01518 for (current_bit=0; current_bit<8; current_bit++) {
01519 if (byte & (1<<current_bit)) {
01520 result[nf++] = (current_byte<<3)+current_bit;
01521 if (nf==n1) {
01522 ibreak = kTRUE;
01523 break;
01524 }
01525 }
01526 }
01527 if (ibreak) return kTRUE;
01528 }
01529 return kTRUE;
01530 }
01531
01532
01533 Bool_t TGeoVoxelFinder::IntersectAndStore(Int_t n1, UChar_t *array1)
01534 {
01535
01536 Int_t nd = fVolume->GetNdaughters();
01537
01538 fNcandidates = 0;
01539 Int_t nbytes = 1+((nd-1)>>3);
01540 memcpy(fBits1, array1, nbytes*sizeof(UChar_t));
01541 Int_t current_byte;
01542 Int_t current_bit;
01543 UChar_t byte;
01544 Bool_t ibreak = kFALSE;
01545 Int_t icand;
01546 for (current_byte=0; current_byte<nbytes; current_byte++) {
01547 byte = array1[current_byte];
01548 icand = current_byte<<3;
01549 if (!byte) continue;
01550 for (current_bit=0; current_bit<8; current_bit++) {
01551 if (byte & (1<<current_bit)) {
01552 fCheckList[fNcandidates++] = icand+current_bit;
01553 if (fNcandidates==n1) {
01554 ibreak = kTRUE;
01555 break;
01556 }
01557 }
01558 }
01559 if (ibreak) return kTRUE;
01560 }
01561 return kTRUE;
01562 }
01563
01564
01565 Bool_t TGeoVoxelFinder::Union(Int_t n1, UChar_t *array1)
01566 {
01567
01568
01569 Int_t nd = fVolume->GetNdaughters();
01570
01571 fNcandidates = 0;
01572 Int_t nbytes = 1+((nd-1)>>3);
01573 Int_t current_byte;
01574 Int_t current_bit;
01575 UChar_t byte;
01576 Bool_t ibreak = kFALSE;
01577 for (current_byte=0; current_byte<nbytes; current_byte++) {
01578
01579 byte = (~fBits1[current_byte]) & array1[current_byte];
01580 if (!byte) continue;
01581 for (current_bit=0; current_bit<8; current_bit++) {
01582 if (byte & (1<<current_bit)) {
01583 fCheckList[fNcandidates++] = (current_byte<<3)+current_bit;
01584 if (fNcandidates==n1) {
01585 ibreak = kTRUE;
01586 break;
01587 }
01588 }
01589 }
01590 fBits1[current_byte] |= byte;
01591 if (ibreak) return kTRUE;
01592 }
01593 return (fNcandidates>0);
01594 }
01595
01596
01597 Bool_t TGeoVoxelFinder::Union(Int_t , UChar_t *array1, Int_t , UChar_t *array2)
01598 {
01599
01600
01601 Int_t nd = fVolume->GetNdaughters();
01602
01603 fNcandidates = 0;
01604 Int_t nbytes = 1+((nd-1)>>3);
01605 Int_t current_byte;
01606 Int_t current_bit;
01607 UChar_t byte;
01608 for (current_byte=0; current_byte<nbytes; current_byte++) {
01609 byte = (~fBits1[current_byte]) & (array1[current_byte] & array2[current_byte]);
01610 if (!byte) continue;
01611 for (current_bit=0; current_bit<8; current_bit++) {
01612 if (byte & (1<<current_bit)) {
01613 fCheckList[fNcandidates++] = (current_byte<<3)+current_bit;
01614 }
01615 }
01616 fBits1[current_byte] |= byte;
01617 }
01618 return (fNcandidates>0);
01619 }
01620
01621
01622 Bool_t TGeoVoxelFinder::Union(Int_t , UChar_t *array1, Int_t , UChar_t *array2, Int_t , UChar_t *array3)
01623 {
01624
01625
01626
01627 Int_t nd = fVolume->GetNdaughters();
01628
01629 fNcandidates = 0;
01630 Int_t nbytes = 1+((nd-1)>>3);
01631 Int_t current_byte;
01632 Int_t current_bit;
01633 UChar_t byte;
01634 for (current_byte=0; current_byte<nbytes; current_byte++) {
01635 byte = (~fBits1[current_byte]) & (array1[current_byte] & array2[current_byte] & array3[current_byte]);
01636 if (!byte) continue;
01637 for (current_bit=0; current_bit<8; current_bit++) {
01638 if (byte & (1<<current_bit)) {
01639 fCheckList[fNcandidates++] = (current_byte<<3)+current_bit;
01640 }
01641 }
01642 fBits1[current_byte] |= byte;
01643 }
01644 return (fNcandidates>0);
01645 }
01646
01647
01648 Bool_t TGeoVoxelFinder::Intersect(Int_t n1, UChar_t *array1, Int_t n2, UChar_t *array2, Int_t &nf, Int_t *result)
01649 {
01650
01651 Int_t nd = fVolume->GetNdaughters();
01652 nf = 0;
01653 Int_t nbytes = 1+((nd-1)>>3);
01654 Int_t current_byte;
01655 Int_t current_bit;
01656 UChar_t byte;
01657 Bool_t ibreak = kFALSE;
01658 for (current_byte=0; current_byte<nbytes; current_byte++) {
01659 byte = array1[current_byte] & array2[current_byte];
01660 if (!byte) continue;
01661 for (current_bit=0; current_bit<8; current_bit++) {
01662 if (byte & (1<<current_bit)) {
01663 result[nf++] = (current_byte<<3)+current_bit;
01664 if ((nf==n1) || (nf==n2)) {
01665 ibreak = kTRUE;
01666 break;
01667 }
01668 }
01669 }
01670 if (ibreak) return kTRUE;
01671 }
01672 return (nf>0);
01673 }
01674
01675
01676 Bool_t TGeoVoxelFinder::IntersectAndStore(Int_t , UChar_t *array1, Int_t , UChar_t *array2)
01677 {
01678
01679 Int_t nd = fVolume->GetNdaughters();
01680
01681 fNcandidates = 0;
01682 Int_t nbytes = 1+((nd-1)>>3);
01683
01684 Int_t current_byte;
01685 Int_t current_bit;
01686 Int_t icand;
01687 UChar_t byte;
01688 for (current_byte=0; current_byte<nbytes; current_byte++) {
01689 byte = array1[current_byte] & array2[current_byte];
01690 icand = current_byte<<3;
01691 fBits1[current_byte] = byte;
01692 if (!byte) continue;
01693 for (current_bit=0; current_bit<8; current_bit++) {
01694 if (byte & (1<<current_bit)) {
01695 fCheckList[fNcandidates++] = icand+current_bit;
01696 }
01697 }
01698 }
01699 return (fNcandidates>0);
01700 }
01701
01702
01703 Bool_t TGeoVoxelFinder::Intersect(Int_t n1, UChar_t *array1, Int_t n2, UChar_t *array2, Int_t n3, UChar_t *array3, Int_t &nf, Int_t *result)
01704 {
01705
01706 Int_t nd = fVolume->GetNdaughters();
01707 nf = 0;
01708 Int_t nbytes = 1+((nd-1)>>3);
01709 Int_t current_byte;
01710 Int_t current_bit;
01711 UChar_t byte;
01712 Bool_t ibreak = kFALSE;
01713 for (current_byte=0; current_byte<nbytes; current_byte++) {
01714 byte = array1[current_byte] & array2[current_byte] & array3[current_byte];
01715 if (!byte) continue;
01716 for (current_bit=0; current_bit<8; current_bit++) {
01717 if (byte & (1<<current_bit)) {
01718 result[nf++] = (current_byte<<3)+current_bit;
01719 if ((nf==n1) || (nf==n2) || (nf==n3)) {
01720 ibreak = kTRUE;
01721 break;
01722 }
01723 }
01724 }
01725 if (ibreak) return kTRUE;
01726 }
01727 return (nf>0);
01728 }
01729
01730
01731 Bool_t TGeoVoxelFinder::IntersectAndStore(Int_t , UChar_t *array1, Int_t , UChar_t *array2, Int_t , UChar_t *array3)
01732 {
01733
01734 Int_t nd = fVolume->GetNdaughters();
01735
01736 fNcandidates = 0;
01737 Int_t nbytes = 1+((nd-1)>>3);
01738
01739 Int_t current_byte;
01740 Int_t current_bit;
01741 Int_t icand;
01742 UChar_t byte;
01743 for (current_byte=0; current_byte<nbytes; current_byte++) {
01744 byte = array1[current_byte] & array2[current_byte] & array3[current_byte];
01745 icand = current_byte<<3;
01746 fBits1[current_byte] = byte;
01747 if (!byte) continue;
01748 for (current_bit=0; current_bit<8; current_bit++) {
01749 if (byte & (1<<current_bit)) {
01750 fCheckList[fNcandidates++] = icand+current_bit;
01751 }
01752 }
01753 }
01754 return (fNcandidates>0);
01755 }
01756
01757 void TGeoVoxelFinder::SortAll(Option_t *)
01758 {
01759
01760 Int_t nd = fVolume->GetNdaughters();
01761 Int_t nperslice = 1+(nd-1)/(8*sizeof(UChar_t));
01762 Int_t nmaxslices = 2*nd+1;
01763 Double_t xmin, xmax, ymin, ymax, zmin, zmax;
01764 TGeoBBox *box = (TGeoBBox*)fVolume->GetShape();
01765
01766 xmin = (box->GetOrigin())[0] - box->GetDX();
01767 xmax = (box->GetOrigin())[0] + box->GetDX();
01768 ymin = (box->GetOrigin())[1] - box->GetDY();
01769 ymax = (box->GetOrigin())[1] + box->GetDY();
01770 zmin = (box->GetOrigin())[2] - box->GetDZ();
01771 zmax = (box->GetOrigin())[2] + box->GetDZ();
01772 if ((xmin>=xmax) || (ymin>=ymax) || (zmin>=zmax)) {
01773 Error("SortAll", "Wrong bounding box for volume %s", fVolume->GetName());
01774 return;
01775 }
01776 Int_t id;
01777
01778 Double_t *boundaries = new Double_t[6*nd];
01779 for (id=0; id<nd; id++) {
01780
01781 boundaries[2*id] = fBoxes[6*id+3]-fBoxes[6*id];
01782 boundaries[2*id+1] = fBoxes[6*id+3]+fBoxes[6*id];
01783
01784 boundaries[2*id+2*nd] = fBoxes[6*id+4]-fBoxes[6*id+1];
01785 boundaries[2*id+2*nd+1] = fBoxes[6*id+4]+fBoxes[6*id+1];
01786
01787 boundaries[2*id+4*nd] = fBoxes[6*id+5]-fBoxes[6*id+2];
01788 boundaries[2*id+4*nd+1] = fBoxes[6*id+5]+fBoxes[6*id+2];
01789 }
01790 Int_t *index = new Int_t[2*nd];
01791 UChar_t *ind = new UChar_t[nmaxslices*nperslice];
01792 Int_t *extra = new Int_t[nmaxslices*4];
01793
01794
01795
01796
01797 Double_t *temp = new Double_t[2*nd];
01798 Int_t current = 0;
01799 Int_t indextra = 0;
01800 Int_t nleft, nright;
01801 Int_t *extra_left = new Int_t[nd];
01802 Int_t *extra_right = new Int_t[nd];
01803 Double_t xxmin, xxmax, xbmin, xbmax, ddx1, ddx2;
01804 UChar_t *bits;
01805 UInt_t loc, bitnumber;
01806 UChar_t bit;
01807
01808
01809 Int_t ib = 0;
01810 TMath::Sort(2*nd, &boundaries[0], &index[0], kFALSE);
01811
01812 for (id=0; id<2*nd; id++) {
01813 if (!ib) {temp[ib++] = boundaries[index[id]]; continue;}
01814 if (TMath::Abs(temp[ib-1]-boundaries[index[id]])>1E-10)
01815 temp[ib++] = boundaries[index[id]];
01816 }
01817
01818 if (ib < 2) {
01819 Error("SortAll", "Cannot voxelize %s :less than 2 boundaries on X", fVolume->GetName());
01820 delete [] boundaries;
01821 delete [] index;
01822 delete [] ind;
01823 delete [] temp;
01824 delete [] extra;
01825 delete [] extra_left;
01826 delete [] extra_right;
01827 SetInvalid();
01828 return;
01829 }
01830 if (ib == 2) {
01831
01832 if (((temp[0]-xmin)<1E-10) && ((temp[1]-xmax)>-1E-10)) {
01833
01834 fPriority[0] = 0;
01835 if (fIndcX) delete [] fIndcX;
01836 fIndcX = 0;
01837 fNx = 0;
01838 if (fXb) delete [] fXb;
01839 fXb = 0;
01840 fIbx = 0;
01841 if (fOBx) delete [] fOBx;
01842 fOBx = 0;
01843 fNox = 0;
01844 } else {
01845 fPriority[0] = 1;
01846 }
01847 } else {
01848 fPriority[0] = 2;
01849 }
01850
01851 if (fPriority[0]) {
01852 if (fXb) delete [] fXb;
01853 fXb = new Double_t[ib];
01854 memcpy(fXb, &temp[0], ib*sizeof(Double_t));
01855 fIbx = ib;
01856 }
01857
01858
01859 if (fPriority[0]==2) {
01860 memset(ind, 0, (nmaxslices*nperslice)*sizeof(UChar_t));
01861 if (fOBx) delete [] fOBx;
01862 fNox = fIbx-1;
01863 fOBx = new Int_t[fNox];
01864 if (fOEx) delete [] fOEx;
01865 fOEx = new Int_t[fNox];
01866 if (fNsliceX) delete [] fNsliceX;
01867 fNsliceX = new Int_t[fNox];
01868 current = 0;
01869 indextra = 0;
01870
01871 for (id=0; id<fNox; id++) {
01872 fOBx[id] = current;
01873 fOEx[id] = indextra;
01874 fNsliceX[id] = 0;
01875 extra[indextra] = extra[indextra+1] = 0;
01876 nleft = nright = 0;
01877 bits = &ind[current];
01878 xxmin = fXb[id];
01879 xxmax = fXb[id+1];
01880 for (Int_t ic=0; ic<nd; ic++) {
01881 xbmin = fBoxes[6*ic+3]-fBoxes[6*ic];
01882 xbmax = fBoxes[6*ic+3]+fBoxes[6*ic];
01883 ddx1 = xbmin-xxmax;
01884 if (ddx1>-1E-10) continue;
01885 ddx2 = xbmax-xxmin;
01886 if (ddx2<1E-10) continue;
01887
01888
01889 fNsliceX[id]++;
01890 bitnumber = (UInt_t)ic;
01891 loc = bitnumber/8;
01892 bit = bitnumber%8;
01893 bits[loc] |= 1<<bit;
01894
01895
01896 ddx1 = xbmin-xxmin;
01897 ddx2 = xbmax-xxmax;
01898 if ((id==0) || (ddx1>-1E-10)) {
01899 extra_left[nleft++] = ic;
01900 }
01901
01902 if ((id==(fNoz-1)) || (ddx2<1E-10)) {
01903 extra_right[nright++] = ic;
01904 }
01905 }
01906
01907 if (fNsliceX[id]>0) current += nperslice;
01908
01909 extra[indextra] = nleft;
01910 extra[indextra+1] = nright;
01911 if (nleft) memcpy(&extra[indextra+2], extra_left, nleft*sizeof(Int_t));
01912 if (nright) memcpy(&extra[indextra+2+nleft], extra_right, nright*sizeof(Int_t));
01913 indextra += 2+nleft+nright;
01914 }
01915 if (fIndcX) delete [] fIndcX;
01916 fNx = current;
01917 fIndcX = new UChar_t[current];
01918 memcpy(fIndcX, ind, current*sizeof(UChar_t));
01919 if (fExtraX) delete [] fExtraX;
01920 fNex = indextra;
01921 if (indextra>nmaxslices*4) printf("Woops!!!\n");
01922 fExtraX = new Int_t[indextra];
01923 memcpy(fExtraX, extra, indextra*sizeof(Int_t));
01924 }
01925
01926
01927 ib = 0;
01928 TMath::Sort(2*nd, &boundaries[2*nd], &index[0], kFALSE);
01929
01930 for (id=0; id<2*nd; id++) {
01931 if (!ib) {temp[ib++] = boundaries[2*nd+index[id]]; continue;}
01932 if (TMath::Abs(temp[ib-1]-boundaries[2*nd+index[id]])>1E-10)
01933 temp[ib++]=boundaries[2*nd+index[id]];
01934 }
01935
01936 if (ib < 2) {
01937 Error("SortAll", "Cannot voxelize %s :less than 2 boundaries on Y", fVolume->GetName());
01938 delete [] boundaries;
01939 delete [] index;
01940 delete [] ind;
01941 delete [] temp;
01942 delete [] extra;
01943 delete [] extra_left;
01944 delete [] extra_right;
01945 SetInvalid();
01946 return;
01947 }
01948 if (ib == 2) {
01949
01950 if (((temp[0]-ymin)<1E-10) && ((temp[1]-ymax)>-1E-10)) {
01951
01952 fPriority[1] = 0;
01953 if (fIndcY) delete [] fIndcY;
01954 fIndcY = 0;
01955 fNy = 0;
01956 if (fYb) delete [] fYb;
01957 fYb = 0;
01958 fIby = 0;
01959 if (fOBy) delete [] fOBy;
01960 fOBy = 0;
01961 fNoy = 0;
01962 } else {
01963 fPriority[1] = 1;
01964 }
01965 } else {
01966 fPriority[1] = 2;
01967 }
01968
01969
01970 if (fPriority[1]) {
01971 if (fYb) delete [] fYb;
01972 fYb = new Double_t[ib];
01973 memcpy(fYb, &temp[0], ib*sizeof(Double_t));
01974 fIby = ib;
01975 }
01976
01977
01978 if (fPriority[1]==2) {
01979
01980 memset(ind, 0, (nmaxslices*nperslice)*sizeof(UChar_t));
01981 if (fOBy) delete [] fOBy;
01982 fNoy = fIby-1;
01983 fOBy = new Int_t[fNoy];
01984 if (fOEy) delete [] fOEy;
01985 fOEy = new Int_t[fNoy];
01986 if (fNsliceY) delete [] fNsliceY;
01987 fNsliceY = new Int_t[fNoy];
01988 current = 0;
01989 indextra = 0;
01990
01991 for (id=0; id<fNoy; id++) {
01992 fOBy[id] = current;
01993 fOEy[id] = indextra;
01994 fNsliceY[id] = 0;
01995 extra[indextra] = extra[indextra+1] = 0;
01996 nleft = nright = 0;
01997 bits = &ind[current];
01998 xxmin = fYb[id];
01999 xxmax = fYb[id+1];
02000 for (Int_t ic=0; ic<nd; ic++) {
02001 xbmin = fBoxes[6*ic+4]-fBoxes[6*ic+1];
02002 xbmax = fBoxes[6*ic+4]+fBoxes[6*ic+1];
02003 ddx1 = xbmin-xxmax;
02004 if (ddx1>-1E-10) continue;
02005 ddx2 = xbmax-xxmin;
02006 if (ddx2<1E-10) continue;
02007
02008
02009 fNsliceY[id]++;
02010 bitnumber = (UInt_t)ic;
02011 loc = bitnumber/8;
02012 bit = bitnumber%8;
02013 bits[loc] |= 1<<bit;
02014
02015
02016 ddx1 = xbmin-xxmin;
02017 ddx2 = xbmax-xxmax;
02018 if ((id==0) || (ddx1>-1E-10)) {
02019 extra_left[nleft++] = ic;
02020 }
02021
02022 if ((id==(fNoz-1)) || (ddx2<1E-10)) {
02023 extra_right[nright++] = ic;
02024 }
02025 }
02026
02027 if (fNsliceY[id]>0) current += nperslice;
02028
02029 extra[indextra] = nleft;
02030 extra[indextra+1] = nright;
02031 if (nleft) memcpy(&extra[indextra+2], extra_left, nleft*sizeof(Int_t));
02032 if (nright) memcpy(&extra[indextra+2+nleft], extra_right, nright*sizeof(Int_t));
02033 indextra += 2+nleft+nright;
02034 }
02035 if (fIndcY) delete [] fIndcY;
02036 fNy = current;
02037 fIndcY = new UChar_t[current];
02038 memcpy(fIndcY, &ind[0], current*sizeof(UChar_t));
02039 if (fExtraY) delete [] fExtraY;
02040 fNey = indextra;
02041 if (indextra>nmaxslices*4) printf("Woops!!!\n");
02042 fExtraY = new Int_t[indextra];
02043 memcpy(fExtraY, extra, indextra*sizeof(Int_t));
02044 }
02045
02046
02047 ib = 0;
02048 TMath::Sort(2*nd, &boundaries[4*nd], &index[0], kFALSE);
02049
02050 for (id=0; id<2*nd; id++) {
02051 if (!ib) {temp[ib++] = boundaries[4*nd+index[id]]; continue;}
02052 if ((TMath::Abs(temp[ib-1]-boundaries[4*nd+index[id]]))>1E-10)
02053 temp[ib++]=boundaries[4*nd+index[id]];
02054 }
02055
02056 if (ib < 2) {
02057 Error("SortAll", "Cannot voxelize %s :less than 2 boundaries on Z", fVolume->GetName());
02058 delete [] boundaries;
02059 delete [] index;
02060 delete [] ind;
02061 delete [] temp;
02062 delete [] extra;
02063 delete [] extra_left;
02064 delete [] extra_right;
02065 SetInvalid();
02066 return;
02067 }
02068 if (ib == 2) {
02069
02070 if (((temp[0]-zmin)<1E-10) && ((temp[1]-zmax)>-1E-10)) {
02071
02072 fPriority[2] = 0;
02073 if (fIndcZ) delete [] fIndcZ;
02074 fIndcZ = 0;
02075 fNz = 0;
02076 if (fZb) delete [] fZb;
02077 fZb = 0;
02078 fIbz = 0;
02079 if (fOBz) delete [] fOBz;
02080 fOBz = 0;
02081 fNoz = 0;
02082 } else {
02083 fPriority[2] = 1;
02084 }
02085 } else {
02086 fPriority[2] = 2;
02087 }
02088
02089
02090 if (fPriority[2]) {
02091 if (fZb) delete [] fZb;
02092 fZb = new Double_t[ib];
02093 memcpy(fZb, &temp[0], ib*sizeof(Double_t));
02094 fIbz = ib;
02095 }
02096
02097
02098 if (fPriority[2]==2) {
02099
02100 memset(ind, 0, (nmaxslices*nperslice)*sizeof(UChar_t));
02101 if (fOBz) delete [] fOBz;
02102 fNoz = fIbz-1;
02103 fOBz = new Int_t[fNoz];
02104 if (fOEz) delete [] fOEz;
02105 fOEz = new Int_t[fNoz];
02106 if (fNsliceZ) delete [] fNsliceZ;
02107 fNsliceZ = new Int_t[fNoz];
02108 current = 0;
02109 indextra = 0;
02110
02111 for (id=0; id<fNoz; id++) {
02112 fOBz[id] = current;
02113 fOEz[id] = indextra;
02114 fNsliceZ[id] = 0;
02115 extra[indextra] = extra[indextra+1] = 0;
02116 nleft = nright = 0;
02117 bits = &ind[current];
02118 xxmin = fZb[id];
02119 xxmax = fZb[id+1];
02120 for (Int_t ic=0; ic<nd; ic++) {
02121 xbmin = fBoxes[6*ic+5]-fBoxes[6*ic+2];
02122 xbmax = fBoxes[6*ic+5]+fBoxes[6*ic+2];
02123 ddx1 = xbmin-xxmax;
02124 if (ddx1>-1E-10) continue;
02125 ddx2 = xbmax-xxmin;
02126 if (ddx2<1E-10) continue;
02127
02128
02129 fNsliceZ[id]++;
02130 bitnumber = (UInt_t)ic;
02131 loc = bitnumber/8;
02132 bit = bitnumber%8;
02133 bits[loc] |= 1<<bit;
02134
02135
02136 ddx1 = xbmin-xxmin;
02137 ddx2 = xbmax-xxmax;
02138 if ((id==0) || (ddx1>-1E-10)) {
02139 extra_left[nleft++] = ic;
02140 }
02141
02142 if ((id==(fNoz-1)) || (ddx2<1E-10)) {
02143 extra_right[nright++] = ic;
02144 }
02145 }
02146
02147 if (fNsliceZ[id]>0) current += nperslice;
02148
02149 extra[indextra] = nleft;
02150 extra[indextra+1] = nright;
02151 if (nleft) memcpy(&extra[indextra+2], extra_left, nleft*sizeof(Int_t));
02152 if (nright) memcpy(&extra[indextra+2+nleft], extra_right, nright*sizeof(Int_t));
02153 indextra += 2+nleft+nright;
02154 }
02155 if (fIndcZ) delete [] fIndcZ;
02156 fNz = current;
02157 fIndcZ = new UChar_t[current];
02158 memcpy(fIndcZ, &ind[0], current*sizeof(UChar_t));
02159 if (fExtraZ) delete [] fExtraZ;
02160 fNez = indextra;
02161 if (indextra>nmaxslices*4) printf("Woops!!!\n");
02162 fExtraZ = new Int_t[indextra];
02163 memcpy(fExtraZ, extra, indextra*sizeof(Int_t));
02164 }
02165 delete [] boundaries;
02166 delete [] index;
02167 delete [] temp;
02168 delete [] ind;
02169 delete [] extra;
02170 delete [] extra_left;
02171 delete [] extra_right;
02172
02173 if ((!fPriority[0]) && (!fPriority[1]) && (!fPriority[2])) {
02174 SetInvalid();
02175 if (nd>1) Error("SortAll", "Volume %s: Cannot make slices on any axis", fVolume->GetName());
02176 }
02177 }
02178
02179
02180 void TGeoVoxelFinder::Print(Option_t *) const
02181 {
02182
02183 if (NeedRebuild()) {
02184 TGeoVoxelFinder *vox = (TGeoVoxelFinder*)this;
02185 vox->Voxelize();
02186 fVolume->FindOverlaps();
02187 }
02188 Int_t id, i;
02189 Int_t nd = fVolume->GetNdaughters();
02190 printf("Voxels for volume %s (nd=%i)\n", fVolume->GetName(), fVolume->GetNdaughters());
02191 printf("priority : x=%i y=%i z=%i\n", fPriority[0], fPriority[1], fPriority[2]);
02192
02193 Int_t nextra;
02194 Int_t nbytes = 1+((fVolume->GetNdaughters()-1)>>3);
02195 UChar_t byte, bit;
02196 UChar_t *slice;
02197 printf("XXX\n");
02198 if (fPriority[0]==2) {
02199 for (id=0; id<fIbx; id++) {
02200 printf("%15.10f\n",fXb[id]);
02201 if (id == (fIbx-1)) break;
02202 printf("slice %i : %i\n", id, fNsliceX[id]);
02203 if (fNsliceX[id]) {
02204 slice = &fIndcX[fOBx[id]];
02205 for (i=0; i<nbytes; i++) {
02206 byte = slice[i];
02207 for (bit=0; bit<8; bit++) {
02208 if (byte & (1<<bit)) printf(" %i ", 8*i+bit);
02209 }
02210 }
02211 printf("\n");
02212 }
02213 GetExtraX(id,kTRUE,nextra);
02214 printf(" extra_about_left = %i\n", nextra);
02215 GetExtraX(id,kFALSE,nextra);
02216 printf(" extra_about_right = %i\n", nextra);
02217 }
02218 } else if (fPriority[0]==1) {
02219 printf("%15.10f\n",fXb[0]);
02220 for (id=0; id<nd; id++) printf(" %i ",id);
02221 printf("\n");
02222 printf("%15.10f\n",fXb[1]);
02223 }
02224 printf("YYY\n");
02225 if (fPriority[1]==2) {
02226 for (id=0; id<fIby; id++) {
02227 printf("%15.10f\n", fYb[id]);
02228 if (id == (fIby-1)) break;
02229 printf("slice %i : %i\n", id, fNsliceY[id]);
02230 if (fNsliceY[id]) {
02231 slice = &fIndcY[fOBy[id]];
02232 for (i=0; i<nbytes; i++) {
02233 byte = slice[i];
02234 for (bit=0; bit<8; bit++) {
02235 if (byte & (1<<bit)) printf(" %i ", 8*i+bit);
02236 }
02237 }
02238 }
02239 GetExtraY(id,kTRUE,nextra);
02240 printf(" extra_about_left = %i\n", nextra);
02241 GetExtraY(id,kFALSE,nextra);
02242 printf(" extra_about_right = %i\n", nextra);
02243 }
02244 } else if (fPriority[1]==1) {
02245 printf("%15.10f\n",fYb[0]);
02246 for (id=0; id<nd; id++) printf(" %i ",id);
02247 printf("\n");
02248 printf("%15.10f\n",fYb[1]);
02249 }
02250
02251 printf("ZZZ\n");
02252 if (fPriority[2]==2) {
02253 for (id=0; id<fIbz; id++) {
02254 printf("%15.10f\n", fZb[id]);
02255 if (id == (fIbz-1)) break;
02256 printf("slice %i : %i\n", id, fNsliceZ[id]);
02257 if (fNsliceZ[id]) {
02258 slice = &fIndcZ[fOBz[id]];
02259 for (i=0; i<nbytes; i++) {
02260 byte = slice[i];
02261 for (bit=0; bit<8; bit++) {
02262 if (byte & (1<<bit)) printf(" %i ", 8*i+bit);
02263 }
02264 }
02265 printf("\n");
02266 }
02267 GetExtraZ(id,kTRUE,nextra);
02268 printf(" extra_about_left = %i\n", nextra);
02269 GetExtraZ(id,kFALSE,nextra);
02270 printf(" extra_about_right = %i\n", nextra);
02271 }
02272 } else if (fPriority[2]==1) {
02273 printf("%15.10f\n",fZb[0]);
02274 for (id=0; id<nd; id++) printf(" %i ",id);
02275 printf("\n");
02276 printf("%15.10f\n",fZb[1]);
02277 }
02278 }
02279
02280
02281 void TGeoVoxelFinder::PrintVoxelLimits(Double_t *point) const
02282 {
02283
02284 if (NeedRebuild()) {
02285 TGeoVoxelFinder *vox = (TGeoVoxelFinder*)this;
02286 vox->Voxelize();
02287 fVolume->FindOverlaps();
02288 }
02289 Int_t im=0;
02290 if (fPriority[0]) {
02291 im = TMath::BinarySearch(fIbx, fXb, point[0]);
02292 if ((im==-1) || (im==fIbx-1)) {
02293 printf("Voxel X limits: OUT\n");
02294 } else {
02295 printf("Voxel X limits: %g %g\n", fXb[im], fXb[im+1]);
02296 }
02297 }
02298 if (fPriority[1]) {
02299 im = TMath::BinarySearch(fIby, fYb, point[1]);
02300 if ((im==-1) || (im==fIby-1)) {
02301 printf("Voxel Y limits: OUT\n");
02302 } else {
02303 printf("Voxel Y limits: %g %g\n", fYb[im], fYb[im+1]);
02304 }
02305 }
02306 if (fPriority[2]) {
02307 im = TMath::BinarySearch(fIbz, fZb, point[2]);
02308 if ((im==-1) || (im==fIbz-1)) {
02309 printf("Voxel Z limits: OUT\n");
02310 } else {
02311 printf("Voxel Z limits: %g %g\n", fZb[im], fZb[im+1]);
02312 }
02313 }
02314 }
02315
02316 void TGeoVoxelFinder::Voxelize(Option_t * )
02317 {
02318
02319
02320 if (fVolume->IsAssembly()) fVolume->GetShape()->ComputeBBox();
02321 Int_t nd = fVolume->GetNdaughters();
02322 TGeoVolume *vd;
02323 for (Int_t i=0; i<nd; i++) {
02324 vd = fVolume->GetNode(i)->GetVolume();
02325 if (vd->IsAssembly()) vd->GetShape()->ComputeBBox();
02326 }
02327 BuildVoxelLimits();
02328 SortAll();
02329 SetNeedRebuild(kFALSE);
02330 }
02331
02332 void TGeoVoxelFinder::Streamer(TBuffer &R__b)
02333 {
02334
02335 if (R__b.IsReading()) {
02336 UInt_t R__s, R__c;
02337 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
02338 if (R__v > 2) {
02339 R__b.ReadClassBuffer(TGeoVoxelFinder::Class(), this, R__v, R__s, R__c);
02340 return;
02341 }
02342
02343
02344 UChar_t *dummy = new UChar_t[R__c-2];
02345 R__b.ReadFastArray(dummy, R__c-2);
02346 delete [] dummy;
02347 SetInvalid(kTRUE);
02348 } else {
02349 R__b.WriteClassBuffer(TGeoVoxelFinder::Class(), this);
02350 }
02351 }