File indexing completed on 2026-10-27 09:40:38
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include "corecel/cont/IdStack.hh"
0010 #include "orange/OrangeTypes.hh"
0011
0012 #include "BvhView.hh"
0013
0014 namespace celeritas
0015 {
0016 namespace detail
0017 {
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 class BvhEnclosingVolFinder
0034 {
0035 public:
0036
0037
0038 using Storage = NativeCRef<BvhTreeData>;
0039
0040
0041
0042 inline CELER_FUNCTION BvhEnclosingVolFinder(BvhTreeRecord const& tree,
0043 Storage const& storage);
0044
0045
0046 template<class F>
0047 inline CELER_FUNCTION LocalVolumeId operator()(Real3 const& pos,
0048 F&& is_inside) const;
0049
0050 private:
0051
0052 BvhView view_;
0053
0054
0055
0056
0057 template<class F>
0058 inline CELER_FUNCTION LocalVolumeId visit_leaf(BvhNodeId leaf_id,
0059 F&& is_inside) const;
0060
0061
0062 template<class F>
0063 inline CELER_FUNCTION LocalVolumeId visit_inf_vols(F&& is_inside) const;
0064
0065
0066 inline CELER_FUNCTION bool visit_bbox(LocalVolumeId const& id,
0067 Real3 const& pos) const;
0068 };
0069
0070
0071
0072
0073
0074
0075
0076 CELER_FUNCTION BvhEnclosingVolFinder::BvhEnclosingVolFinder(
0077 BvhTreeRecord const& tree, Storage const& storage)
0078 : view_(tree, storage)
0079 {
0080 }
0081
0082
0083
0084
0085
0086 template<class F>
0087 CELER_FUNCTION LocalVolumeId BvhEnclosingVolFinder::operator()(
0088 Real3 const& pos, F&& is_inside_vol) const
0089 {
0090 using Side = BvhInternalNode::Side;
0091
0092
0093 using StackT = IdStack<BvhNodeId, max_bvh_depth - 1>;
0094 BvhNodeId stack_spill_[StackT::spill_extent];
0095 StackT stack{stack_spill_};
0096 stack.push(BvhNodeId{0});
0097
0098 while (!stack.empty())
0099 {
0100 if (!view_.is_internal(stack.top()))
0101 {
0102 auto id = this->visit_leaf(stack.top(), is_inside_vol);
0103 stack.pop();
0104
0105 if (id)
0106 {
0107 return id;
0108 }
0109 }
0110 else
0111 {
0112 auto const& node = view_.inner_node(stack.top());
0113 stack.pop();
0114 for (auto s : {Side::right, Side::left})
0115 {
0116 if (is_inside(node.bbox(s), pos))
0117 {
0118 stack.push(node.child(s));
0119 }
0120 }
0121 }
0122 }
0123
0124 return this->visit_inf_vols(is_inside_vol);
0125 }
0126
0127
0128
0129
0130
0131
0132
0133 template<class F>
0134 CELER_FUNCTION LocalVolumeId BvhEnclosingVolFinder::visit_leaf(
0135 BvhNodeId leaf_id, F&& is_inside) const
0136 {
0137 for (auto id : view_.leaf_vol_ids(leaf_id))
0138 {
0139 if (is_inside(id))
0140 {
0141 return id;
0142 }
0143 }
0144 return LocalVolumeId{};
0145 }
0146
0147
0148
0149
0150
0151 template<class F>
0152 CELER_FUNCTION LocalVolumeId BvhEnclosingVolFinder::visit_inf_vols(
0153 F&& is_inside) const
0154 {
0155 for (auto id : view_.inf_vol_ids())
0156 {
0157 if (is_inside(id))
0158 {
0159 return id;
0160 }
0161 }
0162 return LocalVolumeId{};
0163 }
0164
0165
0166
0167
0168
0169 CELER_FUNCTION bool BvhEnclosingVolFinder::visit_bbox(LocalVolumeId const& id,
0170 Real3 const& point) const
0171 {
0172 return is_inside(view_.bbox(id), point);
0173 }
0174
0175
0176 }
0177 }