Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-01-08 10:22:24

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  * \internal \todo Use a \c Tolerance object instead of a single tolerance? (Or
0034  * use local length scale with \c SoftClose.) Also, compare implementations
0035  * with \c SoftSurfaceEqual for consistency.
0036  */
0037 class SurfaceSimplifier
0038 {
0039   private:
0040     template<class... T>
0041     using Optional = std::variant<std::monostate, T...>;
0042 
0043   public:
0044     // Construct with snapping tolerance and reference to sense
0045     inline SurfaceSimplifier(Sense* s, real_type tol);
0046 
0047     //! Construct with reference to sense that may be flipped
0048     explicit inline SurfaceSimplifier(Sense* s) : SurfaceSimplifier{s, 1e-10}
0049     {
0050     }
0051 
0052     // Plane may be snapped to origin
0053     template<Axis T>
0054     Optional<PlaneAligned<T>> operator()(PlaneAligned<T> const&) const;
0055 
0056     // Cylinder at origin will be simplified
0057     template<Axis T>
0058     Optional<CylCentered<T>> operator()(CylAligned<T> const&) const;
0059 
0060     // Cone near origin will be snapped
0061     template<Axis T>
0062     Optional<ConeAligned<T>> operator()(ConeAligned<T> const&) const;
0063 
0064     // Plane may be flipped, adjusted, or become axis-aligned
0065     Optional<PlaneAligned<Axis::x>, PlaneAligned<Axis::y>, PlaneAligned<Axis::z>, Plane>
0066     operator()(Plane const&) const;
0067 
0068     // Sphere near center can be snapped
0069     Optional<SphereCentered> operator()(Sphere const&) const;
0070 
0071     // Simple quadric can be normalized or simplified
0072     Optional<Plane,
0073              Sphere,
0074              CylAligned<Axis::x>,
0075              CylAligned<Axis::y>,
0076              CylAligned<Axis::z>,
0077              ConeAligned<Axis::x>,
0078              ConeAligned<Axis::y>,
0079              ConeAligned<Axis::z>,
0080              SimpleQuadric>
0081     operator()(SimpleQuadric const&) const;
0082 
0083     // Quadric can be normalized or simplified
0084     Optional<SimpleQuadric, GeneralQuadric>
0085     operator()(GeneralQuadric const&) const;
0086 
0087     //! Default: no simplification
0088     template<class S>
0089     std::variant<std::monostate> operator()(S const&) const
0090     {
0091         return {};
0092     }
0093 
0094   private:
0095     Sense* sense_;
0096     real_type tol_;
0097 };
0098 
0099 //---------------------------------------------------------------------------//
0100 // INLINE DEFINITIONS
0101 //---------------------------------------------------------------------------//
0102 /*!
0103  * Construct with snapping tolerance and reference to sense.
0104  */
0105 SurfaceSimplifier::SurfaceSimplifier(Sense* s, real_type tol)
0106     : sense_{s}, tol_{tol}
0107 {
0108     CELER_EXPECT(sense_);
0109     CELER_EXPECT(tol_ >= 0);
0110 }
0111 
0112 //---------------------------------------------------------------------------//
0113 }  // namespace celeritas