Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-15 09:06:15

0001 //------------------------------- -*- C++ -*- -------------------------------//
0002 // Copyright Celeritas contributors: see top-level COPYRIGHT file for details
0003 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0004 //---------------------------------------------------------------------------//
0005 //! \file orange/surf/SurfaceSimplifier.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include <variant>
0010 
0011 #include "corecel/Assert.hh"
0012 #include "orange/OrangeTypes.hh"
0013 
0014 #include "SurfaceFwd.hh"
0015 
0016 namespace celeritas
0017 {
0018 //---------------------------------------------------------------------------//
0019 /*!
0020  * Return a simplified, regularized version of a surface/sense pair.
0021  *
0022  * This class takes a general surface with an associated sense and will
0023  * simplify (e.g., turning a general plane into an axis-aligned one) and
0024  * regularize (e.g., flipping normals so that the plane points in a positive
0025  * direction) it, modifying the sense as needed.
0026  *
0027  * It is meant to be used with \c VariantSurface to visit a surface type.
0028  *
0029  * The result of each simplification type should be a \c std::variant of
0030  * possible simplified class forms, or a \c std::monostate if no simplification
0031  * was applied.
0032  *
0033  * \todo Use a \c Tolerance object instead of a single tolerance, and compare
0034  * implementations with \c SoftSurfaceEqual for consistency.
0035  */
0036 class SurfaceSimplifier
0037 {
0038   private:
0039     template<class... T>
0040     using Optional = std::variant<std::monostate, T...>;
0041 
0042   public:
0043     // Construct with snapping tolerance and reference to sense
0044     inline SurfaceSimplifier(Sense* s, real_type tol);
0045 
0046     //! Construct with reference to sense that may be flipped
0047     explicit inline SurfaceSimplifier(Sense* s) : SurfaceSimplifier{s, 1e-10}
0048     {
0049     }
0050 
0051     // Plane may be snapped to origin
0052     template<Axis T>
0053     Optional<PlaneAligned<T>> operator()(PlaneAligned<T> const&) const;
0054 
0055     // Cylinder at origin will be simplified
0056     template<Axis T>
0057     Optional<CylCentered<T>> operator()(CylAligned<T> const&) const;
0058 
0059     // Cone near origin will be snapped
0060     template<Axis T>
0061     Optional<ConeAligned<T>> operator()(ConeAligned<T> const&) const;
0062 
0063     // Plane may be flipped, adjusted, or become axis-aligned
0064     Optional<PlaneAligned<Axis::x>, PlaneAligned<Axis::y>, PlaneAligned<Axis::z>, Plane>
0065     operator()(Plane const&) const;
0066 
0067     // Sphere near center can be snapped
0068     Optional<SphereCentered> operator()(Sphere const&) const;
0069 
0070     // Simple quadric can be normalized or simplified
0071     Optional<Plane,
0072              Sphere,
0073              CylAligned<Axis::x>,
0074              CylAligned<Axis::y>,
0075              CylAligned<Axis::z>,
0076              ConeAligned<Axis::x>,
0077              ConeAligned<Axis::y>,
0078              ConeAligned<Axis::z>,
0079              SimpleQuadric>
0080     operator()(SimpleQuadric const&) const;
0081 
0082     // Quadric can be normalized or simplified
0083     Optional<SimpleQuadric, GeneralQuadric>
0084     operator()(GeneralQuadric const&) const;
0085 
0086     //! Default: no simplification
0087     template<class S>
0088     std::variant<std::monostate> operator()(S const&) const
0089     {
0090         return {};
0091     }
0092 
0093   private:
0094     Sense* sense_;
0095     real_type tol_;
0096 };
0097 
0098 //---------------------------------------------------------------------------//
0099 // INLINE DEFINITIONS
0100 //---------------------------------------------------------------------------//
0101 /*!
0102  * Construct with snapping tolerance and reference to sense.
0103  */
0104 SurfaceSimplifier::SurfaceSimplifier(Sense* s, real_type tol)
0105     : sense_{s}, tol_{tol}
0106 {
0107     CELER_EXPECT(sense_);
0108     CELER_EXPECT(tol_ >= 0);
0109 }
0110 
0111 //---------------------------------------------------------------------------//
0112 }  // namespace celeritas