fj_kernel/operations/update/
face.rs

1use std::array;
2
3use crate::{
4    objects::{Cycle, Face},
5    operations::Polygon,
6    storage::Handle,
7};
8
9/// Update a [`Face`]
10pub trait UpdateFace {
11    /// Update the exterior of the face
12    fn update_exterior(
13        &self,
14        f: impl FnOnce(&Handle<Cycle>) -> Handle<Cycle>,
15    ) -> Self;
16
17    /// Add the provides interiors to the face
18    fn add_interiors(
19        &self,
20        interiors: impl IntoIterator<Item = Handle<Cycle>>,
21    ) -> Self;
22}
23
24impl UpdateFace for Face {
25    fn update_exterior(
26        &self,
27        f: impl FnOnce(&Handle<Cycle>) -> Handle<Cycle>,
28    ) -> Self {
29        let exterior = f(self.exterior());
30
31        Face::new(
32            self.surface().clone(),
33            exterior,
34            self.interiors().cloned(),
35            self.color(),
36        )
37    }
38
39    fn add_interiors(
40        &self,
41        interiors: impl IntoIterator<Item = Handle<Cycle>>,
42    ) -> Self {
43        let interiors = self.interiors().cloned().chain(interiors);
44
45        Face::new(
46            self.surface().clone(),
47            self.exterior().clone(),
48            interiors,
49            self.color(),
50        )
51    }
52}
53
54impl<const D: usize> UpdateFace for Polygon<D> {
55    fn update_exterior(
56        &self,
57        f: impl FnOnce(&Handle<Cycle>) -> Handle<Cycle>,
58    ) -> Self {
59        let face = self.face.update_exterior(f);
60        let edges = array::from_fn(|i| {
61            face.exterior()
62                .nth_half_edge(i)
63                .expect("Operation should not have changed length of cycle")
64                .clone()
65        });
66        let vertices = array::from_fn(|i| {
67            // The duplicated code here is unfortunate, but unless we get a
68            // stable `array::each_ref` and something like `array::unzip`, I'm
69            // not sure how to avoid it.
70            face.exterior()
71                .nth_half_edge(i)
72                .expect("Operation should not have changed length of cycle")
73                .start_vertex()
74                .clone()
75        });
76
77        Polygon {
78            face,
79            edges,
80            vertices,
81        }
82    }
83
84    fn add_interiors(
85        &self,
86        _: impl IntoIterator<Item = Handle<Cycle>>,
87    ) -> Self {
88        panic!("Adding interiors to `Polygon` is not supported.")
89    }
90}