Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:58:42

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 an
0032 //   instance of "G4Node". An instance of "G4MultiUnion" is subsequently
0033 //   composed of one or several nodes.
0034 
0035 // 19.10.12 M.Gayer - Original implementation from USolids module
0036 // 06.04.17 G.Cosmo - Adapted implementation in Geant4 for VecGeom migration
0037 // --------------------------------------------------------------------
0038 #ifndef G4MULTIUNION_HH
0039 #define G4MULTIUNION_HH
0040 
0041 #include <vector>
0042 
0043 #include "G4VSolid.hh"
0044 #include "G4ThreeVector.hh"
0045 #include "G4Transform3D.hh"
0046 #include "G4Point3D.hh"
0047 #include "G4Vector3D.hh"
0048 #include "G4SurfBits.hh"
0049 #include "G4Voxelizer.hh"
0050 
0051 class G4Polyhedron;
0052 
0053 class G4MultiUnion : public G4VSolid
0054 {
0055     friend class G4Voxelizer;
0056 
0057   public:
0058 
0059     G4MultiUnion() : G4VSolid("") {}
0060     G4MultiUnion(const G4String& name);
0061     ~G4MultiUnion() override;
0062 
0063     // Build the multiple union by adding nodes
0064     void AddNode(G4VSolid& solid, const G4Transform3D& trans);
0065     void AddNode(G4VSolid* solid, const G4Transform3D& trans);
0066 
0067     G4MultiUnion(const G4MultiUnion& rhs);
0068     G4MultiUnion& operator=(const G4MultiUnion& rhs);
0069 
0070     // Accessors
0071     inline const G4Transform3D& GetTransformation(G4int index) const;
0072     inline G4VSolid* GetSolid(G4int index) const;
0073     inline G4int GetNumberOfSolids()const;
0074 
0075     // Navigation methods
0076     EInside Inside(const G4ThreeVector& aPoint) const override;
0077 
0078     EInside InsideIterator(const G4ThreeVector& aPoint) const;
0079 
0080     // Safety methods
0081     G4double DistanceToIn(const G4ThreeVector& aPoint) const override;
0082     G4double DistanceToOut(const G4ThreeVector& aPoint) const override;
0083     inline void SetAccurateSafety(G4bool flag);
0084 
0085     // Exact distance methods
0086     G4double DistanceToIn(const G4ThreeVector& aPoint,
0087                           const G4ThreeVector& aDirection) const override;
0088     G4double DistanceToOut(const G4ThreeVector& aPoint,
0089                            const G4ThreeVector& aDirection,
0090                            const G4bool calcNorm = false,
0091                            G4bool* validNorm = nullptr,
0092                            G4ThreeVector* aNormalVector = nullptr) const override;
0093 
0094     G4double DistanceToInNoVoxels(const G4ThreeVector& aPoint,
0095                                   const G4ThreeVector& aDirection) const;
0096     G4double DistanceToOutVoxels(const G4ThreeVector& aPoint,
0097                                  const G4ThreeVector& aDirection,
0098                                  G4ThreeVector*       aNormalVector) const;
0099     G4double DistanceToOutVoxelsCore(const G4ThreeVector& aPoint,
0100                                      const G4ThreeVector& aDirection,
0101                                      G4ThreeVector*       aNormalVector,
0102                                      G4bool&           aConvex,
0103                                      std::vector<G4int>& candidates) const;
0104     G4double DistanceToOutNoVoxels(const G4ThreeVector& aPoint,
0105                                    const G4ThreeVector& aDirection,
0106                                    G4ThreeVector*       aNormalVector) const;
0107 
0108     G4ThreeVector SurfaceNormal(const G4ThreeVector& aPoint) const override;
0109 
0110     void Extent(EAxis aAxis, G4double& aMin, G4double& aMax) const;
0111     void BoundingLimits(G4ThreeVector& aMin, G4ThreeVector& aMax) const override;
0112     G4bool CalculateExtent(const EAxis pAxis,
0113                            const G4VoxelLimits& pVoxelLimit,
0114                            const G4AffineTransform& pTransform,
0115                            G4double& pMin, G4double& pMax) const override;
0116     G4double GetCubicVolume() override;
0117     G4double GetSurfaceArea() override;
0118 
0119     G4VSolid* Clone() const override ;
0120 
0121     G4GeometryType GetEntityType() const override { return "G4MultiUnion"; }
0122 
0123     void Voxelize();
0124       // Finalize and prepare for use. User MUST call it once before
0125       // navigation use.
0126 
0127     EInside InsideNoVoxels(const G4ThreeVector& aPoint) const;
0128     inline G4Voxelizer& GetVoxels() const;
0129 
0130     std::ostream& StreamInfo(std::ostream& os) const override;
0131 
0132     G4ThreeVector GetPointOnSurface() const override;
0133 
0134     void DescribeYourselfTo ( G4VGraphicsScene& scene ) const override ;
0135     G4Polyhedron* CreatePolyhedron () const override ;
0136     G4Polyhedron* GetPolyhedron () const override;
0137 
0138     G4MultiUnion(__void__&);
0139       // Fake default constructor for usage restricted to direct object
0140       // persistency for clients requiring preallocation of memory for
0141       // persistifiable objects.
0142 
0143   private:
0144 
0145     EInside InsideWithExclusion(const G4ThreeVector& aPoint,
0146                                 G4SurfBits* bits = nullptr) const;
0147     G4int SafetyFromOutsideNumberNode(const G4ThreeVector& aPoint,
0148                                       G4double& safety) const;
0149     G4double DistanceToInCandidates(const G4ThreeVector& aPoint,
0150                                     const G4ThreeVector& aDirection,
0151                                      std::vector<G4int>& candidates,
0152                                     G4SurfBits& bits) const;
0153 
0154     // Conversion utilities
0155     inline G4ThreeVector GetLocalPoint(const G4Transform3D& trans,
0156                                        const G4ThreeVector& gpoint) const;
0157     inline G4ThreeVector GetLocalVector(const G4Transform3D& trans,
0158                                        const G4ThreeVector& gvec) const;
0159     inline G4ThreeVector GetGlobalPoint(const G4Transform3D& trans,
0160                                        const G4ThreeVector& lpoint) const;
0161     inline G4ThreeVector GetGlobalVector(const G4Transform3D& trans,
0162                                        const G4ThreeVector& lvec) const;
0163     void TransformLimits(G4ThreeVector& min, G4ThreeVector& max,
0164                          const G4Transform3D& transformation) const;
0165   private:
0166 
0167     struct G4MultiUnionSurface
0168     {
0169       G4ThreeVector point;
0170       G4VSolid* solid;
0171     };
0172 
0173     std::vector<G4VSolid*> fSolids;
0174     std::vector<G4Transform3D> fTransformObjs;
0175     G4Voxelizer fVoxels;              // Vozelizer for the solid
0176     G4double fCubicVolume = 0.0;      // Cubic Volume
0177     G4double fSurfaceArea = 0.0;      // Surface Area
0178     G4double kRadTolerance;           // Cached radial tolerance
0179     mutable G4bool fAccurate = false; // Accurate safety (off by default)
0180 
0181     mutable G4bool fRebuildPolyhedron = false;
0182     mutable G4Polyhedron* fpPolyhedron = nullptr;
0183 };
0184 
0185 //______________________________________________________________________________
0186 inline G4Voxelizer& G4MultiUnion::GetVoxels() const
0187 {
0188   return (G4Voxelizer&)fVoxels;
0189 }
0190 
0191 //______________________________________________________________________________
0192 inline const G4Transform3D& G4MultiUnion::GetTransformation(G4int index) const
0193 {
0194   return fTransformObjs[index];
0195 }
0196 
0197 //______________________________________________________________________________
0198 inline G4VSolid* G4MultiUnion::GetSolid(G4int index) const
0199 {
0200   return fSolids[index];
0201 }
0202 
0203 //______________________________________________________________________________
0204 inline G4int G4MultiUnion::GetNumberOfSolids() const
0205 {
0206   return G4int(fSolids.size());
0207 }
0208 
0209 //______________________________________________________________________________
0210 inline void G4MultiUnion::SetAccurateSafety(G4bool flag)
0211 {
0212   fAccurate = flag;
0213 }
0214 
0215 //______________________________________________________________________________
0216 inline
0217 G4ThreeVector G4MultiUnion::GetLocalPoint(const G4Transform3D& trans,
0218                                           const G4ThreeVector& global) const
0219 {
0220   // Returns local point coordinates converted from the global frame defined
0221   // by the transformation. This is defined by multiplying the inverse
0222   // transformation with the global vector.
0223 
0224   return trans.inverse()*G4Point3D(global);
0225 }
0226 
0227 //______________________________________________________________________________
0228 inline
0229 G4ThreeVector G4MultiUnion::GetLocalVector(const G4Transform3D& trans,
0230                                            const G4ThreeVector& global) const
0231 {
0232   // Returns local point coordinates converted from the global frame defined
0233   // by the transformation. This is defined by multiplying the inverse
0234   // transformation with the global vector.
0235 
0236   G4Rotate3D rot;
0237   G4Translate3D transl ;
0238   G4Scale3D scale;
0239 
0240   trans.getDecomposition(scale,rot,transl);
0241   return rot.inverse()*G4Vector3D(global);
0242 }
0243 
0244 //______________________________________________________________________________
0245 inline
0246 G4ThreeVector G4MultiUnion::GetGlobalPoint(const G4Transform3D& trans,
0247                                            const G4ThreeVector& local) const
0248 {
0249   // Returns global point coordinates converted from the local frame defined
0250   // by the transformation. This is defined by multiplying this transformation
0251   // with the local vector.
0252 
0253   return trans*G4Point3D(local);
0254 }
0255 
0256 //______________________________________________________________________________
0257 inline
0258 G4ThreeVector G4MultiUnion::GetGlobalVector(const G4Transform3D& trans,
0259                                             const G4ThreeVector& local) const
0260 {
0261   // Returns vector components converted from the local frame defined by the
0262   // transformation to the global one. This is defined by multiplying this
0263   // transformation with the local vector while ignoring the translation.
0264 
0265   G4Rotate3D rot;
0266   G4Translate3D transl ;
0267   G4Scale3D scale;
0268 
0269   trans.getDecomposition(scale,rot,transl);
0270   return rot*G4Vector3D(local);
0271 }
0272 
0273 #endif