12#include "detray/definitions/algebra.hpp"
13#include "detray/definitions/detail/qualifiers.hpp"
14#include "detray/definitions/units.hpp"
15#include "detray/geometry/mask.hpp"
16#include "detray/geometry/shapes/cuboid3D.hpp"
17#include "detray/geometry/shapes/cylinder3D.hpp"
18#include "detray/navigation/intersection/bounding_box/cuboid_intersector.hpp"
19#include "detray/navigation/intersection/intersection.hpp"
20#include "detray/tracks/ray.hpp"
31template <
typename shape_t, concepts::algebra algebra_t>
44 using local_frame =
typename shape_t::template local_frame_type<A>;
47 static constexpr std::size_t
dim{shape_t::dim};
56 template <
typename... Args>
58 std::size_t box_id, Args&&... args)
59 : m_mask(box_id, std::forward<Args>(args)...) {}
65 template <
typename mask_t,
typename S = shape_t>
66 requires std::is_same_v<S, cuboid3D>
68 const mask_t&
mask, std::size_t box_id,
const scalar_t envelope)
69 : m_mask{
mask.local_min_bounds(envelope).values(), box_id} {
71 assert(envelope >= std::numeric_limits<scalar_t>::epsilon());
79 : m_mask(values, box_id) {
80 assert(values.size() == shape::boundaries::e_size &&
81 " Given number of boundaries does not match mask shape.");
89 template <
typename other_shape_t>
90 requires std::is_same_v<
91 typename shape::template local_frame_type<algebra_t>,
92 typename other_shape_t::template local_frame_type<algebra_t>>
96 std::size_t box_id,
const scalar_t env) {
100 constexpr scalar_t inv{detail::invalid_value<scalar_t>()};
107 for (
const auto& vol : aabbs) {
112 min_x = min_point[0] < min_x ? min_point[0] : min_x;
113 min_y = min_point[1] < min_y ? min_point[1] : min_y;
115 max_x = max_point[0] > max_x ? max_point[0] : max_x;
116 max_y = max_point[1] > max_y ? max_point[1] : max_y;
118 if constexpr (min_point.size() > 2) {
119 min_z = min_point[2] < min_z ? min_point[2] : min_z;
120 max_z = max_point[2] > max_z ? max_point[2] : max_z;
124 box_id, min_x - env, min_y - env, min_z - env,
125 max_x + env, max_y + env, max_z + env};
139 constexpr auto id() const -> std::
size_t {
return m_mask.volume_link(); }
149 template <
typename po
int_t>
150 DETRAY_HOST_DEVICE
constexpr auto loc_min() const -> point_t {
151 if constexpr (std::is_same_v<shape, cuboid3D>) {
152 return {m_mask[cuboid3D::e_min_x], m_mask[cuboid3D::e_min_y],
153 m_mask[cuboid3D::e_min_z]};
154 }
else if constexpr (std::is_same_v<shape, cylinder3D>) {
155 return {-m_mask[cylinder3D::e_max_r], m_mask[cylinder3D::e_min_phi],
156 m_mask[cylinder3D::e_min_z]};
161 constexpr scalar_t inv{detail::invalid_value<scalar_t>()};
162 return point_t{-inv, -inv, -inv};
166 template <
typename po
int_t>
167 DETRAY_HOST_DEVICE
constexpr auto loc_max() const -> point_t {
168 if constexpr (std::is_same_v<shape, cuboid3D>) {
169 return {m_mask[cuboid3D::e_max_x], m_mask[cuboid3D::e_max_y],
170 m_mask[cuboid3D::e_max_z]};
171 }
else if constexpr (std::is_same_v<shape, cylinder3D>) {
172 return {m_mask[cylinder3D::e_max_r], m_mask[cylinder3D::e_max_phi],
173 m_mask[cylinder3D::e_max_z]};
179 constexpr scalar_t inv{detail::invalid_value<scalar_t>()};
180 return point_t{inv, inv, inv};
186 template <concepts::transform3D transform3_t>
187 DETRAY_HOST_DEVICE
constexpr auto glob_min(
const transform3_t& trf)
const ->
188 typename transform3_t::point3 {
189 using point3_t =
typename transform3_t::point3;
191 if constexpr (std::is_same_v<shape, cuboid3D>) {
193 }
else if constexpr (std::is_same_v<shape, cylinder3D>) {
201 constexpr scalar_t inv{detail::invalid_value<scalar_t>()};
202 return point3_t{-inv, -inv, -inv};
209 template <concepts::transform3D transform3_t>
210 DETRAY_HOST_DEVICE
constexpr auto glob_max(
const transform3_t& trf)
const ->
211 typename transform3_t::point3 {
212 using point3_t =
typename transform3_t::point3;
214 if constexpr (std::is_same_v<shape, cuboid3D>) {
216 }
else if constexpr (std::is_same_v<shape, cylinder3D>) {
223 constexpr scalar_t inv{detail::invalid_value<scalar_t>()};
224 return point3_t{inv, inv, inv};
228 template <concepts::po
int3D po
int3_t>
229 DETRAY_HOST_DEVICE
constexpr auto center() const -> point3_t {
231 0.5f * (m_mask[cuboid3D::e_max_x] + m_mask[cuboid3D::e_min_x])};
233 0.5f * (m_mask[cuboid3D::e_max_y] + m_mask[cuboid3D::e_min_y])};
235 0.5f * (m_mask[cuboid3D::e_max_z] + m_mask[cuboid3D::e_min_z])};
237 return {detail::is_invalid_value(center_x) ? 0.f : center_x,
238 detail::is_invalid_value(center_y) ? 0.f : center_y,
239 detail::is_invalid_value(center_z) ? 0.f : center_z};
251 template <concepts::transform3D transform3_t,
typename S = shape_t>
252 requires std::is_same_v<S, cuboid3D>
253 DETRAY_HOST_DEVICE
auto transform(
const transform3_t& trf)
const
255 using point3_t =
typename transform3_t::point3;
258 (m_mask[cuboid3D::e_max_x] - m_mask[cuboid3D::e_min_x])};
260 (m_mask[cuboid3D::e_max_y] - m_mask[cuboid3D::e_min_y])};
262 (m_mask[cuboid3D::e_max_z] - m_mask[cuboid3D::e_min_z])};
265 if (detail::is_invalid_value(scalor_x) ||
266 detail::is_invalid_value(scalor_y) ||
267 detail::is_invalid_value(scalor_z)) {
269 assert(detail::is_invalid_value(scalor_x) &&
270 detail::is_invalid_value(scalor_y) &&
271 detail::is_invalid_value(scalor_z));
278 const point3_t new_box_x = scalor_x * trf.x();
279 const point3_t new_box_y = scalor_y * trf.y();
280 const point3_t new_box_z = scalor_z * trf.z();
287 glob_c_points[2] = glob_c_points[0] + new_box_x;
288 glob_c_points[3] = glob_c_points[0] + new_box_y;
289 glob_c_points[4] = glob_c_points[0] + new_box_z;
290 glob_c_points[5] = glob_c_points[1] - new_box_x;
291 glob_c_points[6] = glob_c_points[1] - new_box_y;
292 glob_c_points[7] = glob_c_points[1] - new_box_z;
295 constexpr scalar_t inv{detail::invalid_value<scalar_t>()};
302 for (
const point3_t& p : glob_c_points) {
304 min_x = p[0] < min_x ? p[0] : min_x;
305 max_x = p[0] > max_x ? p[0] : max_x;
306 min_y = p[1] < min_y ? p[1] : min_y;
307 max_y = p[1] > max_y ? p[1] : max_y;
308 min_z = p[2] < min_z ? p[2] : min_z;
309 max_z = p[2] > max_z ? p[2] : max_z;
314 m_mask.volume_link(), min_x, min_y, min_z, max_x, max_y, max_z};
322 template <concepts::po
int po
int_t>
324 const point_t& loc_p,
325 const scalar_t t = std::numeric_limits<scalar_t>::epsilon())
const {
326 return m_mask.is_inside(loc_p, t);
336 const scalar_t t = std::numeric_limits<scalar_t>::epsilon())
const {
337 static_assert(std::is_same_v<shape, cuboid3D>,
338 "aabbs are only implemented in cuboid shape for now");
346 return os << aabb.
bounds().to_string();
constexpr bool is_inside(const point_t &loc_p, const scalar_t t=std::numeric_limits< scalar_t >::epsilon()) const
Checks whether a point lies inside the box.
Definition bounding_volume.hpp:323
typename cuboid3D::boundaries boundaries
Definition bounding_volume.hpp:41
constexpr axis_aligned_bounding_volume(const std::vector< axis_aligned_bounding_volume< other_shape_t, algebra_t > > &aabbs, std::size_t box_id, const scalar_t env)
Construct a bounding box around a set of boxes.
Definition bounding_volume.hpp:93
constexpr auto id() const -> std::size_t
Return the volume identifier.
Definition bounding_volume.hpp:139
constexpr auto bounds() const -> const mask< shape, algebra_t, std::size_t > &
Return the shape mask storing this volume's bounds.
Definition bounding_volume.hpp:144
constexpr auto glob_max(const transform3_t &trf) const -> typename transform3_t::point3
Transform the local maximum bounds into global Cartesian coordinates.
Definition bounding_volume.hpp:210
constexpr auto loc_min() const -> point_t
Definition bounding_volume.hpp:150
constexpr auto glob_min(const transform3_t &trf) const -> typename transform3_t::point3
Transform the local minimum bounds into global Cartesian coordinates.
Definition bounding_volume.hpp:187
dscalar< algebra_t > scalar_t
Definition bounding_volume.hpp:37
typename cuboid3D::template local_frame_type< A > local_frame
Definition bounding_volume.hpp:44
constexpr bool intersect(const detail::ray< algebra_t > &ray, const scalar_t t=std::numeric_limits< scalar_t >::epsilon()) const
Intersect the box with a ray.
Definition bounding_volume.hpp:334
constexpr axis_aligned_bounding_volume(std::size_t box_id, Args &&... args)
Constructor from mask boundary values.
Definition bounding_volume.hpp:57
constexpr auto loc_max() const -> point_t
Definition bounding_volume.hpp:167
friend std::ostream & operator<<(std::ostream &os, const axis_aligned_bounding_volume &aabb)
Print the bounding volume.
Definition bounding_volume.hpp:344
constexpr axis_aligned_bounding_volume(const mask_t &mask, std::size_t box_id, const scalar_t envelope)
Construct around an arbitrary surface mask.
Definition bounding_volume.hpp:67
constexpr auto center() const -> point3_t
Definition bounding_volume.hpp:229
static constexpr std::size_t dim
Definition bounding_volume.hpp:47
cuboid3D shape
Definition bounding_volume.hpp:39
axis_aligned_bounding_volume(const std::vector< scalar_t > &values, std::size_t box_id)
Construct from mask boundary vector.
Definition bounding_volume.hpp:77
constexpr axis_aligned_bounding_volume()=default
Default constructor builds an infinite box.
auto transform(const transform3_t &trf) const -> axis_aligned_bounding_volume
Lower and upper point for minimum axis aligned bounding box of cuboid shape.
Definition bounding_volume.hpp:253
constexpr auto operator[](const std::size_t i) const -> scalar_t
Access one boundary value by its shape-specific index.
Definition bounding_volume.hpp:132
describes a straight-line trajectory
Definition ray.hpp:22
Mask a region on a surface and link it to a volume.
Definition mask.hpp:46
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
std::array< value_t, kDIM > darray
Fixed-size array container.
Definition containers.hpp:30
Checks if a cuboid bonuding box is intersected by a ray.
Definition cuboid_intersector.hpp:27
Projection into a 3D cylindrical coordinate frame.
Definition cylindrical3D.hpp:20
static point3_type local_to_global(const transform3_type &trf, const point3_type &p)
This method transforms from a local 3D cylindrical point to a point in the global cartesian 3D frame.
Definition cylindrical3D.hpp:70