conspire/geometry/ntree/subdivide/
mod.rs1use 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}