Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //----------------------------------*-C++-*----------------------------------//
0002 // Copyright 2023-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/detail/CsgUnitBuilder.hh
0007 //---------------------------------------------------------------------------//
0008 #pragma once
0009 
0010 #include "corecel/Assert.hh"
0011 #include "corecel/io/Label.hh"
0012 #include "orange/OrangeTypes.hh"
0013 
0014 #include "CsgUnit.hh"
0015 #include "LocalSurfaceInserter.hh"
0016 #include "TransformInserter.hh"
0017 #include "../CsgTypes.hh"
0018 
0019 namespace celeritas
0020 {
0021 namespace orangeinp
0022 {
0023 namespace detail
0024 {
0025 //---------------------------------------------------------------------------//
0026 /*!
0027  * Help construct a unit's mutable CSG representation.
0028  *
0029  * This *LOW-LEVEL* class keeps track of the CSG and surface nodes during
0030  * construction. It holds the "construction-time" properties like the local
0031  * surface inserter. The input "CSG Unit" must exceed the lifetime of this
0032  * builder.
0033  *
0034  * The geometry construction tolerance is passed to numerous other classes
0035  * during construction. The input bounding box is used to restrict the maximum
0036  * possible bounding box for any of the child objects.
0037  *
0038  * This class is meant to be used by:
0039  * - Object builders
0040  * - Convex surface builder
0041  */
0042 class CsgUnitBuilder
0043 {
0044   public:
0045     //!@{
0046     //! \name Type aliases
0047     using Tol = Tolerance<>;
0048     using Metadata = CsgUnit::Metadata;
0049     using NodeInsertion = CsgTree::Insertion;
0050     //!@}
0051 
0052   public:
0053     // Construct with an empty unit, tolerance settings, and a priori bbox
0054     CsgUnitBuilder(CsgUnit*, Tol const& tol, BBox const& extents);
0055 
0056     //// ACCESSORS ////
0057 
0058     //! Tolerance, needed for surface simplifier
0059     Tol const& tol() const { return tol_; }
0060 
0061     //! Maximum extents of this unit
0062     BBox const& extents() const { return bbox_; }
0063 
0064     // Access a typed surface, needed for clipping with deduplicated surface
0065     template<class S>
0066     inline S const& surface(NodeId) const;
0067 
0068     // Access a typed CSG node after insertion
0069     template<class T>
0070     inline T const& node(NodeId) const;
0071 
0072     // Access a bounding zone by ID
0073     BoundingZone const& bounds(NodeId) const;
0074 
0075     // Access a transform by ID
0076     inline VariantTransform const& transform(TransformId) const;
0077 
0078     //// MUTATORS ////
0079 
0080     // Insert a surface by forwarding to the surface inserter
0081     template<class... Args>
0082     inline NodeInsertion insert_surface(Args&&... args);
0083 
0084     // Insert a CSG node by forwarding to the CsgTree
0085     template<class... Args>
0086     inline NodeInsertion insert_csg(Args&&... args);
0087 
0088     // Insert a transform
0089     TransformId insert_transform(VariantTransform const& vt);
0090 
0091     // Insert node metadata
0092     inline void insert_md(NodeId node, Metadata&& md);
0093 
0094     // Set a bounding zone and transform for a node
0095     void insert_region(NodeId, BoundingZone const&, TransformId trans_id);
0096 
0097     // Mark a CSG node as a volume of real space
0098     LocalVolumeId insert_volume(NodeId);
0099 
0100     // Fill LocalVolumeId{0} with "exterior" to adjust the interior region
0101     void fill_exterior();
0102 
0103     // Fill a volume node with a material
0104     void fill_volume(LocalVolumeId, GeoMaterialId);
0105 
0106     // Fill a volume node with a daughter using the local transform
0107     void
0108     fill_volume(LocalVolumeId, UniverseId, VariantTransform const& transform);
0109 
0110   private:
0111     CsgUnit* unit_;
0112     Tol tol_;
0113     BBox bbox_;
0114     LocalSurfaceInserter insert_surface_;
0115     TransformInserter insert_transform_;
0116 
0117     // Get a variant surface from a node ID
0118     VariantSurface const& get_surface_impl(NodeId nid) const;
0119 
0120     // TODO: cache of weak_ptr<{Transform,ObjectInterface}> -> NodeId?
0121 };
0122 
0123 //---------------------------------------------------------------------------//
0124 // INLINE DEFINITIONS
0125 //---------------------------------------------------------------------------//
0126 /*!
0127  * Access a typed surface, needed for clipping with deduplicated surface.
0128  */
0129 template<class S>
0130 S const& CsgUnitBuilder::surface(NodeId nid) const
0131 {
0132     VariantSurface const& vs = this->get_surface_impl(nid);
0133     CELER_ASSUME(std::holds_alternative<S>(vs));
0134     return std::get<S>(vs);
0135 }
0136 
0137 //---------------------------------------------------------------------------//
0138 /*!
0139  * Access a CSG node after insertion.
0140  */
0141 template<class T>
0142 T const& CsgUnitBuilder::node(NodeId nid) const
0143 {
0144     auto const& node = unit_->tree[nid];
0145     CELER_ASSUME(std::holds_alternative<T>(node));
0146     return std::get<T>(node);
0147 }
0148 
0149 //---------------------------------------------------------------------------//
0150 /*!
0151  * Access a transform by ID.
0152  */
0153 VariantTransform const& CsgUnitBuilder::transform(TransformId tid) const
0154 {
0155     CELER_EXPECT(tid < unit_->transforms.size());
0156     return unit_->transforms[tid.unchecked_get()];
0157 }
0158 
0159 //---------------------------------------------------------------------------//
0160 /*!
0161  * Insert a surface by forwarding to the surface inserter.
0162  */
0163 template<class... Args>
0164 auto CsgUnitBuilder::insert_surface(Args&&... args) -> NodeInsertion
0165 {
0166     LocalSurfaceId lsid = insert_surface_(std::forward<Args>(args)...);
0167     return this->insert_csg(lsid);
0168 }
0169 
0170 //---------------------------------------------------------------------------//
0171 /*!
0172  * Insert a CSG node by forwarding to the CsgTree.
0173  */
0174 template<class... Args>
0175 auto CsgUnitBuilder::insert_csg(Args&&... args) -> NodeInsertion
0176 {
0177     auto result = unit_->tree.insert(std::forward<Args>(args)...);
0178     if (result.second)
0179     {
0180         unit_->metadata.resize(unit_->tree.size());
0181     }
0182     return result;
0183 }
0184 
0185 //---------------------------------------------------------------------------//
0186 /*!
0187  * Insert node metadata.
0188  */
0189 void CsgUnitBuilder::insert_md(NodeId node, Metadata&& md)
0190 {
0191     CELER_EXPECT(node < unit_->metadata.size());
0192     unit_->metadata[node.unchecked_get()].insert(std::move(md));
0193 }
0194 
0195 //---------------------------------------------------------------------------//
0196 }  // namespace detail
0197 }  // namespace orangeinp
0198 }  // namespace celeritas