Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-13 09:12:55

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 and of QinetiQ Ltd,   *
0020 // * subject to DEFCON 705 IPR conditions.                            *
0021 // * By using,  copying,  modifying or  distributing the software (or *
0022 // * any work based  on the software)  you  agree  to acknowledge its *
0023 // * use  in  resulting  scientific  publications,  and indicate your *
0024 // * acceptance of all terms of the Geant4 Software license.          *
0025 // ********************************************************************
0026 //
0027 // G4TessellatedSolid
0028 //
0029 // Class description:
0030 //
0031 // G4TessellatedSolid is a special Geant4 solid defined by a number of
0032 // facets (UVFacet). It is important that the supplied facets shall form a
0033 // fully enclose space which is the solid.
0034 // At the moment only two types of facet can be used for the construction of
0035 // a G4TessellatedSolid, i.e. the G4TriangularFacet and G4QuadrangularFacet.
0036 //
0037 // How to contruct a G4TessellatedSolid:
0038 //
0039 //    First declare a tessellated solid:
0040 //
0041 //      G4TessellatedSolid* solidTarget = new G4TessellatedSolid("Solid_name");
0042 //
0043 //    Define the facets which form the solid:
0044 //
0045 //      G4double targetSiz = 10*cm ;
0046 //      G4TriangularFacet *facet1 = new
0047 //      G4TriangularFacet (G4ThreeVector(-targetSize,-targetSize,        0.0),
0048 //                         G4ThreeVector(+targetSize,-targetSize,        0.0),
0049 //                         G4ThreeVector(        0.0,        0.0,+targetSize),
0050 //                         ABSOLUTE);
0051 //      G4TriangularFacet *facet2 = new
0052 //      G4TriangularFacet (G4ThreeVector(+targetSize,-targetSize,        0.0),
0053 //                         G4ThreeVector(+targetSize,+targetSize,        0.0),
0054 //                         G4ThreeVector(        0.0,        0.0,+targetSize),
0055 //                         ABSOLUTE);
0056 //      G4TriangularFacet *facet3 = new
0057 //      G4TriangularFacet (G4ThreeVector(+targetSize,+targetSize,        0.0),
0058 //                         G4ThreeVector(-targetSize,+targetSize,        0.0),
0059 //                         G4ThreeVector(        0.0,        0.0,+targetSize),
0060 //                         ABSOLUTE);
0061 //      G4TriangularFacet *facet4 = new
0062 //      G4TriangularFacet (G4ThreeVector(-targetSize,+targetSize,        0.0),
0063 //                         G4ThreeVector(-targetSize,-targetSize,        0.0),
0064 //                         G4ThreeVector(        0.0,        0.0,+targetSize),
0065 //                         ABSOLUTE);
0066 //      G4QuadrangularFacet *facet5 = new
0067 //      G4QuadrangularFacet (G4ThreeVector(-targetSize,-targetSize,      0.0),
0068 //                           G4ThreeVector(-targetSize,+targetSize,      0.0),
0069 //                           G4ThreeVector(+targetSize,+targetSize,      0.0),
0070 //                           G4ThreeVector(+targetSize,-targetSize,      0.0),
0071 //                           ABSOLUTE);
0072 //
0073 //    Then add the facets to the solid:
0074 //
0075 //      solidTarget->AddFacet((UVFacet*) facet1);
0076 //      solidTarget->AddFacet((UVFacet*) facet2);
0077 //      solidTarget->AddFacet((UVFacet*) facet3);
0078 //      solidTarget->AddFacet((UVFacet*) facet4);
0079 //      solidTarget->AddFacet((UVFacet*) facet5);
0080 //
0081 //    Finally declare the solid is complete:
0082 //
0083 //      solidTarget->SetSolidClosed(true);
0084 
0085 // Author: P.R.Truscott (QinetiQ Ltd, UK), 31.10.2004 - Created.
0086 //         M.Gayer (CERN), 12.10.2012 - New implementation with voxelization.
0087 // --------------------------------------------------------------------
0088 #ifndef G4TESSELLATEDSOLID_HH
0089 #define G4TESSELLATEDSOLID_HH
0090 
0091 #include "G4GeomTypes.hh"
0092 
0093 #if defined(G4GEOM_USE_USOLIDS)
0094 #define G4GEOM_USE_UTESSELLATEDSOLID 1
0095 #endif
0096 
0097 #if defined(G4GEOM_USE_UTESSELLATEDSOLID)
0098   #define G4UTessellatedSolid G4TessellatedSolid
0099   #include "G4UTessellatedSolid.hh"
0100 #else
0101 
0102 #include <iostream>
0103 #include <vector>
0104 #include <set>
0105 #include <map>
0106 
0107 #include "G4Types.hh"
0108 #include "G4VSolid.hh"
0109 #include "G4Voxelizer.hh"
0110 #include "G4VFacet.hh"
0111 
0112 struct G4VertexInfo
0113 {
0114   G4int id;
0115   G4double mag2;
0116 };
0117 
0118 class G4VertexComparator
0119 {
0120   public:
0121 
0122     G4bool operator() (const G4VertexInfo& l, const G4VertexInfo& r) const
0123     {
0124       return l.mag2 == r.mag2 ? l.id < r.id : l.mag2 < r.mag2;
0125     }
0126 };
0127 
0128 /**
0129  * @brief G4TessellatedSolid is a solid defined by a number of facets.
0130  * It is important that the supplied facets shall form a fully enclose space
0131  * which is the solid. The facets can be of two types, G4TriangularFacet and
0132  * G4QuadrangularFacet.
0133  */
0134 
0135 class G4TessellatedSolid : public G4VSolid
0136 {
0137   public:
0138 
0139     /**
0140      * Default Constructor.
0141      */
0142     G4TessellatedSolid ();
0143 
0144     /**
0145      * Constructor with solid's name.
0146      *  @param[in] name The name of the solid.
0147      */
0148     G4TessellatedSolid (const G4String& name);
0149 
0150     /**
0151      * Destructor. Clearing all allocated facets and data.
0152      */
0153     ~G4TessellatedSolid () override;
0154 
0155     /**
0156      * Fake default constructor for usage restricted to direct object
0157      * persistency for clients requiring preallocation of memory for
0158      * persistifiable objects.
0159      */
0160     G4TessellatedSolid(__void__&);
0161 
0162     /**
0163      * Copy constructor and assignment operator.
0164      */
0165     G4TessellatedSolid (const G4TessellatedSolid& ts);
0166     G4TessellatedSolid& operator= (const G4TessellatedSolid& right);
0167 
0168     /**
0169      * Operator +=, allowing to add two tessellated solids together, so
0170      * that the solid on the left includes all of the facets in the solid
0171      * on the right. To note that copies of the facets are generated, rather
0172      * than using the original facet set of the solid on the right.
0173      */
0174     G4TessellatedSolid& operator+= (const G4TessellatedSolid& right);
0175 
0176     /**
0177      * Methods for adding or retrieving a facet given an index.
0178      */
0179     G4bool AddFacet (G4VFacet* aFacet);
0180     inline G4VFacet* GetFacet (G4int i) const;
0181 
0182     /**
0183      * Accessors.
0184      */
0185     G4int GetNumberOfFacets () const;
0186     G4int GetFacetIndex (const G4ThreeVector& p) const;
0187     G4double GetMinXExtent () const;
0188     G4double GetMaxXExtent () const;
0189     G4double GetMinYExtent () const;
0190     G4double GetMaxYExtent () const;
0191     G4double GetMinZExtent () const;
0192     G4double GetMaxZExtent () const;
0193 
0194 
0195     /**
0196      * Concrete implementations of the expected query interfaces for
0197      * solids, as defined in the base class G4VSolid.
0198      */
0199     EInside Inside (const G4ThreeVector& p) const override;
0200     G4ThreeVector SurfaceNormal(const G4ThreeVector& p) const override;
0201     G4double DistanceToIn(const G4ThreeVector& p,
0202                                   const G4ThreeVector& v)const override;
0203     G4double DistanceToIn(const G4ThreeVector& p) const override;
0204     G4double DistanceToOut(const G4ThreeVector& p) const override;
0205     G4double DistanceToOut(const G4ThreeVector& p,
0206                                    const G4ThreeVector& v,
0207                                    const G4bool calcNorm,
0208                                          G4bool* validNorm,
0209                                          G4ThreeVector* norm) const override;
0210 
0211     /**
0212      * Returns the outwards pointing unit normal of the shape for the
0213      * surface closest to the point at offset 'p'.
0214      *  @param[in] p The point coordinates.
0215      *  @param[out] n The returned normal vector.
0216      *  @returns false if not a valid normal.
0217      */
0218     virtual G4bool Normal (const G4ThreeVector& p, G4ThreeVector& n) const;
0219 
0220     /**
0221      * Returns the the safety distance from outside the solid at a point 'p'.
0222      *  @param[in] p The point coordinates.
0223      *  @param[in] aAccurate Accuracy flag, if false quickly computes and
0224      *              returns the distance to the voxels bounding-box.
0225      *  @returns The safety distance.
0226      */
0227     virtual G4double SafetyFromOutside(const G4ThreeVector& p,
0228                                              G4bool aAccurate = false) const;
0229 
0230     /**
0231      * Returns the the safety distance from inside the solid at a point 'p'.
0232      *  @param[in] p The point coordinates.
0233      *  @param[in] aAccurate Not used.
0234      *  @returns The safety distance.
0235      */
0236     virtual G4double SafetyFromInside (const G4ThreeVector& p,
0237                                              G4bool aAccurate = false) const;
0238 
0239     /**
0240      * Returns the type ID, "G4TessellatedSolid" of the solid.
0241      */
0242     G4GeometryType GetEntityType () const override;
0243 
0244     /**
0245      * Returns true as the solid has only planar faces.
0246      */
0247     G4bool IsFaceted () const override;
0248 
0249     /**
0250      * Streams the object contents to an output stream.
0251      */
0252     std::ostream& StreamInfo(std::ostream& os) const override;
0253 
0254     /**
0255      * Makes a clone of the object for use in multi-treading.
0256      *  @returns A pointer to the new cloned allocated solid.
0257      */
0258     G4VSolid* Clone() const override;
0259 
0260     /**
0261      * Returns a random point located and uniformly distributed on the
0262      * surface of the solid.
0263      */
0264     G4ThreeVector GetPointOnSurface() const override;
0265 
0266     /**
0267      * Returning an estimation of the solid volume (capacity) and
0268      * surface area, in internal units.
0269      */
0270     G4double GetSurfaceArea() override;
0271     G4double GetCubicVolume() override;
0272 
0273     /**
0274      * Modifier and accessor to close/finalise the solid.
0275      */
0276     void SetSolidClosed (const G4bool t);
0277     G4bool GetSolidClosed () const;
0278 
0279     /**
0280      * Checks the structure of the solid.
0281      *  @returns A value, sum of the following defect indicators, if any
0282      *           (0 means no defects):
0283      *           1 - cubic volume is negative, wrong orientation of facets;
0284      *           2 - some facets have wrong orientation;
0285      *           4 - holes in the surface.
0286      */
0287     G4int CheckStructure() const;
0288 
0289     /**
0290      * Allowing to tune the maximum number of voxels to use for optimisation.
0291      */
0292     inline void SetMaxVoxels(G4int max);
0293 
0294     /**
0295      * Returns the voxels structure.
0296      */
0297     inline G4Voxelizer& GetVoxels();
0298 
0299     /**
0300      * Calculates the minimum and maximum extent of the solid, when under the
0301      * specified transform, and within the specified limits.
0302      *  @param[in] pAxis The axis along which compute the extent.
0303      *  @param[in] pVoxelLimit The limiting space dictated by voxels.
0304      *  @param[in] pTransform The internal transformation applied to the solid.
0305      *  @param[out] pMin The minimum extent value.
0306      *  @param[out] pMax The maximum extent value.
0307      *  @returns True if the solid is intersected by the extent region.
0308      */
0309     G4bool CalculateExtent(const EAxis pAxis,
0310                            const G4VoxelLimits& pVoxelLimit,
0311                            const G4AffineTransform& pTransform,
0312                                  G4double& pMin, G4double& pMax) const override;
0313 
0314     /**
0315      * Computes the bounding limits of the solid.
0316      *  @param[out] pMin The minimum bounding limit point.
0317      *  @param[out] pMax The maximum bounding limit point.
0318      */
0319     void BoundingLimits(G4ThreeVector& pMin, G4ThreeVector& pMax) const override;
0320 
0321     /**
0322      * Methods for creating graphical representations (i.e. for visualisation).
0323      */
0324     G4Polyhedron* CreatePolyhedron() const override;
0325     G4Polyhedron* GetPolyhedron() const override;
0326     void DescribeYourselfTo(G4VGraphicsScene& scene) const override;
0327     G4VisExtent GetExtent() const override;
0328 
0329     /**
0330      * Loggers reporting the total allocated memory.
0331      */
0332     G4int AllocatedMemoryWithoutVoxels();
0333     G4int AllocatedMemory();
0334     void DisplayAllocatedMemory();
0335 
0336   private:
0337 
0338     /**
0339      * Initialisation/reset of data, used in constructors and operators.
0340      */
0341     void Initialize();
0342 
0343     /**
0344      * Resetting/copying data, used in constructors and operators.
0345      */
0346     void DeleteObjects ();
0347     void CopyObjects (const G4TessellatedSolid& s);
0348 
0349     /**
0350      * Internal methods used for computing distances with or without voxels.
0351      */
0352     G4double DistanceToOutNoVoxels(const G4ThreeVector& p,
0353                                    const G4ThreeVector& v,
0354                                          G4ThreeVector& aNormalVector,
0355                                          G4bool&        aConvex,
0356                                          G4double aPstep = kInfinity) const;
0357     G4double DistanceToInCandidates(const std::vector<G4int>& candidates,
0358                                     const G4ThreeVector& aPoint,
0359                                     const G4ThreeVector& aDirection) const;
0360     void DistanceToOutCandidates(const std::vector<G4int>& candidates,
0361                                  const G4ThreeVector& aPoint,
0362                                  const G4ThreeVector& direction,
0363                                        G4double& minDist,
0364                                        G4ThreeVector& minNormal,
0365                                        G4int& minCandidate) const;
0366     G4double DistanceToInNoVoxels(const G4ThreeVector& p,
0367                                   const G4ThreeVector& v,
0368                                         G4double aPstep = kInfinity) const;
0369     G4double DistanceToInCore(const G4ThreeVector &p, const G4ThreeVector& v,
0370                                     G4double aPstep = kInfinity) const;
0371     G4double DistanceToOutCore(const G4ThreeVector& p, const G4ThreeVector& v,
0372                                      G4ThreeVector& aNormalVector,
0373                                      G4bool& aConvex,
0374                                      G4double aPstep = kInfinity) const;
0375 
0376     /**
0377      * Finds those facets that have surface planes that bound the volume.
0378      * To note that this is going to reject concave surfaces as being extreme.
0379      */
0380     void SetExtremeFacets();
0381 
0382     /**
0383      * Internal methods used for checking if a point 'p' is inside the solid
0384      * in presence or not of voxels.
0385      */
0386     EInside InsideNoVoxels (const G4ThreeVector& p) const;
0387     EInside InsideVoxels(const G4ThreeVector& p) const;
0388 
0389     /**
0390      * Performs the voxelisation of the shape, building the optimisation
0391      * structure, according to the specified parameters.
0392      */
0393     void Voxelize();
0394 
0395     /**
0396      * Creates a list of vertices with an additional sorted list, where all
0397      * the items are sorted by magnitude of vertices vector.
0398      */
0399     void CreateVertexList();
0400 
0401     /**
0402      * Utilities for preparation of voxels indeces. Used in Voxelize() function.
0403      */
0404     void PrecalculateInsides();
0405     G4int SetAllUsingStack(const std::vector<G4int>& voxel,
0406                            const std::vector<G4int>& max,
0407                                  G4bool status, G4SurfBits& checked);
0408 
0409     /**
0410      * Utility to compare sorted voxels.
0411      */
0412     static G4bool CompareSortedVoxel(const std::pair<G4int, G4double>& l,
0413                                      const std::pair<G4int, G4double>& r);
0414 
0415 
0416     /**
0417       * Prepares a set of predefined random vectors, used to generate rays
0418       * from a user-defined point. Used in Inside() function to determine
0419       * whether the point is inside or outside of the tessellated solid.
0420       * All vectors should be unit vectors.
0421       */
0422     void SetRandomVectors();
0423 
0424     /**
0425      * Computes the minimum distance of a point 'p' from a 'facet'.
0426      */
0427     G4double MinDistanceFacet(const G4ThreeVector& p, G4bool simple,
0428                                     G4VFacet* &facet) const;
0429 
0430     /**
0431      * Computes if a point 'p' is outside or not of the computed extent,
0432      * given a 'tolerance'. Used internally in Inside() functions.
0433      *  @returns true if the point is within the extent.
0434      */
0435     inline G4bool OutsideOfExtent(const G4ThreeVector& p,
0436                                         G4double tolerance = 0.0) const;
0437 
0438   protected:
0439 
0440     G4double kCarToleranceHalf;
0441 
0442   private:
0443 
0444     mutable G4bool fRebuildPolyhedron = false;
0445     mutable G4Polyhedron* fpPolyhedron = nullptr;
0446 
0447     std::vector<G4VFacet*> fFacets;
0448     std::set<G4VFacet*> fExtremeFacets; // Does all other facets lie on
0449                                         // or behind this surface?
0450 
0451     G4GeometryType fGeometryType;
0452     G4double       fCubicVolume = 0.0;
0453     G4double       fSurfaceArea = 0.0;
0454 
0455     std::vector<G4ThreeVector> fVertexList;
0456 
0457     std::set<G4VertexInfo,G4VertexComparator> fFacetList;
0458 
0459     G4ThreeVector fMinExtent, fMaxExtent;
0460 
0461     G4bool fSolidClosed = false;
0462 
0463     std::vector<G4ThreeVector> fRandir;
0464 
0465     G4int fMaxTries;
0466 
0467     G4Voxelizer fVoxels;  // Pointer to the voxelized solid
0468 
0469     G4SurfBits fInsides;
0470 };
0471 
0472 ///////////////////////////////////////////////////////////////////////////////
0473 // Inline Methods
0474 ///////////////////////////////////////////////////////////////////////////////
0475 
0476 inline G4VFacet* G4TessellatedSolid::GetFacet (G4int i) const
0477 {
0478   return fFacets[i];
0479 }
0480 
0481 inline void G4TessellatedSolid::SetMaxVoxels(G4int max)
0482 {
0483   fVoxels.SetMaxVoxels(max);
0484 }
0485 
0486 inline G4Voxelizer& G4TessellatedSolid::GetVoxels()
0487 {
0488   return fVoxels;
0489 }
0490 
0491 inline G4bool G4TessellatedSolid::OutsideOfExtent(const G4ThreeVector& p,
0492                                                   G4double tolerance) const
0493 {
0494   return ( p.x() < fMinExtent.x() - tolerance
0495         || p.x() > fMaxExtent.x() + tolerance
0496         || p.y() < fMinExtent.y() - tolerance
0497         || p.y() > fMaxExtent.y() + tolerance
0498         || p.z() < fMinExtent.z() - tolerance
0499         || p.z() > fMaxExtent.z() + tolerance);
0500 }
0501 
0502 #endif
0503 
0504 #endif