epoint_core/
octree.rs

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}