Skip to main content

conspire/geometry/ntree/subdivide/
mod.rs

1use crate::geometry::ntree::node::slot::Slot;
2use crate::geometry::ntree::{
3    Orthotree,
4    node::{Kind, cell::Cell},
5};
6use std::array::from_fn;
7
8const fn mirror_facet(facet: usize) -> usize {
9    facet ^ 1
10}
11
12pub(crate) const fn insert_bit(x: usize, axis: usize, bit: usize) -> usize {
13    let low_mask = (1usize << axis) - 1;
14    let low = x & low_mask;
15    let high = x >> axis;
16    low | (bit << axis) | (high << (axis + 1))
17}
18
19impl<const D: usize, const L: usize, const M: usize, const N: usize, T, U, V>
20    Orthotree<D, L, M, N, T, U, V>
21where
22    T: Cell,
23    U: Slot,
24    V: Copy,
25{
26    fn nodes_on_face(facet: usize) -> [usize; L] {
27        from_fn(|k| insert_bit(k, facet / 2, facet % 2))
28    }
29    fn nodes_on_other_face(face: usize) -> [usize; L] {
30        Self::nodes_on_face(mirror_facet(face))
31    }
32    pub fn subdivide(&mut self, index: usize) -> Result<(), &'static str> {
33        let base = self.len();
34        if U::at(base + N - 1).is_none() {
35            return Err("tree exceeds the nodes an index can address");
36        }
37        let indices = from_fn(|n| U::at(base + n).unwrap());
38        let mut orthants = self.nodes[index].subdivide(indices)?;
39        for (facet, node_facet) in self.nodes[index].facets.into_iter().enumerate() {
40            if let Some(facet_node) = node_facet
41                && let Some(neighbors) = self[facet_node].orthants().copied()
42            {
43                for (node, neighbor) in Self::nodes_on_face(facet)
44                    .into_iter()
45                    .zip(Self::nodes_on_other_face(facet))
46                {
47                    if orthants[node].facets[facet].is_none() {
48                        orthants[node].facets[facet] = Some(neighbors[neighbor])
49                    } else {
50                        panic!("temporary to assess need for Option<>")
51                    }
52                    if self[neighbors[neighbor]].facets[mirror_facet(facet)].is_none() {
53                        self[neighbors[neighbor]].facets[mirror_facet(facet)] = Some(indices[node])
54                    } else {
55                        panic!("temporary to assess need for Option<>")
56                    }
57                }
58            }
59        }
60        self.extend(orthants);
61        self.nodes[index].kind = Kind::Tree(indices);
62        self.nodes[index].value = None;
63        Ok(())
64    }
65}