1use crate::{Error, PointData};
2use ecoord::HasAabb;
3use ecoord::octree::{OctantIndex, Octree};
4use itertools::Itertools;
5use nalgebra::Point3;
6
7#[derive(Debug, Clone, Copy, PartialEq)]
8struct PointWithIndex {
9 index: usize,
10 point: Point3<f64>,
11}
12
13impl HasAabb for PointWithIndex {
14 fn center(&self) -> Point3<f64> {
15 self.point
16 }
17
18 fn min(&self) -> Point3<f64> {
19 self.point
20 }
21
22 fn max(&self) -> Point3<f64> {
23 self.point
24 }
25}
26
27impl PointData {
28 pub fn compute_octree(
29 &mut self,
30 max_items_per_octant: usize,
31 shuffle_seed_number: Option<u64>,
32 ) -> Result<(), Error> {
33 let all_points: Vec<PointWithIndex> = self
34 .get_all_points()
35 .into_iter()
36 .enumerate()
37 .map(|(index, point)| PointWithIndex { index, point })
38 .collect();
39
40 let octree = Octree::new(all_points, max_items_per_octant, shuffle_seed_number)?;
41
42 let octant_indices: Vec<(usize, OctantIndex)> = octree
43 .cells()
44 .iter()
45 .flat_map(|(octant_index, points)| points.iter().map(move |p| (p.index, *octant_index)))
46 .sorted_by_key(|(i, _)| *i)
47 .collect();
48 self.add_octant_indices(octant_indices.into_iter().map(|p| p.1).collect())?;
49
50 Ok(())
51 }
52}