55 const vector<int> empty(0);
58 for (
int i = 0; i <= 2; ++i) max[i] =
fBoundaries[i].size();
59 unsigned int size = max[0] * max[1] * max[2];
65 for (xyz[2] = 0; xyz[2] < max[2]; ++xyz[2])
67 for (xyz[1] = 0; xyz[1] < max[1]; ++xyz[1])
69 for (xyz[0] = 0; xyz[0] < max[0]; ++xyz[0])
79 c.reserve(candidates.size());
80 c.assign(candidates.begin(), candidates.end());
86 cout <<
"Non-empty voxels count: " <<
fCandidates.size() << endl;
98 if (
int numNodes = solids.size())
109 for (
int i = 0; i < numNodes; ++i)
120 orbToleranceVector.
Set(tolerance);
121 min -= orbToleranceVector;
122 max += orbToleranceVector;
126 min -= toleranceVector;
127 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);
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;
644 #endif // USOLIDSONLY
648 vector<int> voxel(3), maxVoxels(3);
649 for (
int i = 0; i <= 2; ++i) maxVoxels[i] = boundaries[i].size();
652 for (voxel[2] = 0; voxel[2] < maxVoxels[2] - 1; ++voxel[2])
654 for (voxel[1] = 0; voxel[1] < maxVoxels[1] - 1; ++voxel[1])
656 for (voxel[0] = 0; voxel[0] < maxVoxels[0] - 1; ++voxel[0])
658 vector<int> candidates;
663 for (
int i = 0; i <= 2; ++i)
665 int index = voxel[i];
666 const vector<double>& boundary = boundaries[i];
667 double hlen = 0.5 * (boundary[index + 1] - boundary[index]);
669 box.
pos[i] = boundary[index] + hlen;
672 vector<int>(candidates).swap(candidates);
685 int size = facets.size();
687 for (
int i = 0; i < (int) facets.size(); ++i)
688 if (facets[i]->GetNumberOfVertices() > 3) size++;
690 if ((size >= 10 || maxVoxels > 0) && maxVoxels != 0 && maxVoxels != 1)
698 if (maxVoxels < 0 && reductionRatio ==
UVector3())
728 cout <<
"Total number of voxels after reduction: " <<
fCountOfVoxels << endl;
735 UBits bitmasksMini[3];
738 std::vector<double> miniBoundaries[3];
740 for (
int i = 0; i <= 2; ++i) miniBoundaries[i] =
fBoundaries[i];
753 cout <<
"Total number of mini voxels: " << total << endl;
765 for (
int i = 0; i < 3; ++i)
779 cout <<
" Candidates in voxel [" << voxels[0] <<
" ; " << voxels[1] <<
" ; " << voxels[2] <<
"]: ";
780 vector<int> candidates;
783 for (
int i = 0; i < count; ++i) cout << candidates[i];
784 cout <<
"] " << endl;
789 inline void findComponents2(
unsigned int mask, vector<int>& list,
int i)
791 for (
int bit = 0; bit < (int)(8 *
sizeof(
unsigned int)); bit++)
794 list.push_back(8 *
sizeof(
unsigned int)*i + bit);
795 if (!(mask >>= 1))
break;
799 inline void findComponents3(
unsigned int mask, vector<int>& list,
int i)
809 for (
int byte = 0; byte < (int)(
sizeof(
unsigned int)); byte++)
811 if (
int maskByte = mask & 0xFF)
815 static const int firstBits[256] =
817 8, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
818 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
819 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
820 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
821 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
822 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
823 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
824 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
825 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
826 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
827 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
828 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
829 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
830 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
831 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
832 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
835 int bit = firstBits[maskByte];
836 list.push_back(8 * (
sizeof(
unsigned int)*i + byte) + bit);
837 maskByte -= 1 << bit;
845 #endif // USOLIDSONLY
849 for (
int byte = 0; byte < (int)(
sizeof(
unsigned int)); byte++)
851 if (
int maskByte = mask & 0xFF)
853 for (
int bit = 0; bit < 8; bit++)
856 list.push_back(8 * (
sizeof(
unsigned int)*i + byte) + bit);
857 if (!(maskByte >>= 1))
break;
871 for (
int i = 0; i <= 2; ++i)
884 unsigned int mask = 0xFFffFFff;
889 if (!(mask = ((
unsigned int*)
fBitmasks[0].fAllBits)[slice]))
return 0;
894 if (!(mask &= ((
unsigned int*)
fBitmasks[1].fAllBits)[slice]
900 if (!(mask &= ((
unsigned int*)
fBitmasks[2].fAllBits)[slice]
903 if (crossed && (!(mask &= ~((
unsigned int*)crossed->
fAllBits)[0])))
return 0;
909 unsigned int* masks[3], mask;
910 for (
int i = 0; i <= 2; ++i)
916 unsigned int* maskCrossed = crossed ? (
unsigned int*)crossed->
fAllBits : NULL;
922 if (!(mask = masks[0][i]))
continue;
923 if (!(mask &= masks[1][i]))
continue;
924 if (!(mask &= masks[2][i]))
continue;
925 if (maskCrossed && !(mask &= ~maskCrossed[i]))
continue;
952 if (!(mask = ((
unsigned int*) bitmasks[0].fAllBits)[voxels[0]]
954 if (!(mask &= ((
unsigned int*) bitmasks[1].fAllBits)[voxels[1]]
956 if (!(mask &= ((
unsigned int*) bitmasks[2].fAllBits)[voxels[2]]
958 if (crossed && (!(mask &= ~((
unsigned int*)crossed->
fAllBits)[0])))
return 0;
964 unsigned int* masks[3], mask;
965 for (
int i = 0; i <= 2; ++i)
966 masks[i] = ((
unsigned int*) bitmasks[i].fAllBits) + voxels[i] *
fNPerSlice;
968 unsigned int* maskCrossed = crossed ? (
unsigned int*)crossed->
fAllBits : NULL;
974 if (!(mask = masks[0][i]))
continue;
975 if (!(mask &= masks[1][i]))
continue;
976 if (!(mask &= masks[2][i]))
continue;
977 if (maskCrossed && !(mask &= ~maskCrossed[i]))
continue;
999 for (
int i = 0; i < 3; ++i)
1026 double safe, safx, safy, safz;
1027 safe = safx = -f.
x + std::abs(aPoint.
x);
1028 safy = -f.
y + std::abs(aPoint.
y);
1029 if (safy > safe) safe = safy;
1030 safz = -f.
z + std::abs(aPoint.
z);
1031 if (safz > safe) safe = safz;
1032 if (safe < 0.0)
return 0.0;
1038 safsq += safx * safx;
1043 safsq += safy * safy;
1048 safsq += safz * safz;
1051 if (count == 1)
return safe;
1052 return std::sqrt(safsq);
1061 for (
int i = 0; i <= 2; ++i)
1065 int index = curVoxel[i];
1066 if (direction[i] >= 1e-10)
1081 if (direction[i] <= -1e-10)
1093 double dif = boundary[index] - point[i];
1094 double distance = dif / direction[i];
1096 if (shift > distance)
1106 if (direction[cur] > 0)
1108 if (++curVoxel[cur] >= (
int)
fBoundaries[cur].size() - 1)
1113 if (--curVoxel[cur] < 0)
1145 for (
int i = 0; i < csize; ++i)
1146 size +=
sizeof(vector<int>) +
fCandidates[i].capacity() *
sizeof(int);
1260 #endif // USOLIDSONLY
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
static void DeRegister(G4VSolid *pSolid)
vector< UVoxelInfo > & fVoxels
unsigned int GetNbytes() const
void findComponentsFastest(unsigned int mask, vector< int > &list, int i)
void CreateMiniVoxels(std::vector< double > fBoundaries[], UBits bitmasks[])
virtual double Extent(const UVector3)=0
void SetMaxVoxels(int max)
bool operator()(int l, int r)
void ResetAllBits(bool value=false)
static double Tolerance()
bool Contains(const UVector3 &point) const
std::vector< UVoxelBox > fBoxes
void BuildVoxelLimits(std::vector< VUSolid * > &solids, std::vector< UTransform3D * > &transforms)
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
static G4SolidStore * GetInstance()
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 SaveVectorToExternalFile(const std::vector< double > &vector, const std::string &filename)
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)
void Voxelize(std::vector< VUSolid * > &solids, std::vector< UTransform3D * > &transforms)
UVector3 fBoundingBoxSize
static const G4double pos
void TransformLimits(UVector3 &min, UVector3 &max, const UTransform3D &transformation)
UVector3 fBoundingBoxCenter