@@ -50,6 +50,7 @@ class tracking_volume {
5050 public:
5151 // / In case the geometry needs to be printed
5252 using name_map = dmap<dindex, std::string>;
53+ using object_id = descr_t ::object_id;
5354
5455 // / Not allowed: always needs a detector and a descriptor.
5556 tracking_volume () = delete ;
@@ -67,6 +68,11 @@ class tracking_volume {
6768 constexpr tracking_volume (const detector_t &det, const dindex vol_idx)
6869 : tracking_volume(det, det.volume(vol_idx)) {}
6970
71+ static consteval bool is_surface_id (const object_id id) {
72+ return (id == object_id::e_portal || id == object_id::e_sensitive ||
73+ id == object_id::e_passive);
74+ }
75+
7076 // / @returns access to the underlying detector
7177 DETRAY_HOST_DEVICE
7278 auto detector () const -> const detector_t & { return m_detector; }
@@ -136,16 +142,87 @@ class tracking_volume {
136142 m_desc.template sf_link <surface_id::e_portal>()};
137143 }
138144
139- // / Apply a functor to all surfaces in the volume's acceleration structures
145+ // / Apply a functor to all surfaces in one of the volume's acceleration
146+ // / structures
140147 // /
148+ // / @tparam I type of object to retrieve (passive, portal, sensitive etc)
141149 // / @tparam functor_t the prescription to be applied to the surfaces
142150 // / @tparam Args types of additional arguments to the functor
151+ template <object_id I, typename functor_t , typename ... Args>
152+ DETRAY_HOST_DEVICE constexpr void visit_accelerator (Args &&... args) const {
153+ static_assert (I < object_id::e_all);
154+
155+ if (const auto &link{m_desc.template accel_link <I>()};
156+ !link.is_invalid ()) {
157+ if constexpr (tracking_volume::is_surface_id (I)) {
158+ // Run over the surfaces in a single acceleration data structure
159+ // and apply the functor to the resulting neighborhood
160+ m_detector.accelerator_store ().template visit <functor_t >(
161+ link, std::forward<Args>(args)...);
162+ } else {
163+ // TODO: Call volume accelerator to find daughter volumes
164+ // [...]
165+ }
166+ }
167+ }
168+
169+ // / Apply a functor to all acceleration structures of this volume.
170+ // /
171+ // / @tparam I type of object to retrieve (passive, portal, sensitive etc)
172+ // / @tparam functor_t the prescription to be applied to the acc structure
173+ // / @tparam Args types of additional arguments to the functor
143174 template <typename functor_t ,
144- int I = static_cast <int >(descr_t ::object_id::e_size) - 1 ,
145- typename ... Args>
146- DETRAY_HOST_DEVICE constexpr void visit_surfaces (Args &&... args) const {
147- visit_surfaces_impl<detail::surface_getter<functor_t >>(
175+ int I = static_cast <int >(object_id::e_all) - 1 , typename ... Args>
176+ DETRAY_HOST_DEVICE constexpr void visit_accelerators (
177+ Args &&... args) const {
178+ // Get the acceleration data structures for this volume and only visit,
179+ // if object type is contained in volume
180+ visit_accelerator<static_cast <object_id>(I), functor_t >(
148181 std::forward<Args>(args)...);
182+ // Check the next surface type
183+ if constexpr (I > 0 ) {
184+ visit_accelerators<functor_t , I - 1 , Args...>(
185+ std::forward<Args>(args)...);
186+ }
187+ }
188+
189+ // / Apply a functor to all surfaces of a given surface id (portal, passive,
190+ // / sensitive) in the volume
191+ // /
192+ // / @tparam functor_t the prescription to be applied to the surfaces
193+ // / @tparam Args types of additional arguments to the functor
194+ template <surface_id I, typename functor_t , typename ... Args>
195+ DETRAY_HOST_DEVICE constexpr void visit_surfaces (Args &&... args) const {
196+ using surface_getter_t = detail::surface_getter<functor_t >;
197+
198+ // Dispatch to the correct acceleration structure
199+ switch (I) {
200+ case surface_id::e_portal: {
201+ visit_accelerator<object_id::e_portal, surface_getter_t >(
202+ std::forward<Args>(args)...);
203+ break ;
204+ }
205+ case surface_id::e_sensitive: {
206+ visit_accelerator<object_id::e_sensitive, surface_getter_t >(
207+ std::forward<Args>(args)...);
208+ break ;
209+ }
210+ case surface_id::e_passive: {
211+ visit_accelerator<object_id::e_passive, surface_getter_t >(
212+ std::forward<Args>(args)...);
213+ break ;
214+ }
215+ default : {
216+ // Visit all surface types, but not other geomteric objects
217+ // (e.g. daughter volumes)
218+ visit_accelerator<object_id::e_portal, surface_getter_t >(
219+ std::forward<Args>(args)...);
220+ visit_accelerator<object_id::e_sensitive, surface_getter_t >(
221+ std::forward<Args>(args)...);
222+ visit_accelerator<object_id::e_passive, surface_getter_t >(
223+ std::forward<Args>(args)...);
224+ }
225+ }
149226 }
150227
151228 // / Apply a functor to a neighborhood of surfaces around a track position
@@ -155,14 +232,20 @@ class tracking_volume {
155232 // / customization point for the navigation)
156233 // / @tparam track_t the track around which to build up the neighborhood
157234 // / @tparam Args types of additional arguments to the functor
158- template <typename functor_t ,
159- int I = static_cast <int >(descr_t ::object_id::e_size) - 1 ,
160- typename track_t , typename config_t , typename ... Args>
235+ template <object_id I, typename functor_t , typename track_t ,
236+ typename config_t , typename ... Args>
161237 DETRAY_HOST_DEVICE constexpr void visit_neighborhood (
162238 const track_t &track, const config_t &cfg, const context_t &ctx,
163239 Args &&... args) const {
164- visit_surfaces_impl<detail::neighborhood_getter<functor_t >>(
165- m_detector, m_desc, track, cfg, ctx, std::forward<Args>(args)...);
240+ if constexpr (I == object_id::e_all) {
241+ visit_accelerators<detail::neighborhood_getter<functor_t >>(
242+ m_detector, m_desc, track, cfg, ctx,
243+ std::forward<Args>(args)...);
244+ } else {
245+ visit_accelerator<I, detail::neighborhood_getter<functor_t >>(
246+ m_detector, m_desc, track, cfg, ctx,
247+ std::forward<Args>(args)...);
248+ }
166249 }
167250
168251 // / Call a functor on the volume material with additional arguments.
@@ -301,32 +384,6 @@ class tracking_volume {
301384 }
302385
303386 private:
304- // / Apply a functor to all acceleration structures of this volume.
305- // /
306- // / @tparam functor_t the prescription to be applied to the acc structure
307- // / @tparam Args types of additional arguments to the functor
308- template <typename functor_t ,
309- int I = static_cast <int >(descr_t ::object_id::e_size) - 1 ,
310- typename ... Args>
311- DETRAY_HOST_DEVICE constexpr void visit_surfaces_impl (
312- Args &&... args) const {
313- // Get the acceleration data structures for this volume and only visit,
314- // if object type is contained in volume
315- if (const auto &link{m_desc.template accel_link <
316- static_cast <typename descr_t ::object_id>(I)>()};
317- !link.is_invalid ()) {
318- // Run over the surfaces in a single acceleration data structure
319- // and apply the functor to the resulting neighborhood
320- m_detector.accelerator_store ().template visit <functor_t >(
321- link, std::forward<Args>(args)...);
322- }
323- // Check the next surface type
324- if constexpr (I > 0 ) {
325- visit_surfaces_impl<functor_t , I - 1 , Args...>(
326- std::forward<Args>(args)...);
327- }
328- }
329-
330387 // / Access to the detector stores
331388 const detector_t &m_detector;
332389 // / Access to the descriptor
0 commit comments