Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/geometry/solids/specific/src/G4Voxelizer.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /geometry/solids/specific/src/G4Voxelizer.cc (Version 11.3.0) and /geometry/solids/specific/src/G4Voxelizer.cc (Version 10.2)


  1 //                                                  1 
  2 // *******************************************    
  3 // * License and Disclaimer                       
  4 // *                                              
  5 // * The  Geant4 software  is  copyright of th    
  6 // * the Geant4 Collaboration.  It is provided    
  7 // * conditions of the Geant4 Software License    
  8 // * LICENSE and available at  http://cern.ch/    
  9 // * include a list of copyright holders.         
 10 // *                                              
 11 // * Neither the authors of this software syst    
 12 // * institutes,nor the agencies providing fin    
 13 // * work  make  any representation or  warran    
 14 // * regarding  this  software system or assum    
 15 // * use.  Please see the license in the file     
 16 // * for the full disclaimer and the limitatio    
 17 // *                                              
 18 // * This  code  implementation is the result     
 19 // * technical work of the GEANT4 collaboratio    
 20 // * By using,  copying,  modifying or  distri    
 21 // * any work based  on the software)  you  ag    
 22 // * use  in  resulting  scientific  publicati    
 23 // * acceptance of all terms of the Geant4 Sof    
 24 // *******************************************    
 25 //                                                
 26 // G4Voxelizer implementation                     
 27 //                                                
 28 // 19.10.12 Marek Gayer, created                  
 29 // -------------------------------------------    
 30                                                   
 31 #include <iostream>                               
 32 #include <iomanip>                                
 33 #include <sstream>                                
 34 #include <algorithm>                              
 35 #include <set>                                    
 36                                                   
 37 #include "G4VSolid.hh"                            
 38                                                   
 39 #include "G4CSGSolid.hh"                          
 40 #include "G4GeometryTolerance.hh"                 
 41 #include "G4Orb.hh"                               
 42 #include "G4PhysicalConstants.hh"                 
 43 #include "G4SolidStore.hh"                        
 44 #include "G4Types.hh"                             
 45 #include "G4Voxelizer.hh"                         
 46 #include "Randomize.hh"                           
 47 #include "geomdefs.hh"                            
 48                                                   
 49 using namespace std;                              
 50                                                   
 51 G4ThreadLocal G4int G4Voxelizer::fDefaultVoxel    
 52                                                   
 53 //____________________________________________    
 54 G4Voxelizer::G4Voxelizer()                        
 55   : fBoundingBox("VoxBBox", 1, 1, 1)              
 56 {                                                 
 57   fCountOfVoxels = fNPerSlice = fTotalCandidat    
 58                                                   
 59   fTolerance = G4GeometryTolerance::GetInstanc    
 60                                                   
 61   SetMaxVoxels(fDefaultVoxelsCount);              
 62                                                   
 63   G4SolidStore::GetInstance()->DeRegister(&fBo    
 64 }                                                 
 65                                                   
 66 //____________________________________________    
 67 G4Voxelizer::~G4Voxelizer() = default;            
 68                                                   
 69 //____________________________________________    
 70 void G4Voxelizer::BuildEmpty()                    
 71 {                                                 
 72   // by reserving the size of candidates, we w    
 73   // the vector which could cause fragmentatio    
 74   //                                              
 75   std::vector<G4int> xyz(3), max(3), candidate    
 76   const std::vector<G4int> empty(0);              
 77                                                   
 78   for (auto i = 0; i <= 2; ++i) max[i] = (G4in    
 79   unsigned int size = max[0] * max[1] * max[2]    
 80                                                   
 81   fEmpty.Clear();                                 
 82   fEmpty.ResetBitNumber(size-1);                  
 83   fEmpty.ResetAllBits(true);                      
 84                                                   
 85   for (xyz[2] = 0; xyz[2] < max[2]; ++xyz[2])     
 86   {                                               
 87     for (xyz[1] = 0; xyz[1] < max[1]; ++xyz[1]    
 88     {                                             
 89       for (xyz[0] = 0; xyz[0] < max[0]; ++xyz[    
 90       {                                           
 91         if (GetCandidatesVoxelArray(xyz, candi    
 92         {                                         
 93           G4int index = GetVoxelsIndex(xyz);      
 94           fEmpty.SetBitNumber(index, false);      
 95                                                   
 96           // rather than assigning directly wi    
 97           // "fCandidates[index] = candidates;    
 98           // capacity would be just exact, we     
 99           //                                      
100           std::vector<G4int> &c = (fCandidates    
101           c.reserve(candidates.size());           
102           c.assign(candidates.begin(), candida    
103         }                                         
104       }                                           
105     }                                             
106   }                                               
107 #ifdef G4SPECSDEBUG                               
108   G4cout << "Non-empty voxels count: " << fCan    
109 #endif                                            
110 }                                                 
111                                                   
112 //____________________________________________    
113 void G4Voxelizer::BuildVoxelLimits(std::vector    
114                                    std::vector    
115 {                                                 
116   // "BuildVoxelLimits"'s aim is to store the     
117   // well as the half lengths related to the b    
118   // These quantities are stored in the array     
119   // node                                         
120   //                                              
121   if (std::size_t numNodes = solids.size()) //    
122   {                                               
123     fBoxes.resize(numNodes); // Array which wi    
124     fNPerSlice = G4int(1 + (fBoxes.size() - 1)    
125                                                   
126     // related to a particular node, but also     
127     // the coordinates of its origin              
128                                                   
129     G4ThreeVector toleranceVector(fTolerance,f    
130                                                   
131     for (std::size_t i = 0; i < numNodes; ++i)    
132     {                                             
133       G4VSolid& solid = *solids[i];               
134       G4Transform3D transform = transforms[i];    
135       G4ThreeVector min, max;                     
136                                                   
137       solid.BoundingLimits(min, max);             
138       if (solid.GetEntityType() == "G4Orb")       
139       {                                           
140         G4Orb& orb = *(G4Orb*) &solid;            
141         G4ThreeVector orbToleranceVector;         
142         G4double tolerance = orb.GetRadialTole    
143         orbToleranceVector.set(tolerance,toler    
144         min -= orbToleranceVector;                
145         max += orbToleranceVector;                
146       }                                           
147       else                                        
148       {                                           
149         min -= toleranceVector;                   
150         max += toleranceVector;                   
151       }                                           
152       TransformLimits(min, max, transform);       
153       fBoxes[i].hlen = (max - min) / 2.;          
154       fBoxes[i].pos =  (max + min) / 2.;          
155     }                                             
156     fTotalCandidates = (G4int)fBoxes.size();      
157   }                                               
158 }                                                 
159                                                   
160 //____________________________________________    
161 void G4Voxelizer::BuildVoxelLimits(std::vector    
162 {                                                 
163   // "BuildVoxelLimits"'s aim is to store the     
164   // as the half lengths related to the boundi    
165   // These quantities are stored in the array     
166   // node.                                        
167                                                   
168   if (std::size_t numNodes = facets.size()) //    
169   {                                               
170     fBoxes.resize(numNodes); // Array which wi    
171     fNPerSlice = G4int(1+(fBoxes.size()-1)/(8*    
172                                                   
173     G4ThreeVector toleranceVector(10*fToleranc    
174                                                   
175     for (std::size_t i = 0; i < numNodes; ++i)    
176     {                                             
177       G4VFacet &facet = *facets[i];               
178       G4ThreeVector min, max;                     
179       G4ThreeVector x(1,0,0), y(0,1,0), z(0,0,    
180       G4ThreeVector extent;                       
181       max.set (facet.Extent(x), facet.Extent(y    
182       min.set (-facet.Extent(-x), -facet.Exten    
183       min -= toleranceVector;                     
184       max += toleranceVector;                     
185       G4ThreeVector hlen = (max - min) / 2;       
186       fBoxes[i].hlen = hlen;                      
187       fBoxes[i].pos = min + hlen;                 
188     }                                             
189     fTotalCandidates = (G4int)fBoxes.size();      
190   }                                               
191 }                                                 
192                                                   
193 //____________________________________________    
194 void G4Voxelizer::DisplayVoxelLimits() const      
195 {                                                 
196   // "DisplayVoxelLimits" displays the dX, dY,    
197                                                   
198   std::size_t numNodes = fBoxes.size();           
199   G4long oldprec = G4cout.precision(16);          
200   for(std::size_t i = 0; i < numNodes; ++i)       
201   {                                               
202     G4cout << setw(10) << setiosflags(ios::fix    
203       "    -> Node " << i+1 <<  ":\n" <<          
204       "\t * [x,y,z] = " << fBoxes[i].hlen <<      
205       "\t * [x,y,z] = " << fBoxes[i].pos << "\    
206   }                                               
207   G4cout.precision(oldprec);                      
208 }                                                 
209                                                   
210 //____________________________________________    
211 void G4Voxelizer::CreateSortedBoundary(std::ve    
212                                        G4int a    
213 {                                                 
214   // "CreateBoundaries"'s aim is to determine     
215   // bounding fBoxes, along each axis. The cre    
216   // in the array "boundariesRaw"                 
217                                                   
218   std::size_t numNodes = fBoxes.size(); // Num    
219                                                   
220   // Determination of the boundaries along x,     
221   //                                              
222   for(std::size_t i = 0 ; i < numNodes; ++i)      
223   {                                               
224     // For each node, the boundaries are creat    
225     // built in method "BuildVoxelLimits"         
226     //                                            
227     G4double p = fBoxes[i].pos[axis], d = fBox    
228                                                   
229     // x boundaries                               
230     //                                            
231 #ifdef G4SPECSDEBUG                               
232     G4cout << "Boundary " << p - d << " - " <<    
233 #endif                                            
234     boundary[2*i] = p - d;                        
235     boundary[2*i+1] = p + d;                      
236   }                                               
237   std::sort(boundary.begin(), boundary.end());    
238 }                                                 
239                                                   
240 //____________________________________________    
241 void G4Voxelizer::BuildBoundaries()               
242 {                                                 
243   // "SortBoundaries" orders the boundaries al    
244   // and also does not take into account redun    
245   // boundaries are separated by a distance st    
246   // The sorted boundaries are respectively st    
247   //              * boundaries[0..2]              
248                                                   
249   // In addition, the number of elements conta    
250   // are precise thanks to variables: boundari    
251   // boundariesCountZ.                            
252                                                   
253   if (std::size_t numNodes = fBoxes.size())       
254   {                                               
255     const G4double tolerance = fTolerance / 10    
256       // Minimal distance to discriminate two     
257                                                   
258     std::vector<G4double> sortedBoundary(2*num    
259                                                   
260     for (auto j = 0; j <= 2; ++j)                 
261     {                                             
262       CreateSortedBoundary(sortedBoundary, j);    
263       std::vector<G4double> &boundary = fBound    
264       boundary.clear();                           
265                                                   
266       for(std::size_t i = 0 ; i < 2*numNodes;     
267       {                                           
268         G4double newBoundary = sortedBoundary[    
269 #ifdef G4SPECSDEBUG                               
270         if (j == 0) G4cout << "Examining " <<     
271 #endif                                            
272         auto size = (G4int)boundary.size();       
273         if((size == 0) || std::abs(boundary[si    
274         {                                         
275           {                                       
276 #ifdef G4SPECSDEBUG                               
277             if (j == 0) G4cout << "Adding boun    
278                                << G4endl;         
279 #endif                                            
280             boundary.push_back(newBoundary);      
281             continue;                             
282           }                                       
283         }                                         
284         // If two successive boundaries are to    
285         // only the first one is considered       
286       }                                           
287                                                   
288       auto n = (G4int)boundary.size();            
289       G4int max = 100000;                         
290       if (n > max/2)                              
291       {                                           
292         G4int skip = n / (max /2); // n has to    
293                                    // therefor    
294         std::vector<G4double> reduced;            
295         for (G4int i = 0; i < n; ++i)             
296         {                                         
297           // 50 ok for 2k, 1000, 2000             
298           auto size = (G4int)boundary.size();     
299           if (i % skip == 0 || i == 0 || i ==     
300           {                                       
301             // this condition of merging bound    
302             // it did not count with right par    
303             // completely ommited and not incl    
304             // Now should be OK                   
305             //                                    
306             reduced.push_back(boundary[i]);       
307           }                                       
308         }                                         
309         boundary = std::move(reduced);            
310       }                                           
311     }                                             
312   }                                               
313 }                                                 
314                                                   
315 //____________________________________________    
316 void G4Voxelizer::DisplayBoundaries()             
317 {                                                 
318   char axis[3] = {'X', 'Y', 'Z'};                 
319   for (auto i = 0; i <= 2; ++i)                   
320   {                                               
321     G4cout << " * " << axis[i] << " axis:" <<     
322     DisplayBoundaries(fBoundaries[i]);            
323   }                                               
324 }                                                 
325                                                   
326 //____________________________________________    
327 void G4Voxelizer::DisplayBoundaries(std::vecto    
328 {                                                 
329   // Prints the positions of the boundaries of    
330                                                   
331   std::size_t count = boundaries.size();          
332   G4long oldprec = G4cout.precision(16);          
333   for(std::size_t i = 0; i < count; ++i)          
334   {                                               
335     G4cout << setw(10) << setiosflags(ios::fix    
336     if(i != count-1) G4cout << "-> ";             
337   }                                               
338   G4cout << "|" << G4endl << "Number of bounda    
339   G4cout.precision(oldprec);                      
340 }                                                 
341                                                   
342 //____________________________________________    
343 void G4Voxelizer::BuildBitmasks(std::vector<G4    
344                                 G4SurfBits bit    
345 {                                                 
346   // "BuildListNodes" stores in the bitmasks s    
347   // along an axis.                               
348                                                   
349   std::size_t numNodes = fBoxes.size();           
350   G4int bitsPerSlice = GetBitsPerSlice();         
351                                                   
352   for (auto k = 0; k < 3; ++k)                    
353   {                                               
354     std::vector<G4double>& boundary = boundari    
355     G4int voxelsCount = (G4int)boundary.size()    
356     G4SurfBits& bitmask = bitmasks[k];            
357                                                   
358     if (!countsOnly)                              
359     {                                             
360       bitmask.Clear();                            
361 #ifdef G4SPECSDEBUG                               
362       G4cout << "Allocating bitmask..." << G4e    
363 #endif                                            
364       bitmask.SetBitNumber(voxelsCount*bitsPer    
365         // it is here so we can set the maximu    
366         // will rellocate the memory and set a    
367     }                                             
368     std::vector<G4int>& candidatesCount = fCan    
369     candidatesCount.resize(voxelsCount);          
370                                                   
371     for(G4int i = 0 ; i < voxelsCount; ++i) {     
372                                                   
373     // Loop on the nodes, number of slices per    
374     //                                            
375     for(std::size_t j = 0 ; j < numNodes; ++j)    
376     {                                             
377       // Determination of the minimum and maxi    
378       // of the bounding boxe of each node        
379       //                                          
380       G4double p = fBoxes[j].pos[k], d = fBoxe    
381                                                   
382       G4double min = p - d; // - localToleranc    
383       G4double max = p + d; // + localToleranc    
384                                                   
385       G4int i = BinarySearch(boundary, min);      
386       if (i < 0)  { i = 0; }                      
387                                                   
388       do    // Loop checking, 13.08.2015, G.Co    
389       {                                           
390         if (!countsOnly)                          
391         {                                         
392           bitmask.SetBitNumber(i*bitsPerSlice+    
393         }                                         
394         candidatesCount[i]++;                     
395         ++i;                                      
396       }                                           
397       while (max > boundary[i] && i < voxelsCo    
398     }                                             
399   }                                               
400 #ifdef G4SPECSDEBUG                               
401   G4cout << "Build list nodes completed." << G    
402 #endif                                            
403 }                                                 
404                                                   
405 //____________________________________________    
406 G4String G4Voxelizer::GetCandidatesAsString(co    
407 {                                                 
408   // Decodes the candidates in mask as G4Strin    
409                                                   
410   stringstream ss;                                
411   auto numNodes = (G4int)fBoxes.size();           
412                                                   
413   for(auto i=0; i<numNodes; ++i)                  
414   {                                               
415     if (bits.TestBitNumber(i))  { ss << i+1 <<    
416   }                                               
417   return ss.str();                                
418 }                                                 
419                                                   
420 //____________________________________________    
421 void G4Voxelizer::DisplayListNodes() const        
422 {                                                 
423   // Prints which solids are present in the sl    
424                                                   
425   char axis[3] = {'X', 'Y', 'Z'};                 
426   G4int size=8*sizeof(G4int)*fNPerSlice;          
427   G4SurfBits bits(size);                          
428                                                   
429   for (auto j = 0; j <= 2; ++j)                   
430   {                                               
431     G4cout << " * " << axis[j] << " axis:" <<     
432     auto count = (G4int)fBoundaries[j].size();    
433     for(G4int i=0; i < count-1; ++i)              
434     {                                             
435       G4cout << "    Slice #" << i+1 << ": ["     
436              << " ; " << fBoundaries[j][i+1] <    
437       bits.set(size,(const char *)fBitmasks[j]    
438                                  *fNPerSlice*s    
439       G4String result = GetCandidatesAsString(    
440       G4cout << "[ " << result.c_str() << "]      
441     }                                             
442   }                                               
443 }                                                 
444                                                   
445 //____________________________________________    
446 void G4Voxelizer::BuildBoundingBox()              
447 {                                                 
448   G4ThreeVector min(fBoundaries[0].front(),       
449                     fBoundaries[1].front(),       
450                     fBoundaries[2].front());      
451   G4ThreeVector max(fBoundaries[0].back(),        
452                     fBoundaries[1].back(),        
453                     fBoundaries[2].back());       
454   BuildBoundingBox(min, max);                     
455 }                                                 
456                                                   
457 //____________________________________________    
458 void G4Voxelizer::BuildBoundingBox(G4ThreeVect    
459                                    G4ThreeVect    
460                                    G4double to    
461 {                                                 
462   for (auto i = 0; i <= 2; ++i)                   
463   {                                               
464     G4double min = amin[i];                       
465     G4double max = amax[i];                       
466     fBoundingBoxSize[i] = (max - min) / 2 + to    
467     fBoundingBoxCenter[i] = min + fBoundingBox    
468   }                                               
469   fBoundingBox.SetXHalfLength(fBoundingBoxSize    
470   fBoundingBox.SetYHalfLength(fBoundingBoxSize    
471   fBoundingBox.SetZHalfLength(fBoundingBoxSize    
472 }                                                 
473                                                   
474 // algorithm -                                    
475                                                   
476 // in order to get balanced voxels, merge shou    
477 // where the number of voxels is least the num    
478 // We will keep sorted list (std::set) with al    
479 // comparator function between two voxels, whi    
480 // by looking at his right neighbor.              
481 // First, we will add all the voxels into the     
482 // We will be pick the first item in the tree,    
483 // merged voxel into the a list for future red    
484 // rebuilded later, therefore they need not to    
485 // The merged voxel need to be added to the tr    
486 // would be updated.                              
487                                                   
488 //____________________________________________    
489 void G4Voxelizer::SetReductionRatio(G4int maxV    
490                                     G4ThreeVec    
491 {                                                 
492   G4double maxTotal = (G4double) fCandidatesCo    
493                     * fCandidatesCounts[1].siz    
494                                                   
495   if (maxVoxels > 0 && maxVoxels < maxTotal)      
496   {                                               
497     G4double ratio = (G4double) maxVoxels / ma    
498     ratio = std::pow(ratio, 1./3.);               
499     if (ratio > 1)  { ratio = 1; }                
500     reductionRatio.set(ratio,ratio,ratio);        
501   }                                               
502 }                                                 
503                                                   
504 //____________________________________________    
505 void G4Voxelizer::BuildReduceVoxels(std::vecto    
506                                     G4ThreeVec    
507 {                                                 
508   for (auto k = 0; k <= 2; ++k)                   
509   {                                               
510     std::vector<G4int> &candidatesCount = fCan    
511     auto max = (G4int)candidatesCount.size();     
512     std::vector<G4VoxelInfo> voxels(max);         
513     G4VoxelComparator comp(voxels);               
514     std::set<G4int, G4VoxelComparator> voxelSe    
515     std::vector<G4int> mergings;                  
516                                                   
517     for (G4int j = 0; j < max; ++j)               
518     {                                             
519       G4VoxelInfo &voxel = voxels[j];             
520       voxel.count = candidatesCount[j];           
521       voxel.previous = j - 1;                     
522       voxel.next = j + 1;                         
523       voxels[j] = voxel;                          
524     }                                             
525                                                   
526     for (G4int j = 0; j < max - 1; ++j)  { vox    
527       // we go to size-1 to make sure we will     
528                                                   
529     G4double reduction = reductionRatio[k];       
530     if (reduction != 0)                           
531     {                                             
532       G4int count = 0, currentCount;              
533       while ((currentCount = (G4int)voxelSet.s    
534       {                                           
535         G4double currentRatio = 1 - (G4double)    
536         if ((currentRatio <= reduction) && (cu    
537           break;                                  
538         const G4int pos = *voxelSet.begin();      
539         mergings.push_back(pos + 1);              
540                                                   
541         G4VoxelInfo& voxel = voxels[pos];         
542         G4VoxelInfo& nextVoxel = voxels[voxel.    
543                                                   
544         if (voxelSet.erase(pos) != 1)             
545         {                                         
546           ;// k = k;                              
547         }                                         
548         if (voxel.next != max - 1)                
549           if (voxelSet.erase(voxel.next) != 1)    
550           {                                       
551             ;// k = k;                            
552           }                                       
553         if (voxel.previous != -1)                 
554           if (voxelSet.erase(voxel.previous) !    
555           {                                       
556             ;// k = k;                            
557           }                                       
558         nextVoxel.count += voxel.count;           
559         voxel.count = 0;                          
560         nextVoxel.previous = voxel.previous;      
561                                                   
562         if (voxel.next != max - 1)                
563           voxelSet.insert(voxel.next);            
564                                                   
565         if (voxel.previous != -1)                 
566         {                                         
567           voxels[voxel.previous].next = voxel.    
568           voxelSet.insert(voxel.previous);        
569         }                                         
570         ++count;                                  
571       }  // Loop checking, 13.08.2015, G.Cosmo    
572     }                                             
573                                                   
574     if (!mergings.empty())                        
575     {                                             
576       std::sort(mergings.begin(), mergings.end    
577                                                   
578       const std::vector<G4double>& boundary =     
579       auto mergingsSize = (G4int)mergings.size    
580       vector<G4double> reducedBoundary;           
581       G4int skip = mergings[0], i = 0;            
582       max = (G4int)boundary.size();               
583       for (G4int j = 0; j < max; ++j)             
584       {                                           
585         if (j != skip)                            
586         {                                         
587           reducedBoundary.push_back(boundary[j    
588         }                                         
589         else if (++i < mergingsSize)              
590         {                                         
591           skip = mergings[i];                     
592         }                                         
593       }                                           
594       boundaries[k] = std::move(reducedBoundar    
595     }                                             
596 /*                                                
597     G4int count = 0;                              
598     while (true)    // Loop checking, 13.08.20    
599     {                                             
600       G4double reduction = reductionRatio[k];     
601       if (reduction == 0)                         
602         break;                                    
603       G4int currentCount = voxelSet.size();       
604       if (currentCount <= 2)                      
605         break;                                    
606       G4double currentRatio = 1 - (G4double) c    
607       if (currentRatio <= reduction && current    
608         break;                                    
609       const G4int pos = *voxelSet.begin();        
610       mergings.push_back(pos);                    
611                                                   
612       G4VoxelInfo &voxel = voxels[pos];           
613       G4VoxelInfo &nextVoxel = voxels[voxel.ne    
614                                                   
615       voxelSet.erase(pos);                        
616       if (voxel.next != max - 1) { voxelSet.er    
617       if (voxel.previous != -1)  { voxelSet.er    
618                                                   
619       nextVoxel.count += voxel.count;             
620       voxel.count = 0;                            
621       nextVoxel.previous = voxel.previous;        
622                                                   
623       if (voxel.next != max - 1)                  
624         voxelSet.insert(voxel.next);              
625                                                   
626       if (voxel.previous != -1)                   
627       {                                           
628         voxels[voxel.previous].next = voxel.ne    
629         voxelSet.insert(voxel.previous);          
630       }                                           
631       ++count;                                    
632     }                                             
633                                                   
634     if (mergings.size())                          
635     {                                             
636       std::sort(mergings.begin(), mergings.end    
637                                                   
638       std::vector<G4double> &boundary = bounda    
639       std::vector<G4double> reducedBoundary(bo    
640       G4int skip = mergings[0] + 1, cur = 0, i    
641       max = boundary.size();                      
642       for (G4int j = 0; j < max; ++j)             
643       {                                           
644         if (j != skip)                            
645         {                                         
646           reducedBoundary[cur++] = boundary[j]    
647         }                                         
648         else                                      
649         {                                         
650           if (++i < (G4int)mergings.size())  {    
651         }                                         
652       }                                           
653       boundaries[k] = reducedBoundary;            
654     }                                             
655 */                                                
656   }                                               
657 }                                                 
658                                                   
659 //____________________________________________    
660 void G4Voxelizer::BuildReduceVoxels2(std::vect    
661                                      G4ThreeVe    
662 {                                                 
663   for (auto k = 0; k <= 2; ++k)                   
664   {                                               
665     std::vector<G4int> &candidatesCount = fCan    
666     auto max = (G4int)candidatesCount.size();     
667     G4int total = 0;                              
668     for (G4int i = 0; i < max; ++i) total += c    
669                                                   
670     G4double reduction = reductionRatio[k];       
671     if (reduction == 0)                           
672       break;                                      
673                                                   
674     G4int destination = (G4int) (reduction * m    
675     if (destination > 1000) destination = 1000    
676     if (destination < 2) destination = 2;         
677     G4double average = ((G4double)total / max)    
678                                                   
679     std::vector<G4int> mergings;                  
680                                                   
681     std::vector<G4double> &boundary = boundari    
682     std::vector<G4double> reducedBoundary(dest    
683                                                   
684     G4int sum = 0, cur = 0;                       
685     for (G4int i = 0; i < max; ++i)               
686     {                                             
687       sum += candidatesCount[i];                  
688       if (sum > average * (cur + 1) || i == 0)    
689       {                                           
690         G4double val = boundary[i];               
691         reducedBoundary[cur] = val;               
692         ++cur;                                    
693         if (cur == destination)                   
694           break;                                  
695       }                                           
696     }                                             
697     reducedBoundary[destination-1] = boundary[    
698     boundaries[k] = std::move(reducedBoundary)    
699   }                                               
700 }                                                 
701                                                   
702 //____________________________________________    
703 void G4Voxelizer::Voxelize(std::vector<G4VSoli    
704                            std::vector<G4Trans    
705 {                                                 
706   BuildVoxelLimits(solids, transforms);           
707   BuildBoundaries();                              
708   BuildBitmasks(fBoundaries, fBitmasks);          
709   BuildBoundingBox();                             
710   BuildEmpty(); // this does not work well for    
711                 // actually only makes perform    
712                 // these are only pre-calculat    
713                                                   
714   for (auto & fCandidatesCount : fCandidatesCo    
715   {                                               
716     fCandidatesCount.resize(0);                   
717   }                                               
718 }                                                 
719                                                   
720 //____________________________________________    
721 void G4Voxelizer::CreateMiniVoxels(std::vector    
722                                    G4SurfBits     
723 {                                                 
724   std::vector<G4int> voxel(3), maxVoxels(3);      
725   for (auto i = 0; i <= 2; ++i) maxVoxels[i] =    
726                                                   
727   G4ThreeVector point;                            
728   for (voxel[2] = 0; voxel[2] < maxVoxels[2] -    
729   {                                               
730     for (voxel[1] = 0; voxel[1] < maxVoxels[1]    
731     {                                             
732       for (voxel[0] = 0; voxel[0] < maxVoxels[    
733       {                                           
734         std::vector<G4int> candidates;            
735         if (GetCandidatesVoxelArray(voxel, bit    
736         {                                         
737           // find a box for corresponding non-    
738           G4VoxelBox box;                         
739           for (auto i = 0; i <= 2; ++i)           
740           {                                       
741             G4int index = voxel[i];               
742             const std::vector<G4double> &bound    
743             G4double hlen = 0.5 * (boundary[in    
744             box.hlen[i] = hlen;                   
745             box.pos[i] = boundary[index] + hle    
746           }                                       
747           fVoxelBoxes.push_back(box);             
748           std::vector<G4int>(candidates).swap(    
749           fVoxelBoxesCandidates.push_back(std:    
750         }                                         
751       }                                           
752     }                                             
753   }                                               
754 }                                                 
755                                                   
756 //____________________________________________    
757 void G4Voxelizer::Voxelize(std::vector<G4VFace    
758 {                                                 
759   G4int maxVoxels = fMaxVoxels;                   
760   G4ThreeVector reductionRatio = fReductionRat    
761                                                   
762   std::size_t size = facets.size();               
763   if (size < 10)                                  
764   {                                               
765     for (const auto & facet : facets)             
766     {                                             
767       if (facet->GetNumberOfVertices() > 3) ++    
768     }                                             
769   }                                               
770                                                   
771   if ((size >= 10 || maxVoxels > 0) && maxVoxe    
772   {                                               
773 #ifdef G4SPECSDEBUG                               
774     G4cout << "Building voxel limits..." << G4    
775 #endif                                            
776                                                   
777     BuildVoxelLimits(facets);                     
778                                                   
779 #ifdef G4SPECSDEBUG                               
780     G4cout << "Building boundaries..." << G4en    
781 #endif                                            
782                                                   
783     BuildBoundaries();                            
784                                                   
785 #ifdef G4SPECSDEBUG                               
786     G4cout << "Building bitmasks..." << G4endl    
787 #endif                                            
788                                                   
789     BuildBitmasks(fBoundaries, nullptr, true);    
790                                                   
791     if (maxVoxels < 0 && reductionRatio == G4T    
792     {                                             
793       maxVoxels = fTotalCandidates;               
794       if (fTotalCandidates > 1000000) maxVoxel    
795     }                                             
796                                                   
797     SetReductionRatio(maxVoxels, reductionRati    
798                                                   
799     fCountOfVoxels = CountVoxels(fBoundaries);    
800                                                   
801 #ifdef G4SPECSDEBUG                               
802     G4cout << "Total number of voxels: " << fC    
803 #endif                                            
804                                                   
805     BuildReduceVoxels2(fBoundaries, reductionR    
806                                                   
807     fCountOfVoxels = CountVoxels(fBoundaries);    
808                                                   
809 #ifdef G4SPECSDEBUG                               
810     G4cout << "Total number of voxels after re    
811            << fCountOfVoxels << G4endl;           
812 #endif                                            
813                                                   
814 #ifdef G4SPECSDEBUG                               
815     G4cout << "Building bitmasks..." << G4endl    
816 #endif                                            
817                                                   
818     BuildBitmasks(fBoundaries, fBitmasks);        
819                                                   
820     G4ThreeVector reductionRatioMini;             
821                                                   
822     G4SurfBits bitmasksMini[3];                   
823                                                   
824     // section for building mini voxels           
825                                                   
826     std::vector<G4double> miniBoundaries[3];      
827                                                   
828     for (auto i = 0; i <= 2; ++i)  { miniBound    
829                                                   
830     G4int voxelsCountMini = (fCountOfVoxels >=    
831                           ? 100 : G4int(fCount    
832                                                   
833     SetReductionRatio(voxelsCountMini, reducti    
834                                                   
835 #ifdef G4SPECSDEBUG                               
836     G4cout << "Building reduced voxels..." <<     
837 #endif                                            
838                                                   
839     BuildReduceVoxels(miniBoundaries, reductio    
840                                                   
841 #ifdef G4SPECSDEBUG                               
842     G4int total = CountVoxels(miniBoundaries);    
843     G4cout << "Total number of mini voxels: "     
844 #endif                                            
845                                                   
846 #ifdef G4SPECSDEBUG                               
847     G4cout << "Building mini bitmasks..." << G    
848 #endif                                            
849                                                   
850     BuildBitmasks(miniBoundaries, bitmasksMini    
851                                                   
852 #ifdef G4SPECSDEBUG                               
853     G4cout << "Creating Mini Voxels..." << G4e    
854 #endif                                            
855                                                   
856     CreateMiniVoxels(miniBoundaries, bitmasksM    
857                                                   
858 #ifdef G4SPECSDEBUG                               
859     G4cout << "Building bounding box..." << G4    
860 #endif                                            
861                                                   
862     BuildBoundingBox();                           
863                                                   
864 #ifdef G4SPECSDEBUG                               
865     G4cout << "Building empty..." << G4endl;      
866 #endif                                            
867                                                   
868     BuildEmpty();                                 
869                                                   
870 #ifdef G4SPECSDEBUG                               
871     G4cout << "Deallocating unnecessary fields    
872 #endif                                            
873     // deallocate fields unnecessary during ru    
874     //                                            
875     fBoxes.resize(0);                             
876     for (auto i = 0; i < 3; ++i)                  
877     {                                             
878       fCandidatesCounts[i].resize(0);             
879       fBitmasks[i].Clear();                       
880     }                                             
881   }                                               
882 }                                                 
883                                                   
884                                                   
885 //____________________________________________    
886 void G4Voxelizer::GetCandidatesVoxel(std::vect    
887 {                                                 
888   // "GetCandidates" should compute which soli    
889   // the voxel defined by the three slices cha    
890                                                   
891   G4cout << "   Candidates in voxel [" << voxe    
892          << " ; " << voxels[2] << "]: ";          
893   std::vector<G4int> candidates;                  
894   G4int count = GetCandidatesVoxelArray(voxels    
895   G4cout << "[ ";                                 
896   for (G4int i = 0; i < count; ++i) G4cout <<     
897   G4cout << "]  " << G4endl;                      
898 }                                                 
899                                                   
900 //____________________________________________    
901 void G4Voxelizer::FindComponentsFastest(unsign    
902                                          std::    
903 {                                                 
904   for (G4int byte = 0; byte < (G4int) (sizeof(    
905   {                                               
906     if (G4int maskByte = mask & 0xFF)             
907     {                                             
908       for (G4int bit = 0; bit < 8; ++bit)         
909       {                                           
910         if ((maskByte & 1) != 0)                  
911           { list.push_back(8*(sizeof(unsigned     
912         if ((maskByte >>= 1) == 0) break;         
913       }                                           
914     }                                             
915     mask >>= 8;                                   
916   }                                               
917 }                                                 
918                                                   
919 //____________________________________________    
920 void G4Voxelizer::TransformLimits(G4ThreeVecto    
921                                   const G4Tran    
922 {                                                 
923   // The goal of this method is to convert the    
924   // (representing the bounding box of a given    
925   // to the main frame, using "transformation"    
926                                                   
927   G4ThreeVector vertices[8] =     // Deteminat    
928   {                               // the exten    
929     G4ThreeVector(min.x(), min.y(), min.z()),     
930     G4ThreeVector(min.x(), max.y(), min.z()),     
931     G4ThreeVector(max.x(), max.y(), min.z()),     
932     G4ThreeVector(max.x(), min.y(), min.z()),     
933     G4ThreeVector(min.x(), min.y(), max.z()),     
934     G4ThreeVector(min.x(), max.y(), max.z()),     
935     G4ThreeVector(max.x(), max.y(), max.z()),     
936     G4ThreeVector(max.x(), min.y(), max.z())      
937   };                                              
938                                                   
939   min.set(kInfinity,kInfinity,kInfinity);         
940   max.set(-kInfinity,-kInfinity,-kInfinity);      
941                                                   
942   // Loop on th vertices                          
943   G4int limit = sizeof(vertices) / sizeof(G4Th    
944   for (G4int i = 0 ; i < limit; ++i)              
945   {                                               
946     // From local frame to the global one:        
947     // Current positions on the three axis:       
948     G4ThreeVector current = GetGlobalPoint(tra    
949                                                   
950     // If need be, replacement of the min & ma    
951     if (current.x() > max.x()) max.setX(curren    
952     if (current.x() < min.x()) min.setX(curren    
953                                                   
954     if (current.y() > max.y()) max.setY(curren    
955     if (current.y() < min.y()) min.setY(curren    
956                                                   
957     if (current.z() > max.z()) max.setZ(curren    
958     if (current.z() < min.z()) min.setZ(curren    
959   }                                               
960 }                                                 
961                                                   
962 //____________________________________________    
963 G4int G4Voxelizer::GetCandidatesVoxelArray(con    
964                           std::vector<G4int> &    
965 {                                                 
966   // Method returning the candidates correspon    
967                                                   
968   list.clear();                                   
969                                                   
970   for (auto i = 0; i <= 2; ++i)                   
971   {                                               
972     if(point[i] < fBoundaries[i].front() || po    
973       return 0;                                   
974   }                                               
975                                                   
976   if (fTotalCandidates == 1)                      
977   {                                               
978     list.push_back(0);                            
979     return 1;                                     
980   }                                               
981   else                                            
982   {                                               
983     if (fNPerSlice == 1)                          
984     {                                             
985       unsigned int mask = 0xFFffFFff;             
986       G4int slice;                                
987       if (fBoundaries[0].size() > 2)              
988       {                                           
989         slice = BinarySearch(fBoundaries[0], p    
990         if ((mask = ((unsigned int*) fBitmasks    
991           return 0;                               
992       }                                           
993       if (fBoundaries[1].size() > 2)              
994       {                                           
995         slice = BinarySearch(fBoundaries[1], p    
996         if ((mask &= ((unsigned int*) fBitmask    
997           return 0;                               
998       }                                           
999       if (fBoundaries[2].size() > 2)              
1000       {                                          
1001         slice = BinarySearch(fBoundaries[2],     
1002         if ((mask &= ((unsigned int*) fBitmas    
1003           return 0;                              
1004       }                                          
1005       if ((crossed != nullptr) && ((mask &= ~    
1006         return 0;                                
1007                                                  
1008       FindComponentsFastest(mask, list, 0);      
1009     }                                            
1010     else                                         
1011     {                                            
1012       unsigned int* masks[3], mask; // masks     
1013       for (auto i = 0; i <= 2; ++i)              
1014       {                                          
1015         G4int slice = BinarySearch(fBoundarie    
1016         masks[i] = ((unsigned int*) fBitmasks    
1017                  + slice * fNPerSlice;           
1018       }                                          
1019       unsigned int* maskCrossed = crossed !=     
1020                                 ? (unsigned i    
1021                                                  
1022       for (G4int i = 0 ; i < fNPerSlice; ++i)    
1023       {                                          
1024         // Logic "and" of the masks along the    
1025         // removing "if (!" and ") continue"     
1026         //                                       
1027         if ((mask = masks[0][i]) == 0u) conti    
1028         if ((mask &= masks[1][i]) == 0u) cont    
1029         if ((mask &= masks[2][i]) == 0u) cont    
1030         if ((maskCrossed != nullptr) && ((mas    
1031                                                  
1032         FindComponentsFastest(mask, list, i);    
1033       }                                          
1034     }                                            
1035 /*                                               
1036     if (fNPerSlice == 1)                         
1037     {                                            
1038       unsigned int mask;                         
1039       G4int slice = BinarySearch(fBoundaries[    
1040       if (!(mask = ((unsigned int *) fBitmask    
1041       )) return 0;                               
1042       slice = BinarySearch(fBoundaries[1], po    
1043       if (!(mask &= ((unsigned int *) fBitmas    
1044       )) return 0;                               
1045       slice = BinarySearch(fBoundaries[2], po    
1046       if (!(mask &= ((unsigned int *) fBitmas    
1047       )) return 0;                               
1048       if (crossed && (!(mask &= ~((unsigned i    
1049         return 0;                                
1050                                                  
1051       FindComponentsFastest(mask, list, 0);      
1052     }                                            
1053     else                                         
1054     {                                            
1055       unsigned int *masks[3], mask; // masks     
1056       for (auto i = 0; i <= 2; ++i)              
1057       {                                          
1058         G4int slice = BinarySearch(fBoundarie    
1059         masks[i] = ((unsigned int *) fBitmask    
1060       }                                          
1061       unsigned int *maskCrossed =                
1062         crossed ? (unsigned int *)crossed->fA    
1063                                                  
1064       for (G4int i = 0 ; i < fNPerSlice; ++i)    
1065       {                                          
1066         // Logic "and" of the masks along the    
1067         // removing "if (!" and ") continue"     
1068         //                                       
1069         if (!(mask = masks[0][i])) continue;     
1070         if (!(mask &= masks[1][i])) continue;    
1071         if (!(mask &= masks[2][i])) continue;    
1072         if (maskCrossed && !(mask &= ~maskCro    
1073                                                  
1074         FindComponentsFastest(mask, list, i);    
1075       }                                          
1076     }                                            
1077 */                                               
1078   }                                              
1079   return (G4int)list.size();                     
1080 }                                                
1081                                                  
1082 //___________________________________________    
1083 G4int                                            
1084 G4Voxelizer::GetCandidatesVoxelArray(const st    
1085                                      const G4    
1086                                      std::vec    
1087                                      G4SurfBi    
1088 {                                                
1089   list.clear();                                  
1090                                                  
1091   if (fTotalCandidates == 1)                     
1092   {                                              
1093     list.push_back(0);                           
1094     return 1;                                    
1095   }                                              
1096   else                                           
1097   {                                              
1098     if (fNPerSlice == 1)                         
1099     {                                            
1100       unsigned int mask;                         
1101       if ((mask = ((unsigned int *) bitmasks[    
1102         return 0;                                
1103       if ((mask &= ((unsigned int *) bitmasks    
1104         return 0;                                
1105       if ((mask &= ((unsigned int *) bitmasks    
1106         return 0;                                
1107       if ((crossed != nullptr) && ((mask &= ~    
1108         return 0;                                
1109                                                  
1110       FindComponentsFastest(mask, list, 0);      
1111     }                                            
1112     else                                         
1113     {                                            
1114       unsigned int *masks[3], mask; // masks     
1115       for (auto i = 0; i <= 2; ++i)              
1116       {                                          
1117         masks[i] = ((unsigned int *) bitmasks    
1118                  + voxels[i]*fNPerSlice;         
1119       }                                          
1120       unsigned int *maskCrossed = crossed !=     
1121                                 ? (unsigned i    
1122                                                  
1123       for (G4int i = 0 ; i < fNPerSlice; ++i)    
1124       {                                          
1125         // Logic "and" of the masks along the    
1126         // removing "if (!" and ") continue"     
1127         //                                       
1128         if ((mask = masks[0][i]) == 0u) conti    
1129         if ((mask &= masks[1][i]) == 0u) cont    
1130         if ((mask &= masks[2][i]) == 0u) cont    
1131         if ((maskCrossed != nullptr) && ((mas    
1132                                                  
1133         FindComponentsFastest(mask, list, i);    
1134       }                                          
1135     }                                            
1136   }                                              
1137   return (G4int)list.size();                     
1138 }                                                
1139                                                  
1140 //___________________________________________    
1141 G4int                                            
1142 G4Voxelizer::GetCandidatesVoxelArray(const st    
1143                           std::vector<G4int>&    
1144 {                                                
1145   // Method returning the candidates correspo    
1146                                                  
1147   return GetCandidatesVoxelArray(voxels, fBit    
1148 }                                                
1149                                                  
1150 //___________________________________________    
1151 G4bool G4Voxelizer::Contains(const G4ThreeVec    
1152 {                                                
1153   for (auto i = 0; i < 3; ++i)                   
1154   {                                              
1155     if (point[i] < fBoundaries[i].front() ||     
1156       return false;                              
1157   }                                              
1158   return true;                                   
1159 }                                                
1160                                                  
1161 //___________________________________________    
1162 G4double                                         
1163 G4Voxelizer::DistanceToFirst(const G4ThreeVec    
1164                              const G4ThreeVec    
1165 {                                                
1166   G4ThreeVector pointShifted = point - fBound    
1167   G4double shift = fBoundingBox.DistanceToIn(    
1168   return shift;                                  
1169 }                                                
1170                                                  
1171 //___________________________________________    
1172 G4double                                         
1173 G4Voxelizer::DistanceToBoundingBox(const G4Th    
1174 {                                                
1175   G4ThreeVector pointShifted = point - fBound    
1176   G4double shift = MinDistanceToBox(pointShif    
1177   return shift;                                  
1178 }                                                
1179                                                  
1180 //___________________________________________    
1181 G4double                                         
1182 G4Voxelizer::MinDistanceToBox (const G4ThreeV    
1183                                const G4ThreeV    
1184 {                                                
1185   // Estimates the isotropic safety from a po    
1186   // any of its surfaces. The algorithm may b    
1187   // fast underestimate.                         
1188                                                  
1189   G4double safe, safx, safy, safz;               
1190   safe = safx = -f.x() + std::abs(aPoint.x())    
1191   safy = -f.y() + std::abs(aPoint.y());          
1192   if ( safy > safe ) safe = safy;                
1193   safz = -f.z() + std::abs(aPoint.z());          
1194   if ( safz > safe ) safe = safz;                
1195   if (safe < 0.0) return 0.0; // point is ins    
1196                                                  
1197   G4double safsq = 0.0;                          
1198   G4int count = 0;                               
1199   if ( safx > 0 ) { safsq += safx*safx; ++cou    
1200   if ( safy > 0 ) { safsq += safy*safy; ++cou    
1201   if ( safz > 0 ) { safsq += safz*safz; ++cou    
1202   if (count == 1) return safe;                   
1203   return std::sqrt(safsq);                       
1204 }                                                
1205                                                  
1206 //___________________________________________    
1207 G4double                                         
1208 G4Voxelizer::DistanceToNext(const G4ThreeVect    
1209                             const G4ThreeVect    
1210                                   std::vector    
1211 {                                                
1212   G4double shift = kInfinity;                    
1213                                                  
1214   G4int cur = 0; // the smallest index, which    
1215   for (G4int i = 0; i <= 2; ++i)                 
1216   {                                              
1217     // Looking for the next voxels on the con    
1218     //                                           
1219     const std::vector<G4double>& boundary = f    
1220     G4int index = curVoxel[i];                   
1221     if (direction[i] >= 1e-10)                   
1222     {                                            
1223       ++index;                                   
1224     }                                            
1225     else                                         
1226     {                                            
1227       if (direction[i] > -1e-10)                 
1228         continue;                                
1229     }                                            
1230     G4double dif = boundary[index] - point[i]    
1231     G4double distance = dif / direction[i];      
1232                                                  
1233     if (shift > distance)                        
1234     {                                            
1235       shift = distance;                          
1236       cur = i;                                   
1237     }                                            
1238   }                                              
1239                                                  
1240   if (shift != kInfinity)                        
1241   {                                              
1242     // updating current voxel using the index    
1243     // to the closest voxel boundary on the r    
1244                                                  
1245     if (direction[cur] > 0)                      
1246     {                                            
1247       if (++curVoxel[cur] >= (G4int) fBoundar    
1248         shift = kInfinity;                       
1249     }                                            
1250     else                                         
1251     {                                            
1252       if (--curVoxel[cur] < 0)                   
1253         shift = kInfinity;                       
1254     }                                            
1255   }                                              
1256                                                  
1257 /*                                               
1258   for (auto i = 0; i <= 2; ++i)                  
1259   {                                              
1260     // Looking for the next voxels on the con    
1261     //                                           
1262     const std::vector<G4double> &boundary = f    
1263     G4int cur = curVoxel[i];                     
1264     if(direction[i] >= 1e-10)                    
1265     {                                            
1266         if (boundary[++cur] - point[i] < fTol    
1267         if (++cur >= (G4int) boundary.size())    
1268           continue;                              
1269     }                                            
1270     else                                         
1271     {                                            
1272       if(direction[i] <= -1e-10)                 
1273       {                                          
1274         if (point[i] - boundary[cur] < fToler    
1275           if (--cur < 0)                         
1276             continue;                            
1277       }                                          
1278       else                                       
1279         continue;                                
1280     }                                            
1281     G4double dif = boundary[cur] - point[i];     
1282     G4double distance = dif / direction[i];      
1283                                                  
1284     if (shift > distance)                        
1285       shift = distance;                          
1286   }                                              
1287 */                                               
1288   return shift;                                  
1289 }                                                
1290                                                  
1291 //___________________________________________    
1292 G4bool                                           
1293 G4Voxelizer::UpdateCurrentVoxel(const G4Three    
1294                                 const G4Three    
1295                                 std::vector<G    
1296 {                                                
1297   for (auto i = 0; i <= 2; ++i)                  
1298   {                                              
1299     G4int index = curVoxel[i];                   
1300     const std::vector<G4double> &boundary = f    
1301                                                  
1302     if (direction[i] > 0)                        
1303     {                                            
1304       if (point[i] >= boundary[++index])         
1305         if (++curVoxel[i] >= (G4int) boundary    
1306           return false;                          
1307     }                                            
1308     else                                         
1309     {                                            
1310       if (point[i] < boundary[index])            
1311         if (--curVoxel[i] < 0)                   
1312           return false;                          
1313     }                                            
1314 #ifdef G4SPECSDEBUG                              
1315     G4int indexOK = BinarySearch(boundary, po    
1316     if (curVoxel[i] != indexOK)                  
1317       curVoxel[i] = indexOK; // put breakpoin    
1318 #endif                                           
1319   }                                              
1320   return true;                                   
1321 }                                                
1322                                                  
1323 //___________________________________________    
1324 void G4Voxelizer::SetMaxVoxels(G4int max)        
1325 {                                                
1326   fMaxVoxels = max;                              
1327   fReductionRatio.set(0,0,0);                    
1328 }                                                
1329                                                  
1330 //___________________________________________    
1331 void G4Voxelizer::SetMaxVoxels(const G4ThreeV    
1332 {                                                
1333   fMaxVoxels = -1;                               
1334   fReductionRatio = ratioOfReduction;            
1335 }                                                
1336                                                  
1337 //___________________________________________    
1338 void G4Voxelizer::SetDefaultVoxelsCount(G4int    
1339 {                                                
1340   fDefaultVoxelsCount = count;                   
1341 }                                                
1342                                                  
1343 //___________________________________________    
1344 G4int G4Voxelizer::GetDefaultVoxelsCount()       
1345 {                                                
1346   return fDefaultVoxelsCount;                    
1347 }                                                
1348                                                  
1349 //___________________________________________    
1350 G4int G4Voxelizer::AllocatedMemory()             
1351 {                                                
1352   G4int size = fEmpty.GetNbytes();               
1353   size += fBoxes.capacity() * sizeof(G4VoxelB    
1354   size += sizeof(G4double) * (fBoundaries[0].    
1355         + fBoundaries[1].capacity() + fBounda    
1356   size += sizeof(G4int) * (fCandidatesCounts[    
1357         + fCandidatesCounts[1].capacity() + f    
1358   size += fBitmasks[0].GetNbytes() + fBitmask    
1359         + fBitmasks[2].GetNbytes();              
1360                                                  
1361   auto csize = (G4int)fCandidates.size();        
1362   for (G4int i = 0; i < csize; ++i)              
1363   {                                              
1364     size += sizeof(vector<G4int>) + fCandidat    
1365   }                                              
1366                                                  
1367   return size;                                   
1368 }                                                
1369