File indexing completed on 2026-10-27 09:40:39
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include <vector>
0010
0011 #include "corecel/cont/EnumArray.hh"
0012 #include "geocel/BoundingBox.hh" // IWYU pragma: keep
0013
0014 #include "BvhData.hh"
0015 #include "../OrangeTypes.hh"
0016
0017 namespace celeritas
0018 {
0019 namespace detail
0020 {
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 class BvhPartitioner
0033 {
0034 public:
0035
0036
0037 using Real3 = Array<fast_real_type, 3>;
0038 using VecBBox = std::vector<FastBBox>;
0039 using VecReal3 = std::vector<Real3>;
0040 using VecIndices = std::vector<LocalVolumeId>;
0041 using Side = BvhInternalNode::Side;
0042
0043
0044
0045 struct Partition
0046 {
0047 Axis axis = Axis::size_;
0048 fast_real_type position{};
0049
0050 EnumArray<Side, VecIndices> indices;
0051 EnumArray<Side, FastBBox> bboxes;
0052
0053 explicit operator bool() const
0054 {
0055 return axis != Axis::size_ && std::isfinite(position)
0056 && !indices[Side::left].empty()
0057 && !indices[Side::right].empty() && bboxes[Side::left]
0058 && bboxes[Side::right];
0059 }
0060 };
0061
0062
0063 public:
0064
0065 explicit BvhPartitioner(VecBBox const& bboxes,
0066 VecReal3 const& centers,
0067 size_type num_part_cands);
0068
0069
0070 Partition operator()(VecIndices const& indices) const;
0071
0072 private:
0073
0074 using AxesCenters = std::vector<std::vector<fast_real_type>>;
0075
0076
0077
0078
0079 VecBBox const& bboxes_;
0080
0081 VecReal3 const& centers_;
0082
0083 size_type num_part_cands_{0};
0084
0085 static constexpr size_type volume_threshold_ = 2;
0086
0087 static constexpr real_type overlap_threshold_ = real_type{0.5};
0088
0089
0090
0091
0092 AxesCenters calc_axes_centers(VecIndices const& indices) const;
0093
0094
0095 Partition make_partition(
0096 VecIndices const& indices, Axis axis, real_type position) const;
0097
0098
0099 real_type calc_cost(Partition const& partition) const;
0100 };
0101
0102
0103 }
0104 }