Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-22 08:52:21

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 // G4Voxelizer
0027 //
0028 // Class description:
0029 //
0030 // Voxelizer for tessellated surfaces and solids positioning in 3D space,
0031 // used in G4TessellatedSolid and G4MultiUnion.
0032 
0033 // Author: Marek Gayer (CERN), 19.10.2012 - Created
0034 // --------------------------------------------------------------------
0035 #ifndef G4VOXELIZER_HH
0036 #define G4VOXELIZER_HH
0037 
0038 #include <vector>
0039 #include <string>
0040 #include <map>
0041 
0042 #include "G4Transform3D.hh"
0043 #include "G4RotationMatrix.hh"
0044 #include "G4SurfBits.hh"
0045 #include "G4Box.hh"
0046 #include "G4VFacet.hh"
0047 #include "G4VSolid.hh"
0048 
0049 struct G4VoxelBox
0050 {
0051   G4ThreeVector hlen; // half length of the box
0052   G4ThreeVector pos; // position of the box
0053 };
0054 
0055 struct G4VoxelInfo
0056 {
0057   G4int count;
0058   G4int previous;
0059   G4int next;
0060 };
0061 
0062 /**
0063  * @brief G4Voxelizer is a tool for generating the optimisation structure
0064  * of tessellated surfaces and solids positioned in 3D space; it is used in
0065  * G4TessellatedSolid and G4MultiUnion.
0066  */
0067 
0068 class G4Voxelizer
0069 {
0070   public:
0071 
0072     /**
0073      * Constructor and default Destructor.
0074      */
0075     G4Voxelizer();
0076     ~G4Voxelizer() = default;
0077 
0078     /**
0079      * Builds the voxelisation structure for solids positioned in space.
0080      *  @param[in] solids The list of solids.
0081      *  @param[in] transforms The associated transformation in space.
0082      */
0083     void Voxelize(std::vector<G4VSolid*>& solids,
0084                   std::vector<G4Transform3D>& transforms);
0085 
0086     /**
0087      * Builds the voxelisation structure for facets forming a shape.
0088      *  @param[in] facets The list of facets.
0089      */
0090     void Voxelize(std::vector<G4VFacet*>& facets);
0091 
0092     /**
0093      * Displays the dX, dY, dZ, pX, pY and pZ for each node.
0094      */
0095     void DisplayVoxelLimits() const;
0096 
0097     /**
0098      * Prints the positions of the boundaries of the slices on the three axes.
0099      */
0100     void DisplayBoundaries();
0101 
0102     /**
0103      * Prints which solids are present in the slices previously elaborated.
0104      */
0105     void DisplayListNodes() const;
0106 
0107     /**
0108      * Displays the nodes located in a voxel characterised by its three indexes.
0109      */
0110     void GetCandidatesVoxel(std::vector<G4int>& voxels);
0111 
0112     /**
0113      * Methods returning in a vector container the nodes located in a voxel
0114      * characterised by its three indexes.
0115      *  @returns The total candidates number.
0116      */
0117     G4int GetCandidatesVoxelArray(const G4ThreeVector& point,
0118                                         std::vector<G4int>& list,
0119                                         G4SurfBits* crossed = nullptr) const;
0120     G4int GetCandidatesVoxelArray(const std::vector<G4int>& voxels,
0121                                   const G4SurfBits bitmasks[],
0122                                         std::vector<G4int>& list,
0123                                         G4SurfBits* crossed = nullptr) const;
0124     G4int GetCandidatesVoxelArray(const std::vector<G4int>& voxels,
0125                                         std::vector<G4int>& list,
0126                                         G4SurfBits* crossed = nullptr)const;
0127 
0128     /**
0129      * Returns the pointer to the array containing the characteristics
0130      * of each box.
0131      */
0132     inline const std::vector<G4VoxelBox>& GetBoxes() const;
0133 
0134     /**
0135      * Returns the boundary vector, given an 'index'.
0136      */
0137     inline const std::vector<G4double>& GetBoundary(G4int index) const;
0138 
0139     /**
0140      * Utility method for checking/updating current voxel given in input.
0141      */
0142     G4bool UpdateCurrentVoxel(const G4ThreeVector& point,
0143                               const G4ThreeVector& direction,
0144                                     std::vector<G4int>& curVoxel) const;
0145 
0146     /**
0147      * Updates current voxel based on provided 'point'.
0148      */
0149     inline void GetVoxel(std::vector<G4int>& curVoxel,
0150                          const G4ThreeVector& point) const;
0151 
0152     /**
0153      * Returns memory size of a slice.
0154      */
0155     inline G4int GetBitsPerSlice () const;
0156 
0157     /**
0158      * Returns true if 'point' is contained within boundaries.
0159      */
0160     G4bool Contains(const G4ThreeVector& point) const;
0161 
0162     /**
0163      * Returns the distance to next boundary, given 'point' and 'direction'
0164      * and updates current voxel 'curVoxel', using the index corresponding
0165      * to the closest voxel boundary on the ray.
0166      */
0167     G4double DistanceToNext(const G4ThreeVector& point,
0168                             const G4ThreeVector& direction,
0169                                   std::vector<G4int>& curVoxel) const;
0170 
0171     /**
0172      * Returns the distance to first bounding box, given 'point' and 'direction'.
0173      */
0174     G4double DistanceToFirst(const G4ThreeVector& point,
0175                              const G4ThreeVector& direction) const;
0176 
0177     /**
0178      * Returns the minimum distance of 'point' to the bounding box.
0179      */
0180     G4double DistanceToBoundingBox(const G4ThreeVector& point) const;
0181 
0182     /**
0183      * Utility for estimating the isotropic safety from a point 'p' outside
0184      * the current solid to any of its surfaces. The algorithm may be accurate
0185      * or should provide a fast underestimate, based on safety point 'f'.
0186      */
0187     G4double MinDistanceToBox (const G4ThreeVector& p,
0188                                const G4ThreeVector& f) const;
0189 
0190     /**
0191      * Accessors for voxels and points.
0192      */
0193     inline G4int GetVoxelsIndex(G4int x, G4int y, G4int z) const;
0194     inline G4int GetVoxelsIndex(const std::vector<G4int>& voxels) const;
0195     inline G4bool GetPointVoxel(const G4ThreeVector& p,
0196                                 std::vector<G4int>& voxels) const;
0197     inline G4int GetPointIndex(const G4ThreeVector& p) const;
0198 
0199     /**
0200      * Returns the empty bits container.
0201      */
0202     inline const G4SurfBits& Empty() const;
0203 
0204     /**
0205      * Returns true if empty bit in container, given an 'index'.
0206      */
0207     inline G4bool IsEmpty(G4int index) const;
0208 
0209     /**
0210      * Setters/getter for the maximum number of voxels.
0211      */
0212     void SetMaxVoxels(G4int max);
0213     void SetMaxVoxels(const G4ThreeVector& reductionRatio);
0214     inline G4int GetMaxVoxels(G4ThreeVector& ratioOfReduction);
0215 
0216     /**
0217      * Logger returning the size of total allocated memory.
0218      */
0219     G4int AllocatedMemory();
0220 
0221     /**
0222      * Utility accessors/functions for voxels.
0223      */
0224     inline long long GetCountOfVoxels() const;
0225     inline long long CountVoxels(std::vector<G4double> boundaries[]) const;
0226     inline const std::vector<G4int>&
0227                  GetCandidates(std::vector<G4int>& curVoxel) const;
0228     inline G4int GetVoxelBoxesSize() const;
0229     inline const G4VoxelBox& GetVoxelBox(G4int i) const;
0230     inline const std::vector<G4int>& GetVoxelBoxCandidates(G4int i) const;
0231     inline G4int GetTotalCandidates() const;
0232     static void SetDefaultVoxelsCount(G4int count);
0233     static G4int GetDefaultVoxelsCount();
0234 
0235   private:
0236 
0237     /**
0238      * Binary search function for retrieving a value in a vector.
0239      */
0240     template <typename T> 
0241     inline G4int BinarySearch(const std::vector<T>& vec, T value) const;
0242 
0243     /**
0244      * Utilities.
0245      */
0246     G4String GetCandidatesAsString(const G4SurfBits& bits) const;
0247     void CreateSortedBoundary(std::vector<G4double>& boundaryRaw, G4int axis);
0248     void DisplayBoundaries(std::vector<G4double>& fBoundaries);
0249     void FindComponentsFastest(unsigned int mask,
0250                                std::vector<G4int>& list, G4int i) const;
0251     inline G4ThreeVector GetGlobalPoint(const G4Transform3D& trans,
0252                                         const G4ThreeVector& lpoint) const;
0253     void TransformLimits(G4ThreeVector& min, G4ThreeVector& max,
0254                          const G4Transform3D& transformation) const;
0255 
0256     /**
0257      * Build utilities.
0258      */
0259     void BuildEmpty ();
0260     void BuildBoundaries();
0261     void BuildReduceVoxels(std::vector<G4double> fBoundaries[],
0262                            G4ThreeVector reductionRatio);
0263     void BuildReduceVoxels2(std::vector<G4double> fBoundaries[],
0264                             G4ThreeVector reductionRatio);
0265     void BuildVoxelLimits(std::vector<G4VSolid*>& solids,
0266                           std::vector<G4Transform3D>& transforms);
0267     void BuildVoxelLimits(std::vector<G4VFacet*>& facets);
0268     void CreateMiniVoxels(std::vector<G4double> fBoundaries[],
0269                           G4SurfBits bitmasks[]);
0270     void BuildBitmasks(std::vector<G4double> fBoundaries[],
0271                        G4SurfBits bitmasks[], G4bool countsOnly = false);
0272     void BuildBoundingBox();
0273     void BuildBoundingBox(G4ThreeVector& amin, G4ThreeVector& amax,
0274                           G4double tolerance = 0.0);
0275     void SetReductionRatio(G4int maxVoxels, G4ThreeVector& reductionRatio);
0276 
0277 
0278   private:
0279 
0280    /**
0281     * @brief G4VoxelComparator is utility class used for comparing voxels.
0282     */
0283 
0284     class G4VoxelComparator
0285     {
0286       public:
0287 
0288       std::vector<G4VoxelInfo>& fVoxels;
0289 
0290       G4VoxelComparator(std::vector<G4VoxelInfo>& voxels) : fVoxels(voxels) {}
0291 
0292       G4bool operator()(const G4int& l, const G4int& r) const
0293       {
0294         G4VoxelInfo &lv = fVoxels[l], &rv = fVoxels[r];
0295         G4int left = lv.count +  fVoxels[lv.next].count;
0296         G4int right = rv.count + fVoxels[rv.next].count;
0297         return (left == right) ? l < r : left < right;
0298       }
0299     };
0300 
0301     static G4int fDefaultVoxelsCount;
0302 
0303     std::vector<G4VoxelBox> fVoxelBoxes;
0304     std::vector<std::vector<G4int> > fVoxelBoxesCandidates;
0305     mutable std::map<G4int, std::vector<G4int> > fCandidates;
0306 
0307     const std::vector<G4int> fNoCandidates;
0308 
0309     long long fCountOfVoxels;
0310 
0311     G4int fNPerSlice;
0312 
0313     std::vector<G4VoxelBox> fBoxes;
0314       // Array of box limits on the 3 cartesian axis
0315 
0316     std::vector<G4double> fBoundaries[3];
0317       // Sorted and if need skimmed fBoundaries along X,Y,Z axis
0318 
0319     std::vector<G4int> fCandidatesCounts[3]; 
0320 
0321     G4int fTotalCandidates;
0322 
0323     G4SurfBits fBitmasks[3];
0324 
0325     G4ThreeVector fBoundingBoxCenter;
0326 
0327     G4Box fBoundingBox;
0328 
0329     G4ThreeVector fBoundingBoxSize;
0330 
0331     G4ThreeVector fReductionRatio;
0332 
0333     G4int fMaxVoxels;
0334 
0335     G4double fTolerance;
0336 
0337     G4SurfBits fEmpty;
0338 };
0339 
0340 #include "G4Voxelizer.icc"
0341 
0342 #endif