35 ClassImp(TGeoVoxelFinder);
40 TGeoVoxelFinder::TGeoVoxelFinder()
75 memset(fPriority, 0, 3*
sizeof(Int_t));
81 TGeoVoxelFinder::TGeoVoxelFinder(TGeoVolume *vol)
84 Fatal(
"TGeoVoxelFinder",
"Null pointer for volume");
88 fVolume->SetCylVoxels(kFALSE);
121 memset(fPriority, 0, 3*
sizeof(Int_t));
128 TGeoVoxelFinder::~TGeoVoxelFinder()
130 if (fOBx)
delete [] fOBx;
131 if (fOBy)
delete [] fOBy;
132 if (fOBz)
delete [] fOBz;
133 if (fOEx)
delete [] fOEx;
134 if (fOEy)
delete [] fOEy;
135 if (fOEz)
delete [] fOEz;
137 if (fBoxes)
delete [] fBoxes;
139 if (fXb)
delete [] fXb;
140 if (fYb)
delete [] fYb;
141 if (fZb)
delete [] fZb;
143 if (fNsliceX)
delete [] fNsliceX;
144 if (fNsliceY)
delete [] fNsliceY;
145 if (fNsliceZ)
delete [] fNsliceZ;
146 if (fIndcX)
delete [] fIndcX;
147 if (fIndcY)
delete [] fIndcY;
148 if (fIndcZ)
delete [] fIndcZ;
149 if (fExtraX)
delete [] fExtraX;
150 if (fExtraY)
delete [] fExtraY;
151 if (fExtraZ)
delete [] fExtraZ;
157 Int_t TGeoVoxelFinder::GetNcandidates(TGeoStateInfo &td)
const
159 return td.fVoxNcandidates;
164 Int_t* TGeoVoxelFinder::GetCheckList(Int_t &nelem, TGeoStateInfo &td)
const
166 nelem = td.fVoxNcandidates;
167 return td.fVoxCheckList;
173 void TGeoVoxelFinder::BuildVoxelLimits()
175 Int_t nd = fVolume->GetNdaughters();
179 if (fBoxes)
delete [] fBoxes;
181 fBoxes =
new Double_t[fNboxes];
182 Double_t vert[24] = {0};
183 Double_t pt[3] = {0};
184 Double_t xyz[6] = {0};
187 for (
id=0;
id<nd;
id++) {
188 node = fVolume->GetNode(
id);
190 box = (TGeoBBox*)node->GetVolume()->GetShape();
191 box->SetBoxPoints(&vert[0]);
192 for (Int_t point=0; point<8; point++) {
193 DaughterToMother(
id, &vert[3*point], &pt[0]);
195 xyz[0] = xyz[1] = pt[0];
196 xyz[2] = xyz[3] = pt[1];
197 xyz[4] = xyz[5] = pt[2];
200 for (Int_t j=0; j<3; j++) {
201 if (pt[j] < xyz[2*j]) xyz[2*j]=pt[j];
202 if (pt[j] > xyz[2*j+1]) xyz[2*j+1]=pt[j];
205 fBoxes[6*id] = 0.5*(xyz[1]-xyz[0]);
206 fBoxes[6*
id+1] = 0.5*(xyz[3]-xyz[2]);
207 fBoxes[6*
id+2] = 0.5*(xyz[5]-xyz[4]);
208 fBoxes[6*
id+3] = 0.5*(xyz[0]+xyz[1]);
209 fBoxes[6*
id+4] = 0.5*(xyz[2]+xyz[3]);
210 fBoxes[6*
id+5] = 0.5*(xyz[4]+xyz[5]);
218 void TGeoVoxelFinder::DaughterToMother(Int_t
id,
const Double_t *local, Double_t *master)
const
220 TGeoMatrix *mat = fVolume->GetNode(
id)->GetMatrix();
221 if (!mat) memcpy(master,local,3*
sizeof(Double_t));
222 else mat->LocalToMaster(local, master);
228 Bool_t TGeoVoxelFinder::IsSafeVoxel(
const Double_t *point, Int_t inode, Double_t minsafe)
const
231 TGeoVoxelFinder *vox = (TGeoVoxelFinder*)
this;
233 fVolume->FindOverlaps();
235 Double_t dxyz, minsafe2=minsafe*minsafe;
239 for (i=0; i<3; i++) {
240 dxyz = TMath::Abs(point[i]-fBoxes[ist+i+3])-fBoxes[ist+i];
241 if (dxyz>-1E-6) rsq+=dxyz*dxyz;
242 if (rsq > minsafe2*(1.+TGeoShape::Tolerance()))
return kTRUE;
250 Double_t TGeoVoxelFinder::Efficiency()
252 printf(
"Voxelization efficiency for %s\n", fVolume->GetName());
255 fVolume->FindOverlaps();
257 Double_t nd = Double_t(fVolume->GetNdaughters());
259 Double_t effslice = 0;
262 for (
id=0;
id<fIbx-1;
id++) {
263 effslice += fNsliceX[id];
265 if (!TGeoShape::IsSameWithinTolerance(effslice,0)) effslice = nd/effslice;
266 else printf(
"Woops : slice X\n");
268 printf(
"X efficiency : %g\n", effslice);
272 for (
id=0;
id<fIby-1;
id++) {
273 effslice += fNsliceY[id];
275 if (!TGeoShape::IsSameWithinTolerance(effslice,0)) effslice = nd/effslice;
276 else printf(
"Woops : slice X\n");
278 printf(
"Y efficiency : %g\n", effslice);
282 for (
id=0;
id<fIbz-1;
id++) {
283 effslice += fNsliceZ[id];
285 if (!TGeoShape::IsSameWithinTolerance(effslice,0)) effslice = nd/effslice;
286 else printf(
"Woops : slice X\n");
288 printf(
"Z efficiency : %g\n", effslice);
291 printf(
"Total efficiency : %g\n", eff);
297 void TGeoVoxelFinder::FindOverlaps(Int_t inode)
const
300 Double_t xmin, xmax, ymin, ymax, zmin, zmax;
301 Double_t xmin1, xmax1, ymin1, ymax1, zmin1, zmax1;
303 Int_t nd = fVolume->GetNdaughters();
305 Int_t *otmp =
new Int_t[nd-1];
307 TGeoNode *node = fVolume->GetNode(inode);
308 xmin = fBoxes[6*inode+3] - fBoxes[6*inode];
309 xmax = fBoxes[6*inode+3] + fBoxes[6*inode];
310 ymin = fBoxes[6*inode+4] - fBoxes[6*inode+1];
311 ymax = fBoxes[6*inode+4] + fBoxes[6*inode+1];
312 zmin = fBoxes[6*inode+5] - fBoxes[6*inode+2];
313 zmax = fBoxes[6*inode+5] + fBoxes[6*inode+2];
315 for (Int_t ib=0; ib<nd; ib++) {
316 if (ib == inode)
continue;
317 xmin1 = fBoxes[6*ib+3] - fBoxes[6*ib];
318 xmax1 = fBoxes[6*ib+3] + fBoxes[6*ib];
319 ymin1 = fBoxes[6*ib+4] - fBoxes[6*ib+1];
320 ymax1 = fBoxes[6*ib+4] + fBoxes[6*ib+1];
321 zmin1 = fBoxes[6*ib+5] - fBoxes[6*ib+2];
322 zmax1 = fBoxes[6*ib+5] + fBoxes[6*ib+2];
326 if (ddx1*ddx2 <= 0.)
continue;
329 if (ddx1*ddx2 <= 0.)
continue;
332 if (ddx1*ddx2 <= 0.)
continue;
337 node->SetOverlaps(ovlps, 0);
340 ovlps =
new Int_t[novlp];
341 memcpy(ovlps, otmp, novlp*
sizeof(Int_t));
343 node->SetOverlaps(ovlps, novlp);
349 Bool_t TGeoVoxelFinder::GetIndices(
const Double_t *point, TGeoStateInfo &td)
351 td.fVoxSlices[0] = -2;
352 td.fVoxSlices[1] = -2;
353 td.fVoxSlices[2] = -2;
356 td.fVoxSlices[0] = TMath::BinarySearch(fIbx, fXb, point[0]);
357 if ((td.fVoxSlices[0]<0) || (td.fVoxSlices[0]>=fIbx-1)) {
361 if (fPriority[0]==2) {
363 if (!fNsliceX[td.fVoxSlices[0]]) flag = kFALSE;
368 td.fVoxSlices[1] = TMath::BinarySearch(fIby, fYb, point[1]);
369 if ((td.fVoxSlices[1]<0) || (td.fVoxSlices[1]>=fIby-1)) {
373 if (fPriority[1]==2) {
375 if (!fNsliceY[td.fVoxSlices[1]]) flag = kFALSE;
380 td.fVoxSlices[2] = TMath::BinarySearch(fIbz, fZb, point[2]);
381 if ((td.fVoxSlices[2]<0) || (td.fVoxSlices[2]>=fIbz-1))
return kFALSE;
382 if (fPriority[2]==2) {
384 if (!fNsliceZ[td.fVoxSlices[2]])
return kFALSE;
394 Int_t *TGeoVoxelFinder::GetExtraX(Int_t islice, Bool_t left, Int_t &nextra)
const
398 if (fPriority[0]!=2)
return list;
400 nextra = fExtraX[fOEx[islice]];
401 list = &fExtraX[fOEx[islice]+2];
403 nextra = fExtraX[fOEx[islice]+1];
404 list = &fExtraX[fOEx[islice]+2+fExtraX[fOEx[islice]]];
413 Int_t *TGeoVoxelFinder::GetExtraY(Int_t islice, Bool_t left, Int_t &nextra)
const
417 if (fPriority[1]!=2)
return list;
419 nextra = fExtraY[fOEy[islice]];
420 list = &fExtraY[fOEy[islice]+2];
422 nextra = fExtraY[fOEy[islice]+1];
423 list = &fExtraY[fOEy[islice]+2+fExtraY[fOEy[islice]]];
432 Int_t *TGeoVoxelFinder::GetExtraZ(Int_t islice, Bool_t left, Int_t &nextra)
const
436 if (fPriority[2]!=2)
return list;
438 nextra = fExtraZ[fOEz[islice]];
439 list = &fExtraZ[fOEz[islice]+2];
441 nextra = fExtraZ[fOEz[islice]+1];
442 list = &fExtraZ[fOEz[islice]+2+fExtraZ[fOEz[islice]]];
450 Int_t *TGeoVoxelFinder::GetValidExtra(Int_t *list, Int_t &ncheck, TGeoStateInfo &td)
452 td.fVoxNcandidates = 0;
454 UInt_t bitnumber, loc;
456 for (icand=0; icand<ncheck; icand++) {
457 bitnumber = (UInt_t)list[icand];
460 byte = (~td.fVoxBits1[loc]) & (1<<bit);
461 if (byte) td.fVoxCheckList[td.fVoxNcandidates++]=list[icand];
463 ncheck = td.fVoxNcandidates;
464 return td.fVoxCheckList;
470 Int_t *TGeoVoxelFinder::GetValidExtra(Int_t , UChar_t *array1, Int_t *list, Int_t &ncheck, TGeoStateInfo &td)
472 td.fVoxNcandidates = 0;
474 UInt_t bitnumber, loc;
476 for (icand=0; icand<ncheck; icand++) {
477 bitnumber = (UInt_t)list[icand];
480 byte = (~td.fVoxBits1[loc]) & array1[loc] & (1<<bit);
481 if (byte) td.fVoxCheckList[td.fVoxNcandidates++]=list[icand];
483 ncheck = td.fVoxNcandidates;
484 return td.fVoxCheckList;
490 Int_t *TGeoVoxelFinder::GetValidExtra(Int_t , UChar_t *array1, Int_t , UChar_t *array2, Int_t *list, Int_t &ncheck, TGeoStateInfo &td)
492 td.fVoxNcandidates = 0;
494 UInt_t bitnumber, loc;
496 for (icand=0; icand<ncheck; icand++) {
497 bitnumber = (UInt_t)list[icand];
500 byte = (~td.fVoxBits1[loc]) & array1[loc] & array2[loc] & (1<<bit);
501 if (byte) td.fVoxCheckList[td.fVoxNcandidates++]=list[icand];
503 ncheck = td.fVoxNcandidates;
504 return td.fVoxCheckList;
511 Int_t *TGeoVoxelFinder::GetNextCandidates(
const Double_t *point, Int_t &ncheck, TGeoStateInfo &td)
515 fVolume->FindOverlaps();
518 if (td.fVoxLimits[0]<0)
return 0;
519 if (td.fVoxLimits[1]<0)
return 0;
520 if (td.fVoxLimits[2]<0)
return 0;
523 memcpy(&dind[0], &td.fVoxSlices[0], 3*
sizeof(Int_t));
525 dmin[0] = dmin[1] = dmin[2] = TGeoShape::Big();
527 Double_t maxstep = TMath::Min(gGeoManager->GetStep(), td.fVoxLimits[TMath::LocMin(3, td.fVoxLimits)]);
529 Bool_t isXlimit=kFALSE, isYlimit=kFALSE, isZlimit=kFALSE;
530 Bool_t isForcedX=kFALSE, isForcedY=kFALSE, isForcedZ=kFALSE;
532 dforced[0] = dforced[1] = dforced[2] = TGeoShape::Big();
536 if (fPriority[0] && td.fVoxInc[0]) {
538 dind[0] += td.fVoxInc[0];
539 if (td.fVoxInc[0]==1) {
540 if (dind[0]<0 || dind[0]>fIbx-1)
return 0;
541 dmin[0] = (fXb[dind[0]]-point[0])*td.fVoxInvdir[0];
543 if (td.fVoxSlices[0]<0 || td.fVoxSlices[0]>fIbx-1)
return 0;
544 dmin[0] = (fXb[td.fVoxSlices[0]]-point[0])*td.fVoxInvdir[0];
546 isXlimit = (dmin[0]>maxstep)?kTRUE:kFALSE;
551 if ((td.fVoxSlices[0]==-1) || (td.fVoxSlices[0]==fIbx-1)) {
553 dforced[0] = dmin[0];
556 if (isXlimit)
return 0;
558 if (fPriority[0]==2) {
560 if (fNsliceX[td.fVoxSlices[0]]==0) {
562 dforced[0] = dmin[0];
565 if (isXlimit)
return 0;
572 dmin[0] = td.fVoxLimits[0];
576 if (fPriority[1] && td.fVoxInc[1]) {
578 dind[1] += td.fVoxInc[1];
579 if (td.fVoxInc[1]==1) {
580 if (dind[1]<0 || dind[1]>fIby-1)
return 0;
581 dmin[1] = (fYb[dind[1]]-point[1])*td.fVoxInvdir[1];
583 if (td.fVoxSlices[1]<0 || td.fVoxSlices[1]>fIby-1)
return 0;
584 dmin[1] = (fYb[td.fVoxSlices[1]]-point[1])*td.fVoxInvdir[1];
586 isYlimit = (dmin[1]>maxstep)?kTRUE:kFALSE;
592 if ((td.fVoxSlices[1]==-1) || (td.fVoxSlices[1]==fIby-1)) {
594 dforced[1] = dmin[1];
597 if (isYlimit)
return 0;
599 if (fPriority[1]==2) {
601 if (fNsliceY[td.fVoxSlices[1]]==0) {
603 dforced[1] = dmin[1];
606 if (isYlimit)
return 0;
613 dmin[1] = td.fVoxLimits[1];
617 if (fPriority[2] && td.fVoxInc[2]) {
619 dind[2] += td.fVoxInc[2];
620 if (td.fVoxInc[2]==1) {
621 if (dind[2]<0 || dind[2]>fIbz-1)
return 0;
622 dmin[2] = (fZb[dind[2]]-point[2])*td.fVoxInvdir[2];
624 if (td.fVoxSlices[2]<0 || td.fVoxSlices[2]>fIbz-1)
return 0;
625 dmin[2] = (fZb[td.fVoxSlices[2]]-point[2])*td.fVoxInvdir[2];
627 isZlimit = (dmin[2]>maxstep)?kTRUE:kFALSE;
633 if ((td.fVoxSlices[2]==-1) || (td.fVoxSlices[2]==fIbz-1)) {
635 dforced[2] = dmin[2];
638 if (isZlimit)
return 0;
640 if (fPriority[2]==2) {
642 if (fNsliceZ[td.fVoxSlices[2]]==0) {
644 dforced[2] = dmin[2];
647 if (isZlimit)
return 0;
654 dmin[2] = td.fVoxLimits[2];
670 if (dforced[1]>dslice) {
676 if (dforced[2]>dslice) {
685 if (dforced[2]>dslice) {
698 if (dforced[2]>dslice) {
711 islice = TMath::LocMin(3, dmin);
712 dslice = dmin[islice];
713 if (dslice>=maxstep) {
723 Int_t ndd[2] = {0,0};
728 if (isXlimit)
return 0;
730 td.fVoxSlices[0]=dind[0];
733 if (dslice>td.fVoxLimits[1])
return 0;
734 if (dslice>td.fVoxLimits[2])
return 0;
735 if ((dslice>dmin[1]) && td.fVoxInc[1]) {
736 xptnew = point[1]+dslice/td.fVoxInvdir[1];
739 td.fVoxSlices[1] += td.fVoxInc[1];
740 if (td.fVoxInc[1]==1) {
741 if (td.fVoxSlices[1]<-1 || td.fVoxSlices[1]>fIby-2)
break;
742 if (fYb[td.fVoxSlices[1]+1]>=xptnew)
break;
744 if (td.fVoxSlices[1]<0 || td.fVoxSlices[1]>fIby-1)
break;
745 if (fYb[td.fVoxSlices[1]]<= xptnew)
break;
750 if ((dslice>dmin[2]) && td.fVoxInc[2]) {
751 xptnew = point[2]+dslice/td.fVoxInvdir[2];
754 td.fVoxSlices[2] += td.fVoxInc[2];
755 if (td.fVoxInc[2]==1) {
756 if (td.fVoxSlices[2]<-1 || td.fVoxSlices[2]>fIbz-2)
break;
757 if (fZb[td.fVoxSlices[2]+1]>=xptnew)
break;
759 if (td.fVoxSlices[2]<0 || td.fVoxSlices[2]>fIbz-1)
break;
760 if (fZb[td.fVoxSlices[2]]<= xptnew)
break;
767 if (fPriority[0]==1) {
770 if (fPriority[1]==2) {
771 if (td.fVoxSlices[1]<0 || td.fVoxSlices[1]>=fIby-1)
return td.fVoxCheckList;
772 ndd[0] = fNsliceY[td.fVoxSlices[1]];
773 if (!ndd[0])
return td.fVoxCheckList;
774 slice1 = &fIndcY[fOBy[td.fVoxSlices[1]]];
777 if (fPriority[2]==2) {
778 if (td.fVoxSlices[2]<0 || td.fVoxSlices[2]>=fIbz-1)
return td.fVoxCheckList;
779 ndd[1] = fNsliceZ[td.fVoxSlices[2]];
780 if (!ndd[1])
return td.fVoxCheckList;
783 slice2 = &fIndcZ[fOBz[td.fVoxSlices[2]]];
785 slice1 = &fIndcZ[fOBz[td.fVoxSlices[2]]];
790 IntersectAndStore(ndd[0], slice1, td);
792 IntersectAndStore(ndd[0], slice1, ndd[1], slice2, td);
794 ncheck = td.fVoxNcandidates;
795 return td.fVoxCheckList;
798 left = (td.fVoxInc[0]>0)?kTRUE:kFALSE;
799 new_list = GetExtraX(td.fVoxSlices[0], left, ncheck);
801 if (!ncheck)
return td.fVoxCheckList;
802 if (fPriority[1]==2) {
803 if (td.fVoxSlices[1]<0 || td.fVoxSlices[1]>=fIby-1) {
805 return td.fVoxCheckList;
807 ndd[0] = fNsliceY[td.fVoxSlices[1]];
810 return td.fVoxCheckList;
812 slice1 = &fIndcY[fOBy[td.fVoxSlices[1]]];
815 if (fPriority[2]==2) {
816 if (td.fVoxSlices[2]<0 || td.fVoxSlices[2]>=fIbz-1) {
818 return td.fVoxCheckList;
820 ndd[1] = fNsliceZ[td.fVoxSlices[2]];
823 return td.fVoxCheckList;
827 slice2 = &fIndcZ[fOBz[td.fVoxSlices[2]]];
829 slice1 = &fIndcZ[fOBz[td.fVoxSlices[2]]];
833 if (!islices)
return GetValidExtra(new_list, ncheck, td);
835 return GetValidExtra(ndd[0], slice1, new_list, ncheck,td);
837 return GetValidExtra(ndd[0], slice1, ndd[1], slice2, new_list, ncheck, td);
840 if (isYlimit)
return 0;
842 td.fVoxSlices[1]=dind[1];
845 if (dslice>td.fVoxLimits[0])
return 0;
846 if (dslice>td.fVoxLimits[2])
return 0;
847 if ((dslice>dmin[0]) && td.fVoxInc[0]) {
848 xptnew = point[0]+dslice/td.fVoxInvdir[0];
851 td.fVoxSlices[0] += td.fVoxInc[0];
852 if (td.fVoxInc[0]==1) {
853 if (td.fVoxSlices[0]<-1 || td.fVoxSlices[0]>fIbx-2)
break;
854 if (fXb[td.fVoxSlices[0]+1]>=xptnew)
break;
856 if (td.fVoxSlices[0]<0 || td.fVoxSlices[0]>fIbx-1)
break;
857 if (fXb[td.fVoxSlices[0]]<= xptnew)
break;
862 if ((dslice>dmin[2]) && td.fVoxInc[2]) {
863 xptnew = point[2]+dslice/td.fVoxInvdir[2];
866 td.fVoxSlices[2] += td.fVoxInc[2];
867 if (td.fVoxInc[2]==1) {
868 if (td.fVoxSlices[2]<-1 || td.fVoxSlices[2]>fIbz-2)
break;
869 if (fZb[td.fVoxSlices[2]+1]>=xptnew)
break;
871 if (td.fVoxSlices[2]<0 || td.fVoxSlices[2]>fIbz-1)
break;
872 if (fZb[td.fVoxSlices[2]]<= xptnew)
break;
879 if (fPriority[1]==1) {
882 if (fPriority[0]==2) {
883 if (td.fVoxSlices[0]<0 || td.fVoxSlices[0]>=fIbx-1)
return td.fVoxCheckList;
884 ndd[0] = fNsliceX[td.fVoxSlices[0]];
885 if (!ndd[0])
return td.fVoxCheckList;
886 slice1 = &fIndcX[fOBx[td.fVoxSlices[0]]];
889 if (fPriority[2]==2) {
890 if (td.fVoxSlices[2]<0 || td.fVoxSlices[2]>=fIbz-1)
return td.fVoxCheckList;
891 ndd[1] = fNsliceZ[td.fVoxSlices[2]];
892 if (!ndd[1])
return td.fVoxCheckList;
895 slice2 = &fIndcZ[fOBz[td.fVoxSlices[2]]];
897 slice1 = &fIndcZ[fOBz[td.fVoxSlices[2]]];
902 IntersectAndStore(ndd[0], slice1, td);
904 IntersectAndStore(ndd[0], slice1, ndd[1], slice2, td);
906 ncheck = td.fVoxNcandidates;
907 return td.fVoxCheckList;
910 left = (td.fVoxInc[1]>0)?kTRUE:kFALSE;
911 new_list = GetExtraY(td.fVoxSlices[1], left, ncheck);
913 if (!ncheck)
return td.fVoxCheckList;
914 if (fPriority[0]==2) {
915 if (td.fVoxSlices[0]<0 || td.fVoxSlices[0]>=fIbx-1) {
917 return td.fVoxCheckList;
919 ndd[0] = fNsliceX[td.fVoxSlices[0]];
922 return td.fVoxCheckList;
924 slice1 = &fIndcX[fOBx[td.fVoxSlices[0]]];
927 if (fPriority[2]==2) {
928 if (td.fVoxSlices[2]<0 || td.fVoxSlices[2]>=fIbz-1) {
930 return td.fVoxCheckList;
932 ndd[1] = fNsliceZ[td.fVoxSlices[2]];
935 return td.fVoxCheckList;
939 slice2 = &fIndcZ[fOBz[td.fVoxSlices[2]]];
941 slice1 = &fIndcZ[fOBz[td.fVoxSlices[2]]];
945 if (!islices)
return GetValidExtra(new_list, ncheck, td);
947 return GetValidExtra(ndd[0], slice1, new_list, ncheck, td);
949 return GetValidExtra(ndd[0], slice1, ndd[1], slice2, new_list, ncheck, td);
952 if (isZlimit)
return 0;
954 td.fVoxSlices[2]=dind[2];
957 if (dslice>td.fVoxLimits[1])
return 0;
958 if (dslice>td.fVoxLimits[0])
return 0;
959 if ((dslice>dmin[1]) && td.fVoxInc[1]) {
960 xptnew = point[1]+dslice/td.fVoxInvdir[1];
963 td.fVoxSlices[1] += td.fVoxInc[1];
964 if (td.fVoxInc[1]==1) {
965 if (td.fVoxSlices[1]<-1 || td.fVoxSlices[1]>fIby-2)
break;
966 if (fYb[td.fVoxSlices[1]+1]>=xptnew)
break;
968 if (td.fVoxSlices[1]<0 || td.fVoxSlices[1]>fIby-1)
break;
969 if (fYb[td.fVoxSlices[1]]<= xptnew)
break;
974 if ((dslice>dmin[0]) && td.fVoxInc[0]) {
975 xptnew = point[0]+dslice/td.fVoxInvdir[0];
978 td.fVoxSlices[0] += td.fVoxInc[0];
979 if (td.fVoxInc[0]==1) {
980 if (td.fVoxSlices[0]<-1 || td.fVoxSlices[0]>fIbx-2)
break;
981 if (fXb[td.fVoxSlices[0]+1]>=xptnew)
break;
983 if (td.fVoxSlices[0]<0 || td.fVoxSlices[0]>fIbx-1)
break;
984 if (fXb[td.fVoxSlices[0]]<= xptnew)
break;
991 if (fPriority[2]==1) {
994 if (fPriority[1]==2) {
995 if (td.fVoxSlices[1]<0 || td.fVoxSlices[1]>=fIby-1)
return td.fVoxCheckList;
996 ndd[0] = fNsliceY[td.fVoxSlices[1]];
997 if (!ndd[0])
return td.fVoxCheckList;
998 slice1 = &fIndcY[fOBy[td.fVoxSlices[1]]];
1001 if (fPriority[0]==2) {
1002 if (td.fVoxSlices[0]<0 || td.fVoxSlices[0]>=fIbx-1)
return td.fVoxCheckList;
1003 ndd[1] = fNsliceX[td.fVoxSlices[0]];
1004 if (!ndd[1])
return td.fVoxCheckList;
1007 slice2 = &fIndcX[fOBx[td.fVoxSlices[0]]];
1009 slice1 = &fIndcX[fOBx[td.fVoxSlices[0]]];
1014 IntersectAndStore(ndd[0], slice1, td);
1016 IntersectAndStore(ndd[0], slice1, ndd[1], slice2, td);
1018 ncheck = td.fVoxNcandidates;
1019 return td.fVoxCheckList;
1022 left = (td.fVoxInc[2]>0)?kTRUE:kFALSE;
1023 new_list = GetExtraZ(td.fVoxSlices[2], left, ncheck);
1025 if (!ncheck)
return td.fVoxCheckList;
1026 if (fPriority[1]==2) {
1027 if (td.fVoxSlices[1]<0 || td.fVoxSlices[1]>=fIby-1) {
1029 return td.fVoxCheckList;
1031 ndd[0] = fNsliceY[td.fVoxSlices[1]];
1034 return td.fVoxCheckList;
1036 slice1 = &fIndcY[fOBy[td.fVoxSlices[1]]];
1039 if (fPriority[0]==2) {
1040 if (td.fVoxSlices[0]<0 || td.fVoxSlices[0]>=fIbx-1) {
1042 return td.fVoxCheckList;
1044 ndd[1] = fNsliceX[td.fVoxSlices[0]];
1047 return td.fVoxCheckList;
1051 slice2 = &fIndcX[fOBx[td.fVoxSlices[0]]];
1053 slice1 = &fIndcX[fOBx[td.fVoxSlices[0]]];
1057 if (!islices)
return GetValidExtra(new_list, ncheck, td);
1059 return GetValidExtra(ndd[0], slice1, new_list, ncheck, td);
1061 return GetValidExtra(ndd[0], slice1, ndd[1], slice2, new_list, ncheck, td);
1064 Error(
"GetNextCandidates",
"Invalid islice=%i inside %s", islice, fVolume->GetName());
1072 void TGeoVoxelFinder::SortCrossedVoxels(
const Double_t *point,
const Double_t *dir, TGeoStateInfo &td)
1074 if (NeedRebuild()) {
1075 TGeoVoxelFinder *vox = (TGeoVoxelFinder*)
this;
1077 fVolume->FindOverlaps();
1081 td.fVoxNcandidates = 0;
1082 Int_t loc = 1+((fVolume->GetNdaughters()-1)>>3);
1085 memset(td.fVoxBits1, 0, loc);
1086 memset(td.fVoxInc, 0, 3*
sizeof(Int_t));
1087 for (Int_t i=0; i<3; i++) {
1088 td.fVoxInvdir[i] = TGeoShape::Big();
1089 if (TMath::Abs(dir[i])<1E-10)
continue;
1090 td.fVoxInc[i] = (dir[i]>0)?1:-1;
1091 td.fVoxInvdir[i] = 1./dir[i];
1093 Bool_t flag = GetIndices(point, td);
1094 TGeoBBox *box = (TGeoBBox*)(fVolume->GetShape());
1095 const Double_t *box_orig = box->GetOrigin();
1096 if (td.fVoxInc[0]==0) {
1097 td.fVoxLimits[0] = TGeoShape::Big();
1099 if (td.fVoxSlices[0]==-2) {
1101 td.fVoxLimits[0] = (box_orig[0]-point[0]+td.fVoxInc[0]*box->GetDX())*td.fVoxInvdir[0];
1103 if (td.fVoxInc[0]==1) {
1104 td.fVoxLimits[0] = (fXb[fIbx-1]-point[0])*td.fVoxInvdir[0];
1106 td.fVoxLimits[0] = (fXb[0]-point[0])*td.fVoxInvdir[0];
1110 if (td.fVoxInc[1]==0) {
1111 td.fVoxLimits[1] = TGeoShape::Big();
1113 if (td.fVoxSlices[1]==-2) {
1115 td.fVoxLimits[1] = (box_orig[1]-point[1]+td.fVoxInc[1]*box->GetDY())*td.fVoxInvdir[1];
1117 if (td.fVoxInc[1]==1) {
1118 td.fVoxLimits[1] = (fYb[fIby-1]-point[1])*td.fVoxInvdir[1];
1120 td.fVoxLimits[1] = (fYb[0]-point[1])*td.fVoxInvdir[1];
1124 if (td.fVoxInc[2]==0) {
1125 td.fVoxLimits[2] = TGeoShape::Big();
1127 if (td.fVoxSlices[2]==-2) {
1129 td.fVoxLimits[2] = (box_orig[2]-point[2]+td.fVoxInc[2]*box->GetDZ())*td.fVoxInvdir[2];
1131 if (td.fVoxInc[2]==1) {
1132 td.fVoxLimits[2] = (fZb[fIbz-1]-point[2])*td.fVoxInvdir[2];
1134 td.fVoxLimits[2] = (fZb[0]-point[2])*td.fVoxInvdir[2];
1147 memset(&nd[0], 0, 3*
sizeof(Int_t));
1148 UChar_t *slicex = 0;
1149 if (fPriority[0]==2) {
1150 nd[0] = fNsliceX[td.fVoxSlices[0]];
1151 slicex=&fIndcX[fOBx[td.fVoxSlices[0]]];
1154 UChar_t *slicey = 0;
1155 if (fPriority[1]==2) {
1156 nd[1] = fNsliceY[td.fVoxSlices[1]];
1159 slicey=&fIndcY[fOBy[td.fVoxSlices[1]]];
1161 slicex=&fIndcY[fOBy[td.fVoxSlices[1]]];
1165 UChar_t *slicez = 0;
1166 if (fPriority[2]==2) {
1167 nd[2] = fNsliceZ[td.fVoxSlices[2]];
1169 if (slicex && slicey) {
1170 slicez=&fIndcZ[fOBz[td.fVoxSlices[2]]];
1173 slicey=&fIndcZ[fOBz[td.fVoxSlices[2]]];
1176 slicex=&fIndcZ[fOBz[td.fVoxSlices[2]]];
1184 Error(
"SortCrossedVoxels",
"no slices for %s", fVolume->GetName());
1188 IntersectAndStore(nd[0], slicex, td);
1191 IntersectAndStore(nd[0], slicex, nd[1], slicey, td);
1194 IntersectAndStore(nd[0], slicex, nd[1], slicey, nd[2], slicez, td);
1206 Int_t *TGeoVoxelFinder::GetCheckList(
const Double_t *point, Int_t &nelem, TGeoStateInfo &td)
1208 if (NeedRebuild()) {
1210 fVolume->FindOverlaps();
1212 if (fVolume->GetNdaughters() == 1) {
1214 if (point[0]<fXb[0] || point[0]>fXb[1])
return 0;
1217 if (point[1]<fYb[0] || point[1]>fYb[1])
return 0;
1221 if (point[2]<fZb[0] || point[2]>fZb[1])
return 0;
1223 td.fVoxCheckList[0] = 0;
1225 return td.fVoxCheckList;
1228 UChar_t *slice1 = 0;
1229 UChar_t *slice2 = 0;
1230 UChar_t *slice3 = 0;
1231 Int_t nd[3] = {0,0,0};
1234 im = TMath::BinarySearch(fIbx, fXb, point[0]);
1235 if ((im==-1) || (im==fIbx-1))
return 0;
1236 if (fPriority[0]==2) {
1237 nd[0] = fNsliceX[im];
1238 if (!nd[0])
return 0;
1240 slice1 = &fIndcX[fOBx[im]];
1245 im = TMath::BinarySearch(fIby, fYb, point[1]);
1246 if ((im==-1) || (im==fIby-1))
return 0;
1247 if (fPriority[1]==2) {
1248 nd[1] = fNsliceY[im];
1249 if (!nd[1])
return 0;
1252 slice2 = &fIndcY[fOBy[im]];
1254 slice1 = &fIndcY[fOBy[im]];
1261 im = TMath::BinarySearch(fIbz, fZb, point[2]);
1262 if ((im==-1) || (im==fIbz-1))
return 0;
1263 if (fPriority[2]==2) {
1264 nd[2] = fNsliceZ[im];
1265 if (!nd[2])
return 0;
1267 if (slice1 && slice2) {
1268 slice3 = &fIndcZ[fOBz[im]];
1271 slice2 = &fIndcZ[fOBz[im]];
1274 slice1 = &fIndcZ[fOBz[im]];
1282 Bool_t intersect = kFALSE;
1285 Error(
"GetCheckList",
"No slices for %s", fVolume->GetName());
1288 intersect = Intersect(nd[0], slice1, nelem, td.fVoxCheckList);
1291 intersect = Intersect(nd[0], slice1, nd[1], slice2, nelem, td.fVoxCheckList);
1294 intersect = Intersect(nd[0], slice1, nd[1], slice2, nd[2], slice3, nelem, td.fVoxCheckList);
1296 if (intersect)
return td.fVoxCheckList;
1303 Int_t *TGeoVoxelFinder::GetVoxelCandidates(Int_t i, Int_t j, Int_t k, Int_t &ncheck, TGeoStateInfo &td)
1305 UChar_t *slice1 = 0;
1306 UChar_t *slice2 = 0;
1307 UChar_t *slice3 = 0;
1308 Int_t nd[3] = {0,0,0};
1310 if (fPriority[0]==2) {
1311 nd[0] = fNsliceX[i];
1312 if (!nd[0])
return 0;
1314 slice1 = &fIndcX[fOBx[i]];
1317 if (fPriority[1]==2) {
1318 nd[1] = fNsliceY[j];
1319 if (!nd[1])
return 0;
1322 slice2 = &fIndcY[fOBy[j]];
1324 slice1 = &fIndcY[fOBy[j]];
1329 if (fPriority[2]==2) {
1330 nd[2] = fNsliceZ[k];
1331 if (!nd[2])
return 0;
1333 if (slice1 && slice2) {
1334 slice3 = &fIndcZ[fOBz[k]];
1337 slice2 = &fIndcZ[fOBz[k]];
1340 slice1 = &fIndcZ[fOBz[k]];
1345 Bool_t intersect = kFALSE;
1348 Error(
"GetCheckList",
"No slices for %s", fVolume->GetName());
1351 intersect = Intersect(nd[0], slice1, ncheck, td.fVoxCheckList);
1354 intersect = Intersect(nd[0], slice1, nd[1], slice2, ncheck, td.fVoxCheckList);
1357 intersect = Intersect(nd[0], slice1, nd[1], slice2, nd[2], slice3, ncheck, td.fVoxCheckList);
1359 if (intersect)
return td.fVoxCheckList;
1367 Int_t *TGeoVoxelFinder::GetNextVoxel(
const Double_t *point,
const Double_t * , Int_t &ncheck, TGeoStateInfo &td)
1369 if (NeedRebuild()) {
1371 fVolume->FindOverlaps();
1373 if (td.fVoxCurrent==0) {
1377 ncheck = td.fVoxNcandidates;
1378 return td.fVoxCheckList;
1384 return GetNextCandidates(point, ncheck, td);
1390 Bool_t TGeoVoxelFinder::Intersect(Int_t n1, UChar_t *array1, Int_t &nf, Int_t *result)
1392 Int_t nd = fVolume->GetNdaughters();
1394 Int_t nbytes = 1+((nd-1)>>3);
1398 Bool_t ibreak = kFALSE;
1399 for (current_byte=0; current_byte<nbytes; current_byte++) {
1400 byte = array1[current_byte];
1401 if (!byte)
continue;
1402 for (current_bit=0; current_bit<8; current_bit++) {
1403 if (byte & (1<<current_bit)) {
1404 result[nf++] = (current_byte<<3)+current_bit;
1411 if (ibreak)
return kTRUE;
1419 Bool_t TGeoVoxelFinder::IntersectAndStore(Int_t n1, UChar_t *array1, TGeoStateInfo &td)
1421 Int_t nd = fVolume->GetNdaughters();
1423 td.fVoxNcandidates = 0;
1424 Int_t nbytes = 1+((nd-1)>>3);
1426 memset(td.fVoxBits1, 0xFF, nbytes*
sizeof(UChar_t));
1427 while (td.fVoxNcandidates<nd) {
1428 td.fVoxCheckList[td.fVoxNcandidates] = td.fVoxNcandidates;
1429 ++td.fVoxNcandidates;
1433 memcpy(td.fVoxBits1, array1, nbytes*
sizeof(UChar_t));
1437 Bool_t ibreak = kFALSE;
1439 for (current_byte=0; current_byte<nbytes; current_byte++) {
1440 byte = array1[current_byte];
1441 icand = current_byte<<3;
1442 if (!byte)
continue;
1443 for (current_bit=0; current_bit<8; current_bit++) {
1444 if (byte & (1<<current_bit)) {
1445 td.fVoxCheckList[td.fVoxNcandidates++] = icand+current_bit;
1446 if (td.fVoxNcandidates==n1) {
1452 if (ibreak)
return kTRUE;
1461 Bool_t TGeoVoxelFinder::Union(Int_t n1, UChar_t *array1, TGeoStateInfo &td)
1463 Int_t nd = fVolume->GetNdaughters();
1465 td.fVoxNcandidates = 0;
1466 Int_t nbytes = 1+((nd-1)>>3);
1470 Bool_t ibreak = kFALSE;
1471 for (current_byte=0; current_byte<nbytes; current_byte++) {
1473 byte = (~td.fVoxBits1[current_byte]) & array1[current_byte];
1474 if (!byte)
continue;
1475 for (current_bit=0; current_bit<8; current_bit++) {
1476 if (byte & (1<<current_bit)) {
1477 td.fVoxCheckList[td.fVoxNcandidates++] = (current_byte<<3)+current_bit;
1478 if (td.fVoxNcandidates==n1) {
1484 td.fVoxBits1[current_byte] |= byte;
1485 if (ibreak)
return kTRUE;
1487 return (td.fVoxNcandidates>0);
1494 Bool_t TGeoVoxelFinder::Union(Int_t , UChar_t *array1, Int_t , UChar_t *array2, TGeoStateInfo &td)
1496 Int_t nd = fVolume->GetNdaughters();
1498 td.fVoxNcandidates = 0;
1499 Int_t nbytes = 1+((nd-1)>>3);
1503 for (current_byte=0; current_byte<nbytes; current_byte++) {
1504 byte = (~td.fVoxBits1[current_byte]) & (array1[current_byte] & array2[current_byte]);
1505 if (!byte)
continue;
1506 for (current_bit=0; current_bit<8; current_bit++) {
1507 if (byte & (1<<current_bit)) {
1508 td.fVoxCheckList[td.fVoxNcandidates++] = (current_byte<<3)+current_bit;
1511 td.fVoxBits1[current_byte] |= byte;
1513 return (td.fVoxNcandidates>0);
1521 Bool_t TGeoVoxelFinder::Union(Int_t , UChar_t *array1, Int_t , UChar_t *array2, Int_t , UChar_t *array3, TGeoStateInfo &td)
1523 Int_t nd = fVolume->GetNdaughters();
1525 td.fVoxNcandidates = 0;
1526 Int_t nbytes = 1+((nd-1)>>3);
1530 for (current_byte=0; current_byte<nbytes; current_byte++) {
1531 byte = (~td.fVoxBits1[current_byte]) & (array1[current_byte] & array2[current_byte] & array3[current_byte]);
1532 if (!byte)
continue;
1533 for (current_bit=0; current_bit<8; current_bit++) {
1534 if (byte & (1<<current_bit)) {
1535 td.fVoxCheckList[td.fVoxNcandidates++] = (current_byte<<3)+current_bit;
1538 td.fVoxBits1[current_byte] |= byte;
1540 return (td.fVoxNcandidates>0);
1546 Bool_t TGeoVoxelFinder::Intersect(Int_t n1, UChar_t *array1, Int_t n2, UChar_t *array2, Int_t &nf, Int_t *result)
1548 Int_t nd = fVolume->GetNdaughters();
1550 Int_t nbytes = 1+((nd-1)>>3);
1554 Bool_t ibreak = kFALSE;
1555 for (current_byte=0; current_byte<nbytes; current_byte++) {
1556 byte = array1[current_byte] & array2[current_byte];
1557 if (!byte)
continue;
1558 for (current_bit=0; current_bit<8; current_bit++) {
1559 if (byte & (1<<current_bit)) {
1560 result[nf++] = (current_byte<<3)+current_bit;
1561 if ((nf==n1) || (nf==n2)) {
1567 if (ibreak)
return kTRUE;
1575 Bool_t TGeoVoxelFinder::IntersectAndStore(Int_t , UChar_t *array1, Int_t , UChar_t *array2, TGeoStateInfo &td)
1577 Int_t nd = fVolume->GetNdaughters();
1579 td.fVoxNcandidates = 0;
1580 Int_t nbytes = 1+((nd-1)>>3);
1586 for (current_byte=0; current_byte<nbytes; current_byte++) {
1587 byte = array1[current_byte] & array2[current_byte];
1588 icand = current_byte<<3;
1589 td.fVoxBits1[current_byte] = byte;
1590 if (!byte)
continue;
1591 for (current_bit=0; current_bit<8; current_bit++) {
1592 if (byte & (1<<current_bit)) {
1593 td.fVoxCheckList[td.fVoxNcandidates++] = icand+current_bit;
1597 return (td.fVoxNcandidates>0);
1603 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)
1605 Int_t nd = fVolume->GetNdaughters();
1607 Int_t nbytes = 1+((nd-1)>>3);
1611 Bool_t ibreak = kFALSE;
1612 for (current_byte=0; current_byte<nbytes; current_byte++) {
1613 byte = array1[current_byte] & array2[current_byte] & array3[current_byte];
1614 if (!byte)
continue;
1615 for (current_bit=0; current_bit<8; current_bit++) {
1616 if (byte & (1<<current_bit)) {
1617 result[nf++] = (current_byte<<3)+current_bit;
1618 if ((nf==n1) || (nf==n2) || (nf==n3)) {
1624 if (ibreak)
return kTRUE;
1632 Bool_t TGeoVoxelFinder::IntersectAndStore(Int_t , UChar_t *array1, Int_t , UChar_t *array2, Int_t , UChar_t *array3, TGeoStateInfo &td)
1634 Int_t nd = fVolume->GetNdaughters();
1636 td.fVoxNcandidates = 0;
1637 Int_t nbytes = 1+((nd-1)>>3);
1643 for (current_byte=0; current_byte<nbytes; current_byte++) {
1644 byte = array1[current_byte] & array2[current_byte] & array3[current_byte];
1645 icand = current_byte<<3;
1646 td.fVoxBits1[current_byte] = byte;
1647 if (!byte)
continue;
1648 for (current_bit=0; current_bit<8; current_bit++) {
1649 if (byte & (1<<current_bit)) {
1650 td.fVoxCheckList[td.fVoxNcandidates++] = icand+current_bit;
1654 return (td.fVoxNcandidates>0);
1659 void TGeoVoxelFinder::SortAll(Option_t *)
1661 Int_t nd = fVolume->GetNdaughters();
1662 Int_t nperslice = 1+(nd-1)/(8*
sizeof(UChar_t));
1663 Int_t nmaxslices = 2*nd+1;
1664 Double_t xmin, xmax, ymin, ymax, zmin, zmax;
1665 TGeoBBox *box = (TGeoBBox*)fVolume->GetShape();
1667 xmin = (box->GetOrigin())[0] - box->GetDX();
1668 xmax = (box->GetOrigin())[0] + box->GetDX();
1669 ymin = (box->GetOrigin())[1] - box->GetDY();
1670 ymax = (box->GetOrigin())[1] + box->GetDY();
1671 zmin = (box->GetOrigin())[2] - box->GetDZ();
1672 zmax = (box->GetOrigin())[2] + box->GetDZ();
1673 if ((xmin>=xmax) || (ymin>=ymax) || (zmin>=zmax)) {
1674 Error(
"SortAll",
"Wrong bounding box for volume %s", fVolume->GetName());
1679 Double_t *boundaries =
new Double_t[6*nd];
1680 for (
id=0;
id<nd;
id++) {
1682 boundaries[2*id] = fBoxes[6*
id+3]-fBoxes[6*id];
1683 boundaries[2*
id+1] = fBoxes[6*
id+3]+fBoxes[6*id];
1685 boundaries[2*
id+2*nd] = fBoxes[6*
id+4]-fBoxes[6*
id+1];
1686 boundaries[2*
id+2*nd+1] = fBoxes[6*
id+4]+fBoxes[6*
id+1];
1688 boundaries[2*
id+4*nd] = fBoxes[6*
id+5]-fBoxes[6*
id+2];
1689 boundaries[2*
id+4*nd+1] = fBoxes[6*
id+5]+fBoxes[6*
id+2];
1691 Int_t *index =
new Int_t[2*nd];
1692 UChar_t *ind =
new UChar_t[nmaxslices*nperslice];
1693 Int_t *extra =
new Int_t[nmaxslices*4];
1698 Double_t *temp =
new Double_t[2*nd];
1701 Int_t nleft, nright;
1702 Int_t *extra_left =
new Int_t[nd];
1703 Int_t *extra_right =
new Int_t[nd];
1704 Double_t xxmin, xxmax, xbmin, xbmax, ddx1, ddx2;
1706 UInt_t loc, bitnumber;
1711 TMath::Sort(2*nd, &boundaries[0], &index[0], kFALSE);
1713 for (
id=0;
id<2*nd;
id++) {
1714 if (!ib) {temp[ib++] = boundaries[index[id]];
continue;}
1715 if (TMath::Abs(temp[ib-1]-boundaries[index[
id]])>1E-10)
1716 temp[ib++] = boundaries[index[id]];
1720 Error(
"SortAll",
"Cannot voxelize %s :less than 2 boundaries on X", fVolume->GetName());
1721 delete [] boundaries;
1726 delete [] extra_left;
1727 delete [] extra_right;
1733 if (((temp[0]-xmin)<1E-10) && ((temp[1]-xmax)>-1E-10)) {
1736 if (fIndcX)
delete [] fIndcX;
1739 if (fXb)
delete [] fXb;
1742 if (fOBx)
delete [] fOBx;
1753 if (fXb)
delete [] fXb;
1754 fXb =
new Double_t[ib];
1755 memcpy(fXb, &temp[0], ib*
sizeof(Double_t));
1760 if (fPriority[0]==2) {
1761 memset(ind, 0, (nmaxslices*nperslice)*
sizeof(UChar_t));
1762 if (fOBx)
delete [] fOBx;
1764 fOBx =
new Int_t[fNox];
1765 if (fOEx)
delete [] fOEx;
1766 fOEx =
new Int_t[fNox];
1767 if (fNsliceX)
delete [] fNsliceX;
1768 fNsliceX =
new Int_t[fNox];
1772 for (
id=0;
id<fNox;
id++) {
1774 fOEx[id] = indextra;
1776 extra[indextra] = extra[indextra+1] = 0;
1778 bits = &ind[current];
1781 for (Int_t ic=0; ic<nd; ic++) {
1782 xbmin = fBoxes[6*ic+3]-fBoxes[6*ic];
1783 xbmax = fBoxes[6*ic+3]+fBoxes[6*ic];
1785 if (ddx1>-1E-10)
continue;
1787 if (ddx2<1E-10)
continue;
1791 bitnumber = (UInt_t)ic;
1794 bits[loc] |= 1<<bit;
1799 if ((
id==0) || (ddx1>-1E-10)) {
1800 extra_left[nleft++] = ic;
1803 if ((
id==(fNoz-1)) || (ddx2<1E-10)) {
1804 extra_right[nright++] = ic;
1808 if (fNsliceX[
id]>0) current += nperslice;
1810 extra[indextra] = nleft;
1811 extra[indextra+1] = nright;
1812 if (nleft) memcpy(&extra[indextra+2], extra_left, nleft*
sizeof(Int_t));
1813 if (nright) memcpy(&extra[indextra+2+nleft], extra_right, nright*
sizeof(Int_t));
1814 indextra += 2+nleft+nright;
1816 if (fIndcX)
delete [] fIndcX;
1818 fIndcX =
new UChar_t[current];
1819 memcpy(fIndcX, ind, current*
sizeof(UChar_t));
1820 if (fExtraX)
delete [] fExtraX;
1822 if (indextra>nmaxslices*4) printf(
"Woops!!!\n");
1823 fExtraX =
new Int_t[indextra];
1824 memcpy(fExtraX, extra, indextra*
sizeof(Int_t));
1829 TMath::Sort(2*nd, &boundaries[2*nd], &index[0], kFALSE);
1831 for (
id=0;
id<2*nd;
id++) {
1832 if (!ib) {temp[ib++] = boundaries[2*nd+index[id]];
continue;}
1833 if (TMath::Abs(temp[ib-1]-boundaries[2*nd+index[
id]])>1E-10)
1834 temp[ib++]=boundaries[2*nd+index[id]];
1838 Error(
"SortAll",
"Cannot voxelize %s :less than 2 boundaries on Y", fVolume->GetName());
1839 delete [] boundaries;
1844 delete [] extra_left;
1845 delete [] extra_right;
1851 if (((temp[0]-ymin)<1E-10) && ((temp[1]-ymax)>-1E-10)) {
1854 if (fIndcY)
delete [] fIndcY;
1857 if (fYb)
delete [] fYb;
1860 if (fOBy)
delete [] fOBy;
1872 if (fYb)
delete [] fYb;
1873 fYb =
new Double_t[ib];
1874 memcpy(fYb, &temp[0], ib*
sizeof(Double_t));
1879 if (fPriority[1]==2) {
1881 memset(ind, 0, (nmaxslices*nperslice)*
sizeof(UChar_t));
1882 if (fOBy)
delete [] fOBy;
1884 fOBy =
new Int_t[fNoy];
1885 if (fOEy)
delete [] fOEy;
1886 fOEy =
new Int_t[fNoy];
1887 if (fNsliceY)
delete [] fNsliceY;
1888 fNsliceY =
new Int_t[fNoy];
1892 for (
id=0;
id<fNoy;
id++) {
1894 fOEy[id] = indextra;
1896 extra[indextra] = extra[indextra+1] = 0;
1898 bits = &ind[current];
1901 for (Int_t ic=0; ic<nd; ic++) {
1902 xbmin = fBoxes[6*ic+4]-fBoxes[6*ic+1];
1903 xbmax = fBoxes[6*ic+4]+fBoxes[6*ic+1];
1905 if (ddx1>-1E-10)
continue;
1907 if (ddx2<1E-10)
continue;
1911 bitnumber = (UInt_t)ic;
1914 bits[loc] |= 1<<bit;
1919 if ((
id==0) || (ddx1>-1E-10)) {
1920 extra_left[nleft++] = ic;
1923 if ((
id==(fNoz-1)) || (ddx2<1E-10)) {
1924 extra_right[nright++] = ic;
1928 if (fNsliceY[
id]>0) current += nperslice;
1930 extra[indextra] = nleft;
1931 extra[indextra+1] = nright;
1932 if (nleft) memcpy(&extra[indextra+2], extra_left, nleft*
sizeof(Int_t));
1933 if (nright) memcpy(&extra[indextra+2+nleft], extra_right, nright*
sizeof(Int_t));
1934 indextra += 2+nleft+nright;
1936 if (fIndcY)
delete [] fIndcY;
1938 fIndcY =
new UChar_t[current];
1939 memcpy(fIndcY, &ind[0], current*
sizeof(UChar_t));
1940 if (fExtraY)
delete [] fExtraY;
1942 if (indextra>nmaxslices*4) printf(
"Woops!!!\n");
1943 fExtraY =
new Int_t[indextra];
1944 memcpy(fExtraY, extra, indextra*
sizeof(Int_t));
1949 TMath::Sort(2*nd, &boundaries[4*nd], &index[0], kFALSE);
1951 for (
id=0;
id<2*nd;
id++) {
1952 if (!ib) {temp[ib++] = boundaries[4*nd+index[id]];
continue;}
1953 if ((TMath::Abs(temp[ib-1]-boundaries[4*nd+index[
id]]))>1E-10)
1954 temp[ib++]=boundaries[4*nd+index[id]];
1958 Error(
"SortAll",
"Cannot voxelize %s :less than 2 boundaries on Z", fVolume->GetName());
1959 delete [] boundaries;
1964 delete [] extra_left;
1965 delete [] extra_right;
1971 if (((temp[0]-zmin)<1E-10) && ((temp[1]-zmax)>-1E-10)) {
1974 if (fIndcZ)
delete [] fIndcZ;
1977 if (fZb)
delete [] fZb;
1980 if (fOBz)
delete [] fOBz;
1992 if (fZb)
delete [] fZb;
1993 fZb =
new Double_t[ib];
1994 memcpy(fZb, &temp[0], ib*
sizeof(Double_t));
1999 if (fPriority[2]==2) {
2001 memset(ind, 0, (nmaxslices*nperslice)*
sizeof(UChar_t));
2002 if (fOBz)
delete [] fOBz;
2004 fOBz =
new Int_t[fNoz];
2005 if (fOEz)
delete [] fOEz;
2006 fOEz =
new Int_t[fNoz];
2007 if (fNsliceZ)
delete [] fNsliceZ;
2008 fNsliceZ =
new Int_t[fNoz];
2012 for (
id=0;
id<fNoz;
id++) {
2014 fOEz[id] = indextra;
2016 extra[indextra] = extra[indextra+1] = 0;
2018 bits = &ind[current];
2021 for (Int_t ic=0; ic<nd; ic++) {
2022 xbmin = fBoxes[6*ic+5]-fBoxes[6*ic+2];
2023 xbmax = fBoxes[6*ic+5]+fBoxes[6*ic+2];
2025 if (ddx1>-1E-10)
continue;
2027 if (ddx2<1E-10)
continue;
2031 bitnumber = (UInt_t)ic;
2034 bits[loc] |= 1<<bit;
2039 if ((
id==0) || (ddx1>-1E-10)) {
2040 extra_left[nleft++] = ic;
2043 if ((
id==(fNoz-1)) || (ddx2<1E-10)) {
2044 extra_right[nright++] = ic;
2048 if (fNsliceZ[
id]>0) current += nperslice;
2050 extra[indextra] = nleft;
2051 extra[indextra+1] = nright;
2052 if (nleft) memcpy(&extra[indextra+2], extra_left, nleft*
sizeof(Int_t));
2053 if (nright) memcpy(&extra[indextra+2+nleft], extra_right, nright*
sizeof(Int_t));
2054 indextra += 2+nleft+nright;
2056 if (fIndcZ)
delete [] fIndcZ;
2058 fIndcZ =
new UChar_t[current];
2059 memcpy(fIndcZ, &ind[0], current*
sizeof(UChar_t));
2060 if (fExtraZ)
delete [] fExtraZ;
2062 if (indextra>nmaxslices*4) printf(
"Woops!!!\n");
2063 fExtraZ =
new Int_t[indextra];
2064 memcpy(fExtraZ, extra, indextra*
sizeof(Int_t));
2066 delete [] boundaries;
2071 delete [] extra_left;
2072 delete [] extra_right;
2074 if ((!fPriority[0]) && (!fPriority[1]) && (!fPriority[2])) {
2076 if (nd>1) Error(
"SortAll",
"Volume %s: Cannot make slices on any axis", fVolume->GetName());
2083 void TGeoVoxelFinder::Print(Option_t *)
const
2085 if (NeedRebuild()) {
2086 TGeoVoxelFinder *vox = (TGeoVoxelFinder*)
this;
2088 fVolume->FindOverlaps();
2091 Int_t nd = fVolume->GetNdaughters();
2092 printf(
"Voxels for volume %s (nd=%i)\n", fVolume->GetName(), fVolume->GetNdaughters());
2093 printf(
"priority : x=%i y=%i z=%i\n", fPriority[0], fPriority[1], fPriority[2]);
2096 Int_t nbytes = 1+((fVolume->GetNdaughters()-1)>>3);
2100 if (fPriority[0]==2) {
2101 for (
id=0;
id<fIbx;
id++) {
2102 printf(
"%15.10f\n",fXb[
id]);
2103 if (
id == (fIbx-1))
break;
2104 printf(
"slice %i : %i\n",
id, fNsliceX[
id]);
2106 slice = &fIndcX[fOBx[id]];
2107 for (i=0; i<nbytes; i++) {
2109 for (bit=0; bit<8; bit++) {
2110 if (byte & (1<<bit)) printf(
" %i ", 8*i+bit);
2115 GetExtraX(
id,kTRUE,nextra);
2116 printf(
" extra_about_left = %i\n", nextra);
2117 GetExtraX(
id,kFALSE,nextra);
2118 printf(
" extra_about_right = %i\n", nextra);
2120 }
else if (fPriority[0]==1) {
2121 printf(
"%15.10f\n",fXb[0]);
2122 for (
id=0;
id<nd;
id++) printf(
" %i ",
id);
2124 printf(
"%15.10f\n",fXb[1]);
2127 if (fPriority[1]==2) {
2128 for (
id=0;
id<fIby;
id++) {
2129 printf(
"%15.10f\n", fYb[
id]);
2130 if (
id == (fIby-1))
break;
2131 printf(
"slice %i : %i\n",
id, fNsliceY[
id]);
2133 slice = &fIndcY[fOBy[id]];
2134 for (i=0; i<nbytes; i++) {
2136 for (bit=0; bit<8; bit++) {
2137 if (byte & (1<<bit)) printf(
" %i ", 8*i+bit);
2141 GetExtraY(
id,kTRUE,nextra);
2142 printf(
" extra_about_left = %i\n", nextra);
2143 GetExtraY(
id,kFALSE,nextra);
2144 printf(
" extra_about_right = %i\n", nextra);
2146 }
else if (fPriority[1]==1) {
2147 printf(
"%15.10f\n",fYb[0]);
2148 for (
id=0;
id<nd;
id++) printf(
" %i ",
id);
2150 printf(
"%15.10f\n",fYb[1]);
2154 if (fPriority[2]==2) {
2155 for (
id=0;
id<fIbz;
id++) {
2156 printf(
"%15.10f\n", fZb[
id]);
2157 if (
id == (fIbz-1))
break;
2158 printf(
"slice %i : %i\n",
id, fNsliceZ[
id]);
2160 slice = &fIndcZ[fOBz[id]];
2161 for (i=0; i<nbytes; i++) {
2163 for (bit=0; bit<8; bit++) {
2164 if (byte & (1<<bit)) printf(
" %i ", 8*i+bit);
2169 GetExtraZ(
id,kTRUE,nextra);
2170 printf(
" extra_about_left = %i\n", nextra);
2171 GetExtraZ(
id,kFALSE,nextra);
2172 printf(
" extra_about_right = %i\n", nextra);
2174 }
else if (fPriority[2]==1) {
2175 printf(
"%15.10f\n",fZb[0]);
2176 for (
id=0;
id<nd;
id++) printf(
" %i ",
id);
2178 printf(
"%15.10f\n",fZb[1]);
2185 void TGeoVoxelFinder::PrintVoxelLimits(
const Double_t *point)
const
2187 if (NeedRebuild()) {
2188 TGeoVoxelFinder *vox = (TGeoVoxelFinder*)
this;
2190 fVolume->FindOverlaps();
2194 im = TMath::BinarySearch(fIbx, fXb, point[0]);
2195 if ((im==-1) || (im==fIbx-1)) {
2196 printf(
"Voxel X limits: OUT\n");
2198 printf(
"Voxel X limits: %g %g\n", fXb[im], fXb[im+1]);
2202 im = TMath::BinarySearch(fIby, fYb, point[1]);
2203 if ((im==-1) || (im==fIby-1)) {
2204 printf(
"Voxel Y limits: OUT\n");
2206 printf(
"Voxel Y limits: %g %g\n", fYb[im], fYb[im+1]);
2210 im = TMath::BinarySearch(fIbz, fZb, point[2]);
2211 if ((im==-1) || (im==fIbz-1)) {
2212 printf(
"Voxel Z limits: OUT\n");
2214 printf(
"Voxel Z limits: %g %g\n", fZb[im], fZb[im+1]);
2222 void TGeoVoxelFinder::Voxelize(Option_t * )
2224 if (fVolume->IsAssembly()) fVolume->GetShape()->ComputeBBox();
2225 Int_t nd = fVolume->GetNdaughters();
2227 for (Int_t i=0; i<nd; i++) {
2228 vd = fVolume->GetNode(i)->GetVolume();
2229 if (vd->IsAssembly()) vd->GetShape()->ComputeBBox();
2233 SetNeedRebuild(kFALSE);
2238 void TGeoVoxelFinder::Streamer(TBuffer &R__b)
2240 if (R__b.IsReading()) {
2242 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
2244 R__b.ReadClassBuffer(TGeoVoxelFinder::Class(),
this, R__v, R__s, R__c);
2249 UChar_t *dummy =
new UChar_t[R__c-2];
2250 R__b.ReadFastArray(dummy, R__c-2);
2254 R__b.WriteClassBuffer(TGeoVoxelFinder::Class(),
this);