File indexing completed on 2026-05-27 07:23:59
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011
0012 #include "detray/definitions/detail/qualifiers.hpp"
0013 #include "detray/definitions/geometry.hpp"
0014 #include "detray/definitions/indexing.hpp"
0015
0016
0017 #include <ostream>
0018 #include <utility>
0019
0020 namespace detray {
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 template <typename ID, typename acc_link_t = dtyped_index<dindex, dindex>,
0036 typename mat_link_t = dtyped_index<dindex, dindex>>
0037 class volume_descriptor {
0038 public:
0039
0040 using object_id = ID;
0041
0042
0043 using sf_link_type =
0044 dmulti_index<dindex_range,
0045 static_cast<std::size_t>(
0046 static_cast<std::underlying_type_t<surface_id>>(
0047 surface_id::e_all))>;
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058 using accel_link_type = dmulti_index<acc_link_t, ID::e_size>;
0059
0060
0061 using material_link = mat_link_t;
0062 using material_id = typename material_link::id_type;
0063
0064
0065 constexpr volume_descriptor() = default;
0066
0067
0068
0069
0070 explicit constexpr volume_descriptor(const volume_id id) : m_id{id} {}
0071
0072
0073 static consteval bool is_surface_id(const object_id id) {
0074 return (id == object_id::e_portal || id == object_id::e_sensitive ||
0075 id == object_id::e_passive);
0076 }
0077
0078
0079 static consteval bool is_volume_id(const object_id id) {
0080 return (id == object_id::e_volume);
0081 }
0082
0083
0084 DETRAY_HOST_DEVICE
0085 constexpr auto id() const -> volume_id { return m_id; }
0086
0087
0088 DETRAY_HOST_DEVICE
0089 constexpr auto index() const -> dindex { return m_index; }
0090
0091
0092 DETRAY_HOST
0093 constexpr auto set_index(const dindex index) -> void { m_index = index; }
0094
0095
0096 DETRAY_HOST_DEVICE
0097 constexpr auto transform() const -> dindex { return m_transform; }
0098
0099
0100 DETRAY_HOST
0101 constexpr auto set_transform(const dindex trf_idx) -> void {
0102 m_transform = trf_idx;
0103 }
0104
0105
0106 DETRAY_HOST_DEVICE constexpr auto sf_link() const -> const sf_link_type& {
0107 return m_sf_links;
0108 }
0109
0110
0111 template <surface_id id>
0112 DETRAY_HOST_DEVICE constexpr auto sf_link() const -> const
0113 typename sf_link_type::index_type& {
0114 return detail::get<static_cast<uint>(id)>(m_sf_links);
0115 }
0116
0117
0118 template <surface_id id>
0119 DETRAY_HOST_DEVICE constexpr auto sf_link() ->
0120 typename sf_link_type::index_type& {
0121 return detail::get<static_cast<uint>(id)>(m_sf_links);
0122 }
0123
0124
0125 DETRAY_HOST_DEVICE constexpr auto full_sf_range() const ->
0126 typename sf_link_type::index_type {
0127 using idx_range_t = typename sf_link_type::index_type;
0128
0129 const auto& pt_range = sf_link<surface_id::e_portal>();
0130 const auto& sen_range = sf_link<surface_id::e_sensitive>();
0131 const auto& psv_range = sf_link<surface_id::e_passive>();
0132
0133
0134 dindex min{detail::get<0>(pt_range)};
0135 dindex max{detail::get<1>(pt_range)};
0136
0137 constexpr idx_range_t empty{};
0138 if (sen_range != empty) {
0139 min = detail::get<0>(sen_range) < min ? detail::get<0>(sen_range) : min;
0140 max = detail::get<1>(sen_range) > max ? detail::get<1>(sen_range) : max;
0141 }
0142
0143 if (psv_range != empty) {
0144 min = detail::get<0>(psv_range) < min ? detail::get<0>(psv_range) : min;
0145 max = detail::get<1>(psv_range) > max ? detail::get<1>(psv_range) : max;
0146 }
0147
0148 return idx_range_t{min, max};
0149 }
0150
0151
0152 DETRAY_HOST_DEVICE constexpr dindex n_surfaces() const {
0153 const auto sf_idx_range = full_sf_range();
0154
0155 assert(sf_idx_range[1] > sf_idx_range[0]);
0156 return sf_idx_range[1] - sf_idx_range[0];
0157 }
0158
0159
0160 DETRAY_HOST_DEVICE constexpr dindex to_local_sf_index(dindex sf_idx) const {
0161 auto full_range = full_sf_range();
0162
0163 assert(full_range[0] <= sf_idx);
0164 assert(sf_idx < full_range[1]);
0165
0166 return sf_idx - full_range[0];
0167 }
0168
0169
0170 DETRAY_HOST_DEVICE constexpr dindex to_global_sf_index(dindex sf_idx) const {
0171 auto full_range = full_sf_range();
0172 dindex glob_index{sf_idx + full_range[0]};
0173
0174 assert(full_range[0] <= glob_index);
0175 assert(glob_index < full_range[1]);
0176
0177 return glob_index;
0178 }
0179
0180
0181
0182
0183
0184
0185
0186
0187 template <surface_id id>
0188 DETRAY_HOST auto update_sf_link(
0189 const typename sf_link_type::index_type& other) noexcept -> void {
0190 auto& rg = sf_link<id>();
0191
0192 if (constexpr typename sf_link_type::index_type empty{}; rg == empty) {
0193 rg = other;
0194 } else {
0195
0196 assert(detail::get<1>(rg) == detail::get<0>(other));
0197 rg.set_upper(other.upper());
0198 }
0199 }
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209 template <surface_id id>
0210 DETRAY_HOST auto update_sf_link(std::size_t shift,
0211 std::size_t n_surfaces = 0) noexcept -> void {
0212 auto& rg = sf_link<id>();
0213
0214 if (constexpr typename sf_link_type::index_type empty{}; rg == empty) {
0215 rg = {0u, static_cast<dindex>(n_surfaces)};
0216 }
0217
0218 rg.shift(static_cast<dindex>(shift));
0219 }
0220
0221
0222 DETRAY_HOST_DEVICE
0223 constexpr auto material() const -> const material_link& { return m_mat_link; }
0224
0225
0226 DETRAY_HOST
0227 constexpr auto set_material(const material_link& mat_link) -> void {
0228 m_mat_link = mat_link;
0229 }
0230
0231
0232
0233 DETRAY_HOST
0234 constexpr auto set_material(const material_id mat_id, const dindex mat_idx)
0235 -> void {
0236 m_mat_link = {mat_id,
0237 static_cast<typename material_link::index_type>(mat_idx)};
0238 }
0239
0240
0241 DETRAY_HOST_DEVICE
0242 constexpr auto has_material() const -> bool {
0243 return (m_mat_link.id() != material_link::id_type::e_none) &&
0244 !m_mat_link.is_invalid();
0245 }
0246
0247
0248 DETRAY_HOST_DEVICE constexpr auto accel_link() const
0249 -> const accel_link_type& {
0250 return m_accel_links;
0251 }
0252
0253
0254
0255 DETRAY_HOST_DEVICE constexpr auto accel_link(const ID& id) const
0256 -> const acc_link_t& {
0257 static_assert(static_cast<std::size_t>(ID::e_size) >= 1);
0258 assert(static_cast<std::size_t>(id) < static_cast<std::size_t>(ID::e_size));
0259 return accel_link_helper<static_cast<ID>(
0260 static_cast<std::size_t>(ID::e_size) - 1)>(id);
0261 }
0262
0263
0264 template <ID obj_id>
0265 DETRAY_HOST_DEVICE constexpr auto accel_link() const -> const acc_link_t& {
0266 return detail::get<obj_id>(m_accel_links);
0267 }
0268
0269
0270 template <ID obj_id>
0271 DETRAY_HOST constexpr auto set_accel_link(const acc_link_t link) -> void {
0272 detail::get<obj_id>(m_accel_links) = link;
0273 }
0274
0275
0276
0277 template <ID obj_id>
0278 DETRAY_HOST constexpr auto set_accel_link(
0279 const typename acc_link_t::id_type id,
0280 const typename acc_link_t::index_type index) -> void {
0281 detail::get<obj_id>(m_accel_links) = acc_link_t{id, index};
0282 }
0283
0284
0285
0286
0287 DETRAY_HOST constexpr auto set_accel_link(
0288 const ID obj_id, const typename acc_link_t::id_type accel_id,
0289 const typename acc_link_t::index_type index) -> void {
0290 m_accel_links[obj_id] = acc_link_t{accel_id, index};
0291 }
0292
0293
0294
0295
0296 DETRAY_HOST_DEVICE
0297 constexpr auto operator==(const volume_descriptor& rhs) const -> bool {
0298 return (m_id == rhs.m_id && m_index == rhs.m_index &&
0299 m_accel_links == rhs.m_accel_links);
0300 }
0301
0302
0303 DETRAY_HOST
0304 friend std::ostream& operator<<(std::ostream& os,
0305 const volume_descriptor& v_desc) {
0306 os << "id = " << v_desc.id() << "(" << static_cast<int>(v_desc.id()) << ")";
0307 os << " | index = " << v_desc.index();
0308 os << " | trf. = " << v_desc.transform();
0309 os << " | acc link: " << v_desc.accel_link();
0310 os << " | sf link: " << v_desc.sf_link();
0311 os << " | mat link: " << v_desc.material();
0312 return os;
0313 }
0314
0315 private:
0316
0317
0318 template <ID obj_id>
0319 DETRAY_HOST_DEVICE constexpr auto accel_link_helper(const ID& id) const
0320 -> const acc_link_t& {
0321 if (id == obj_id) {
0322 return accel_link<obj_id>();
0323 } else if constexpr (static_cast<std::size_t>(obj_id) > 0) {
0324 return accel_link_helper<static_cast<ID>(
0325 static_cast<std::size_t>(obj_id) - 1)>(id);
0326 } else {
0327 __builtin_unreachable();
0328 }
0329 }
0330
0331
0332 volume_id m_id{volume_id::e_unknown};
0333
0334
0335 dindex m_index{dindex_invalid};
0336
0337
0338 dindex m_transform{dindex_invalid};
0339
0340
0341 sf_link_type m_sf_links{};
0342
0343
0344 material_link m_mat_link = {};
0345
0346
0347 accel_link_type m_accel_links{};
0348 };
0349
0350 }