56 : fBoundingBox(
"VoxBBox", 1, 1, 1)
79 const std::vector<G4int>
empty(0);
82 unsigned int size =
max[0] *
max[1] *
max[2];
88 for (xyz[2] = 0; xyz[2] <
max[2]; ++xyz[2])
90 for (xyz[1] = 0; xyz[1] <
max[1]; ++xyz[1])
92 for (xyz[0] = 0; xyz[0] <
max[0]; ++xyz[0])
104 c.reserve(candidates.size());
105 c.assign(candidates.begin(), candidates.end());
117 std::vector<G4Transform3D>& transforms)
124 if (
G4int numNodes = solids.size())
134 for (
G4int i = 0; i < numNodes; ++i)
146 orbToleranceVector.
set(tolerance,tolerance,tolerance);
147 min -= orbToleranceVector;
148 max += orbToleranceVector;
152 min -= toleranceVector;
153 max += toleranceVector;
171 if (
G4int numNodes = facets.size())
178 for (
G4int i = 0; i < numNodes; ++i)
186 min -= toleranceVector;
187 max += toleranceVector;
203 for(
G4int i = 0; i < numNodes; ++i)
205 G4cout << setw(10) << setiosflags(ios::fixed) <<
206 " -> Node " << i+1 <<
":\n" <<
207 "\t * [x,y,z] = " <<
fBoxes[i].hlen <<
208 "\t * [x,y,z] = " <<
fBoxes[i].pos <<
"\n";
210 G4cout.precision(oldprec);
225 for(
G4int i = 0 ; i < numNodes; ++i)
235 G4cout <<
"Boundary " << p - d <<
" - " << p + d <<
G4endl;
237 boundary[2*i] = p - d;
238 boundary[2*i+1] = p + d;
240 std::sort(boundary.begin(), boundary.end());
261 std::vector<G4double> sortedBoundary(2*numNodes);
265 for (
auto j = 0; j <= 2; ++j)
273 for(
G4int i = 0 ; i < 2*numNodes; ++i)
275 G4double newBoundary = sortedBoundary[i];
277 if (j == 0)
G4cout <<
"Examining " << newBoundary <<
"..." <<
G4endl;
279 G4int size = boundary.size();
280 if(!size || std::abs(boundary[size-1] - newBoundary) > tolerance)
285 if (j == 0)
G4cout <<
"Adding boundary " << newBoundary <<
"..."
288 boundary.push_back(newBoundary);
296 G4int n = boundary.size();
302 std::vector<G4double> reduced;
303 for (
G4int i = 0; i <
n; ++i)
306 G4int size = boundary.size();
307 if (i % skip == 0 || i == 0 || i == size - 1)
314 reduced.push_back(boundary[i]);
326 char axis[3] = {
'X',
'Y',
'Z'};
327 for (
auto i = 0; i <= 2; ++i)
329 G4cout <<
" * " << axis[i] <<
" axis:" <<
G4endl <<
" | ";
339 G4int count = boundaries.size();
341 for(
G4int i = 0; i < count; ++i)
343 G4cout << setw(10) << setiosflags(ios::fixed) << boundaries[i];
344 if(i != count-1)
G4cout <<
"-> ";
347 G4cout.precision(oldprec);
360 for (
auto k = 0; k < 3; ++k)
363 std::vector<G4double>& boundary = boundaries[k];
364 G4int voxelsCount = boundary.size() - 1;
373 bitmask.
SetBitNumber(voxelsCount*bitsPerSlice-1,
false);
378 candidatesCount.resize(voxelsCount);
380 for(
G4int i = 0 ; i < voxelsCount; ++i) { candidatesCount[i] = 0; }
384 for(
G4int j = 0 ; j < numNodes; ++j)
395 if (i < 0) { i = 0; }
403 candidatesCount[i]++;
407 while (
max > boundary[i] && i < voxelsCount);
423 for(
G4int i=0; i<numNodes; ++i)
435 char axis[3] = {
'X',
'Y',
'Z'};
439 for (
auto j = 0; j <= 2; ++j)
443 for(
G4int i=0; i < count-1; ++i)
472 for (
auto i = 0; i <= 2; ++i)
505 if (maxVoxels > 0 && maxVoxels < maxTotal)
508 ratio = std::pow(ratio, 1./3.);
509 if (ratio > 1) { ratio = 1; }
510 reductionRatio.
set(ratio,ratio,ratio);
518 for (
auto k = 0; k <= 2; ++k)
522 std::vector<G4VoxelInfo> voxels(
max);
524 std::set<G4int, G4VoxelComparator> voxelSet(comp);
525 std::vector<G4int> mergings;
530 voxel.
count = candidatesCount[j];
536 for (
G4int j = 0; j <
max - 1; ++j) { voxelSet.insert(j); }
539 G4double reduction = reductionRatio[k];
542 G4int count = 0, currentCount;
543 while ((currentCount = voxelSet.size()) > 2)
546 if ((currentRatio <= reduction) && (currentCount <= 1000))
548 const G4int pos = *voxelSet.begin();
549 mergings.push_back(
pos + 1);
554 if (voxelSet.erase(
pos) != 1)
559 if (voxelSet.erase(voxel.
next) != 1)
564 if (voxelSet.erase(voxel.
previous) != 1)
573 voxelSet.insert(voxel.
next);
586 std::sort(mergings.begin(), mergings.end());
588 const std::vector<G4double>& boundary = boundaries[k];
589 int mergingsSize = mergings.size();
590 vector<G4double> reducedBoundary;
591 G4int skip = mergings[0], i = 0;
592 max = boundary.size();
597 reducedBoundary.push_back(boundary[j]);
599 else if (++i < mergingsSize)
604 boundaries[k] = reducedBoundary;
673 for (
auto k = 0; k <= 2; ++k)
680 G4double reduction = reductionRatio[k];
685 if (destination > 1000) destination = 1000;
686 if (destination < 2) destination = 2;
689 std::vector<G4int> mergings;
691 std::vector<G4double> &boundary = boundaries[k];
692 std::vector<G4double> reducedBoundary(destination);
694 G4int sum = 0, cur = 0;
697 sum += candidatesCount[i];
698 if (sum > average * (cur + 1) || i == 0)
701 reducedBoundary[cur] = val;
703 if (cur == destination)
707 reducedBoundary[destination-1] = boundary[
max];
708 boundaries[k] = reducedBoundary;
714 std::vector<G4Transform3D>& transforms)
724 for (
auto i = 0; i < 3; ++i)
734 std::vector<G4int> voxel(3), maxVoxels(3);
735 for (
auto i = 0; i <= 2; ++i) maxVoxels[i] = boundaries[i].size();
738 for (voxel[2] = 0; voxel[2] < maxVoxels[2] - 1; ++voxel[2])
740 for (voxel[1] = 0; voxel[1] < maxVoxels[1] - 1; ++voxel[1])
742 for (voxel[0] = 0; voxel[0] < maxVoxels[0] - 1; ++voxel[0])
744 std::vector<G4int> candidates;
749 for (
auto i = 0; i <= 2; ++i)
751 G4int index = voxel[i];
752 const std::vector<G4double> &boundary = boundaries[i];
753 G4double hlen = 0.5 * (boundary[index+1] - boundary[index]);
755 box.
pos[i] = boundary[index] + hlen;
758 std::vector<G4int>(candidates).swap(candidates);
772 G4int size = facets.size();
775 for (
G4int i = 0; i < (
G4int) facets.size(); ++i)
777 if (facets[i]->GetNumberOfVertices() > 3) size++;
781 if ((size >= 10 || maxVoxels > 0) && maxVoxels != 0 && maxVoxels != 1)
820 G4cout <<
"Total number of voxels after reduction: "
836 std::vector<G4double> miniBoundaries[3];
838 for (
auto i = 0; i <= 2; ++i) { miniBoundaries[i] =
fBoundaries[i]; }
881 G4cout <<
"Deallocating unnecessary fields during runtime..." <<
G4endl;
886 for (
auto i = 0; i < 3; ++i)
901 G4cout <<
" Candidates in voxel [" << voxels[0] <<
" ; " << voxels[1]
902 <<
" ; " << voxels[2] <<
"]: ";
903 std::vector<G4int> candidates;
906 for (
G4int i = 0; i < count; ++i)
G4cout << candidates[i];
912 std::vector<G4int>& list,
G4int i)
914 for (
G4int byte = 0;
byte < (
G4int) (
sizeof(
unsigned int)); ++byte)
916 if (
G4int maskByte = mask & 0xFF)
918 for (
G4int bit = 0; bit < 8; ++bit)
921 { list.push_back(8*(
sizeof(
unsigned int)*i+
byte) + bit); }
922 if (!(maskByte >>= 1))
break;
954 for (
G4int i = 0 ; i < limit; ++i)
961 if (current.
x() >
max.x())
max.setX(current.
x());
962 if (current.
x() <
min.x())
min.setX(current.
x());
964 if (current.
y() >
max.y())
max.setY(current.
y());
965 if (current.
y() <
min.y())
min.setY(current.
y());
967 if (current.
z() >
max.z())
max.setZ(current.
z());
968 if (current.
z() <
min.z())
min.setZ(current.
z());
974 std::vector<G4int> &list,
G4SurfBits *crossed)
const
980 for (
auto i = 0; i <= 2; ++i)
995 unsigned int mask = 0xFFffFFff;
1000 if (!(mask = ((
unsigned int*)
fBitmasks[0].fAllBits)[slice]))
1006 if (!(mask &= ((
unsigned int*)
fBitmasks[1].fAllBits)[slice]))
1012 if (!(mask &= ((
unsigned int*)
fBitmasks[2].fAllBits)[slice]))
1015 if (crossed && (!(mask &= ~((
unsigned int*)crossed->
fAllBits)[0])))
1022 unsigned int* masks[3], mask;
1023 for (
auto i = 0; i <= 2; ++i)
1026 masks[i] = ((
unsigned int*)
fBitmasks[i].fAllBits)
1029 unsigned int* maskCrossed = crossed
1030 ? (
unsigned int*)crossed->
fAllBits : 0;
1037 if (!(mask = masks[0][i]))
continue;
1038 if (!(mask &= masks[1][i]))
continue;
1039 if (!(mask &= masks[2][i]))
continue;
1040 if (maskCrossed && !(mask &= ~maskCrossed[i]))
continue;
1096 std::vector<G4int>& list,
1111 if (!(mask = ((
unsigned int *) bitmasks[0].fAllBits)[voxels[0]]))
1113 if (!(mask &= ((
unsigned int *) bitmasks[1].fAllBits)[voxels[1]]))
1115 if (!(mask &= ((
unsigned int *) bitmasks[2].fAllBits)[voxels[2]]))
1117 if (crossed && (!(mask &= ~((
unsigned int *)crossed->
fAllBits)[0])))
1124 unsigned int *masks[3], mask;
1125 for (
auto i = 0; i <= 2; ++i)
1127 masks[i] = ((
unsigned int *) bitmasks[i].fAllBits)
1130 unsigned int *maskCrossed = crossed !=
nullptr
1131 ? (
unsigned int *)crossed->
fAllBits : 0;
1138 if (!(mask = masks[0][i]))
continue;
1139 if (!(mask &= masks[1][i]))
continue;
1140 if (!(mask &= masks[2][i]))
continue;
1141 if (maskCrossed && !(mask &= ~maskCrossed[i]))
continue;
1153 std::vector<G4int>& list,
G4SurfBits* crossed)
const
1163 for (
auto i = 0; i < 3; ++i)
1200 safe = safx = -f.
x() + std::abs(aPoint.
x());
1201 safy = -f.
y() + std::abs(aPoint.
y());
1202 if ( safy > safe ) safe = safy;
1203 safz = -f.
z() + std::abs(aPoint.
z());
1204 if ( safz > safe ) safe = safz;
1205 if (safe < 0.0)
return 0.0;
1209 if ( safx > 0 ) { safsq += safx*safx; ++count; }
1210 if ( safy > 0 ) { safsq += safy*safy; ++count; }
1211 if ( safz > 0 ) { safsq += safz*safz; ++count; }
1212 if (count == 1)
return safe;
1213 return std::sqrt(safsq);
1220 std::vector<G4int>& curVoxel)
const
1225 for (
G4int i = 0; i <= 2; ++i)
1229 const std::vector<G4double>& boundary =
fBoundaries[i];
1230 G4int index = curVoxel[i];
1231 if (direction[i] >= 1e-10)
1237 if (direction[i] > -1e-10)
1240 G4double dif = boundary[index] - point[i];
1241 G4double distance = dif / direction[i];
1243 if (shift > distance)
1255 if (direction[cur] > 0)
1262 if (--curVoxel[cur] < 0)
1305 std::vector<G4int>& curVoxel)
const
1307 for (
auto i = 0; i <= 2; ++i)
1309 G4int index = curVoxel[i];
1310 const std::vector<G4double> &boundary =
fBoundaries[i];
1312 if (direction[i] > 0)
1314 if (point[i] >= boundary[++index])
1315 if (++curVoxel[i] >= (
G4int) boundary.size() - 1)
1320 if (point[i] < boundary[index])
1321 if (--curVoxel[i] < 0)
1326 if (curVoxel[i] != indexOK)
1327 curVoxel[i] = indexOK;
1372 for (
G4int i = 0; i < csize; ++i)
static const G4double pos
static const G4int amax[]
static const G4int amin[]
CLHEP::Hep3Vector G4ThreeVector
G4GLOB_DLL std::ostream G4cout
void set(double x, double y, double z)
void SetZHalfLength(G4double dz)
void SetYHalfLength(G4double dy)
void SetXHalfLength(G4double dx)
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
G4double GetSurfaceTolerance() const
static G4GeometryTolerance * GetInstance()
G4double GetRadialTolerance() const
static void DeRegister(G4VSolid *pSolid)
static G4SolidStore * GetInstance()
unsigned int GetNbytes() const
void ResetAllBits(G4bool value=false)
void ResetBitNumber(unsigned int bitnumber)
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)=0
virtual void BoundingLimits(G4ThreeVector &pMin, G4ThreeVector &pMax) const
virtual G4GeometryType GetEntityType() const =0
G4ThreeVector fBoundingBoxSize
long long CountVoxels(std::vector< G4double > boundaries[]) const
G4double DistanceToBoundingBox(const G4ThreeVector &point) const
G4ThreeVector fBoundingBoxCenter
static void FindComponentsFastest(unsigned int mask, std::vector< G4int > &list, G4int i)
std::vector< G4VoxelBox > fBoxes
static G4ThreadLocal G4int fDefaultVoxelsCount
std::vector< G4double > fBoundaries[3]
std::vector< G4VoxelBox > fVoxelBoxes
void BuildReduceVoxels(std::vector< G4double > fBoundaries[], G4ThreeVector reductionRatio)
G4bool UpdateCurrentVoxel(const G4ThreeVector &point, const G4ThreeVector &direction, std::vector< G4int > &curVoxel) const
void DisplayListNodes() const
void DisplayVoxelLimits() const
void SetReductionRatio(G4int maxVoxels, G4ThreeVector &reductionRatio)
std::vector< std::vector< G4int > > fVoxelBoxesCandidates
G4ThreeVector fReductionRatio
static void SetDefaultVoxelsCount(G4int count)
void BuildVoxelLimits(std::vector< G4VSolid * > &solids, std::vector< G4Transform3D > &transforms)
void BuildReduceVoxels2(std::vector< G4double > fBoundaries[], G4ThreeVector reductionRatio)
G4int GetBitsPerSlice() const
G4double DistanceToFirst(const G4ThreeVector &point, const G4ThreeVector &direction) const
void TransformLimits(G4ThreeVector &min, G4ThreeVector &max, const G4Transform3D &transformation) const
std::map< G4int, std::vector< G4int > > fCandidates
G4int GetCandidatesVoxelArray(const G4ThreeVector &point, std::vector< G4int > &list, G4SurfBits *crossed=nullptr) const
std::vector< G4int > fCandidatesCounts[3]
static G4double MinDistanceToBox(const G4ThreeVector &aPoint, const G4ThreeVector &f)
void SetMaxVoxels(G4int max)
void BuildBitmasks(std::vector< G4double > fBoundaries[], G4SurfBits bitmasks[], G4bool countsOnly=false)
void GetCandidatesVoxel(std::vector< G4int > &voxels)
static G4int GetDefaultVoxelsCount()
static G4int BinarySearch(const std::vector< T > &vec, T value)
G4String GetCandidatesAsString(const G4SurfBits &bits) const
G4double DistanceToNext(const G4ThreeVector &point, const G4ThreeVector &direction, std::vector< G4int > &curVoxel) const
void CreateSortedBoundary(std::vector< G4double > &boundaryRaw, G4int axis)
void Voxelize(std::vector< G4VSolid * > &solids, std::vector< G4Transform3D > &transforms)
G4ThreeVector GetGlobalPoint(const G4Transform3D &trans, const G4ThreeVector &lpoint) const
G4int GetVoxelsIndex(G4int x, G4int y, G4int z) const
G4bool Contains(const G4ThreeVector &point) const
void CreateMiniVoxels(std::vector< G4double > fBoundaries[], G4SurfBits bitmasks[])
static const G4double kInfinity
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