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 = {})
96 DETRAY_VERBOSE_HOST(
"Generate cuboid portals...");
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;
108 constexpr auto invalid_src_link{detail::invalid_value<std::uint64_t>()};
111 assert(volume.id() == volume_id::e_cuboid);
113 std::size_t n_surfaces{surfaces.size()};
114 assert(n_surfaces != 0u);
117 auto surfaces_offset{
static_cast<dindex>(n_surfaces)};
120 constexpr auto rectangle_id{detector_t::masks::id::e_rectangle2D};
123 constexpr auto no_material = surface_t::material_id::e_none;
127 constexpr scalar_type max_shift{0.01f *
128 std::numeric_limits<scalar_type>::max()};
131 std::vector<aabb_t> boxes;
132 boxes.reserve(n_surfaces);
134 for (
const auto &sf : surfaces) {
135 masks.template visit<bounding_box_creator>(
136 sf.mask(), m_envelope, transforms.at(sf.transform(), ctx), boxes);
139 aabb_t world_box{boxes, boxes.size(), m_envelope};
142 const point3_t center = world_box.template center<point3_t>();
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>();
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])};
155 const dindex volume_idx{volume.index()};
156 const nav_link_t volume_link{detail::invalid_value<nav_link_t>()};
164 mask_link_t mask_link{};
165 mask_link.set_id(rectangle_id);
168 if constexpr (concepts::interval<typename mask_link_t::index_type>) {
169 mask_link.set_index({mask_idx, 1u});
171 mask_link.set_index(mask_idx);
173 masks.template emplace_back<rectangle_id>(empty_context{}, volume_link, h_x,
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));
183 dindex trf_idx{transforms.size(ctx) - 2};
185 {trf_idx, mask_link, material_link, volume_idx, surface_id::e_portal},
189 {++trf_idx, mask_link, material_link, volume_idx, surface_id::e_portal},
196 masks.template emplace_back<rectangle_id>(empty_context{}, volume_link, h_x,
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,
207 transforms.emplace_back(ctx,
static_cast<vector3_t
>(center - shift), new_z,
211 {++trf_idx, mask_link, material_link, volume_idx, surface_id::e_portal},
215 {++trf_idx, mask_link, material_link, volume_idx, surface_id::e_portal},
222 masks.template emplace_back<rectangle_id>(empty_context{}, volume_link, h_z,
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,
232 transforms.emplace_back(ctx,
static_cast<vector3_t
>(center - shift), new_z,
236 {++trf_idx, mask_link, material_link, volume_idx, surface_id::e_portal},
240 {++trf_idx, mask_link, material_link, volume_idx, surface_id::e_portal},
243 return {surfaces_offset,
static_cast<dindex>(surfaces.size())};