48G4int G4Voxelizer::fDefaultVoxelsCount = -1;
52 : fBoundingBox(
"VoxBBox", 1, 1, 1)
54 fCountOfVoxels = fNPerSlice = fTotalCandidates = 0;
64void G4Voxelizer::BuildEmpty()
69 std::vector<G4int> xyz(3), max(3), candidates(fTotalCandidates);
70 const std::vector<G4int> empty(0);
72 for (
auto i = 0; i <= 2; ++i)
74 max[i] = (
G4int)fBoundaries[i].size();
76 unsigned int size =
max[0] *
max[1] *
max[2];
79 fEmpty.ResetBitNumber(size-1);
80 fEmpty.ResetAllBits(
true);
82 for (xyz[2] = 0; xyz[2] <
max[2]; ++xyz[2])
84 for (xyz[1] = 0; xyz[1] <
max[1]; ++xyz[1])
86 for (xyz[0] = 0; xyz[0] <
max[0]; ++xyz[0])
91 fEmpty.SetBitNumber(index,
false);
97 std::vector<G4int> &c = (fCandidates[index] = empty);
98 c.reserve(candidates.size());
99 c.assign(candidates.begin(), candidates.end());
105 G4cout <<
"Non-empty voxels count: " << fCandidates.size() <<
G4endl;
110void G4Voxelizer::BuildVoxelLimits(std::vector<G4VSolid*>& solids,
111 std::vector<G4Transform3D>& transforms)
118 if (std::size_t numNodes = solids.size())
120 fBoxes.resize(numNodes);
121 fNPerSlice =
G4int(1 + (fBoxes.size() - 1) / (8 *
sizeof(
unsigned int)));
126 G4ThreeVector toleranceVector(fTolerance,fTolerance,fTolerance);
128 for (std::size_t i = 0; i < numNodes; ++i)
130 G4VSolid& solid = *solids[i];
137 G4Orb& orb = *(G4Orb*) &solid;
140 orbToleranceVector.
set(tolerance,tolerance,tolerance);
141 min -= orbToleranceVector;
142 max += orbToleranceVector;
146 min -= toleranceVector;
147 max += toleranceVector;
149 TransformLimits(min, max, transform);
150 fBoxes[i].hlen = (
max -
min) / 2.;
151 fBoxes[i].pos = (
max +
min) / 2.;
153 fTotalCandidates = (
G4int)fBoxes.size();
158void G4Voxelizer::BuildVoxelLimits(std::vector<G4VFacet*>& facets)
165 if (std::size_t numNodes = facets.size())
167 fBoxes.resize(numNodes);
168 fNPerSlice =
G4int(1+(fBoxes.size()-1)/(8*
sizeof(
unsigned int)));
170 G4ThreeVector toleranceVector(10*fTolerance, 10*fTolerance, 10*fTolerance);
172 for (std::size_t i = 0; i < numNodes; ++i)
174 G4VFacet &facet = *facets[i];
180 min -= toleranceVector;
181 max += toleranceVector;
183 fBoxes[i].hlen = hlen;
184 fBoxes[i].pos =
min + hlen;
186 fTotalCandidates = (
G4int)fBoxes.size();
195 std::size_t numNodes = fBoxes.size();
197 for(std::size_t i = 0; i < numNodes; ++i)
199 G4cout << setw(10) << setiosflags(ios::fixed) <<
200 " -> Node " << i+1 <<
":\n" <<
201 "\t * [x,y,z] = " << fBoxes[i].hlen <<
202 "\t * [x,y,z] = " << fBoxes[i].pos <<
"\n";
204 G4cout.precision(oldprec);
208void G4Voxelizer::CreateSortedBoundary(std::vector<G4double>& boundary,
215 std::size_t numNodes = fBoxes.size();
219 for(std::size_t i = 0 ; i < numNodes; ++i)
229 G4cout <<
"Boundary " << p - d <<
" - " << p + d <<
G4endl;
231 boundary[2*i] = p - d;
232 boundary[2*i+1] = p + d;
234 std::sort(boundary.begin(), boundary.end());
238void G4Voxelizer::BuildBoundaries()
250 if (std::size_t numNodes = fBoxes.size())
252 const G4double tolerance = fTolerance / 100.0;
255 std::vector<G4double> sortedBoundary(2*numNodes);
257 for (
auto j = 0; j <= 2; ++j)
259 CreateSortedBoundary(sortedBoundary, j);
260 std::vector<G4double> &boundary = fBoundaries[j];
263 for(std::size_t i = 0 ; i < 2*numNodes; ++i)
265 G4double newBoundary = sortedBoundary[i];
267 if (j == 0)
G4cout <<
"Examining " << newBoundary <<
"..." <<
G4endl;
269 auto size = (
G4int)boundary.size();
270 if((size == 0) || std::abs(boundary[size-1] - newBoundary) > tolerance)
274 if (j == 0)
G4cout <<
"Adding boundary " << newBoundary <<
"..."
277 boundary.push_back(newBoundary);
285 auto n = (
G4int)boundary.size();
291 std::vector<G4double> reduced;
292 for (
G4int i = 0; i <
n; ++i)
295 auto size = (
G4int)boundary.size();
296 if (i % skip == 0 || i == 0 || i == size - 1)
303 reduced.push_back(boundary[i]);
306 boundary = std::move(reduced);
315 char axis[3] = {
'X',
'Y',
'Z'};
316 for (
auto i = 0; i <= 2; ++i)
328 std::size_t count = boundaries.size();
330 for(std::size_t i = 0; i < count; ++i)
332 G4cout << setw(10) << setiosflags(ios::fixed) << boundaries[i];
333 if(i != count-1) {
G4cout <<
"-> "; }
336 G4cout.precision(oldprec);
340void G4Voxelizer::BuildBitmasks(std::vector<G4double> boundaries[],
346 std::size_t numNodes = fBoxes.size();
349 for (
auto k = 0; k < 3; ++k)
351 std::vector<G4double>& boundary = boundaries[k];
352 G4int voxelsCount = (
G4int)boundary.size() - 1;
353 G4SurfBits& bitmask = bitmasks[k];
361 bitmask.
SetBitNumber(voxelsCount*bitsPerSlice-1,
false);
365 std::vector<G4int>& candidatesCount = fCandidatesCounts[k];
366 candidatesCount.resize(voxelsCount);
368 for(
G4int i = 0 ; i < voxelsCount; ++i)
370 candidatesCount[i] = 0;
375 for(std::size_t j = 0 ; j < numNodes; ++j)
380 G4double p = fBoxes[j].pos[k], d = fBoxes[j].hlen[k];
385 G4int i = BinarySearch(boundary, min);
386 if (i < 0) { i = 0; }
394 candidatesCount[i]++;
397 while (max > boundary[i] && i < voxelsCount);
411 auto numNodes = (
G4int)fBoxes.size();
413 for(
auto i=0; i<numNodes; ++i)
425 char axis[3] = {
'X',
'Y',
'Z'};
429 for (
auto j = 0; j <= 2; ++j)
432 auto count = (
G4int)fBoundaries[j].size();
433 for(
G4int i=0; i < count-1; ++i)
435 G4cout <<
" Slice #" << i+1 <<
": [" << fBoundaries[j][i]
436 <<
" ; " << fBoundaries[j][i+1] <<
"] -> ";
437 bits.
set(size,(
const char *)fBitmasks[j].fAllBits+i
438 *fNPerSlice*
sizeof(
G4int));
439 G4String result = GetCandidatesAsString(bits);
446void G4Voxelizer::BuildBoundingBox()
449 fBoundaries[1].front(),
450 fBoundaries[2].front());
452 fBoundaries[1].back(),
453 fBoundaries[2].back());
454 BuildBoundingBox(min, max);
462 for (
auto i = 0; i <= 2; ++i)
466 fBoundingBoxSize[i] = (
max -
min) / 2 + tolerance * 0.5;
467 fBoundingBoxCenter[i] =
min + fBoundingBoxSize[i];
469 fBoundingBox.SetXHalfLength(fBoundingBoxSize.x());
470 fBoundingBox.SetYHalfLength(fBoundingBoxSize.y());
471 fBoundingBox.SetZHalfLength(fBoundingBoxSize.z());
489void G4Voxelizer::SetReductionRatio(
G4int maxVoxels,
493 * fCandidatesCounts[1].size() * fCandidatesCounts[2].size();
495 if (maxVoxels > 0 && maxVoxels < maxTotal)
498 ratio = std::pow(ratio, 1./3.);
499 if (ratio > 1) { ratio = 1; }
500 reductionRatio.
set(ratio,ratio,ratio);
505void G4Voxelizer::BuildReduceVoxels(std::vector<G4double> boundaries[],
508 for (
auto k = 0; k <= 2; ++k)
510 std::vector<G4int> &candidatesCount = fCandidatesCounts[k];
511 auto max = (
G4int)candidatesCount.size();
512 std::vector<G4VoxelInfo> voxels(max);
513 G4VoxelComparator comp(voxels);
514 std::set<G4int, G4VoxelComparator> voxelSet(comp);
515 std::vector<G4int> mergings;
519 G4VoxelInfo &voxel = voxels[j];
520 voxel.
count = candidatesCount[j];
526 for (
G4int j = 0; j <
max - 1; ++j) { voxelSet.insert(j); }
529 G4double reduction = reductionRatio[k];
532 G4int count = 0, currentCount;
533 while ((currentCount = (
G4int)voxelSet.size()) > 2)
536 if ((currentRatio <= reduction) && (currentCount <= 1000)) {
break; }
537 const G4int pos = *voxelSet.begin();
538 mergings.push_back(pos + 1);
540 G4VoxelInfo& voxel = voxels[
pos];
541 G4VoxelInfo& nextVoxel = voxels[voxel.
next];
543 if (voxelSet.erase(pos) != 1)
547 if (voxel.
next != max - 1)
549 if (voxelSet.erase(voxel.
next) != 1)
556 if (voxelSet.erase(voxel.
previous) != 1)
565 if (voxel.
next != max - 1)
567 voxelSet.insert(voxel.
next);
579 if (!mergings.empty())
581 std::sort(mergings.begin(), mergings.end());
583 const std::vector<G4double>& boundary = boundaries[k];
584 auto mergingsSize = (
G4int)mergings.size();
585 vector<G4double> reducedBoundary;
586 G4int skip = mergings[0], i = 0;
592 reducedBoundary.push_back(boundary[j]);
594 else if (++i < mergingsSize)
599 boundaries[k] = std::move(reducedBoundary);
605void G4Voxelizer::BuildReduceVoxels2(std::vector<G4double> boundaries[],
608 for (
auto k = 0; k <= 2; ++k)
610 std::vector<G4int> &candidatesCount = fCandidatesCounts[k];
611 auto max = (
G4int)candidatesCount.size();
615 total += candidatesCount[i];
618 G4double reduction = reductionRatio[k];
619 if (reduction == 0) {
break; }
621 G4int destination = (
G4int) (reduction * max) + 1;
622 if (destination > 1000) { destination = 1000; }
623 if (destination < 2) { destination = 2; }
626 std::vector<G4int> mergings;
628 std::vector<G4double> &boundary = boundaries[k];
629 std::vector<G4double> reducedBoundary(destination);
631 G4int sum = 0, cur = 0;
634 sum += candidatesCount[i];
635 if (sum > average * (cur + 1) || i == 0)
638 reducedBoundary[cur] = val;
640 if (cur == destination) {
break; }
643 reducedBoundary[destination-1] = boundary[
max];
644 boundaries[k] = std::move(reducedBoundary);
650 std::vector<G4Transform3D>& transforms)
652 BuildVoxelLimits(solids, transforms);
654 BuildBitmasks(fBoundaries, fBitmasks);
660 for (
auto & fCandidatesCount : fCandidatesCounts)
662 fCandidatesCount.resize(0);
667void G4Voxelizer::CreateMiniVoxels(std::vector<G4double> boundaries[],
670 std::vector<G4int> voxel(3), maxVoxels(3);
671 for (
auto i = 0; i <= 2; ++i)
673 maxVoxels[i] = (
G4int)boundaries[i].size();
677 for (voxel[2] = 0; voxel[2] < maxVoxels[2] - 1; ++voxel[2])
679 for (voxel[1] = 0; voxel[1] < maxVoxels[1] - 1; ++voxel[1])
681 for (voxel[0] = 0; voxel[0] < maxVoxels[0] - 1; ++voxel[0])
683 std::vector<G4int> candidates;
688 for (
auto i = 0; i <= 2; ++i)
690 G4int index = voxel[i];
691 const std::vector<G4double> &boundary = boundaries[i];
692 G4double hlen = 0.5 * (boundary[index+1] - boundary[index]);
694 box.
pos[i] = boundary[index] + hlen;
696 fVoxelBoxes.push_back(box);
697 std::vector<G4int>(candidates).swap(candidates);
698 fVoxelBoxesCandidates.push_back(std::move(candidates));
708 G4int maxVoxels = fMaxVoxels;
711 std::size_t size = facets.size();
714 for (
const auto & facet : facets)
716 if (facet->GetNumberOfVertices() > 3) { ++size; }
720 if ((size >= 10 || maxVoxels > 0) && maxVoxels != 0 && maxVoxels != 1)
726 BuildVoxelLimits(facets);
738 BuildBitmasks(fBoundaries,
nullptr,
true);
742 maxVoxels = fTotalCandidates;
743 if (fTotalCandidates > 1000000) { maxVoxels = 1000000; }
746 SetReductionRatio(maxVoxels, reductionRatio);
751 G4cout <<
"Total number of voxels: " << fCountOfVoxels <<
G4endl;
754 BuildReduceVoxels2(fBoundaries, reductionRatio);
759 G4cout <<
"Total number of voxels after reduction: "
760 << fCountOfVoxels <<
G4endl;
767 BuildBitmasks(fBoundaries, fBitmasks);
775 std::vector<G4double> miniBoundaries[3];
777 for (
auto i = 0; i <= 2; ++i)
779 miniBoundaries[i] = fBoundaries[i];
782 G4int voxelsCountMini = (fCountOfVoxels >= 1000)
783 ? 100 :
G4int(fCountOfVoxels / 10);
785 SetReductionRatio(voxelsCountMini, reductionRatioMini);
791 BuildReduceVoxels(miniBoundaries, reductionRatioMini);
795 G4cout <<
"Total number of mini voxels: " << total <<
G4endl;
802 BuildBitmasks(miniBoundaries, bitmasksMini);
808 CreateMiniVoxels(miniBoundaries, bitmasksMini);
823 G4cout <<
"Deallocating unnecessary fields during runtime..." <<
G4endl;
828 for (
auto i = 0; i < 3; ++i)
830 fCandidatesCounts[i].resize(0);
831 fBitmasks[i].Clear();
843 G4cout <<
" Candidates in voxel [" << voxels[0] <<
" ; " << voxels[1]
844 <<
" ; " << voxels[2] <<
"]: ";
845 std::vector<G4int> candidates;
848 for (
G4int i = 0; i < count; ++i)
856void G4Voxelizer::FindComponentsFastest(
unsigned int mask,
857 std::vector<G4int>& list,
G4int i)
const
859 for (
G4int byte = 0;
byte < (
G4int) (
sizeof(
unsigned int)); ++byte)
861 if (
G4int maskByte = mask & 0xFF)
863 for (
G4int bit = 0; bit < 8; ++bit)
865 if ((maskByte & 1) != 0)
866 { list.push_back(8*(
sizeof(
unsigned int)*i+
byte) + bit); }
867 if ((maskByte >>= 1) == 0) {
break; }
894 min.set(kInfinity,kInfinity,kInfinity);
895 max.set(-kInfinity,-kInfinity,-kInfinity);
899 for (
G4int i = 0 ; i < limit; ++i)
903 G4ThreeVector current = GetGlobalPoint(transformation, vertices[i]);
906 if (current.
x() >
max.x()) {
max.setX(current.
x()); }
907 if (current.
x() <
min.x()) {
min.setX(current.
x()); }
909 if (current.
y() >
max.y()) {
max.setY(current.
y()); }
910 if (current.
y() <
min.y()) {
min.setY(current.
y()); }
912 if (current.
z() >
max.z()) {
max.setZ(current.
z()); }
913 if (current.
z() <
min.z()) {
min.setZ(current.
z()); }
919 std::vector<G4int> &list,
G4SurfBits *crossed)
const
925 for (
auto i = 0; i <= 2; ++i)
927 if(point[i] < fBoundaries[i].front() || point[i] >= fBoundaries[i].back())
933 if (fTotalCandidates == 1)
941 unsigned int mask = 0xFFffFFff;
943 if (fBoundaries[0].size() > 2)
945 slice = BinarySearch(fBoundaries[0], point.
x());
946 if ((mask = ((
unsigned int*) fBitmasks[0].fAllBits)[slice]) == 0u)
951 if (fBoundaries[1].size() > 2)
953 slice = BinarySearch(fBoundaries[1], point.
y());
954 if ((mask &= ((
unsigned int*) fBitmasks[1].fAllBits)[slice]) == 0u)
959 if (fBoundaries[2].size() > 2)
961 slice = BinarySearch(fBoundaries[2], point.
z());
962 if ((mask &= ((
unsigned int*) fBitmasks[2].fAllBits)[slice]) == 0u)
967 if ((crossed !=
nullptr) && ((mask &= ~((
unsigned int*)crossed->
fAllBits)[0]) == 0u))
971 FindComponentsFastest(mask, list, 0);
975 unsigned int* masks[3], mask;
976 for (
auto i = 0; i <= 2; ++i)
978 G4int slice = BinarySearch(fBoundaries[i], point[i]);
979 masks[i] = ((
unsigned int*) fBitmasks[i].fAllBits)
980 + slice * fNPerSlice;
982 unsigned int* maskCrossed = crossed !=
nullptr
983 ? (
unsigned int*)crossed->
fAllBits :
nullptr;
985 for (
G4int i = 0 ; i < fNPerSlice; ++i)
990 if ((mask = masks[0][i]) == 0u) {
continue; }
991 if ((mask &= masks[1][i]) == 0u) {
continue; }
992 if ((mask &= masks[2][i]) == 0u) {
continue; }
993 if ((maskCrossed !=
nullptr) && ((mask &= ~maskCrossed[i]) == 0u))
997 FindComponentsFastest(mask, list, i);
1000 return (
G4int)list.size();
1007 std::vector<G4int>& list,
1012 if (fTotalCandidates == 1)
1018 if (fNPerSlice == 1)
1021 if ((mask = ((
unsigned int *) bitmasks[0].fAllBits)[voxels[0]]) == 0u)
1025 if ((mask &= ((
unsigned int *) bitmasks[1].fAllBits)[voxels[1]]) == 0u)
1029 if ((mask &= ((
unsigned int *) bitmasks[2].fAllBits)[voxels[2]]) == 0u)
1033 if ((crossed !=
nullptr) && ((mask &= ~((
unsigned int *)crossed->
fAllBits)[0]) == 0u))
1037 FindComponentsFastest(mask, list, 0);
1041 unsigned int *masks[3], mask;
1042 for (
auto i = 0; i <= 2; ++i)
1044 masks[i] = ((
unsigned int *) bitmasks[i].fAllBits)
1045 + voxels[i]*fNPerSlice;
1047 unsigned int *maskCrossed = crossed !=
nullptr
1048 ? (
unsigned int *)crossed->
fAllBits :
nullptr;
1050 for (
G4int i = 0 ; i < fNPerSlice; ++i)
1055 if ((mask = masks[0][i]) == 0u) {
continue; }
1056 if ((mask &= masks[1][i]) == 0u) {
continue; }
1057 if ((mask &= masks[2][i]) == 0u) {
continue; }
1058 if ((maskCrossed !=
nullptr) && ((mask &= ~maskCrossed[i]) == 0u))
1062 FindComponentsFastest(mask, list, i);
1065 return (
G4int)list.size();
1071 std::vector<G4int>& list,
G4SurfBits* crossed)
const
1081 for (
auto i = 0; i < 3; ++i)
1083 if (point[i] < fBoundaries[i].front() || point[i] > fBoundaries[i].back())
1097 G4double shift = fBoundingBox.DistanceToIn(pointShifted, direction);
1120 safe = safx = -f.
x() + std::abs(aPoint.
x());
1121 safy = -f.
y() + std::abs(aPoint.
y());
1122 if ( safy > safe ) { safe = safy; }
1123 safz = -f.
z() + std::abs(aPoint.
z());
1124 if ( safz > safe ) { safe = safz; }
1125 if (safe < 0.0) {
return 0.0; }
1129 if ( safx > 0 ) { safsq += safx*safx; ++count; }
1130 if ( safy > 0 ) { safsq += safy*safy; ++count; }
1131 if ( safz > 0 ) { safsq += safz*safz; ++count; }
1132 if (count == 1) {
return safe; }
1133 return std::sqrt(safsq);
1140 std::vector<G4int>& curVoxel)
const
1145 for (
G4int i = 0; i <= 2; ++i)
1149 const std::vector<G4double>& boundary = fBoundaries[i];
1150 G4int index = curVoxel[i];
1151 if (direction[i] >= 1e-10)
1157 if (direction[i] > -1e-10) {
continue; }
1159 G4double dif = boundary[index] - point[i];
1160 G4double distance = dif / direction[i];
1162 if (shift > distance)
1169 if (shift != kInfinity)
1174 if (direction[cur] > 0)
1176 if (++curVoxel[cur] >= (
G4int) fBoundaries[cur].size() - 1)
1183 if (--curVoxel[cur] < 0)
1196 std::vector<G4int>& curVoxel)
const
1198 for (
auto i = 0; i <= 2; ++i)
1200 G4int index = curVoxel[i];
1201 const std::vector<G4double> &boundary = fBoundaries[i];
1203 if (direction[i] > 0)
1205 if (point[i] >= boundary[++index])
1207 if (++curVoxel[i] >= (
G4int) boundary.size() - 1) {
return false; }
1212 if (point[i] < boundary[index])
1214 if (--curVoxel[i] < 0) {
return false; }
1218 G4int indexOK = BinarySearch(boundary, point[i]);
1219 if (curVoxel[i] != indexOK)
1220 curVoxel[i] = indexOK;
1230 fReductionRatio.set(0,0,0);
1237 fReductionRatio = ratioOfReduction;
1243 fDefaultVoxelsCount = count;
1249 return fDefaultVoxelsCount;
1255 G4int size = fEmpty.GetNbytes();
1256 size += fBoxes.capacity() *
sizeof(
G4VoxelBox);
1257 size +=
sizeof(
G4double) * (fBoundaries[0].capacity()
1258 + fBoundaries[1].capacity() + fBoundaries[2].capacity());
1259 size +=
sizeof(
G4int) * (fCandidatesCounts[0].capacity()
1260 + fCandidatesCounts[1].capacity() + fCandidatesCounts[2].capacity());
1261 size += fBitmasks[0].GetNbytes() + fBitmasks[1].GetNbytes()
1262 + fBitmasks[2].GetNbytes();
1264 auto csize = (
G4int)fCandidates.size();
1265 for (
G4int i = 0; i < csize; ++i)
1267 size +=
sizeof(vector<G4int>) + fCandidates[i].capacity() *
sizeof(
G4int);
CLHEP::Hep3Vector G4ThreeVector
G4GLOB_DLL std::ostream G4cout
void set(double x, double y, double z)
G4double GetSurfaceTolerance() const
static G4GeometryTolerance * GetInstance()
G4double GetRadialTolerance() const
static void DeRegister(G4VSolid *pSolid)
static G4SolidStore * GetInstance()
G4SurfBits provides a simple container of bits, to be used for optimization of tessellated surfaces....
void SetBitNumber(unsigned int bitnumber, G4bool value=true)
void set(unsigned int nbits, const char *array)
G4bool TestBitNumber(unsigned int bitnumber) const
virtual G4double Extent(const G4ThreeVector axis)=0
virtual void BoundingLimits(G4ThreeVector &pMin, G4ThreeVector &pMax) const
virtual G4GeometryType GetEntityType() const =0
long long CountVoxels(std::vector< G4double > boundaries[]) const
G4double DistanceToBoundingBox(const G4ThreeVector &point) const
G4double MinDistanceToBox(const G4ThreeVector &p, const G4ThreeVector &f) const
G4bool UpdateCurrentVoxel(const G4ThreeVector &point, const G4ThreeVector &direction, std::vector< G4int > &curVoxel) const
void DisplayListNodes() const
void DisplayVoxelLimits() const
static void SetDefaultVoxelsCount(G4int count)
G4int GetBitsPerSlice() const
G4double DistanceToFirst(const G4ThreeVector &point, const G4ThreeVector &direction) const
G4int GetCandidatesVoxelArray(const G4ThreeVector &point, std::vector< G4int > &list, G4SurfBits *crossed=nullptr) const
void SetMaxVoxels(G4int max)
void GetCandidatesVoxel(std::vector< G4int > &voxels)
static G4int GetDefaultVoxelsCount()
G4double DistanceToNext(const G4ThreeVector &point, const G4ThreeVector &direction, std::vector< G4int > &curVoxel) const
void Voxelize(std::vector< G4VSolid * > &solids, std::vector< G4Transform3D > &transforms)
G4int GetVoxelsIndex(G4int x, G4int y, G4int z) const
G4bool Contains(const G4ThreeVector &point) const
G4double total(Particle const *const p1, Particle const *const p2)
T max(const T t1, const T t2)
brief Return the largest of the two arguments
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
const axis_t axis_to_type< N >::axis