Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:05:56

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