Geant4-11
Data Structures | Public Member Functions | Static Public Member Functions | Private Member Functions | Static Private Member Functions | Private Attributes | Static Private Attributes
G4Voxelizer Class Reference

#include <G4Voxelizer.hh>

Data Structures

class  G4VoxelComparator
 

Public Member Functions

G4int AllocatedMemory ()
 
G4bool Contains (const G4ThreeVector &point) const
 
long long CountVoxels (std::vector< G4double > boundaries[]) const
 
void DisplayBoundaries ()
 
void DisplayListNodes () const
 
void DisplayVoxelLimits () const
 
G4double DistanceToBoundingBox (const G4ThreeVector &point) const
 
G4double DistanceToFirst (const G4ThreeVector &point, const G4ThreeVector &direction) const
 
G4double DistanceToNext (const G4ThreeVector &point, const G4ThreeVector &direction, std::vector< G4int > &curVoxel) const
 
const G4SurfBitsEmpty () const
 
 G4Voxelizer ()
 
G4int GetBitsPerSlice () const
 
const std::vector< G4double > & GetBoundary (G4int index) const
 
const std::vector< G4VoxelBox > & GetBoxes () const
 
const std::vector< G4int > & GetCandidates (std::vector< G4int > &curVoxel) const
 
void GetCandidatesVoxel (std::vector< G4int > &voxels)
 
G4int GetCandidatesVoxelArray (const G4ThreeVector &point, std::vector< G4int > &list, G4SurfBits *crossed=nullptr) const
 
G4int GetCandidatesVoxelArray (const std::vector< G4int > &voxels, const G4SurfBits bitmasks[], std::vector< G4int > &list, G4SurfBits *crossed=nullptr) const
 
G4int GetCandidatesVoxelArray (const std::vector< G4int > &voxels, std::vector< G4int > &list, G4SurfBits *crossed=nullptr) const
 
long long GetCountOfVoxels () const
 
G4int GetMaxVoxels (G4ThreeVector &ratioOfReduction)
 
G4int GetPointIndex (const G4ThreeVector &p) const
 
G4bool GetPointVoxel (const G4ThreeVector &p, std::vector< G4int > &voxels) const
 
G4int GetTotalCandidates () const
 
void GetVoxel (std::vector< G4int > &curVoxel, const G4ThreeVector &point) const
 
const G4VoxelBoxGetVoxelBox (G4int i) const
 
const std::vector< G4int > & GetVoxelBoxCandidates (G4int i) const
 
G4int GetVoxelBoxesSize () const
 
G4int GetVoxelsIndex (const std::vector< G4int > &voxels) const
 
G4int GetVoxelsIndex (G4int x, G4int y, G4int z) const
 
G4bool IsEmpty (G4int index) const
 
void SetMaxVoxels (const G4ThreeVector &reductionRatio)
 
void SetMaxVoxels (G4int max)
 
G4bool UpdateCurrentVoxel (const G4ThreeVector &point, const G4ThreeVector &direction, std::vector< G4int > &curVoxel) const
 
void Voxelize (std::vector< G4VFacet * > &facets)
 
void Voxelize (std::vector< G4VSolid * > &solids, std::vector< G4Transform3D > &transforms)
 
 ~G4Voxelizer ()
 

Static Public Member Functions

template<typename T >
static G4int BinarySearch (const std::vector< T > &vec, T value)
 
static G4int GetDefaultVoxelsCount ()
 
static G4double MinDistanceToBox (const G4ThreeVector &aPoint, const G4ThreeVector &f)
 
static void SetDefaultVoxelsCount (G4int count)
 

Private Member Functions

void BuildBitmasks (std::vector< G4double > fBoundaries[], G4SurfBits bitmasks[], G4bool countsOnly=false)
 
void BuildBoundaries ()
 
void BuildBoundingBox ()
 
void BuildBoundingBox (G4ThreeVector &amin, G4ThreeVector &amax, G4double tolerance=0.0)
 
void BuildEmpty ()
 
void BuildReduceVoxels (std::vector< G4double > fBoundaries[], G4ThreeVector reductionRatio)
 
void BuildReduceVoxels2 (std::vector< G4double > fBoundaries[], G4ThreeVector reductionRatio)
 
void BuildVoxelLimits (std::vector< G4VFacet * > &facets)
 
void BuildVoxelLimits (std::vector< G4VSolid * > &solids, std::vector< G4Transform3D > &transforms)
 
void CreateMiniVoxels (std::vector< G4double > fBoundaries[], G4SurfBits bitmasks[])
 
void CreateSortedBoundary (std::vector< G4double > &boundaryRaw, G4int axis)
 
void DisplayBoundaries (std::vector< G4double > &fBoundaries)
 
G4String GetCandidatesAsString (const G4SurfBits &bits) const
 
G4ThreeVector GetGlobalPoint (const G4Transform3D &trans, const G4ThreeVector &lpoint) const
 
void SetReductionRatio (G4int maxVoxels, G4ThreeVector &reductionRatio)
 
void TransformLimits (G4ThreeVector &min, G4ThreeVector &max, const G4Transform3D &transformation) const
 

Static Private Member Functions

static void FindComponentsFastest (unsigned int mask, std::vector< G4int > &list, G4int i)
 

Private Attributes

G4SurfBits fBitmasks [3]
 
std::vector< G4doublefBoundaries [3]
 
G4Box fBoundingBox
 
G4ThreeVector fBoundingBoxCenter
 
G4ThreeVector fBoundingBoxSize
 
std::vector< G4VoxelBoxfBoxes
 
std::map< G4int, std::vector< G4int > > fCandidates
 
std::vector< G4intfCandidatesCounts [3]
 
long long fCountOfVoxels
 
G4SurfBits fEmpty
 
G4int fMaxVoxels
 
const std::vector< G4intfNoCandidates
 
G4int fNPerSlice
 
G4ThreeVector fReductionRatio
 
G4double fTolerance
 
G4int fTotalCandidates
 
std::vector< G4VoxelBoxfVoxelBoxes
 
std::vector< std::vector< G4int > > fVoxelBoxesCandidates
 

Static Private Attributes

static G4ThreadLocal G4int fDefaultVoxelsCount = -1
 

Detailed Description

Definition at line 62 of file G4Voxelizer.hh.

Constructor & Destructor Documentation

◆ G4Voxelizer()

G4Voxelizer::G4Voxelizer ( )

Definition at line 55 of file G4Voxelizer.cc.

56 : fBoundingBox("VoxBBox", 1, 1, 1)
57{
59
61
63
65}
G4double GetSurfaceTolerance() const
static G4GeometryTolerance * GetInstance()
static void DeRegister(G4VSolid *pSolid)
static G4SolidStore * GetInstance()
G4double fTolerance
Definition: G4Voxelizer.hh:256
G4int fTotalCandidates
Definition: G4Voxelizer.hh:242
static G4ThreadLocal G4int fDefaultVoxelsCount
Definition: G4Voxelizer.hh:222
G4int fNPerSlice
Definition: G4Voxelizer.hh:232
G4Box fBoundingBox
Definition: G4Voxelizer.hh:248
void SetMaxVoxels(G4int max)
long long fCountOfVoxels
Definition: G4Voxelizer.hh:230

References G4SolidStore::DeRegister(), fBoundingBox, fCountOfVoxels, fDefaultVoxelsCount, fNPerSlice, fTolerance, fTotalCandidates, G4SolidStore::GetInstance(), G4GeometryTolerance::GetInstance(), G4GeometryTolerance::GetSurfaceTolerance(), and SetMaxVoxels().

◆ ~G4Voxelizer()

G4Voxelizer::~G4Voxelizer ( )

Definition at line 68 of file G4Voxelizer.cc.

69{
70}

Member Function Documentation

◆ AllocatedMemory()

G4int G4Voxelizer::AllocatedMemory ( )

Definition at line 1360 of file G4Voxelizer.cc.

1361{
1362 G4int size = fEmpty.GetNbytes();
1363 size += fBoxes.capacity() * sizeof(G4VoxelBox);
1364 size += sizeof(G4double) * (fBoundaries[0].capacity()
1365 + fBoundaries[1].capacity() + fBoundaries[2].capacity());
1366 size += sizeof(G4int) * (fCandidatesCounts[0].capacity()
1367 + fCandidatesCounts[1].capacity() + fCandidatesCounts[2].capacity());
1368 size += fBitmasks[0].GetNbytes() + fBitmasks[1].GetNbytes()
1369 + fBitmasks[2].GetNbytes();
1370
1371 G4int csize = fCandidates.size();
1372 for (G4int i = 0; i < csize; ++i)
1373 {
1374 size += sizeof(vector<G4int>) + fCandidates[i].capacity() * sizeof(G4int);
1375 }
1376
1377 return size;
1378}
double G4double
Definition: G4Types.hh:83
int G4int
Definition: G4Types.hh:85
unsigned int GetNbytes() const
Definition: G4SurfBits.hh:93
std::vector< G4VoxelBox > fBoxes
Definition: G4Voxelizer.hh:234
G4SurfBits fBitmasks[3]
Definition: G4Voxelizer.hh:244
std::vector< G4double > fBoundaries[3]
Definition: G4Voxelizer.hh:237
G4SurfBits fEmpty
Definition: G4Voxelizer.hh:258
std::map< G4int, std::vector< G4int > > fCandidates
Definition: G4Voxelizer.hh:226
std::vector< G4int > fCandidatesCounts[3]
Definition: G4Voxelizer.hh:240

References fBitmasks, fBoundaries, fBoxes, fCandidates, fCandidatesCounts, fEmpty, and G4SurfBits::GetNbytes().

Referenced by G4TessellatedSolid::AllocatedMemory().

◆ BinarySearch()

template<typename T >
static G4int G4Voxelizer::BinarySearch ( const std::vector< T > &  vec,
value 
)
inlinestatic

◆ BuildBitmasks()

void G4Voxelizer::BuildBitmasks ( std::vector< G4double fBoundaries[],
G4SurfBits  bitmasks[],
G4bool  countsOnly = false 
)
private

Definition at line 351 of file G4Voxelizer.cc.

353{
354 // "BuildListNodes" stores in the bitmasks solids present in each slice
355 // along an axis.
356
357 G4int numNodes = fBoxes.size();
358 G4int bitsPerSlice = GetBitsPerSlice();
359
360 for (auto k = 0; k < 3; ++k)
361 {
362 G4int total = 0;
363 std::vector<G4double>& boundary = boundaries[k];
364 G4int voxelsCount = boundary.size() - 1;
365 G4SurfBits& bitmask = bitmasks[k];
366
367 if (!countsOnly)
368 {
369 bitmask.Clear();
370#ifdef G4SPECSDEBUG
371 G4cout << "Allocating bitmask..." << G4endl;
372#endif
373 bitmask.SetBitNumber(voxelsCount*bitsPerSlice-1, false);
374 // it is here so we can set the maximum number of bits. this line
375 // will rellocate the memory and set all to zero
376 }
377 std::vector<G4int>& candidatesCount = fCandidatesCounts[k];
378 candidatesCount.resize(voxelsCount);
379
380 for(G4int i = 0 ; i < voxelsCount; ++i) { candidatesCount[i] = 0; }
381
382 // Loop on the nodes, number of slices per axis
383 //
384 for(G4int j = 0 ; j < numNodes; ++j)
385 {
386 // Determination of the minimum and maximum position along x
387 // of the bounding boxe of each node
388 //
389 G4double p = fBoxes[j].pos[k], d = fBoxes[j].hlen[k];
390
391 G4double min = p - d; // - localTolerance;
392 G4double max = p + d; // + localTolerance;
393
394 G4int i = BinarySearch(boundary, min);
395 if (i < 0) { i = 0; }
396
397 do // Loop checking, 13.08.2015, G.Cosmo
398 {
399 if (!countsOnly)
400 {
401 bitmask.SetBitNumber(i*bitsPerSlice+j);
402 }
403 candidatesCount[i]++;
404 ++total;
405 ++i;
406 }
407 while (max > boundary[i] && i < voxelsCount);
408 }
409 }
410#ifdef G4SPECSDEBUG
411 G4cout << "Build list nodes completed." << G4endl;
412#endif
413}
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
void Clear()
Definition: G4SurfBits.cc:89
void SetBitNumber(unsigned int bitnumber, G4bool value=true)
Definition: G4SurfBits.hh:114
G4int GetBitsPerSlice() const
static G4int BinarySearch(const std::vector< T > &vec, T value)
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

References BinarySearch(), G4SurfBits::Clear(), fBoxes, fCandidatesCounts, G4cout, G4endl, GetBitsPerSlice(), G4INCL::Math::max(), G4INCL::Math::min(), G4SurfBits::SetBitNumber(), and G4INCL::CrossSections::total().

Referenced by Voxelize().

◆ BuildBoundaries()

void G4Voxelizer::BuildBoundaries ( )
private

Definition at line 244 of file G4Voxelizer.cc.

245{
246 // "SortBoundaries" orders the boundaries along each axis (increasing order)
247 // and also does not take into account redundant boundaries, i.e. if two
248 // boundaries are separated by a distance strictly inferior to "tolerance".
249 // The sorted boundaries are respectively stored in:
250 // * boundaries[0..2]
251
252 // In addition, the number of elements contained in the three latter arrays
253 // are precise thanks to variables: boundariesCountX, boundariesCountY and
254 // boundariesCountZ.
255
256 if (G4int numNodes = fBoxes.size())
257 {
258 const G4double tolerance = fTolerance / 100.0;
259 // Minimal distance to discriminate two boundaries.
260
261 std::vector<G4double> sortedBoundary(2*numNodes);
262
263 G4int considered;
264
265 for (auto j = 0; j <= 2; ++j)
266 {
267 CreateSortedBoundary(sortedBoundary, j);
268 std::vector<G4double> &boundary = fBoundaries[j];
269 boundary.clear();
270
271 considered = 0;
272
273 for(G4int i = 0 ; i < 2*numNodes; ++i)
274 {
275 G4double newBoundary = sortedBoundary[i];
276#ifdef G4SPECSDEBUG
277 if (j == 0) G4cout << "Examining " << newBoundary << "..." << G4endl;
278#endif
279 G4int size = boundary.size();
280 if(!size || std::abs(boundary[size-1] - newBoundary) > tolerance)
281 {
282 considered++;
283 {
284#ifdef G4SPECSDEBUG
285 if (j == 0) G4cout << "Adding boundary " << newBoundary << "..."
286 << G4endl;
287#endif
288 boundary.push_back(newBoundary);
289 continue;
290 }
291 }
292 // If two successive boundaries are too close from each other,
293 // only the first one is considered
294 }
295
296 G4int n = boundary.size();
297 G4int max = 100000;
298 if (n > max/2)
299 {
300 G4int skip = n / (max /2); // n has to be 2x bigger then 50.000.
301 // therefore only from 100.000 reduced
302 std::vector<G4double> reduced;
303 for (G4int i = 0; i < n; ++i)
304 {
305 // 50 ok for 2k, 1000, 2000
306 G4int size = boundary.size();
307 if (i % skip == 0 || i == 0 || i == size - 1)
308 {
309 // this condition of merging boundaries was wrong,
310 // it did not count with right part, which can be
311 // completely ommited and not included in final consideration.
312 // Now should be OK
313 //
314 reduced.push_back(boundary[i]);
315 }
316 }
317 boundary = reduced;
318 }
319 }
320 }
321}
void CreateSortedBoundary(std::vector< G4double > &boundaryRaw, G4int axis)
Definition: G4Voxelizer.cc:214

References CreateSortedBoundary(), fBoundaries, fBoxes, fTolerance, G4cout, G4endl, G4INCL::Math::max(), and CLHEP::detail::n.

Referenced by Voxelize().

◆ BuildBoundingBox() [1/2]

void G4Voxelizer::BuildBoundingBox ( )
private

Definition at line 456 of file G4Voxelizer.cc.

457{
458 G4ThreeVector min(fBoundaries[0].front(),
459 fBoundaries[1].front(),
460 fBoundaries[2].front());
461 G4ThreeVector max(fBoundaries[0].back(),
462 fBoundaries[1].back(),
463 fBoundaries[2].back());
465}
void BuildBoundingBox()
Definition: G4Voxelizer.cc:456

References BuildBoundingBox(), fBoundaries, G4INCL::Math::max(), and G4INCL::Math::min().

Referenced by BuildBoundingBox(), and Voxelize().

◆ BuildBoundingBox() [2/2]

void G4Voxelizer::BuildBoundingBox ( G4ThreeVector amin,
G4ThreeVector amax,
G4double  tolerance = 0.0 
)
private

Definition at line 468 of file G4Voxelizer.cc.

471{
472 for (auto i = 0; i <= 2; ++i)
473 {
474 G4double min = amin[i];
475 G4double max = amax[i];
476 fBoundingBoxSize[i] = (max - min) / 2 + tolerance * 0.5;
478 }
482}
static const G4int amax[]
static const G4int amin[]
double z() const
double x() const
double y() const
void SetZHalfLength(G4double dz)
Definition: G4Box.cc:172
void SetYHalfLength(G4double dy)
Definition: G4Box.cc:149
void SetXHalfLength(G4double dx)
Definition: G4Box.cc:125
G4ThreeVector fBoundingBoxSize
Definition: G4Voxelizer.hh:250
G4ThreeVector fBoundingBoxCenter
Definition: G4Voxelizer.hh:246

References amax, amin, fBoundingBox, fBoundingBoxCenter, fBoundingBoxSize, G4INCL::Math::max(), G4INCL::Math::min(), G4Box::SetXHalfLength(), G4Box::SetYHalfLength(), G4Box::SetZHalfLength(), CLHEP::Hep3Vector::x(), CLHEP::Hep3Vector::y(), and CLHEP::Hep3Vector::z().

◆ BuildEmpty()

void G4Voxelizer::BuildEmpty ( )
private

Definition at line 73 of file G4Voxelizer.cc.

74{
75 // by reserving the size of candidates, we would avoid reallocation of
76 // the vector which could cause fragmentation
77 //
78 std::vector<G4int> xyz(3), max(3), candidates(fTotalCandidates);
79 const std::vector<G4int> empty(0);
80
81 for (auto i = 0; i <= 2; ++i) max[i] = fBoundaries[i].size();
82 unsigned int size = max[0] * max[1] * max[2];
83
84 fEmpty.Clear();
85 fEmpty.ResetBitNumber(size-1);
86 fEmpty.ResetAllBits(true);
87
88 for (xyz[2] = 0; xyz[2] < max[2]; ++xyz[2])
89 {
90 for (xyz[1] = 0; xyz[1] < max[1]; ++xyz[1])
91 {
92 for (xyz[0] = 0; xyz[0] < max[0]; ++xyz[0])
93 {
94 if (GetCandidatesVoxelArray(xyz, candidates))
95 {
96 G4int index = GetVoxelsIndex(xyz);
97 fEmpty.SetBitNumber(index, false);
98
99 // rather than assigning directly with:
100 // "fCandidates[index] = candidates;", in an effort to ensure that
101 // capacity would be just exact, we rather use following 3 lines
102 //
103 std::vector<G4int> &c = (fCandidates[index] = empty);
104 c.reserve(candidates.size());
105 c.assign(candidates.begin(), candidates.end());
106 }
107 }
108 }
109 }
110#ifdef G4SPECSDEBUG
111 G4cout << "Non-empty voxels count: " << fCandidates.size() << G4endl;
112#endif
113}
void ResetAllBits(G4bool value=false)
Definition: G4SurfBits.cc:155
void ResetBitNumber(unsigned int bitnumber)
Definition: G4SurfBits.hh:154
G4int GetCandidatesVoxelArray(const G4ThreeVector &point, std::vector< G4int > &list, G4SurfBits *crossed=nullptr) const
Definition: G4Voxelizer.cc:973
G4int GetVoxelsIndex(G4int x, G4int y, G4int z) const

References G4SurfBits::Clear(), anonymous_namespace{G4MTcoutDestination.cc}::empty, fBoundaries, fCandidates, fEmpty, fTotalCandidates, G4cout, G4endl, GetCandidatesVoxelArray(), GetVoxelsIndex(), G4INCL::Math::max(), G4SurfBits::ResetAllBits(), G4SurfBits::ResetBitNumber(), and G4SurfBits::SetBitNumber().

Referenced by Voxelize().

◆ BuildReduceVoxels()

void G4Voxelizer::BuildReduceVoxels ( std::vector< G4double fBoundaries[],
G4ThreeVector  reductionRatio 
)
private

Definition at line 515 of file G4Voxelizer.cc.

517{
518 for (auto k = 0; k <= 2; ++k)
519 {
520 std::vector<G4int> &candidatesCount = fCandidatesCounts[k];
521 G4int max = candidatesCount.size();
522 std::vector<G4VoxelInfo> voxels(max);
523 G4VoxelComparator comp(voxels);
524 std::set<G4int, G4VoxelComparator> voxelSet(comp);
525 std::vector<G4int> mergings;
526
527 for (G4int j = 0; j < max; ++j)
528 {
529 G4VoxelInfo &voxel = voxels[j];
530 voxel.count = candidatesCount[j];
531 voxel.previous = j - 1;
532 voxel.next = j + 1;
533 voxels[j] = voxel;
534 }
535
536 for (G4int j = 0; j < max - 1; ++j) { voxelSet.insert(j); }
537 // we go to size-1 to make sure we will not merge the last element
538
539 G4double reduction = reductionRatio[k];
540 if (reduction != 0)
541 {
542 G4int count = 0, currentCount;
543 while ((currentCount = voxelSet.size()) > 2)
544 {
545 G4double currentRatio = 1 - (G4double) count / max;
546 if ((currentRatio <= reduction) && (currentCount <= 1000))
547 break;
548 const G4int pos = *voxelSet.begin();
549 mergings.push_back(pos + 1);
550
551 G4VoxelInfo& voxel = voxels[pos];
552 G4VoxelInfo& nextVoxel = voxels[voxel.next];
553
554 if (voxelSet.erase(pos) != 1)
555 {
556 ;// k = k;
557 }
558 if (voxel.next != max - 1)
559 if (voxelSet.erase(voxel.next) != 1)
560 {
561 ;// k = k;
562 }
563 if (voxel.previous != -1)
564 if (voxelSet.erase(voxel.previous) != 1)
565 {
566 ;// k = k;
567 }
568 nextVoxel.count += voxel.count;
569 voxel.count = 0;
570 nextVoxel.previous = voxel.previous;
571
572 if (voxel.next != max - 1)
573 voxelSet.insert(voxel.next);
574
575 if (voxel.previous != -1)
576 {
577 voxels[voxel.previous].next = voxel.next;
578 voxelSet.insert(voxel.previous);
579 }
580 ++count;
581 } // Loop checking, 13.08.2015, G.Cosmo
582 }
583
584 if (mergings.size())
585 {
586 std::sort(mergings.begin(), mergings.end());
587
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();
593 for (G4int j = 0; j < max; ++j)
594 {
595 if (j != skip)
596 {
597 reducedBoundary.push_back(boundary[j]);
598 }
599 else if (++i < mergingsSize)
600 {
601 skip = mergings[i];
602 }
603 }
604 boundaries[k] = reducedBoundary;
605 }
606/*
607 G4int count = 0;
608 while (true) // Loop checking, 13.08.2015, G.Cosmo
609 {
610 G4double reduction = reductionRatio[k];
611 if (reduction == 0)
612 break;
613 G4int currentCount = voxelSet.size();
614 if (currentCount <= 2)
615 break;
616 G4double currentRatio = 1 - (G4double) count / max;
617 if (currentRatio <= reduction && currentCount <= 1000)
618 break;
619 const G4int pos = *voxelSet.begin();
620 mergings.push_back(pos);
621
622 G4VoxelInfo &voxel = voxels[pos];
623 G4VoxelInfo &nextVoxel = voxels[voxel.next];
624
625 voxelSet.erase(pos);
626 if (voxel.next != max - 1) { voxelSet.erase(voxel.next); }
627 if (voxel.previous != -1) { voxelSet.erase(voxel.previous); }
628
629 nextVoxel.count += voxel.count;
630 voxel.count = 0;
631 nextVoxel.previous = voxel.previous;
632
633 if (voxel.next != max - 1)
634 voxelSet.insert(voxel.next);
635
636 if (voxel.previous != -1)
637 {
638 voxels[voxel.previous].next = voxel.next;
639 voxelSet.insert(voxel.previous);
640 }
641 ++count;
642 }
643
644 if (mergings.size())
645 {
646 std::sort(mergings.begin(), mergings.end());
647
648 std::vector<G4double> &boundary = boundaries[k];
649 std::vector<G4double> reducedBoundary(boundary.size() - mergings.size());
650 G4int skip = mergings[0] + 1, cur = 0, i = 0;
651 max = boundary.size();
652 for (G4int j = 0; j < max; ++j)
653 {
654 if (j != skip)
655 {
656 reducedBoundary[cur++] = boundary[j];
657 }
658 else
659 {
660 if (++i < (G4int)mergings.size()) { skip = mergings[i] + 1; }
661 }
662 }
663 boundaries[k] = reducedBoundary;
664 }
665*/
666 }
667}
static const G4double pos
G4int previous
Definition: G4Voxelizer.hh:58

References G4VoxelInfo::count, fCandidatesCounts, G4INCL::Math::max(), G4VoxelInfo::next, pos, and G4VoxelInfo::previous.

Referenced by Voxelize().

◆ BuildReduceVoxels2()

void G4Voxelizer::BuildReduceVoxels2 ( std::vector< G4double fBoundaries[],
G4ThreeVector  reductionRatio 
)
private

Definition at line 670 of file G4Voxelizer.cc.

672{
673 for (auto k = 0; k <= 2; ++k)
674 {
675 std::vector<G4int> &candidatesCount = fCandidatesCounts[k];
676 G4int max = candidatesCount.size();
677 G4int total = 0;
678 for (G4int i = 0; i < max; ++i) total += candidatesCount[i];
679
680 G4double reduction = reductionRatio[k];
681 if (reduction == 0)
682 break;
683
684 G4int destination = (G4int) (reduction * max) + 1;
685 if (destination > 1000) destination = 1000;
686 if (destination < 2) destination = 2;
687 G4double average = ((G4double)total / max) / reduction;
688
689 std::vector<G4int> mergings;
690
691 std::vector<G4double> &boundary = boundaries[k];
692 std::vector<G4double> reducedBoundary(destination);
693
694 G4int sum = 0, cur = 0;
695 for (G4int i = 0; i < max; ++i)
696 {
697 sum += candidatesCount[i];
698 if (sum > average * (cur + 1) || i == 0)
699 {
700 G4double val = boundary[i];
701 reducedBoundary[cur] = val;
702 ++cur;
703 if (cur == destination)
704 break;
705 }
706 }
707 reducedBoundary[destination-1] = boundary[max];
708 boundaries[k] = reducedBoundary;
709 }
710}

References fCandidatesCounts, G4INCL::Math::max(), and G4INCL::CrossSections::total().

Referenced by Voxelize().

◆ BuildVoxelLimits() [1/2]

void G4Voxelizer::BuildVoxelLimits ( std::vector< G4VFacet * > &  facets)
private

Definition at line 164 of file G4Voxelizer.cc.

165{
166 // "BuildVoxelLimits"'s aim is to store the coordinates of the origin as well
167 // as the half lengths related to the bounding box of each node.
168 // These quantities are stored in the array "fBoxes" (6 different values per
169 // node.
170
171 if (G4int numNodes = facets.size()) // Number of nodes
172 {
173 fBoxes.resize(numNodes); // Array which will store the half lengths
174 fNPerSlice = 1+(fBoxes.size()-1)/(8*sizeof(unsigned int));
175
176 G4ThreeVector toleranceVector(10*fTolerance, 10*fTolerance, 10*fTolerance);
177
178 for (G4int i = 0; i < numNodes; ++i)
179 {
180 G4VFacet &facet = *facets[i];
182 G4ThreeVector x(1,0,0), y(0,1,0), z(0,0,1);
183 G4ThreeVector extent;
184 max.set (facet.Extent(x), facet.Extent(y), facet.Extent(z));
185 min.set (-facet.Extent(-x), -facet.Extent(-y), -facet.Extent(-z));
186 min -= toleranceVector;
187 max += toleranceVector;
188 G4ThreeVector hlen = (max - min) / 2;
189 fBoxes[i].hlen = hlen;
190 fBoxes[i].pos = min + hlen;
191 }
192 fTotalCandidates = fBoxes.size();
193 }
194}
virtual G4double Extent(const G4ThreeVector)=0

References G4VFacet::Extent(), fBoxes, fNPerSlice, fTolerance, fTotalCandidates, G4INCL::Math::max(), and G4INCL::Math::min().

◆ BuildVoxelLimits() [2/2]

void G4Voxelizer::BuildVoxelLimits ( std::vector< G4VSolid * > &  solids,
std::vector< G4Transform3D > &  transforms 
)
private

Definition at line 116 of file G4Voxelizer.cc.

118{
119 // "BuildVoxelLimits"'s aim is to store the coordinates of the origin as
120 // well as the half lengths related to the bounding box of each node.
121 // These quantities are stored in the array "fBoxes" (6 different values per
122 // node
123 //
124 if (G4int numNodes = solids.size()) // Number of nodes in "multiUnion"
125 {
126 fBoxes.resize(numNodes); // Array which will store the half lengths
127 fNPerSlice = 1 + (fBoxes.size() - 1) / (8 * sizeof(unsigned int));
128
129 // related to a particular node, but also
130 // the coordinates of its origin
131
133
134 for (G4int i = 0; i < numNodes; ++i)
135 {
136 G4VSolid& solid = *solids[i];
137 G4Transform3D transform = transforms[i];
139
140 solid.BoundingLimits(min, max);
141 if (solid.GetEntityType() == "G4Orb")
142 {
143 G4Orb& orb = *(G4Orb*) &solid;
144 G4ThreeVector orbToleranceVector;
145 G4double tolerance = orb.GetRadialTolerance() / 2.0;
146 orbToleranceVector.set(tolerance,tolerance,tolerance);
147 min -= orbToleranceVector;
148 max += orbToleranceVector;
149 }
150 else
151 {
152 min -= toleranceVector;
153 max += toleranceVector;
154 }
156 fBoxes[i].hlen = (max - min) / 2.;
157 fBoxes[i].pos = (max + min) / 2.;
158 }
159 fTotalCandidates = fBoxes.size();
160 }
161}
void set(double x, double y, double z)
Definition: G4Orb.hh:56
G4double GetRadialTolerance() const
virtual void BoundingLimits(G4ThreeVector &pMin, G4ThreeVector &pMax) const
Definition: G4VSolid.cc:665
virtual G4GeometryType GetEntityType() const =0
void TransformLimits(G4ThreeVector &min, G4ThreeVector &max, const G4Transform3D &transformation) const
Definition: G4Voxelizer.cc:930
G4bool transform(G4String &input, const G4String &type)

References G4VSolid::BoundingLimits(), fBoxes, fNPerSlice, fTolerance, fTotalCandidates, G4VSolid::GetEntityType(), G4Orb::GetRadialTolerance(), G4INCL::Math::max(), G4INCL::Math::min(), CLHEP::Hep3Vector::set(), G4coutFormatters::anonymous_namespace{G4coutFormatters.cc}::transform(), and TransformLimits().

Referenced by Voxelize().

◆ Contains()

G4bool G4Voxelizer::Contains ( const G4ThreeVector point) const

Definition at line 1161 of file G4Voxelizer.cc.

1162{
1163 for (auto i = 0; i < 3; ++i)
1164 {
1165 if (point[i] < fBoundaries[i].front() || point[i] > fBoundaries[i].back())
1166 return false;
1167 }
1168 return true;
1169}

References fBoundaries.

Referenced by G4TessellatedSolid::DistanceToOutCore().

◆ CountVoxels()

long long G4Voxelizer::CountVoxels ( std::vector< G4double boundaries[]) const
inline

Referenced by Voxelize().

◆ CreateMiniVoxels()

void G4Voxelizer::CreateMiniVoxels ( std::vector< G4double fBoundaries[],
G4SurfBits  bitmasks[] 
)
private

Definition at line 731 of file G4Voxelizer.cc.

733{
734 std::vector<G4int> voxel(3), maxVoxels(3);
735 for (auto i = 0; i <= 2; ++i) maxVoxels[i] = boundaries[i].size();
736
737 G4ThreeVector point;
738 for (voxel[2] = 0; voxel[2] < maxVoxels[2] - 1; ++voxel[2])
739 {
740 for (voxel[1] = 0; voxel[1] < maxVoxels[1] - 1; ++voxel[1])
741 {
742 for (voxel[0] = 0; voxel[0] < maxVoxels[0] - 1; ++voxel[0])
743 {
744 std::vector<G4int> candidates;
745 if (GetCandidatesVoxelArray(voxel, bitmasks, candidates, 0))
746 {
747 // find a box for corresponding non-empty voxel
748 G4VoxelBox box;
749 for (auto i = 0; i <= 2; ++i)
750 {
751 G4int index = voxel[i];
752 const std::vector<G4double> &boundary = boundaries[i];
753 G4double hlen = 0.5 * (boundary[index+1] - boundary[index]);
754 box.hlen[i] = hlen;
755 box.pos[i] = boundary[index] + hlen;
756 }
757 fVoxelBoxes.push_back(box);
758 std::vector<G4int>(candidates).swap(candidates);
759 fVoxelBoxesCandidates.push_back(candidates);
760 }
761 }
762 }
763 }
764}
std::vector< G4VoxelBox > fVoxelBoxes
Definition: G4Voxelizer.hh:224
std::vector< std::vector< G4int > > fVoxelBoxesCandidates
Definition: G4Voxelizer.hh:225
G4ThreeVector hlen
Definition: G4Voxelizer.hh:51
G4ThreeVector pos
Definition: G4Voxelizer.hh:52

References fVoxelBoxes, fVoxelBoxesCandidates, GetCandidatesVoxelArray(), G4VoxelBox::hlen, and G4VoxelBox::pos.

Referenced by Voxelize().

◆ CreateSortedBoundary()

void G4Voxelizer::CreateSortedBoundary ( std::vector< G4double > &  boundaryRaw,
G4int  axis 
)
private

Definition at line 214 of file G4Voxelizer.cc.

216{
217 // "CreateBoundaries"'s aim is to determine the slices induced by the
218 // bounding fBoxes, along each axis. The created boundaries are stored
219 // in the array "boundariesRaw"
220
221 G4int numNodes = fBoxes.size(); // Number of nodes in structure
222
223 // Determination of the boundaries along x, y and z axis
224 //
225 for(G4int i = 0 ; i < numNodes; ++i)
226 {
227 // For each node, the boundaries are created by using the array "fBoxes"
228 // built in method "BuildVoxelLimits"
229 //
230 G4double p = fBoxes[i].pos[axis], d = fBoxes[i].hlen[axis];
231
232 // x boundaries
233 //
234#ifdef G4SPECSDEBUG
235 G4cout << "Boundary " << p - d << " - " << p + d << G4endl;
236#endif
237 boundary[2*i] = p - d;
238 boundary[2*i+1] = p + d;
239 }
240 std::sort(boundary.begin(), boundary.end());
241}

References fBoxes, G4cout, and G4endl.

Referenced by BuildBoundaries().

◆ DisplayBoundaries() [1/2]

void G4Voxelizer::DisplayBoundaries ( )

Definition at line 324 of file G4Voxelizer.cc.

325{
326 char axis[3] = {'X', 'Y', 'Z'};
327 for (auto i = 0; i <= 2; ++i)
328 {
329 G4cout << " * " << axis[i] << " axis:" << G4endl << " | ";
331 }
332}
void DisplayBoundaries()
Definition: G4Voxelizer.cc:324

References DisplayBoundaries(), fBoundaries, G4cout, and G4endl.

Referenced by DisplayBoundaries().

◆ DisplayBoundaries() [2/2]

void G4Voxelizer::DisplayBoundaries ( std::vector< G4double > &  fBoundaries)
private

Definition at line 335 of file G4Voxelizer.cc.

336{
337 // Prints the positions of the boundaries of the slices on the three axes
338
339 G4int count = boundaries.size();
340 G4int oldprec = G4cout.precision(16);
341 for(G4int i = 0; i < count; ++i)
342 {
343 G4cout << setw(10) << setiosflags(ios::fixed) << boundaries[i];
344 if(i != count-1) G4cout << "-> ";
345 }
346 G4cout << "|" << G4endl << "Number of boundaries: " << count << G4endl;
347 G4cout.precision(oldprec);
348}

References G4cout, and G4endl.

◆ DisplayListNodes()

void G4Voxelizer::DisplayListNodes ( ) const

Definition at line 431 of file G4Voxelizer.cc.

432{
433 // Prints which solids are present in the slices previously elaborated.
434
435 char axis[3] = {'X', 'Y', 'Z'};
436 G4int size=8*sizeof(G4int)*fNPerSlice;
437 G4SurfBits bits(size);
438
439 for (auto j = 0; j <= 2; ++j)
440 {
441 G4cout << " * " << axis[j] << " axis:" << G4endl;
442 G4int count = fBoundaries[j].size();
443 for(G4int i=0; i < count-1; ++i)
444 {
445 G4cout << " Slice #" << i+1 << ": [" << fBoundaries[j][i]
446 << " ; " << fBoundaries[j][i+1] << "] -> ";
447 bits.set(size,(const char *)fBitmasks[j].fAllBits+i
448 *fNPerSlice*sizeof(G4int));
449 G4String result = GetCandidatesAsString(bits);
450 G4cout << "[ " << result.c_str() << "] " << G4endl;
451 }
452 }
453}
G4String GetCandidatesAsString(const G4SurfBits &bits) const
Definition: G4Voxelizer.cc:416

References fBitmasks, fBoundaries, fNPerSlice, G4cout, G4endl, GetCandidatesAsString(), and G4SurfBits::set().

◆ DisplayVoxelLimits()

void G4Voxelizer::DisplayVoxelLimits ( ) const

Definition at line 197 of file G4Voxelizer.cc.

198{
199 // "DisplayVoxelLimits" displays the dX, dY, dZ, pX, pY and pZ for each node
200
201 G4int numNodes = fBoxes.size();
202 G4int oldprec = G4cout.precision(16);
203 for(G4int i = 0; i < numNodes; ++i)
204 {
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";
209 }
210 G4cout.precision(oldprec);
211}

References fBoxes, and G4cout.

◆ DistanceToBoundingBox()

G4double G4Voxelizer::DistanceToBoundingBox ( const G4ThreeVector point) const

Definition at line 1183 of file G4Voxelizer.cc.

1184{
1185 G4ThreeVector pointShifted = point - fBoundingBoxCenter;
1186 G4double shift = MinDistanceToBox(pointShifted, fBoundingBoxSize);
1187 return shift;
1188}
static G4double MinDistanceToBox(const G4ThreeVector &aPoint, const G4ThreeVector &f)

References fBoundingBoxCenter, fBoundingBoxSize, and MinDistanceToBox().

Referenced by G4MultiUnion::DistanceToIn(), and G4TessellatedSolid::SafetyFromOutside().

◆ DistanceToFirst()

G4double G4Voxelizer::DistanceToFirst ( const G4ThreeVector point,
const G4ThreeVector direction 
) const

Definition at line 1173 of file G4Voxelizer.cc.

1175{
1176 G4ThreeVector pointShifted = point - fBoundingBoxCenter;
1177 G4double shift = fBoundingBox.DistanceToIn(pointShifted, direction);
1178 return shift;
1179}
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
Definition: G4Box.cc:325

References G4Box::DistanceToIn(), fBoundingBox, and fBoundingBoxCenter.

Referenced by G4MultiUnion::DistanceToIn(), and G4TessellatedSolid::DistanceToInCore().

◆ DistanceToNext()

G4double G4Voxelizer::DistanceToNext ( const G4ThreeVector point,
const G4ThreeVector direction,
std::vector< G4int > &  curVoxel 
) const

Definition at line 1218 of file G4Voxelizer.cc.

1221{
1222 G4double shift = kInfinity;
1223
1224 G4int cur = 0; // the smallest index, which would be than increased
1225 for (G4int i = 0; i <= 2; ++i)
1226 {
1227 // Looking for the next voxels on the considered direction X,Y,Z axis
1228 //
1229 const std::vector<G4double>& boundary = fBoundaries[i];
1230 G4int index = curVoxel[i];
1231 if (direction[i] >= 1e-10)
1232 {
1233 ++index;
1234 }
1235 else
1236 {
1237 if (direction[i] > -1e-10)
1238 continue;
1239 }
1240 G4double dif = boundary[index] - point[i];
1241 G4double distance = dif / direction[i];
1242
1243 if (shift > distance)
1244 {
1245 shift = distance;
1246 cur = i;
1247 }
1248 }
1249
1250 if (shift != kInfinity)
1251 {
1252 // updating current voxel using the index corresponding
1253 // to the closest voxel boundary on the ray
1254
1255 if (direction[cur] > 0)
1256 {
1257 if (++curVoxel[cur] >= (G4int) fBoundaries[cur].size() - 1)
1258 shift = kInfinity;
1259 }
1260 else
1261 {
1262 if (--curVoxel[cur] < 0)
1263 shift = kInfinity;
1264 }
1265 }
1266
1267/*
1268 for (auto i = 0; i <= 2; ++i)
1269 {
1270 // Looking for the next voxels on the considered direction X,Y,Z axis
1271 //
1272 const std::vector<G4double> &boundary = fBoundaries[i];
1273 G4int cur = curVoxel[i];
1274 if(direction[i] >= 1e-10)
1275 {
1276 if (boundary[++cur] - point[i] < fTolerance) // make sure shift would
1277 if (++cur >= (G4int) boundary.size()) // be non-zero
1278 continue;
1279 }
1280 else
1281 {
1282 if(direction[i] <= -1e-10)
1283 {
1284 if (point[i] - boundary[cur] < fTolerance) // make sure shift would
1285 if (--cur < 0) // be non-zero
1286 continue;
1287 }
1288 else
1289 continue;
1290 }
1291 G4double dif = boundary[cur] - point[i];
1292 G4double distance = dif / direction[i];
1293
1294 if (shift > distance)
1295 shift = distance;
1296 }
1297*/
1298 return shift;
1299}
static const G4double kInfinity
Definition: geomdefs.hh:41

References fBoundaries, and kInfinity.

Referenced by G4MultiUnion::DistanceToIn(), G4TessellatedSolid::DistanceToInCore(), G4TessellatedSolid::DistanceToOutCore(), and G4TessellatedSolid::InsideVoxels().

◆ Empty()

const G4SurfBits & G4Voxelizer::Empty ( ) const
inline

◆ FindComponentsFastest()

void G4Voxelizer::FindComponentsFastest ( unsigned int  mask,
std::vector< G4int > &  list,
G4int  i 
)
staticprivate

Definition at line 911 of file G4Voxelizer.cc.

913{
914 for (G4int byte = 0; byte < (G4int) (sizeof(unsigned int)); ++byte)
915 {
916 if (G4int maskByte = mask & 0xFF)
917 {
918 for (G4int bit = 0; bit < 8; ++bit)
919 {
920 if (maskByte & 1)
921 { list.push_back(8*(sizeof(unsigned int)*i+ byte) + bit); }
922 if (!(maskByte >>= 1)) break;
923 }
924 }
925 mask >>= 8;
926 }
927}

Referenced by GetCandidatesVoxelArray().

◆ GetBitsPerSlice()

G4int G4Voxelizer::GetBitsPerSlice ( ) const
inline

◆ GetBoundary()

const std::vector< G4double > & G4Voxelizer::GetBoundary ( G4int  index) const
inline

◆ GetBoxes()

const std::vector< G4VoxelBox > & G4Voxelizer::GetBoxes ( ) const
inline

◆ GetCandidates()

const std::vector< G4int > & G4Voxelizer::GetCandidates ( std::vector< G4int > &  curVoxel) const
inline

◆ GetCandidatesAsString()

G4String G4Voxelizer::GetCandidatesAsString ( const G4SurfBits bits) const
private

Definition at line 416 of file G4Voxelizer.cc.

417{
418 // Decodes the candidates in mask as G4String.
419
420 stringstream ss;
421 G4int numNodes = fBoxes.size();
422
423 for(G4int i=0; i<numNodes; ++i)
424 {
425 if (bits.TestBitNumber(i)) { ss << i+1 << " "; }
426 }
427 return ss.str();
428}
G4bool TestBitNumber(unsigned int bitnumber) const
Definition: G4SurfBits.hh:141

References fBoxes, and G4SurfBits::TestBitNumber().

Referenced by DisplayListNodes().

◆ GetCandidatesVoxel()

void G4Voxelizer::GetCandidatesVoxel ( std::vector< G4int > &  voxels)

Definition at line 896 of file G4Voxelizer.cc.

897{
898 // "GetCandidates" should compute which solids are possibly contained in
899 // the voxel defined by the three slices characterized by the passed indexes.
900
901 G4cout << " Candidates in voxel [" << voxels[0] << " ; " << voxels[1]
902 << " ; " << voxels[2] << "]: ";
903 std::vector<G4int> candidates;
904 G4int count = GetCandidatesVoxelArray(voxels, candidates);
905 G4cout << "[ ";
906 for (G4int i = 0; i < count; ++i) G4cout << candidates[i];
907 G4cout << "] " << G4endl;
908}

References G4cout, G4endl, and GetCandidatesVoxelArray().

◆ GetCandidatesVoxelArray() [1/3]

G4int G4Voxelizer::GetCandidatesVoxelArray ( const G4ThreeVector point,
std::vector< G4int > &  list,
G4SurfBits crossed = nullptr 
) const

Definition at line 973 of file G4Voxelizer.cc.

975{
976 // Method returning the candidates corresponding to the passed point
977
978 list.clear();
979
980 for (auto i = 0; i <= 2; ++i)
981 {
982 if(point[i] < fBoundaries[i].front() || point[i] >= fBoundaries[i].back())
983 return 0;
984 }
985
986 if (fTotalCandidates == 1)
987 {
988 list.push_back(0);
989 return 1;
990 }
991 else
992 {
993 if (fNPerSlice == 1)
994 {
995 unsigned int mask = 0xFFffFFff;
996 G4int slice;
997 if (fBoundaries[0].size() > 2)
998 {
999 slice = BinarySearch(fBoundaries[0], point.x());
1000 if (!(mask = ((unsigned int*) fBitmasks[0].fAllBits)[slice]))
1001 return 0;
1002 }
1003 if (fBoundaries[1].size() > 2)
1004 {
1005 slice = BinarySearch(fBoundaries[1], point.y());
1006 if (!(mask &= ((unsigned int*) fBitmasks[1].fAllBits)[slice]))
1007 return 0;
1008 }
1009 if (fBoundaries[2].size() > 2)
1010 {
1011 slice = BinarySearch(fBoundaries[2], point.z());
1012 if (!(mask &= ((unsigned int*) fBitmasks[2].fAllBits)[slice]))
1013 return 0;
1014 }
1015 if (crossed && (!(mask &= ~((unsigned int*)crossed->fAllBits)[0])))
1016 return 0;
1017
1018 FindComponentsFastest(mask, list, 0);
1019 }
1020 else
1021 {
1022 unsigned int* masks[3], mask; // masks for X,Y,Z axis
1023 for (auto i = 0; i <= 2; ++i)
1024 {
1025 G4int slice = BinarySearch(fBoundaries[i], point[i]);
1026 masks[i] = ((unsigned int*) fBitmasks[i].fAllBits)
1027 + slice * fNPerSlice;
1028 }
1029 unsigned int* maskCrossed = crossed
1030 ? (unsigned int*)crossed->fAllBits : 0;
1031
1032 for (G4int i = 0 ; i < fNPerSlice; ++i)
1033 {
1034 // Logic "and" of the masks along the 3 axes x, y, z:
1035 // removing "if (!" and ") continue" => slightly slower
1036 //
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;
1041
1042 FindComponentsFastest(mask, list, i);
1043 }
1044 }
1045/*
1046 if (fNPerSlice == 1)
1047 {
1048 unsigned int mask;
1049 G4int slice = BinarySearch(fBoundaries[0], point.x());
1050 if (!(mask = ((unsigned int *) fBitmasks[0].fAllBits)[slice]
1051 )) return 0;
1052 slice = BinarySearch(fBoundaries[1], point.y());
1053 if (!(mask &= ((unsigned int *) fBitmasks[1].fAllBits)[slice]
1054 )) return 0;
1055 slice = BinarySearch(fBoundaries[2], point.z());
1056 if (!(mask &= ((unsigned int *) fBitmasks[2].fAllBits)[slice]
1057 )) return 0;
1058 if (crossed && (!(mask &= ~((unsigned int *)crossed->fAllBits)[0])))
1059 return 0;
1060
1061 FindComponentsFastest(mask, list, 0);
1062 }
1063 else
1064 {
1065 unsigned int *masks[3], mask; // masks for X,Y,Z axis
1066 for (auto i = 0; i <= 2; ++i)
1067 {
1068 G4int slice = BinarySearch(fBoundaries[i], point[i]);
1069 masks[i] = ((unsigned int *) fBitmasks[i].fAllBits) + slice*fNPerSlice;
1070 }
1071 unsigned int *maskCrossed =
1072 crossed ? (unsigned int *)crossed->fAllBits : 0;
1073
1074 for (G4int i = 0 ; i < fNPerSlice; ++i)
1075 {
1076 // Logic "and" of the masks along the 3 axes x, y, z:
1077 // removing "if (!" and ") continue" => slightly slower
1078 //
1079 if (!(mask = masks[0][i])) continue;
1080 if (!(mask &= masks[1][i])) continue;
1081 if (!(mask &= masks[2][i])) continue;
1082 if (maskCrossed && !(mask &= ~maskCrossed[i])) continue;
1083
1084 FindComponentsFastest(mask, list, i);
1085 }
1086 }
1087*/
1088 }
1089 return list.size();
1090}
unsigned char * fAllBits
Definition: G4SurfBits.hh:104
static void FindComponentsFastest(unsigned int mask, std::vector< G4int > &list, G4int i)
Definition: G4Voxelizer.cc:911

References BinarySearch(), G4SurfBits::fAllBits, fBitmasks, fBoundaries, FindComponentsFastest(), fNPerSlice, fTotalCandidates, CLHEP::Hep3Vector::x(), CLHEP::Hep3Vector::y(), and CLHEP::Hep3Vector::z().

Referenced by BuildEmpty(), CreateMiniVoxels(), G4MultiUnion::DistanceToIn(), G4MultiUnion::DistanceToOut(), G4MultiUnion::DistanceToOutVoxels(), GetCandidatesVoxel(), GetCandidatesVoxelArray(), G4MultiUnion::InsideWithExclusion(), and G4MultiUnion::SurfaceNormal().

◆ GetCandidatesVoxelArray() [2/3]

G4int G4Voxelizer::GetCandidatesVoxelArray ( const std::vector< G4int > &  voxels,
const G4SurfBits  bitmasks[],
std::vector< G4int > &  list,
G4SurfBits crossed = nullptr 
) const

Definition at line 1094 of file G4Voxelizer.cc.

1098{
1099 list.clear();
1100
1101 if (fTotalCandidates == 1)
1102 {
1103 list.push_back(0);
1104 return 1;
1105 }
1106 else
1107 {
1108 if (fNPerSlice == 1)
1109 {
1110 unsigned int mask;
1111 if (!(mask = ((unsigned int *) bitmasks[0].fAllBits)[voxels[0]]))
1112 return 0;
1113 if (!(mask &= ((unsigned int *) bitmasks[1].fAllBits)[voxels[1]]))
1114 return 0;
1115 if (!(mask &= ((unsigned int *) bitmasks[2].fAllBits)[voxels[2]]))
1116 return 0;
1117 if (crossed && (!(mask &= ~((unsigned int *)crossed->fAllBits)[0])))
1118 return 0;
1119
1120 FindComponentsFastest(mask, list, 0);
1121 }
1122 else
1123 {
1124 unsigned int *masks[3], mask; // masks for X,Y,Z axis
1125 for (auto i = 0; i <= 2; ++i)
1126 {
1127 masks[i] = ((unsigned int *) bitmasks[i].fAllBits)
1128 + voxels[i]*fNPerSlice;
1129 }
1130 unsigned int *maskCrossed = crossed != nullptr
1131 ? (unsigned int *)crossed->fAllBits : 0;
1132
1133 for (G4int i = 0 ; i < fNPerSlice; ++i)
1134 {
1135 // Logic "and" of the masks along the 3 axes x, y, z:
1136 // removing "if (!" and ") continue" => slightly slower
1137 //
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;
1142
1143 FindComponentsFastest(mask, list, i);
1144 }
1145 }
1146 }
1147 return list.size();
1148}

References G4SurfBits::fAllBits, FindComponentsFastest(), fNPerSlice, and fTotalCandidates.

◆ GetCandidatesVoxelArray() [3/3]

G4int G4Voxelizer::GetCandidatesVoxelArray ( const std::vector< G4int > &  voxels,
std::vector< G4int > &  list,
G4SurfBits crossed = nullptr 
) const

Definition at line 1152 of file G4Voxelizer.cc.

1154{
1155 // Method returning the candidates corresponding to the passed point
1156
1157 return GetCandidatesVoxelArray(voxels, fBitmasks, list, crossed);
1158}

References fBitmasks, and GetCandidatesVoxelArray().

◆ GetCountOfVoxels()

long long G4Voxelizer::GetCountOfVoxels ( ) const
inline

◆ GetDefaultVoxelsCount()

G4int G4Voxelizer::GetDefaultVoxelsCount ( )
static

Definition at line 1354 of file G4Voxelizer.cc.

1355{
1356 return fDefaultVoxelsCount;
1357}

References fDefaultVoxelsCount.

◆ GetGlobalPoint()

G4ThreeVector G4Voxelizer::GetGlobalPoint ( const G4Transform3D trans,
const G4ThreeVector lpoint 
) const
inlineprivate

Referenced by TransformLimits().

◆ GetMaxVoxels()

G4int G4Voxelizer::GetMaxVoxels ( G4ThreeVector ratioOfReduction)
inline

◆ GetPointIndex()

G4int G4Voxelizer::GetPointIndex ( const G4ThreeVector p) const
inline

◆ GetPointVoxel()

G4bool G4Voxelizer::GetPointVoxel ( const G4ThreeVector p,
std::vector< G4int > &  voxels 
) const
inline

◆ GetTotalCandidates()

G4int G4Voxelizer::GetTotalCandidates ( ) const
inline

◆ GetVoxel()

void G4Voxelizer::GetVoxel ( std::vector< G4int > &  curVoxel,
const G4ThreeVector point 
) const
inline

◆ GetVoxelBox()

const G4VoxelBox & G4Voxelizer::GetVoxelBox ( G4int  i) const
inline

◆ GetVoxelBoxCandidates()

const std::vector< G4int > & G4Voxelizer::GetVoxelBoxCandidates ( G4int  i) const
inline

◆ GetVoxelBoxesSize()

G4int G4Voxelizer::GetVoxelBoxesSize ( ) const
inline

◆ GetVoxelsIndex() [1/2]

G4int G4Voxelizer::GetVoxelsIndex ( const std::vector< G4int > &  voxels) const
inline

◆ GetVoxelsIndex() [2/2]

G4int G4Voxelizer::GetVoxelsIndex ( G4int  x,
G4int  y,
G4int  z 
) const
inline

◆ IsEmpty()

G4bool G4Voxelizer::IsEmpty ( G4int  index) const
inline

◆ MinDistanceToBox()

G4double G4Voxelizer::MinDistanceToBox ( const G4ThreeVector aPoint,
const G4ThreeVector f 
)
static

Definition at line 1192 of file G4Voxelizer.cc.

1194{
1195 // Estimates the isotropic safety from a point outside the current solid to
1196 // any of its surfaces. The algorithm may be accurate or should provide a
1197 // fast underestimate.
1198
1199 G4double safe, safx, safy, safz;
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; // point is inside
1206
1207 G4double safsq = 0.0;
1208 G4int count = 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);
1214}

References CLHEP::Hep3Vector::x(), CLHEP::Hep3Vector::y(), and CLHEP::Hep3Vector::z().

Referenced by DistanceToBoundingBox(), and G4TessellatedSolid::MinDistanceFacet().

◆ SetDefaultVoxelsCount()

void G4Voxelizer::SetDefaultVoxelsCount ( G4int  count)
static

Definition at line 1348 of file G4Voxelizer.cc.

1349{
1350 fDefaultVoxelsCount = count;
1351}

References fDefaultVoxelsCount.

◆ SetMaxVoxels() [1/2]

void G4Voxelizer::SetMaxVoxels ( const G4ThreeVector reductionRatio)

Definition at line 1341 of file G4Voxelizer.cc.

1342{
1343 fMaxVoxels = -1;
1344 fReductionRatio = ratioOfReduction;
1345}
G4int fMaxVoxels
Definition: G4Voxelizer.hh:254
G4ThreeVector fReductionRatio
Definition: G4Voxelizer.hh:252

References fMaxVoxels, and fReductionRatio.

◆ SetMaxVoxels() [2/2]

void G4Voxelizer::SetMaxVoxels ( G4int  max)

◆ SetReductionRatio()

void G4Voxelizer::SetReductionRatio ( G4int  maxVoxels,
G4ThreeVector reductionRatio 
)
private

Definition at line 499 of file G4Voxelizer.cc.

501{
502 G4double maxTotal = (G4double) fCandidatesCounts[0].size()
503 * fCandidatesCounts[1].size() * fCandidatesCounts[2].size();
504
505 if (maxVoxels > 0 && maxVoxels < maxTotal)
506 {
507 G4double ratio = (G4double) maxVoxels / maxTotal;
508 ratio = std::pow(ratio, 1./3.);
509 if (ratio > 1) { ratio = 1; }
510 reductionRatio.set(ratio,ratio,ratio);
511 }
512}

References fCandidatesCounts, and CLHEP::Hep3Vector::set().

Referenced by Voxelize().

◆ TransformLimits()

void G4Voxelizer::TransformLimits ( G4ThreeVector min,
G4ThreeVector max,
const G4Transform3D transformation 
) const
private

Definition at line 930 of file G4Voxelizer.cc.

932{
933 // The goal of this method is to convert the quantities min and max
934 // (representing the bounding box of a given solid in its local frame)
935 // to the main frame, using "transformation"
936
937 G4ThreeVector vertices[8] = // Detemination of the vertices thanks to
938 { // the extension of each solid:
939 G4ThreeVector(min.x(), min.y(), min.z()), // 1st vertice:
940 G4ThreeVector(min.x(), max.y(), min.z()), // 2nd vertice:
941 G4ThreeVector(max.x(), max.y(), min.z()),
942 G4ThreeVector(max.x(), min.y(), min.z()),
943 G4ThreeVector(min.x(), min.y(), max.z()),
944 G4ThreeVector(min.x(), max.y(), max.z()),
945 G4ThreeVector(max.x(), max.y(), max.z()),
946 G4ThreeVector(max.x(), min.y(), max.z())
947 };
948
951
952 // Loop on th vertices
953 G4int limit = sizeof(vertices) / sizeof(G4ThreeVector);
954 for (G4int i = 0 ; i < limit; ++i)
955 {
956 // From local frame to the global one:
957 // Current positions on the three axis:
958 G4ThreeVector current = GetGlobalPoint(transformation, vertices[i]);
959
960 // If need be, replacement of the min & max values:
961 if (current.x() > max.x()) max.setX(current.x());
962 if (current.x() < min.x()) min.setX(current.x());
963
964 if (current.y() > max.y()) max.setY(current.y());
965 if (current.y() < min.y()) min.setY(current.y());
966
967 if (current.z() > max.z()) max.setZ(current.z());
968 if (current.z() < min.z()) min.setZ(current.z());
969 }
970}
CLHEP::Hep3Vector G4ThreeVector
G4ThreeVector GetGlobalPoint(const G4Transform3D &trans, const G4ThreeVector &lpoint) const

References GetGlobalPoint(), kInfinity, G4INCL::Math::max(), G4INCL::Math::min(), CLHEP::Hep3Vector::x(), CLHEP::Hep3Vector::y(), and CLHEP::Hep3Vector::z().

Referenced by BuildVoxelLimits().

◆ UpdateCurrentVoxel()

G4bool G4Voxelizer::UpdateCurrentVoxel ( const G4ThreeVector point,
const G4ThreeVector direction,
std::vector< G4int > &  curVoxel 
) const

Definition at line 1303 of file G4Voxelizer.cc.

1306{
1307 for (auto i = 0; i <= 2; ++i)
1308 {
1309 G4int index = curVoxel[i];
1310 const std::vector<G4double> &boundary = fBoundaries[i];
1311
1312 if (direction[i] > 0)
1313 {
1314 if (point[i] >= boundary[++index])
1315 if (++curVoxel[i] >= (G4int) boundary.size() - 1)
1316 return false;
1317 }
1318 else
1319 {
1320 if (point[i] < boundary[index])
1321 if (--curVoxel[i] < 0)
1322 return false;
1323 }
1324#ifdef G4SPECSDEBUG
1325 G4int indexOK = BinarySearch(boundary, point[i]);
1326 if (curVoxel[i] != indexOK)
1327 curVoxel[i] = indexOK; // put breakpoint here
1328#endif
1329 }
1330 return true;
1331}

References BinarySearch(), and fBoundaries.

Referenced by G4TessellatedSolid::DistanceToInCore(), G4TessellatedSolid::DistanceToOutCore(), and G4TessellatedSolid::InsideVoxels().

◆ Voxelize() [1/2]

void G4Voxelizer::Voxelize ( std::vector< G4VFacet * > &  facets)

Definition at line 767 of file G4Voxelizer.cc.

768{
769 G4int maxVoxels = fMaxVoxels;
770 G4ThreeVector reductionRatio = fReductionRatio;
771
772 G4int size = facets.size();
773 if (size < 10)
774 {
775 for (G4int i = 0; i < (G4int) facets.size(); ++i)
776 {
777 if (facets[i]->GetNumberOfVertices() > 3) size++;
778 }
779 }
780
781 if ((size >= 10 || maxVoxels > 0) && maxVoxels != 0 && maxVoxels != 1)
782 {
783#ifdef G4SPECSDEBUG
784 G4cout << "Building voxel limits..." << G4endl;
785#endif
786
787 BuildVoxelLimits(facets);
788
789#ifdef G4SPECSDEBUG
790 G4cout << "Building boundaries..." << G4endl;
791#endif
792
794
795#ifdef G4SPECSDEBUG
796 G4cout << "Building bitmasks..." << G4endl;
797#endif
798
799 BuildBitmasks(fBoundaries, 0, true);
800
801 if (maxVoxels < 0 && reductionRatio == G4ThreeVector())
802 {
803 maxVoxels = fTotalCandidates;
804 if (fTotalCandidates > 1000000) maxVoxels = 1000000;
805 }
806
807 SetReductionRatio(maxVoxels, reductionRatio);
808
810
811#ifdef G4SPECSDEBUG
812 G4cout << "Total number of voxels: " << fCountOfVoxels << G4endl;
813#endif
814
815 BuildReduceVoxels2(fBoundaries, reductionRatio);
816
818
819#ifdef G4SPECSDEBUG
820 G4cout << "Total number of voxels after reduction: "
822#endif
823
824#ifdef G4SPECSDEBUG
825 G4cout << "Building bitmasks..." << G4endl;
826#endif
827
829
830 G4ThreeVector reductionRatioMini;
831
832 G4SurfBits bitmasksMini[3];
833
834 // section for building mini voxels
835
836 std::vector<G4double> miniBoundaries[3];
837
838 for (auto i = 0; i <= 2; ++i) { miniBoundaries[i] = fBoundaries[i]; }
839
840 G4int voxelsCountMini = (fCountOfVoxels >= 1000)
841 ? 100 : fCountOfVoxels / 10;
842
843 SetReductionRatio(voxelsCountMini, reductionRatioMini);
844
845#ifdef G4SPECSDEBUG
846 G4cout << "Building reduced voxels..." << G4endl;
847#endif
848
849 BuildReduceVoxels(miniBoundaries, reductionRatioMini);
850
851#ifdef G4SPECSDEBUG
852 G4int total = CountVoxels(miniBoundaries);
853 G4cout << "Total number of mini voxels: " << total << G4endl;
854#endif
855
856#ifdef G4SPECSDEBUG
857 G4cout << "Building mini bitmasks..." << G4endl;
858#endif
859
860 BuildBitmasks(miniBoundaries, bitmasksMini);
861
862#ifdef G4SPECSDEBUG
863 G4cout << "Creating Mini Voxels..." << G4endl;
864#endif
865
866 CreateMiniVoxels(miniBoundaries, bitmasksMini);
867
868#ifdef G4SPECSDEBUG
869 G4cout << "Building bounding box..." << G4endl;
870#endif
871
873
874#ifdef G4SPECSDEBUG
875 G4cout << "Building empty..." << G4endl;
876#endif
877
878 BuildEmpty();
879
880#ifdef G4SPECSDEBUG
881 G4cout << "Deallocating unnecessary fields during runtime..." << G4endl;
882#endif
883 // deallocate fields unnecessary during runtime
884 //
885 fBoxes.resize(0);
886 for (auto i = 0; i < 3; ++i)
887 {
888 fCandidatesCounts[i].resize(0);
889 fBitmasks[i].Clear();
890 }
891 }
892}
long long CountVoxels(std::vector< G4double > boundaries[]) const
void BuildReduceVoxels(std::vector< G4double > fBoundaries[], G4ThreeVector reductionRatio)
Definition: G4Voxelizer.cc:515
void SetReductionRatio(G4int maxVoxels, G4ThreeVector &reductionRatio)
Definition: G4Voxelizer.cc:499
void BuildVoxelLimits(std::vector< G4VSolid * > &solids, std::vector< G4Transform3D > &transforms)
Definition: G4Voxelizer.cc:116
void BuildReduceVoxels2(std::vector< G4double > fBoundaries[], G4ThreeVector reductionRatio)
Definition: G4Voxelizer.cc:670
void BuildBoundaries()
Definition: G4Voxelizer.cc:244
void BuildBitmasks(std::vector< G4double > fBoundaries[], G4SurfBits bitmasks[], G4bool countsOnly=false)
Definition: G4Voxelizer.cc:351
void BuildEmpty()
Definition: G4Voxelizer.cc:73
void CreateMiniVoxels(std::vector< G4double > fBoundaries[], G4SurfBits bitmasks[])
Definition: G4Voxelizer.cc:731

References BuildBitmasks(), BuildBoundaries(), BuildBoundingBox(), BuildEmpty(), BuildReduceVoxels(), BuildReduceVoxels2(), BuildVoxelLimits(), G4SurfBits::Clear(), CountVoxels(), CreateMiniVoxels(), fBitmasks, fBoundaries, fBoxes, fCandidatesCounts, fCountOfVoxels, fMaxVoxels, fReductionRatio, fTotalCandidates, G4cout, G4endl, SetReductionRatio(), and G4INCL::CrossSections::total().

◆ Voxelize() [2/2]

void G4Voxelizer::Voxelize ( std::vector< G4VSolid * > &  solids,
std::vector< G4Transform3D > &  transforms 
)

Definition at line 713 of file G4Voxelizer.cc.

715{
716 BuildVoxelLimits(solids, transforms);
720 BuildEmpty(); // this does not work well for multi-union,
721 // actually only makes performance slower,
722 // these are only pre-calculated but not used by multi-union
723
724 for (auto i = 0; i < 3; ++i)
725 {
726 fCandidatesCounts[i].resize(0);
727 }
728}

References BuildBitmasks(), BuildBoundaries(), BuildBoundingBox(), BuildEmpty(), BuildVoxelLimits(), fBitmasks, fBoundaries, and fCandidatesCounts.

Referenced by G4MultiUnion::Voxelize(), and G4TessellatedSolid::Voxelize().

Field Documentation

◆ fBitmasks

G4SurfBits G4Voxelizer::fBitmasks[3]
private

◆ fBoundaries

std::vector<G4double> G4Voxelizer::fBoundaries[3]
private

◆ fBoundingBox

G4Box G4Voxelizer::fBoundingBox
private

Definition at line 248 of file G4Voxelizer.hh.

Referenced by BuildBoundingBox(), DistanceToFirst(), and G4Voxelizer().

◆ fBoundingBoxCenter

G4ThreeVector G4Voxelizer::fBoundingBoxCenter
private

Definition at line 246 of file G4Voxelizer.hh.

Referenced by BuildBoundingBox(), DistanceToBoundingBox(), and DistanceToFirst().

◆ fBoundingBoxSize

G4ThreeVector G4Voxelizer::fBoundingBoxSize
private

Definition at line 250 of file G4Voxelizer.hh.

Referenced by BuildBoundingBox(), and DistanceToBoundingBox().

◆ fBoxes

std::vector<G4VoxelBox> G4Voxelizer::fBoxes
private

◆ fCandidates

std::map<G4int, std::vector<G4int> > G4Voxelizer::fCandidates
mutableprivate

Definition at line 226 of file G4Voxelizer.hh.

Referenced by AllocatedMemory(), and BuildEmpty().

◆ fCandidatesCounts

std::vector<G4int> G4Voxelizer::fCandidatesCounts[3]
private

◆ fCountOfVoxels

long long G4Voxelizer::fCountOfVoxels
private

Definition at line 230 of file G4Voxelizer.hh.

Referenced by G4Voxelizer(), and Voxelize().

◆ fDefaultVoxelsCount

G4ThreadLocal G4int G4Voxelizer::fDefaultVoxelsCount = -1
staticprivate

Definition at line 222 of file G4Voxelizer.hh.

Referenced by G4Voxelizer(), GetDefaultVoxelsCount(), and SetDefaultVoxelsCount().

◆ fEmpty

G4SurfBits G4Voxelizer::fEmpty
private

Definition at line 258 of file G4Voxelizer.hh.

Referenced by AllocatedMemory(), and BuildEmpty().

◆ fMaxVoxels

G4int G4Voxelizer::fMaxVoxels
private

Definition at line 254 of file G4Voxelizer.hh.

Referenced by SetMaxVoxels(), and Voxelize().

◆ fNoCandidates

const std::vector<G4int> G4Voxelizer::fNoCandidates
private

Definition at line 228 of file G4Voxelizer.hh.

◆ fNPerSlice

G4int G4Voxelizer::fNPerSlice
private

◆ fReductionRatio

G4ThreeVector G4Voxelizer::fReductionRatio
private

Definition at line 252 of file G4Voxelizer.hh.

Referenced by SetMaxVoxels(), and Voxelize().

◆ fTolerance

G4double G4Voxelizer::fTolerance
private

Definition at line 256 of file G4Voxelizer.hh.

Referenced by BuildBoundaries(), BuildVoxelLimits(), and G4Voxelizer().

◆ fTotalCandidates

G4int G4Voxelizer::fTotalCandidates
private

◆ fVoxelBoxes

std::vector<G4VoxelBox> G4Voxelizer::fVoxelBoxes
private

Definition at line 224 of file G4Voxelizer.hh.

Referenced by CreateMiniVoxels().

◆ fVoxelBoxesCandidates

std::vector<std::vector<G4int> > G4Voxelizer::fVoxelBoxesCandidates
private

Definition at line 225 of file G4Voxelizer.hh.

Referenced by CreateMiniVoxels().


The documentation for this class was generated from the following files: