12#include "detray/builders/surface_factory_interface.hpp"
13#include "detray/builders/volume_builder_interface.hpp"
14#include "detray/definitions/geometry.hpp"
15#include "detray/geometry/surface.hpp"
16#include "detray/utils/concepts.hpp"
17#include "detray/utils/grid/concepts.hpp"
18#include "detray/utils/logging.hpp"
35template <
typename detector_t>
53 m_volume.set_index(idx);
54 m_volume.set_material(volume_type::material_id::e_none,
dindex_invalid);
58 m_volume.template set_accel_link<
59 static_cast<typename volume_type::object_id
>(0)>(
60 detector_t::accel::id::e_surface_default, 0);
62 DETRAY_VERBOSE_HOST(
"Created builder for volume: " << idx);
72 void has_accel(
bool toggle)
override { m_has_accel = toggle; }
76 bool has_accel()
const override {
return m_has_accel; }
80 DETRAY_HOST
void set_name(std::string volume_name)
override {
81 m_volume_name = std::move(volume_name);
82 DETRAY_VERBOSE_HOST(
"Set volume name: " << m_volume_name);
86 DETRAY_HOST std::string_view
name()
override {
87 if (m_volume_name.empty()) {
89 m_volume_name =
"unknown(volume_" + std::to_string(
vol_index()) +
")";
104 auto operator()() ->
typename detector_t::volume_type&
override {
116 typename detector_t::geometry_context ctx = {}) ->
117 typename detector_t::volume_type*
override {
118 DETRAY_VERBOSE_HOST(
"Build surfaces...");
120 assert(!m_surfaces.empty());
121 assert(!m_transforms.empty());
122 assert(!m_masks.all_empty());
125 m_volume.set_index(
static_cast<dindex>(det.volumes().size()));
127 m_volume.set_transform(det.transform_store().size());
128 det._transforms.push_back(m_trf);
135 m_transforms.clear(ctx);
138 DETRAY_VERBOSE_HOST(
"Successfully built "
139 << m_volume.n_surfaces()
140 <<
" surfaces for volume: " << this->name());
143 return &(det._volumes.back());
149 const typename detector_t::transform3_type& trf = {})
override {
157 const typename detector_t::point3_type& t)
override {
158 m_trf =
typename detector_t::transform3_type{t};
168 const typename detector_t::point3_type& t,
169 const typename detector_t::vector3_type& x,
170 const typename detector_t::vector3_type& z)
override {
171 m_trf =
typename detector_t::transform3_type{t, z, x};
180 typename detector_t::geometry_context ctx = {})
override {
181 DETRAY_VERBOSE_HOST(
"Add surface factory:");
183 (*sf_factory)(m_volume, m_surfaces, m_transforms, m_masks, ctx);
188 typename detector_t::surface_lookup_container&
surfaces()
override {
193 typename detector_t::transform_container&
transforms()
override {
198 typename detector_t::mask_container&
masks()
override {
return m_masks; }
208 template <geo_obj_ids surface_id = static_cast<geo_obj_ids>(0)>
211 const typename detector_t::geometry_context ctx,
212 detector_t& det)
noexcept(
false) ->
void {
214 DETRAY_WARN_HOST(m_volume_name
215 <<
": Geometry data deduplication not yet implemented");
219 const auto trf_offset = det.transform_store().size(ctx);
220 det._transforms.append(std::move(m_transforms), ctx);
223 auto sf_offset{
static_cast<dindex>(det.surfaces().size())};
226 auto find_range = [&](
auto sf_id) {
228 auto is_sf_type = [sf_id](
const auto& sf) {
return sf.id() == sf_id; };
230 auto first =
static_cast<dindex>(
231 math::abs(std::ranges::find_if(m_surfaces, is_sf_type) -
232 std::begin(m_surfaces)));
234 auto last =
static_cast<dindex>(math::abs(
235 std::ranges::rend(m_surfaces) -
236 std::ranges::find_if(std::ranges::rbegin(m_surfaces),
237 std::ranges::rend(m_surfaces), is_sf_type)));
240 return (first >= last)
245 m_volume.template update_sf_link<surface_id::e_portal>(
246 find_range(surface_id::e_portal));
248 m_volume.template update_sf_link<surface_id::e_sensitive>(
249 find_range(surface_id::e_sensitive));
251 m_volume.template update_sf_link<surface_id::e_passive>(
252 find_range(surface_id::e_passive));
257 for (
auto& sf_desc : m_surfaces) {
258 det._masks.template visit<detail::mask_index_update>(sf_desc.mask(),
260 sf_desc.set_volume(m_volume.index());
261 sf_desc.update_transform(trf_offset);
262 sf_desc.set_index(sf_offset++);
264 if (sf_desc.is_portal()) {
268 det._surfaces.insert(sf_desc);
272 constexpr auto default_acc_id{detector_t::accel::id::e_surface_default};
275 typename detector_t::surface_container descriptors;
276 descriptors.reserve(m_surfaces.size());
277 std::ranges::transform(
278 m_surfaces, std::back_inserter(descriptors),
279 [](
typename detector_t::surface_lookup_container::value_type& sf) {
281 typename detector_t::surface_container::value_type
>(sf);
286 DETRAY_VERBOSE_HOST(
"-> Volume has acceleration structure:");
288 typename detector_t::surface_container portals{};
291 std::ranges::copy_if(
292 descriptors, std::back_inserter(portals),
293 [](
auto& sf_desc) {
return !sf_desc.is_sensitive(); });
297 "-> Register only portals/passives with brute force "
300 det._accelerators.template push_back<default_acc_id>(std::move(portals));
303 "-> Register all surfaces with brute force accelerator");
306 det._accelerators.template push_back<default_acc_id>(
307 std::move(descriptors));
310 m_volume.template set_accel_link<surface_id>(
312 det.accelerator_store().template size<default_acc_id>() - 1u);
315 det._masks.append(std::move(m_masks));
318 det._volumes.push_back(m_volume);
323 bool m_has_accel{
false};
326 std::string m_volume_name{};
329 typename detector_t::volume_type m_volume{};
331 typename detector_t::transform3_type m_trf{};
335 typename detector_t::surface_lookup_container m_surfaces{};
336 typename detector_t::transform_container m_transforms{};
337 typename detector_t::mask_container m_masks{};
348 template <
typename group_t,
typename index_t,
typename surface_t>
351 surface_t& sf)
const {
352 sf.update_mask(
static_cast<dindex>(std::size(group)));
How to generate surfaces with their corresponding masks and transforms.
Definition surface_factory_interface.hpp:120
Interface for volume builders (and volume builder decorators).
Definition volume_builder_interface.hpp:66
void add_surfaces(std::shared_ptr< surface_factory_interface< detector_t > > sf_factory, typename detector_t::geometry_context ctx={}) override
Add data for (a) new surface(s) to the builder.
Definition volume_builder.hpp:178
auto vol_index() const -> dindex override
Definition volume_builder.hpp:67
volume_builder(const volume_id id, const dindex idx=0)
Parametrized Constructor.
Definition volume_builder.hpp:51
void add_volume_placement(const typename detector_t::point3_type &t, const typename detector_t::vector3_type &x, const typename detector_t::vector3_type &z) override
Constructs a placement transform from axes x and z and the translation t for the volume.
Definition volume_builder.hpp:167
auto build(detector_t &det, const volume_builder_options &opt, typename detector_t::geometry_context ctx={}) -> typename detector_t::volume_type *override
Build the volume with internal surfaces and portals and add it to the detector instance det.
Definition volume_builder.hpp:115
detector_t::surface_lookup_container & surfaces() override
Definition volume_builder.hpp:188
detector_t::mask_container & masks() override
Definition volume_builder.hpp:198
bool has_accel() const override
Definition volume_builder.hpp:76
void add_volume_placement(const typename detector_t::transform3_type &trf={}) override
Adds a placement transform.
Definition volume_builder.hpp:148
typename detector_t::volume_type volume_type
Volume descriptor type produced by the builder.
Definition volume_builder.hpp:43
void set_name(std::string volume_name) override
Sets the name volume_name for the volume.
Definition volume_builder.hpp:80
dscalar< typename detector_t::algebra_type > scalar_t
Scalar type used by this detector's geometry.
Definition volume_builder.hpp:41
std::string_view name() override
Definition volume_builder.hpp:86
detector_t::transform_container & transforms() override
Definition volume_builder.hpp:193
typename detector_t::geo_obj_ids geo_obj_ids
Identifier enum for the detector's geometry object categories.
Definition volume_builder.hpp:45
auto add_to_detector(const volume_builder_options &opt, const typename detector_t::geometry_context ctx, detector_t &det) noexcept(false) -> void
Adds a new full set of volume components (e.g.
Definition volume_builder.hpp:209
auto operator()() -> typename detector_t::volume_type &override
Access to the volume under construction - non-const.
Definition volume_builder.hpp:104
auto operator()() const -> const typename detector_t::volume_type &override
Access to the volume under construction - const.
Definition volume_builder.hpp:97
void add_volume_placement(const typename detector_t::point3_type &t) override
Constructs a placement transform with identity rotation and translation.
Definition volume_builder.hpp:156
void has_accel(bool toggle) override
Toggles whether sensitive surfaces are added to the brute force method.
Definition volume_builder.hpp:72
Check if a type can be used as a detector.
Definition concepts.hpp:47
Detray include(s).
Definition array_operators.hpp:18
get_scalar_t< A, T > dscalar
Scalar type for algebra A and value type T.
Definition algebra.hpp:64
volume_id
Shape of a detector volume.
Definition geometry.hpp:27
detail::index_range< dindex > dindex_range
Index ranges and sequences.
Definition indexing.hpp:24
unsigned int dindex
Default index type.
Definition indexing.hpp:18
constexpr dindex dindex_invalid
Global invalid index definition.
Definition indexing.hpp:21
std::size_t n_portals(const detector_t &det)
Definition detector_statistics.hpp:24
A functor to update the mask index in surface objects.
Definition volume_builder.hpp:344
void operator()(const group_t &group, const index_t &, surface_t &sf) const
Update a surface's mask index after mask groups are appended.
Definition volume_builder.hpp:349
Options for the volume builder classes.
Definition volume_builder_interface.hpp:29
constexpr bool deduplicate() const
Getters.
Definition volume_builder_interface.hpp:40