Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 10:23:49

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