Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-16 09:03:16

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/orangeinp/IntersectSurfaceBuilder.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include <vector>
0010 
0011 #include "geocel/BoundingBox.hh"
0012 #include "orange/OrangeTypes.hh"
0013 #include "orange/surf/VariantSurface.hh"
0014 
0015 #include "CsgTypes.hh"
0016 
0017 namespace celeritas
0018 {
0019 namespace orangeinp
0020 {
0021 namespace detail
0022 {
0023 class CsgUnitBuilder;
0024 struct IntersectSurfaceState;
0025 }  // namespace detail
0026 
0027 //---------------------------------------------------------------------------//
0028 /*!
0029  * Build a region of intersecting surfaces as a CSG node.
0030  *
0031  * This is the building block for constructing shapes, solids, and so forth.
0032  * The result of this class is:
0033  * - CSG nodes describing the inserted surfaces which have been transformed
0034  *   into the global reference frame
0035  * - Metadata combining the surfaces names with the object name
0036  * - Bounding boxes (interior and exterior)
0037  *
0038  * Internally, this class uses:
0039  * - \c SurfaceClipper to update bounding boxes for closed quadric surfaces
0040  *   (axis aligned cylinders, spheres, planes)
0041  * - \c apply_transform (which calls \c detail::SurfaceTransformer and its
0042  *   siblings) to generate new surfaces based on the local transformed
0043  *   coordinate system
0044  * - \c RecursiveSimplifier to take transformed or user-input surfaces and
0045  *   reduce them to more compact quadric representations
0046  */
0047 class IntersectSurfaceBuilder
0048 {
0049   public:
0050     //!@{
0051     //! \name Type aliases
0052     using Tol = Tolerance<>;
0053     //!@}
0054 
0055   public:
0056     // Get the construction tolerance
0057     Tol const& tol() const;
0058 
0059     // Add a surface with negative quadric value being "inside"
0060     template<class S>
0061     inline void operator()(S const& surf);
0062 
0063     // Add a surface with specified sense (usually inside except for planes)
0064     template<class S>
0065     void operator()(Sense sense, S const& surf);
0066 
0067     // Add a surface with specified sense and explicit face name
0068     template<class S>
0069     void operator()(Sense sense, S const& surf, std::string&& face_name);
0070 
0071     // Promise that the resulting region is inside/outside this bbox
0072     inline void operator()(Sense sense, BBox const& bbox);
0073 
0074   public:
0075     // "Private", to be used by testing and detail
0076     using State = detail::IntersectSurfaceState;
0077     using UnitBuilder = detail::CsgUnitBuilder;
0078     using VecNode = std::vector<NodeId>;
0079 
0080     // Construct with persistent unit builder and less persistent state
0081     IntersectSurfaceBuilder(UnitBuilder* ub, State* state);
0082 
0083   private:
0084     //// TYPES ////
0085 
0086     // Helper for constructing surfaces
0087     UnitBuilder* ub_;
0088 
0089     // State being modified by this builder
0090     State* state_;
0091 
0092     //// HELPER FUNCTION ////
0093 
0094     void insert_transformed(Sense sense,
0095                             VariantSurface const& surf,
0096                             std::string&& ext);
0097     void shrink_exterior(BBox const& bbox);
0098     void grow_interior(BBox const& bbox);
0099 };
0100 
0101 //---------------------------------------------------------------------------//
0102 // FREE FUNCTIONS
0103 //---------------------------------------------------------------------------//
0104 
0105 // Apply a surface builder to an unknown type
0106 void visit(IntersectSurfaceBuilder& csb,
0107            Sense sense,
0108            VariantSurface const& surf);
0109 
0110 //---------------------------------------------------------------------------//
0111 // INLINE FUNCTION DEFINITIONS
0112 //---------------------------------------------------------------------------//
0113 /*!
0114  * Add a surface with negative quadric value being "inside".
0115  */
0116 template<class S>
0117 void IntersectSurfaceBuilder::operator()(S const& surf)
0118 {
0119     return (*this)(Sense::inside, surf);
0120 }
0121 
0122 //---------------------------------------------------------------------------//
0123 /*!
0124  * Promise that all bounding surfaces are inside/outside this bbox.
0125  *
0126  * "inside" will shrink the exterior bbox, and "outside" will grow the interior
0127  * bbox. All bounding surfaces within the region must be *inside* the exterior
0128  * region and *outside* the interior region.
0129  */
0130 void IntersectSurfaceBuilder::operator()(Sense sense, BBox const& bbox)
0131 {
0132     if (sense == Sense::inside)
0133     {
0134         this->shrink_exterior(bbox);
0135     }
0136     else
0137     {
0138         this->grow_interior(bbox);
0139     }
0140 }
0141 
0142 //---------------------------------------------------------------------------//
0143 }  // namespace orangeinp
0144 }  // namespace celeritas