ACTS
Experiment-independent tracking
Loading...
Searching...
No Matches
cuboid_portal_generator.hpp
1// This file is part of the ACTS project.
2//
3// Copyright (C) 2016 CERN for the benefit of the ACTS project
4//
5// This Source Code Form is subject to the terms of the Mozilla Public
6// License, v. 2.0. If a copy of the MPL was not distributed with this
7// file, You can obtain one at https://mozilla.org/MPL/2.0/.
8
9#pragma once
10
11// Project include(s)
12#include "detray/builders/surface_factory_interface.hpp"
13#include "detray/core/concepts.hpp"
14#include "detray/core/detail/data_context.hpp"
15#include "detray/definitions/detail/qualifiers.hpp"
16#include "detray/definitions/geometry.hpp"
17#include "detray/definitions/indexing.hpp"
18#include "detray/definitions/math.hpp"
19#include "detray/geometry/shapes/cuboid3D.hpp"
20#include "detray/utils/bounding_volume.hpp"
21#include "detray/utils/logging.hpp"
22#include "detray/utils/ranges.hpp"
23
24// System include(s)
25#include <cassert>
26#include <limits>
27
28namespace detray {
29
33template <concepts::detector detector_t>
35 : public surface_factory_interface<detector_t> {
36 using algebra_type = typename detector_t::algebra_type;
37 using scalar_type = dscalar<algebra_type>;
38 using transform3_type = dtransform3D<algebra_type>;
39
41 struct bounding_box_creator {
43
44 template <typename mask_group_t, typename idx_range_t>
45 DETRAY_HOST_DEVICE inline void operator()(
46 const mask_group_t &mask_group, const idx_range_t &idx_range,
47 const scalar_type envelope, const transform3_type &trf,
48 std::vector<aabb_t> &boxes) const {
49 for (const auto &mask : detray::ranges::subrange(mask_group, idx_range)) {
50 // Local minimum bounding box
51 aabb_t box{mask, boxes.size(), envelope};
52 // Bounding box in global coordinates (might no longer be
53 // minimum)
54 boxes.push_back(box.transform(trf));
55 }
56 }
57 };
58
59 public:
61 DETRAY_HOST
62 explicit cuboid_portal_generator(const scalar_type env) : m_envelope{env} {}
63
65 DETRAY_HOST
66 auto size() const -> dindex override { return 6u; }
67
68 DETRAY_HOST
69 void clear() override { /*Do nothing*/ };
70
71 DETRAY_HOST
73 surface_data<detector_t> && /*unused*/) override { /*Do nothing*/ }
74
76 DETRAY_HOST
77 auto push_back(std::vector<surface_data<detector_t>> && /*unused*/)
78 -> void override { /*Do nothing*/ }
79
89 DETRAY_HOST
90 auto operator()(typename detector_t::volume_type &volume,
91 typename detector_t::surface_lookup_container &surfaces,
92 typename detector_t::transform_container &transforms,
93 typename detector_t::mask_container &masks,
94 typename detector_t::geometry_context ctx = {})
95 -> dindex_range override {
96 DETRAY_VERBOSE_HOST("Generate cuboid portals...");
97
98 using point3_t = dpoint3D<algebra_type>;
99 using vector3_t = dvector3D<algebra_type>;
100
101 using surface_t = typename detector_t::surface_type;
102 using nav_link_t = typename surface_t::navigation_link;
103 using mask_link_t = typename surface_t::mask_link;
104 using material_link_t = typename surface_t::material_link;
105
107
108 constexpr auto invalid_src_link{detail::invalid_value<std::uint64_t>()};
109
110 // Only build box portals for cuboid volumes
111 assert(volume.id() == volume_id::e_cuboid);
112 // Need surfaces to wrap
113 std::size_t n_surfaces{surfaces.size()};
114 assert(n_surfaces != 0u);
115
116 // The surfaces container is prefilled with other surfaces
117 auto surfaces_offset{static_cast<dindex>(n_surfaces)};
118
119 // Fetch the position in the mask tuple for the rectangle portals
120 constexpr auto rectangle_id{detector_t::masks::id::e_rectangle2D};
121
122 // The material will be added in a later step
123 constexpr auto no_material = surface_t::material_id::e_none;
124 material_link_t material_link{no_material, dindex_invalid};
125
126 // Max distance in case of infinite bounds
127 constexpr scalar_type max_shift{0.01f *
128 std::numeric_limits<scalar_type>::max()};
129
130 // The bounding boxes around the module surfaces
131 std::vector<aabb_t> boxes;
132 boxes.reserve(n_surfaces);
133
134 for (const auto &sf : surfaces) {
135 masks.template visit<bounding_box_creator>(
136 sf.mask(), m_envelope, transforms.at(sf.transform(), ctx), boxes);
137 }
138 // Build an aabb in the global space around the surface aabbs
139 aabb_t world_box{boxes, boxes.size(), m_envelope};
140
141 // translation
142 const point3_t center = world_box.template center<point3_t>();
143
144 // The world box local frame is the global coordinate frame
145 const point3_t box_min = world_box.template loc_min<point3_t>();
146 const point3_t box_max = world_box.template loc_max<point3_t>();
147
148 // Get the half lengths for the rectangle sides and translation
149 const point3_t h_lengths = 0.5f * (box_max - box_min);
150 const scalar_type h_x{math::fabs(h_lengths[0])};
151 const scalar_type h_y{math::fabs(h_lengths[1])};
152 const scalar_type h_z{math::fabs(h_lengths[2])};
153
154 // Volume links for the portal descriptors and the masks
155 const dindex volume_idx{volume.index()};
156 const nav_link_t volume_link{detail::invalid_value<nav_link_t>()};
157
158 // Construct portals in the...
159
160 //
161 // ... x-y plane
162 //
163 // Only one rectangle needed for both surfaces
164 mask_link_t mask_link{};
165 mask_link.set_id(rectangle_id);
166 const auto mask_idx{
167 static_cast<dindex>(masks.template size<rectangle_id>())};
168 if constexpr (concepts::interval<typename mask_link_t::index_type>) {
169 mask_link.set_index({mask_idx, 1u});
170 } else {
171 mask_link.set_index(mask_idx);
172 }
173 masks.template emplace_back<rectangle_id>(empty_context{}, volume_link, h_x,
174 h_y);
175
176 // No rotation, but shift in z for both faces
177 vector3_t shift{static_cast<scalar_type>(0), static_cast<scalar_type>(0),
178 detail::is_invalid_value(h_z) ? max_shift : h_z};
179 transforms.emplace_back(ctx, static_cast<vector3_t>(center + shift));
180 transforms.emplace_back(ctx, static_cast<vector3_t>(center - shift));
181
182 // Build the portal surfaces
183 dindex trf_idx{transforms.size(ctx) - 2};
184 surfaces.push_back(
185 {trf_idx, mask_link, material_link, volume_idx, surface_id::e_portal},
186 invalid_src_link);
187
188 surfaces.push_back(
189 {++trf_idx, mask_link, material_link, volume_idx, surface_id::e_portal},
190 invalid_src_link);
191
192 //
193 // ... x-z plane
194 //
195 mask_link.shift(1u);
196 masks.template emplace_back<rectangle_id>(empty_context{}, volume_link, h_x,
197 h_z);
198
199 // Rotate by 90deg around x-axis, plus shift in y
200 shift = {static_cast<scalar_type>(0),
201 detail::is_invalid_value(h_y) ? max_shift : h_y,
202 static_cast<scalar_type>(0)};
203 vector3_t new_x{1.f, 0.f, 0.f};
204 vector3_t new_z{0.f, -1.f, 0.f};
205 transforms.emplace_back(ctx, static_cast<vector3_t>(center + shift), new_z,
206 new_x);
207 transforms.emplace_back(ctx, static_cast<vector3_t>(center - shift), new_z,
208 new_x);
209
210 surfaces.push_back(
211 {++trf_idx, mask_link, material_link, volume_idx, surface_id::e_portal},
212 invalid_src_link);
213
214 surfaces.push_back(
215 {++trf_idx, mask_link, material_link, volume_idx, surface_id::e_portal},
216 invalid_src_link);
217
218 //
219 // ... y-z plane
220 //
221 mask_link.shift(1u);
222 masks.template emplace_back<rectangle_id>(empty_context{}, volume_link, h_z,
223 h_y);
224
225 // Rotate by 90deg around y-axis, plus shift in x
226 shift = {detail::is_invalid_value(h_x) ? max_shift : h_x,
227 static_cast<scalar_type>(0), static_cast<scalar_type>(0)};
228 new_x = {0.f, 0.f, -1.f};
229 new_z = {1.f, 0.f, 0.f};
230 transforms.emplace_back(ctx, static_cast<vector3_t>(center + shift), new_z,
231 new_x);
232 transforms.emplace_back(ctx, static_cast<vector3_t>(center - shift), new_z,
233 new_x);
234
235 surfaces.push_back(
236 {++trf_idx, mask_link, material_link, volume_idx, surface_id::e_portal},
237 invalid_src_link);
238
239 surfaces.push_back(
240 {++trf_idx, mask_link, material_link, volume_idx, surface_id::e_portal},
241 invalid_src_link);
242
243 return {surfaces_offset, static_cast<dindex>(surfaces.size())};
244 }
245
246 private:
248 scalar_type m_envelope;
249};
250
251} // namespace detray
An axis aligned bounding box of a given.
Definition bounding_volume.hpp:32
cuboid_portal_generator(const scalar_type env)
Use.
Definition cuboid_portal_generator.hpp:62
void push_back(surface_data< detector_t > &&) override
Add data to the factory.
Definition cuboid_portal_generator.hpp:72
auto operator()(typename detector_t::volume_type &volume, typename detector_t::surface_lookup_container &surfaces, typename detector_t::transform_container &transforms, typename detector_t::mask_container &masks, typename detector_t::geometry_context ctx={}) -> dindex_range override
Create minimum aabbs around all surfaces that are passed and then construct world portals from the gl...
Definition cuboid_portal_generator.hpp:90
auto push_back(std::vector< surface_data< detector_t > > &&) -> void override
Ignore inserted surfaces; this factory derives portals from the volume's existing surfaces when invok...
Definition cuboid_portal_generator.hpp:77
void clear() override
Clear all data in the factory.
Definition cuboid_portal_generator.hpp:69
auto size() const -> dindex override
Definition cuboid_portal_generator.hpp:66
Mask a region on a surface and link it to a volume.
Definition mask.hpp:46
Bind transform and mask data together for surface building.
Definition surface_factory_interface.hpp:37
virtual dindex size() const =0
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
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
get_vector3D_t< A, T > dvector3D
Three-dimensional vector type for algebra A and value type T.
Definition algebra.hpp:80
get_transform3D_t< A, T > dtransform3D
Three-dimensional transform type for algebra A and value type T.
Definition algebra.hpp:84
get_point3D_t< A, T > dpoint3D
Three-dimensional point type for algebra A and value type T.
Definition algebra.hpp:72
interface type to construct a subrange_view with CTAD
Definition subrange.hpp:90