fj_kernel/operations/update/
cycle.rs

1use crate::{
2    objects::{Cycle, HalfEdge},
3    storage::Handle,
4};
5
6/// Update a [`Cycle`]
7pub trait UpdateCycle {
8    /// Add half-edges to the cycle
9    fn add_half_edges(
10        &self,
11        half_edges: impl IntoIterator<Item = Handle<HalfEdge>>,
12    ) -> Cycle;
13
14    /// Replace the provided half-edge
15    ///
16    /// # Panics
17    ///
18    /// Panics, unless this operation replaces exactly one half-edge.
19    fn replace_half_edge(
20        &self,
21        original: &Handle<HalfEdge>,
22        replacement: Handle<HalfEdge>,
23    ) -> Cycle;
24
25    /// Update the half-edge at the given index
26    ///
27    /// # Panics
28    ///
29    /// Panics, unless this operation updates exactly one half-edge.
30    fn update_nth_half_edge(
31        &self,
32        index: usize,
33        f: impl FnMut(&Handle<HalfEdge>) -> Handle<HalfEdge>,
34    ) -> Cycle;
35}
36
37impl UpdateCycle for Cycle {
38    fn add_half_edges(
39        &self,
40        half_edges: impl IntoIterator<Item = Handle<HalfEdge>>,
41    ) -> Cycle {
42        let half_edges = self.half_edges().cloned().chain(half_edges);
43        Cycle::new(half_edges)
44    }
45
46    fn replace_half_edge(
47        &self,
48        original: &Handle<HalfEdge>,
49        replacement: Handle<HalfEdge>,
50    ) -> Cycle {
51        let mut num_replacements = 0;
52
53        let half_edges = self.half_edges().map(|half_edge| {
54            if half_edge.id() == original.id() {
55                num_replacements += 1;
56                replacement.clone()
57            } else {
58                half_edge.clone()
59            }
60        });
61
62        let cycle = Cycle::new(half_edges);
63
64        assert_eq!(
65            num_replacements, 1,
66            "Expected operation to replace exactly one half-edge"
67        );
68
69        cycle
70    }
71
72    fn update_nth_half_edge(
73        &self,
74        index: usize,
75        mut f: impl FnMut(&Handle<HalfEdge>) -> Handle<HalfEdge>,
76    ) -> Cycle {
77        let mut num_replacements = 0;
78
79        let half_edges = self.half_edges().enumerate().map(|(i, half_edge)| {
80            if i == index {
81                num_replacements += 1;
82                f(half_edge)
83            } else {
84                half_edge.clone()
85            }
86        });
87
88        let cycle = Cycle::new(half_edges);
89
90        assert_eq!(
91            num_replacements, 1,
92            "Expected operation to replace exactly one half-edge"
93        );
94
95        cycle
96    }
97}