Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-03 09:17:38

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 // G4MultiUnion
0027 //
0028 // Class description:
0029 //
0030 // An instance of "G4MultiUnion" constitutes a grouping of several solids.
0031 // The constituent solids are stored with their respective location in a node
0032 // instance. An instance of "G4MultiUnion" is subsequently composed of one
0033 // or several nodes.
0034 
0035 // Author: Marek Gayer (CERN), 19.10.2012 - Original implementation from USolids
0036 //         Gabriele Cosmo (CERN) 06.04.2017 - Adapted implementation in Geant4
0037 //                                            for VecGeom migration
0038 // --------------------------------------------------------------------
0039 #ifndef G4MULTIUNION_HH
0040 #define G4MULTIUNION_HH
0041 
0042 #include <vector>
0043 
0044 #include "G4VSolid.hh"
0045 #include "G4ThreeVector.hh"
0046 #include "G4Transform3D.hh"
0047 #include "G4Point3D.hh"
0048 #include "G4Vector3D.hh"
0049 #include "G4SurfBits.hh"
0050 #include "G4Voxelizer.hh"
0051 
0052 class G4Polyhedron;
0053 
0054 /**
0055  * @brief An instance of G4MultiUnion constitutes a grouping of several solids.
0056  * The constituent solids are stored with their respective location in a node
0057  * instance. An instance of G4MultiUnion is subsequently composed of one or
0058  * several nodes.
0059  */
0060 
0061 class G4MultiUnion : public G4VSolid
0062 {
0063   friend class G4Voxelizer;
0064 
0065   public:
0066 
0067     /**
0068      * Empty default constructor.
0069      */
0070     G4MultiUnion();
0071 
0072 
0073     /**
0074      * Constructor assigning a name and initialising components.
0075      */
0076     G4MultiUnion(const G4String& name);
0077 
0078     /**
0079      * Default destructor.
0080      */
0081     ~G4MultiUnion() override = default;
0082 
0083     /**
0084      * Fake default constructor for usage restricted to direct object
0085      * persistency for clients requiring preallocation of memory for
0086      * persistifiable objects.
0087      */
0088     G4MultiUnion(__void__&);
0089 
0090     /**
0091      * Methods to build the multiple union by adding nodes (by pointer or ref).
0092      *  @param[in] solid The solid to be added to the structure.
0093      *  @param[in] trans The 3D transformation relative to the structure.
0094      */
0095     void AddNode(G4VSolid& solid, const G4Transform3D& trans);
0096     void AddNode(G4VSolid* solid, const G4Transform3D& trans);
0097 
0098     /**
0099      * Copy constructor and assignment operator.
0100      */
0101     G4MultiUnion(const G4MultiUnion& rhs);
0102     G4MultiUnion& operator=(const G4MultiUnion& rhs);
0103 
0104     /**
0105      * Accessors to retrieve a transformation or a solid, given an index
0106      * and the total number of solids in the structure.
0107      */
0108     inline const G4Transform3D& GetTransformation(G4int index) const;
0109     inline G4VSolid* GetSolid(G4int index) const;
0110     inline G4int GetNumberOfSolids()const;
0111 
0112     /**
0113      * Returns if the given point "aPoint" is inside or not the solid.
0114      */
0115     EInside Inside(const G4ThreeVector& aPoint) const override;
0116 
0117     // Safety methods
0118     G4double DistanceToIn(const G4ThreeVector& aPoint) const override;
0119     G4double DistanceToOut(const G4ThreeVector& aPoint) const override;
0120     inline void SetAccurateSafety(G4bool flag);
0121 
0122     /**
0123      * Returns the distance along the normalised vector "aDirection" to the
0124      * shape, from the point at offset "aPoint". If there is no intersection,
0125      * return kInfinity. The first intersection resulting from leaving a
0126      * surface/volume is discarded. Hence, it is tolerant of points on
0127      * the surface of the shape.
0128      */
0129     G4double DistanceToIn(const G4ThreeVector& aPoint,
0130                           const G4ThreeVector& aDirection) const override;
0131 
0132     /**
0133      * Computes distance from a point presumably inside the solid to the solid
0134      * surface. Ignores first surface along each axis systematically (for points
0135      * inside or outside. Early returns zero in case the second surface is
0136      * behind the starting point.
0137      * The normal vector to the crossed surface is always filled.
0138      * In the case the considered point is located inside the G4MultiUnion
0139      * structure, it acts as follows:
0140      *  - investigation of the candidates for the passed point
0141      *  - progressive moving of the point towards the surface, along the
0142      *    provided direction
0143      *  - processing of the normal.
0144      *  @param[in] aPoint The reference point in space.
0145      *  @param[in] aDirection The normalised direction.
0146      *  @param[in] calcNorm Flag unused.
0147      *  @param[out] validNorm Unused.
0148      *  @param[out] aNormalVector The exiting outwards normal vector (undefined
0149      *              Magnitude). 
0150      *  @returns The distance value to exit a volume.
0151      */
0152     G4double DistanceToOut(const G4ThreeVector& aPoint,
0153                            const G4ThreeVector& aDirection,
0154                            const G4bool calcNorm = false,
0155                            G4bool* validNorm = nullptr,
0156                            G4ThreeVector* aNormalVector = nullptr) const override;
0157 
0158     /**
0159      * Methods to compute the distance to enter/exit a volume, given point and
0160      * direction, in presence of voxels-based optimisation structure or not.
0161      */
0162     G4double DistanceToInNoVoxels(const G4ThreeVector& aPoint,
0163                                   const G4ThreeVector& aDirection) const;
0164     G4double DistanceToOutVoxels(const G4ThreeVector& aPoint,
0165                                  const G4ThreeVector& aDirection,
0166                                        G4ThreeVector* aNormalVector) const;
0167     G4double DistanceToOutNoVoxels(const G4ThreeVector& aPoint,
0168                                    const G4ThreeVector& aDirection,
0169                                          G4ThreeVector* aNormalVector) const;
0170 
0171     /**
0172      * Returns the outwards pointing unit normal of the shape for the
0173      * surface closest to the point at offset "aPoint".
0174      */
0175     G4ThreeVector SurfaceNormal(const G4ThreeVector& aPoint) const override;
0176 
0177     /**
0178      * Determines the bounding box for the considered instance of G4MultiUnion.
0179      *  @param[in] aAxis The axis along which computing the extent.
0180      *  @param[out] aMin The minimum bounding limit point.
0181      *  @param[out] aMax The maximum bounding limit point.
0182      */
0183     void Extent(EAxis aAxis, G4double& aMin, G4double& aMax) const;
0184 
0185     /**
0186      * Computes the bounding limits of the solid.
0187      *  @param[out] aMin The minimum bounding limit point.
0188      *  @param[out] aMax The maximum bounding limit point.
0189      */
0190     void BoundingLimits(G4ThreeVector& aMin, G4ThreeVector& aMax) const override;
0191 
0192     /**
0193      * Calculates the minimum and maximum extent of a solid, when under the
0194      * specified transform, and within the specified limits.
0195      *  @param[in] pAxis The axis along which compute the extent.
0196      *  @param[in] pVoxelLimit The limiting space dictated by voxels.
0197      *  @param[in] pTransform The internal transformation applied to the solid.
0198      *  @param[out] pMin The minimum extent value.
0199      *  @param[out] pMax The maximum extent value.
0200      *  @returns True if the solid is intersected by the extent region.
0201      */
0202     G4bool CalculateExtent(const EAxis pAxis,
0203                            const G4VoxelLimits& pVoxelLimit,
0204                            const G4AffineTransform& pTransform,
0205                            G4double& pMin, G4double& pMax) const override;
0206 
0207     /**
0208      * Returns an estimate of the structure capacity or surface area.
0209      */
0210     G4double GetCubicVolume() override;
0211     G4double GetSurfaceArea() override;
0212 
0213     /**
0214      * Returns the number of solids part of the structure.
0215      */
0216     G4int GetNumOfConstituents() const override;
0217 
0218     /**
0219      * Returns false if any of the solids part of the structure is not faceted.
0220      */
0221     G4bool IsFaceted() const override;
0222 
0223     /**
0224      * Returns a new allocated clone of the multi-union structure.
0225      */
0226     G4VSolid* Clone() const override ;
0227 
0228     /**
0229      * Returns the type ID, "G4MultiUnion" of the solid.
0230      */
0231     G4GeometryType GetEntityType() const override { return "G4MultiUnion"; }
0232 
0233     /**
0234      * Finalises and prepares for use, creating the optimisation structure
0235      * for all solids in the structure. It must be called once before
0236      * navigation use.
0237      */
0238     void Voxelize();
0239 
0240     /**
0241      * Returns the xoxelised optimisation structure.
0242      */
0243     inline G4Voxelizer& GetVoxels() const;
0244 
0245     /**
0246      * Streams the object contents to an output stream.
0247      */
0248     std::ostream& StreamInfo(std::ostream& os) const override;
0249 
0250     /**
0251      * Returns a point (G4ThreeVector) randomly and uniformly generated
0252      * on the surface of a solid.
0253      */
0254     G4ThreeVector GetPointOnSurface() const override;
0255 
0256     /**
0257      * Methods for creating graphical representations (i.e. for visualisation).
0258      */
0259     void DescribeYourselfTo ( G4VGraphicsScene& scene ) const override ;
0260     G4Polyhedron* CreatePolyhedron () const override ;
0261     G4Polyhedron* GetPolyhedron () const override;
0262 
0263   private:
0264 
0265     /**
0266      * Utility methods for safety and distance computation.
0267      */
0268     EInside InsideNoVoxels(const G4ThreeVector& aPoint) const;
0269     EInside InsideWithExclusion(const G4ThreeVector& aPoint,
0270                                       G4SurfBits* bits = nullptr) const;
0271     G4int SafetyFromOutsideNumberNode(const G4ThreeVector& aPoint,
0272                                             G4double& safety) const;
0273     G4double DistanceToInCandidates(const G4ThreeVector& aPoint,
0274                                     const G4ThreeVector& aDirection,
0275                                           std::vector<G4int>& candidates,
0276                                           G4SurfBits& bits) const;
0277 
0278     /**
0279      * Conversion utilities.
0280      */
0281     inline G4ThreeVector GetLocalPoint(const G4Transform3D& trans,
0282                                        const G4ThreeVector& gpoint) const;
0283     inline G4ThreeVector GetLocalVector(const G4Transform3D& trans,
0284                                        const G4ThreeVector& gvec) const;
0285     inline G4ThreeVector GetGlobalPoint(const G4Transform3D& trans,
0286                                        const G4ThreeVector& lpoint) const;
0287     inline G4ThreeVector GetGlobalVector(const G4Transform3D& trans,
0288                                        const G4ThreeVector& lvec) const;
0289     void TransformLimits(G4ThreeVector& min, G4ThreeVector& max,
0290                          const G4Transform3D& transformation) const;
0291 
0292   private:
0293 
0294     struct G4MultiUnionSurface
0295     {
0296       G4ThreeVector point;
0297       G4VSolid* solid;
0298     };
0299 
0300     std::vector<G4VSolid*> fSolids;
0301     std::vector<G4Transform3D> fTransformObjs;
0302     G4Voxelizer fVoxels;              // Vozelizer for the solid
0303     G4double fCubicVolume = 0.0;      // Cubic Volume
0304     G4double fSurfaceArea = 0.0;      // Surface Area
0305     G4double kRadTolerance;           // Cached radial tolerance
0306     mutable G4bool fAccurate = false; // Accurate safety (off by default)
0307 
0308     mutable G4bool fRebuildPolyhedron = false;
0309     mutable G4Polyhedron* fpPolyhedron = nullptr;
0310 };
0311 
0312 #include "G4MultiUnion.icc"
0313 
0314 #endif