Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 09:07:48

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/detail/VolumeBuilder.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include "corecel/Config.hh"
0010 
0011 #include "corecel/io/Label.hh"
0012 #include "orange/transform/VariantTransform.hh"
0013 
0014 #include "../CsgTypes.hh"
0015 
0016 namespace celeritas
0017 {
0018 namespace orangeinp
0019 {
0020 namespace detail
0021 {
0022 //---------------------------------------------------------------------------//
0023 class CsgUnitBuilder;
0024 struct BoundingZone;
0025 class PopVBTransformOnDestruct;
0026 
0027 //---------------------------------------------------------------------------//
0028 /*!
0029  * Construct volumes out of objects.
0030  *
0031  * This class maintains a stack of transforms used by nested objects. It
0032  * ultimately returns a node ID corresponding to the CSG node (and bounding box
0033  * etc.) of the constructed object.
0034  *
0035  * To add a transform, store the result of \c make_scoped_transform within a
0036  * scoping block (generally the calling function). The resulting RAII class
0037  * prevents an imbalance from manual calls to "push" and "pop". For an example
0038  * usage, see \c celeritas::orangeinp::Transformed::build .
0039  */
0040 class VolumeBuilder
0041 {
0042   public:
0043     //!@{
0044     //! \name Type aliases
0045     using Metadata = Label;
0046     using Tol = Tolerance<>;
0047     //!@}
0048 
0049   public:
0050     // Construct with unit builder (and volume name??)
0051     explicit VolumeBuilder(CsgUnitBuilder* ub);
0052 
0053     //// ACCESSORS ////
0054 
0055     // Get the construction tolerance
0056     Tol const& tol() const;
0057 
0058     //!@{
0059     //! Access the unit builder for construction
0060     CsgUnitBuilder const& unit_builder() const { return *ub_; }
0061     CsgUnitBuilder& unit_builder() { return *ub_; }
0062     //!@}
0063 
0064     // Access the local-to-global transform during construction
0065     VariantTransform const& local_transform() const;
0066 
0067     //// MUTATORS ////
0068 
0069     // Add a region to the CSG tree, automatically calculating bounding zone
0070     NodeId insert_region(Metadata&& md, Joined&& j);
0071 
0072     // Add a region to the CSG tree, including a better bounding zone
0073     NodeId insert_region(Metadata&& md, Joined&& j, BoundingZone&& bz);
0074 
0075     // Add a negated region to the CSG tree
0076     NodeId insert_region(Metadata&& md, Negated&& n);
0077 
0078     // Apply a transform within this scope
0079     [[nodiscard]] PopVBTransformOnDestruct
0080     make_scoped_transform(VariantTransform const& t);
0081 
0082   private:
0083     //// DATA ////
0084 
0085     CsgUnitBuilder* ub_;
0086     std::vector<TransformId> transforms_;
0087 
0088     //// PRIVATE METHODS ////
0089 
0090     // Add a new variant transform
0091     void push_transform(VariantTransform&& vt);
0092 
0093     // Pop the last transform, used only by PopVBTransformOnDestruct
0094     void pop_transform();
0095 
0096     //// FRIENDS ////
0097 
0098     friend class PopVBTransformOnDestruct;
0099 };
0100 
0101 //---------------------------------------------------------------------------//
0102 //! Implementation-only RAII helper class for VolumeBuilder (detail detail)
0103 class PopVBTransformOnDestruct
0104 {
0105   private:
0106     friend class VolumeBuilder;
0107 
0108     // Construct with a volume builder pointer
0109     explicit PopVBTransformOnDestruct(VolumeBuilder* vb);
0110 
0111   public:
0112     //! Capture the pointer when move constructed
0113     PopVBTransformOnDestruct(PopVBTransformOnDestruct&& other) noexcept
0114         : vb_(std::exchange(other.vb_, nullptr))
0115     {
0116     }
0117 
0118     //! Capture the pointer when move assigned
0119     PopVBTransformOnDestruct&
0120     operator=(PopVBTransformOnDestruct&& other) noexcept
0121     {
0122         vb_ = std::exchange(other.vb_, nullptr);
0123         return *this;
0124     }
0125 
0126     PopVBTransformOnDestruct(PopVBTransformOnDestruct const&) = default;
0127     PopVBTransformOnDestruct& operator=(PopVBTransformOnDestruct const&)
0128         = default;
0129 
0130     //! Call pop when we own the pointer and go out of scope
0131     ~PopVBTransformOnDestruct() noexcept(!CELERITAS_DEBUG)
0132     {
0133         if (vb_)
0134         {
0135             vb_->pop_transform();
0136         }
0137     }
0138 
0139   private:
0140     VolumeBuilder* vb_{nullptr};
0141 };
0142 
0143 //---------------------------------------------------------------------------//
0144 }  // namespace detail
0145 }  // namespace orangeinp
0146 }  // namespace celeritas