51 const vector<int> empty(0);
54 for (
int i = 0; i <= 2; ++i) max[i] =
fBoundaries[i].size();
55 unsigned int size = max[0] * max[1] * max[2];
61 for (xyz[2] = 0; xyz[2] < max[2]; ++xyz[2])
63 for (xyz[1] = 0; xyz[1] < max[1]; ++xyz[1])
65 for (xyz[0] = 0; xyz[0] < max[0]; ++xyz[0])
75 c.reserve(candidates.size());
76 c.assign(candidates.begin(), candidates.end());
82 cout <<
"Non-empty voxels count: " <<
fCandidates.size() << endl;
95 if (
int numNodes = solids.size())
106 for (
int i = 0; i < numNodes; ++i)
119 orbToleranceVector.
Set(tolerance);
120 min -= orbToleranceVector;
121 max += orbToleranceVector;
125 min -= toleranceVector;
126 max += toleranceVector;
137 #endif // USOLIDSONLY
145 if (
int numNodes = facets.size())
153 for (
int i = 0; i < numNodes; ++i)
157 UVector3 x(1, 0, 0), y(0, 1, 0),
z(0, 0, 1);
161 min -= toleranceVector;
162 max += toleranceVector;
165 fBoxes[i].pos = min + hlen;
176 int numNodes =
fBoxes.size();
177 int oldprc = cout.precision();
178 for (
int i = 0; i < numNodes; ++i)
180 cout << setw(10) << setiosflags(ios::fixed) << setprecision(16) <<
181 " -> Node " << i + 1 <<
":\n" <<
182 "\t * [x,y,z] = " <<
fBoxes[i].hlen <<
183 "\t * [x,y,z] = " <<
fBoxes[i].pos <<
"\n";
185 cout.precision(oldprc) ;
193 int numNodes =
fBoxes.size();
195 for (
int i = 0 ; i < numNodes; ++i)
199 double p =
fBoxes[i].pos[axis], d =
fBoxes[i].hlen[axis];
201 boundary[2 * i] = p - d;
202 boundary[2 * i + 1] = p + d;
204 sort(boundary.begin(), boundary.end());
218 if (
int numNodes =
fBoxes.size())
221 vector<double> sortedBoundary(2 * numNodes);
225 for (
int j = 0; j <= 2; ++j)
233 for (
int i = 0 ; i < 2 * numNodes; ++i)
235 double newBoundary = sortedBoundary[i];
236 int size = boundary.size();
237 if (!size || abs(boundary[size - 1] - newBoundary) > tolerance)
241 boundary.push_back(newBoundary);
251 int n = boundary.size();
255 int skip = n / (max / 2);
256 vector<double> reduced;
257 for (
int i = 0; i <
n; ++i)
260 int size = boundary.size();
261 if (i % skip == 0 || i == 0 || i == size - 1)
262 reduced.push_back(boundary[i]);
272 char axis[3] = {
'X',
'Y',
'Z'};
273 for (
int i = 0; i <= 2; ++i)
275 cout <<
" * " << axis[i] <<
" axis:" << endl <<
" | ";
285 int count = boundaries.size();
286 int oldprc = cout.precision();
287 for (
int i = 0; i < count; ++i)
289 cout << setw(10) << setiosflags(ios::fixed) << setprecision(16) << boundaries[i];
292 if (i != count - 1) cout <<
"-> ";
294 cout <<
"|" << endl <<
"Number of boundaries: " << count << endl;
295 cout.precision(oldprc) ;
302 int numNodes =
fBoxes.size();
305 for (
int k = 0; k < 3; k++)
308 vector<double>& boundary = boundaries[k];
309 int voxelsCount = boundary.size() - 1;
310 UBits& bitmask = bitmasks[k];
312 if (bitmasks != NULL)
315 bitmask.
SetBitNumber(voxelsCount * bitsPerSlice - 1,
false);
318 candidatesCount.resize(voxelsCount);
320 for (
int i = 0 ; i < voxelsCount; ++i) candidatesCount[i] = 0;
323 for (
int j = 0 ; j < numNodes; j++)
337 if (bitmasks != NULL)
340 candidatesCount[i]++;
344 while (max > boundary[i] && i < voxelsCount);
349 UUtils::SaveVectorToExternalFile(candidatesCount, fileName);
384 cout <<
"Build list nodes completed" << endl;
393 int numNodes =
fBoxes.size();
395 for (
int i = 0; i < numNodes; ++i)
397 const string& result = ss.str();
405 char axis[3] = {
'X',
'Y',
'Z'};
410 for (
int j = 0; j <= 2; ++j)
412 cout <<
" * " << axis[j] <<
" axis:" << endl;
414 for (
int i = 0; i < count - 1; ++i)
419 cout <<
"[ " << result.c_str() <<
"] " << endl;
433 for (
int i = 0; i <= 2; ++i)
435 double min = amin[i];
436 double max = amax[i];
470 UVoxelInfo& lv = fVoxels[l], &rv = fVoxels[r];
472 int right = rv.count + fVoxels[rv.next].count;;
473 return (left == right) ? l < r : left <
right;
481 if (maxVoxels > 0 && maxVoxels < maxTotal)
483 double ratio = (double) maxVoxels / maxTotal;
484 ratio = pow(ratio, 1. / 3.);
485 if (ratio > 1) ratio = 1;
486 reductionRatio.
Set(ratio);
492 for (
int k = 0; k <= 2; ++k)
495 int max = candidatesCount.size();
496 vector<UVoxelInfo> voxels(max);
498 set<int, UVoxelComparator> voxelSet(comp);
499 vector<int> mergings;
501 for (
int j = 0; j <
max; ++j)
504 voxel.
count = candidatesCount[j];
511 for (
int j = 0; j < max - 1; ++j) voxelSet.insert(j);
513 double reduction = reductionRatio[k];
516 int count = 0, currentCount;
517 while ((currentCount = voxelSet.size()) > 2)
519 double currentRatio = 1 - (double) count / max;
520 if (currentRatio <= reduction && currentCount <= 1000)
522 const int pos = *voxelSet.begin();
523 mergings.push_back(pos + 1);
528 if (voxelSet.erase(pos) != 1)
532 if (voxel.
next != max - 1)
533 if (voxelSet.erase(voxel.
next) != 1)
538 if (voxelSet.erase(voxel.
previous) != 1)
546 if (voxel.
next != max - 1)
547 voxelSet.insert(voxel.
next);
562 sort(mergings.begin(), mergings.end());
564 const vector<double>& boundary = boundaries[k];
565 int mergingsSize = mergings.size();
566 vector<double> reducedBoundary;
567 int skip = mergings[0], i = 0;
568 max = boundary.size();
569 for (
int j = 0; j <
max; ++j)
572 reducedBoundary.push_back(boundary[j]);
573 else if (++i < mergingsSize)
578 boundaries[k] = reducedBoundary;
586 for (
int k = 0; k <= 2; ++k)
589 int max = candidatesCount.size();
591 for (
int i = 0; i <
max; ++i) total += candidatesCount[i];
593 double reduction = reductionRatio[k];
597 int destination = (int)(reduction * max) + 1;
598 if (destination > 1000) destination = 1000;
599 if (destination < 2) destination = 2;
600 double average = ((double)total / max) / reduction;
602 vector<int> mergings;
604 vector<double>& boundary = boundaries[k];
605 vector<double> reducedBoundary(destination);
607 int sum = 0, cur = 0;
608 for (
int i = 0; i <
max; ++i)
611 sum += candidatesCount[i];
612 if (sum > average * (cur + 1) || i == 0)
614 double val = boundary[i];
615 reducedBoundary[cur] = val;
617 if (cur == destination)
621 reducedBoundary[destination - 1] = boundary[
max];
622 boundaries[k] = reducedBoundary;
645 #endif // USOLIDSONLY
649 vector<int> voxel(3), maxVoxels(3);
650 for (
int i = 0; i <= 2; ++i) maxVoxels[i] = boundaries[i].size();
653 for (voxel[2] = 0; voxel[2] < maxVoxels[2] - 1; ++voxel[2])
655 for (voxel[1] = 0; voxel[1] < maxVoxels[1] - 1; ++voxel[1])
657 for (voxel[0] = 0; voxel[0] < maxVoxels[0] - 1; ++voxel[0])
659 vector<int> candidates;
664 for (
int i = 0; i <= 2; ++i)
666 int index = voxel[i];
667 const vector<double>& boundary = boundaries[i];
668 double hlen = 0.5 * (boundary[index + 1] - boundary[index]);
670 box.
pos[i] = boundary[index] + hlen;
673 vector<int>(candidates).swap(candidates);
686 int size = facets.size();
688 for (
int i = 0; i < (int) facets.size(); ++i)
689 if (facets[i]->GetNumberOfVertices() > 3) size++;
691 if ((size >= 10 || maxVoxels > 0) && maxVoxels != 0 && maxVoxels != 1)
699 if (maxVoxels < 0 && reductionRatio ==
UVector3())
729 cout <<
"Total number of voxels after reduction: " <<
fCountOfVoxels << endl;
736 UBits bitmasksMini[3];
739 std::vector<double> miniBoundaries[3];
741 for (
int i = 0; i <= 2; ++i) miniBoundaries[i] =
fBoundaries[i];
754 cout <<
"Total number of mini voxels: " << total << endl;
766 for (
int i = 0; i < 3; ++i)
780 cout <<
" Candidates in voxel [" << voxels[0] <<
" ; " << voxels[1] <<
" ; " << voxels[2] <<
"]: ";
781 vector<int> candidates;
784 for (
int i = 0; i < count; ++i) cout << candidates[i];
785 cout <<
"] " << endl;
790 inline void findComponents2(
unsigned int mask, vector<int>& list,
int i)
792 for (
int bit = 0; bit < (int)(8 *
sizeof(
unsigned int)); bit++)
795 list.push_back(8 *
sizeof(
unsigned int)*i + bit);
796 if (!(mask >>= 1))
break;
800 inline void findComponents3(
unsigned int mask, vector<int>& list,
int i)
810 for (
int byte = 0; byte < (int)(
sizeof(
unsigned int)); byte++)
812 if (
int maskByte = mask & 0xFF)
816 static const int firstBits[256] =
818 8, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
819 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
820 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
821 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
822 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
823 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
824 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
825 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
826 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
827 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
828 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
829 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
830 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
831 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
832 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
833 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
836 int bit = firstBits[maskByte];
837 list.push_back(8 * (
sizeof(
unsigned int)*i + byte) + bit);
838 maskByte -= 1 << bit;
846 #endif // USOLIDSONLY
850 for (
int byte = 0; byte < (int)(
sizeof(
unsigned int)); byte++)
852 if (
int maskByte = mask & 0xFF)
854 for (
int bit = 0; bit < 8; bit++)
857 list.push_back(8 * (
sizeof(
unsigned int)*i + byte) + bit);
858 if (!(maskByte >>= 1))
break;
872 for (
int i = 0; i <= 2; ++i)
885 unsigned int mask = 0xFFffFFff;
890 if (!(mask = ((
unsigned int*)
fBitmasks[0].fAllBits)[slice]))
return 0;
895 if (!(mask &= ((
unsigned int*)
fBitmasks[1].fAllBits)[slice]
901 if (!(mask &= ((
unsigned int*)
fBitmasks[2].fAllBits)[slice]
904 if (crossed && (!(mask &= ~((
unsigned int*)crossed->
fAllBits)[0])))
return 0;
910 unsigned int* masks[3],
mask;
911 for (
int i = 0; i <= 2; ++i)
917 unsigned int* maskCrossed = crossed ? (
unsigned int*)crossed->
fAllBits : NULL;
923 if (!(mask = masks[0][i]))
continue;
924 if (!(mask &= masks[1][i]))
continue;
925 if (!(mask &= masks[2][i]))
continue;
926 if (maskCrossed && !(mask &= ~maskCrossed[i]))
continue;
953 if (!(mask = ((
unsigned int*) bitmasks[0].fAllBits)[voxels[0]]
955 if (!(mask &= ((
unsigned int*) bitmasks[1].fAllBits)[voxels[1]]
957 if (!(mask &= ((
unsigned int*) bitmasks[2].fAllBits)[voxels[2]]
959 if (crossed && (!(mask &= ~((
unsigned int*)crossed->
fAllBits)[0])))
return 0;
965 unsigned int* masks[3],
mask;
966 for (
int i = 0; i <= 2; ++i)
967 masks[i] = ((
unsigned int*) bitmasks[i].fAllBits) + voxels[i] *
fNPerSlice;
969 unsigned int* maskCrossed = crossed ? (
unsigned int*)crossed->
fAllBits : NULL;
975 if (!(mask = masks[0][i]))
continue;
976 if (!(mask &= masks[1][i]))
continue;
977 if (!(mask &= masks[2][i]))
continue;
978 if (maskCrossed && !(mask &= ~maskCrossed[i]))
continue;
1000 for (
int i = 0; i < 3; ++i)
1027 double safe, safx, safy, safz;
1028 safe = safx = -f.
x + std::abs(aPoint.
x);
1029 safy = -f.
y + std::abs(aPoint.
y);
1030 if (safy > safe) safe = safy;
1031 safz = -f.
z + std::abs(aPoint.
z);
1032 if (safz > safe) safe = safz;
1033 if (safe < 0.0)
return 0.0;
1039 safsq += safx * safx;
1044 safsq += safy * safy;
1049 safsq += safz * safz;
1052 if (count == 1)
return safe;
1053 return std::sqrt(safsq);
1062 for (
int i = 0; i <= 2; ++i)
1066 int index = curVoxel[i];
1067 if (direction[i] >= 1e-10)
1082 if (direction[i] <= -1e-10)
1094 double dif = boundary[index] - point[i];
1095 double distance = dif / direction[i];
1097 if (shift > distance)
1107 if (direction[cur] > 0)
1109 if (++curVoxel[cur] >= (
int)
fBoundaries[cur].size() - 1)
1114 if (--curVoxel[cur] < 0)
1146 for (
int i = 0; i < csize; ++i)
1147 size +=
sizeof(vector<int>) +
fCandidates[i].capacity() *
sizeof(int);
1261 #endif // USOLIDSONLY
void BuildVoxelLimits(std::vector< VUSolid * > &solids, std::vector< UTransform3D > &transforms)
static int fDefaultVoxelsCount
virtual UGeometryType GetEntityType() const =0
int GetVoxelsIndex(int x, int y, int z) const
double DistanceToNext(const UVector3 &point, const UVector3 &direction, std::vector< int > &curVoxel) const
vector< UVoxelInfo > & fVoxels
static void FindComponentsFastest(unsigned int mask, std::vector< int > &list, int i)
unsigned int GetNbytes() const
void CreateMiniVoxels(std::vector< double > fBoundaries[], UBits bitmasks[])
virtual double Extent(const UVector3)=0
void Voxelize(std::vector< VUSolid * > &solids, std::vector< UTransform3D > &transforms)
void SetMaxVoxels(int max)
bool operator()(int l, int r)
static const G4double tolerance
void ResetAllBits(bool value=false)
static double Tolerance()
bool Contains(const UVector3 &point) const
std::vector< UVoxelBox > fBoxes
double DistanceToFirst(const UVector3 &point, const UVector3 &direction) const
std::vector< double > fBoundaries[3]
static int BinarySearch(const std::vector< T > &vec, T value)
static const double kInfinity
void BuildReduceVoxels2(std::vector< double > fBoundaries[], UVector3 reductionRatio)
static double MinDistanceToBox(const UVector3 &aPoint, const UVector3 &f)
std::vector< std::vector< int > > fVoxelBoxesCandidates
int GetCandidatesVoxelArray(const UVector3 &point, std::vector< int > &list, UBits *crossed=NULL) const
void BuildBitmasks(std::vector< double > fBoundaries[], UBits bitmasks[])
void Set(unsigned int nbits, const char *array)
long long CountVoxels(std::vector< double > boundaries[]) const
void SetBitNumber(unsigned int bitnumber, bool value=true)
double DistanceToIn(const UVector3 &aPoint, const UVector3 &aDirection, double aPstep=UUtils::kInfinity) const
std::string GetCandidatesAsString(const UBits &bits)
G4double total(Particle const *const p1, Particle const *const p2)
void Set(double xx, double yy, double zz)
double GetRadialTolerance()
T max(const T t1, const T t2)
brief Return the largest of the two arguments
bool TestBitNumber(unsigned int bitnumber) const
void GetCandidatesVoxel(std::vector< int > &voxels)
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
static int GetDefaultVoxelsCount()
std::vector< UVoxelBox > fVoxelBoxes
int GetBitsPerSlice() const
void BuildReduceVoxels(std::vector< double > fBoundaries[], UVector3 reductionRatio)
std::vector< int > fCandidatesCounts[3]
void CreateSortedBoundary(std::vector< double > &boundaryRaw, int axis)
UVoxelComparator(vector< UVoxelInfo > &voxels)
void DisplayVoxelLimits()
std::map< int, std::vector< int > > fCandidates
virtual void Extent(UVector3 &aMin, UVector3 &aMax) const =0
std::string ToString(int number)
void SetReductionRatio(int maxVoxels, UVector3 &reductionRatio)
double SafetyToBoundingBox(const UVector3 &point) const
void ResetBitNumber(unsigned int bitnumber)
static void SetDefaultVoxelsCount(int count)
UVector3 fBoundingBoxSize
static const G4double pos
void TransformLimits(UVector3 &min, UVector3 &max, const UTransform3D &transformation)
UVector3 fBoundingBoxCenter