Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-10-27 09:40:39

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/detail/BvhView.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include "orange/OrangeTypes.hh"
0010 
0011 #include "BvhData.hh"
0012 
0013 namespace celeritas
0014 {
0015 namespace detail
0016 {
0017 //---------------------------------------------------------------------------//
0018 /*!
0019  * Access data for a BVH internal node.
0020  */
0021 class BvhInternalNodeView
0022 {
0023   public:
0024     //!@{
0025     //! \name Type aliases
0026     using Side = BvhInternalNode::Side;
0027     //!@}
0028 
0029     // Construct from internal node data
0030     inline CELER_FUNCTION explicit BvhInternalNodeView(
0031         BvhInternalNode const& node);
0032 
0033     // Get partition axis
0034     inline CELER_FUNCTION Axis axis() const;
0035 
0036     // Get child node for a side
0037     inline CELER_FUNCTION BvhNodeId child(Side side) const;
0038 
0039     // Get edge bounding box for a side
0040     inline CELER_FUNCTION FastBBox const& bbox(Side side) const;
0041 
0042   private:
0043     BvhInternalNode const& node_;
0044 };
0045 
0046 //---------------------------------------------------------------------------//
0047 /*!
0048  * Traverse BVH tree using a depth-first search.
0049  *
0050  * \todo move to top-level orange directory out of detail namespace
0051  */
0052 class BvhView
0053 {
0054   public:
0055     //!@{
0056     //! \name Type aliases
0057     using Storage = NativeCRef<BvhTreeData>;
0058     using SpanLocalVol = LdgSpan<LocalVolumeId const>;
0059     //!@}
0060 
0061     // Construct from vector of bounding boxes and storage for LocalVolumeIds
0062     inline CELER_FUNCTION BvhView(BvhTreeRecord const& tree,
0063                                   Storage const& storage);
0064 
0065     // Determine if a node is inner, i.e., not a leaf
0066     inline CELER_FUNCTION bool is_internal(BvhNodeId id) const;
0067 
0068     // Get an internal node for a given BvhNodeId
0069     inline CELER_FUNCTION BvhInternalNodeView inner_node(BvhNodeId id) const;
0070 
0071     // Get number of internal nodes
0072     inline CELER_FUNCTION size_type num_internal_nodes() const;
0073 
0074     // Get number of leaf nodes
0075     inline CELER_FUNCTION size_type num_leaf_nodes() const;
0076 
0077     // Get total number of nodes
0078     inline CELER_FUNCTION size_type num_nodes() const;
0079 
0080     // Get the bbox for a given vol_id.
0081     inline CELER_FUNCTION FastBBox const& bbox(LocalVolumeId vol_id) const;
0082 
0083     // Get the vol_ids on a given leaf node
0084     inline CELER_FUNCTION SpanLocalVol leaf_vol_ids(BvhNodeId) const;
0085 
0086     // Get the inf_vol_ids
0087     inline CELER_FUNCTION SpanLocalVol inf_vol_ids() const;
0088 
0089   private:
0090     //// DATA ////
0091     BvhTreeRecord const& tree_;
0092     Storage const& storage_;
0093 };
0094 
0095 //---------------------------------------------------------------------------//
0096 // INLINE DEFINITIONS
0097 //---------------------------------------------------------------------------//
0098 /*!
0099  * Construct from an internal node.
0100  */
0101 CELER_FUNCTION BvhInternalNodeView::BvhInternalNodeView(
0102     BvhInternalNode const& node)
0103     : node_(node)
0104 {
0105     CELER_EXPECT(node_);
0106 }
0107 
0108 //---------------------------------------------------------------------------//
0109 /*!
0110  * Get partition axis.
0111  */
0112 CELER_FUNCTION Axis BvhInternalNodeView::axis() const
0113 {
0114     return node_.axis;
0115 }
0116 
0117 //---------------------------------------------------------------------------//
0118 /*!
0119  * Get child node for a side.
0120  */
0121 CELER_FUNCTION BvhNodeId BvhInternalNodeView::child(
0122     BvhInternalNodeView::Side side) const
0123 {
0124     return node_.edges[side].child;
0125 }
0126 
0127 //---------------------------------------------------------------------------//
0128 /*!
0129  * Get edge bounding box for a side.
0130  */
0131 CELER_FUNCTION FastBBox const& BvhInternalNodeView::bbox(
0132     BvhInternalNodeView::Side side) const
0133 {
0134     return node_.edges[side].bbox;
0135 }
0136 
0137 //---------------------------------------------------------------------------//
0138 /*!
0139  * Construct from vector of bounding boxes and storage.
0140  */
0141 CELER_FUNCTION BvhView::BvhView(BvhTreeRecord const& tree,
0142                                 BvhView::Storage const& storage)
0143     : tree_(tree), storage_(storage)
0144 {
0145     CELER_EXPECT(tree_);
0146 }
0147 
0148 //---------------------------------------------------------------------------//
0149 /*!
0150  *  Determine if a node is inner, i.e., not a leaf.
0151  */
0152 CELER_FUNCTION bool BvhView::is_internal(BvhNodeId id) const
0153 {
0154     return id.unchecked_get() < tree_.internal_nodes.size();
0155 }
0156 
0157 //---------------------------------------------------------------------------//
0158 /*!
0159  *  Get an internal node for a given BvhNodeId.
0160  */
0161 CELER_FUNCTION BvhInternalNodeView BvhView::inner_node(BvhNodeId id) const
0162 {
0163     CELER_EXPECT(this->is_internal(id));
0164     return BvhInternalNodeView{
0165         storage_.internal_nodes[tree_.internal_nodes[id.unchecked_get()]]};
0166 }
0167 
0168 //---------------------------------------------------------------------------//
0169 /*!
0170  *  Get number of internal nodes.
0171  */
0172 CELER_FUNCTION auto BvhView::num_internal_nodes() const -> size_type
0173 {
0174     return tree_.internal_nodes.size();
0175 }
0176 
0177 //---------------------------------------------------------------------------//
0178 /*!
0179  *  Get number of leaf nodes.
0180  */
0181 CELER_FUNCTION auto BvhView::num_leaf_nodes() const -> size_type
0182 {
0183     return tree_.leaf_nodes.size();
0184 }
0185 
0186 //---------------------------------------------------------------------------//
0187 /*!
0188  *  Get total number of nodes.
0189  */
0190 CELER_FUNCTION auto BvhView::num_nodes() const -> size_type
0191 {
0192     return tree_.internal_nodes.size() + tree_.leaf_nodes.size();
0193 }
0194 
0195 //---------------------------------------------------------------------------//
0196 /*!
0197  *  Get the bbox for a given vol_id.
0198  */
0199 CELER_FUNCTION FastBBox const& BvhView::bbox(LocalVolumeId vol_id) const
0200 {
0201     CELER_EXPECT(vol_id.unchecked_get() < tree_.bboxes.size());
0202     return storage_.bboxes[tree_.bboxes[vol_id]];
0203 }
0204 
0205 //---------------------------------------------------------------------------//
0206 /*!
0207  *  Get the vol_ids on a given leaf node.
0208  */
0209 CELER_FUNCTION auto BvhView::leaf_vol_ids(BvhNodeId id) const -> SpanLocalVol
0210 {
0211     CELER_EXPECT(id >= BvhNodeId{this->num_internal_nodes()}
0212                  && id < this->num_nodes());
0213     ItemId<BvhLeafNode> leaf_id
0214         = tree_.leaf_nodes[*id - this->num_internal_nodes()];
0215     CELER_ASSERT(leaf_id < storage_.leaf_nodes.size());
0216     auto&& leaf_node = storage_.leaf_nodes[leaf_id];
0217     return storage_.local_volume_ids[leaf_node.vol_ids];
0218 }
0219 
0220 //---------------------------------------------------------------------------//
0221 /*!
0222  *  Get the inf_vol_ids.
0223  */
0224 CELER_FUNCTION auto BvhView::inf_vol_ids() const -> SpanLocalVol
0225 {
0226     return storage_.local_volume_ids[tree_.inf_vol_ids];
0227 }
0228 
0229 //---------------------------------------------------------------------------//
0230 }  // namespace detail
0231 }  // namespace celeritas