use LockStepForEach for SdfMeanDownsampler
-use crate::{ArrayIndexer, ChunkDownsampler, Get, GetMut, IndexedArray, Local};
+use super::chunk_downsample_for_each;
+use crate::{
+ ArrayForEach, ArrayIndexer, ChunkDownsampler, Get, GetMut, IndexedArray, Local, Stride,
+};
use building_blocks_core::prelude::*;
@@ -12,11 +15,11 @@ where
PointN<N>: IntegerPoint<N>,
T: From<f32>,
f32: From<T>,
- Src: Get<Local<N>, Item = T> + IndexedArray<N>,
- Dst: for<'r> GetMut<'r, Local<N>, Item = &'r mut T> + IndexedArray<N>,
+ Src: Get<Stride, Item = T> + IndexedArray<N>,
+ Dst: for<'r> GetMut<'r, Stride, Item = &'r mut T> + IndexedArray<N>,
{
fn downsample(&self, src_chunk: &Src, dst_chunk: &mut Dst, dst_min: Local<N>, lod_delta: u8) {
- // PERF: the access pattern here might not be very cache friendly
+ let chunk_shape = src_chunk.extent().shape; // Doesn't matter which chunk we choose, they should have the same shape.
debug_assert!(lod_delta > 0);
let lod_delta = lod_delta as i32;
@@ -27,19 +30,20 @@ where
// by the scale factor (the ratio between voxel edge lengths at the different resolutions).
let rescale = 1.0 / (lod_scale_factor * src_shape_per_point.volume()) as f32;
- let dst_shape = src_chunk.extent().shape >> lod_delta;
- debug_assert!(dst_shape > PointN::ZERO);
-
- for p_dst in ExtentN::from_min_and_shape(PointN::ZERO, dst_shape).iter_points() {
- let src_min = p_dst << lod_delta;
- let src_extent = ExtentN::from_min_and_shape(src_min, src_shape_per_point);
-
+ let for_each = chunk_downsample_for_each(chunk_shape, dst_min, lod_delta);
+ N::for_each_lockstep_unchecked(for_each, |_p, (s_dst, s_src)| {
let mut sum = 0.0;
- for p_src in src_extent.iter_points() {
- sum += f32::from(src_chunk.get(Local(p_src)));
- }
-
- *dst_chunk.get_mut(Local(dst_min.0 + p_dst)) = T::from(rescale * sum);
- }
+ N::for_each(
+ ArrayForEach::new_local_unchecked(
+ chunk_shape,
+ Local(PointN::ZERO),
+ ExtentN::from_min_and_shape(PointN::ZERO, src_shape_per_point),
+ ),
+ |_p, neighbor_offset| {
+ sum += f32::from(src_chunk.get(s_src + neighbor_offset));
+ },
+ );
+ *dst_chunk.get_mut(s_dst) = T::from(rescale * sum);
+ });
}
}
