conspire/geometry/mesh/smooth/
mod.rs1mod laplace;
2mod taubin;
3
4use crate::{
5 geometry::mesh::{Mesh, differential::laplace::Weighting},
6 math::Scalar,
7};
8
9pub enum Smoothing {
10 Laplace {
11 iterations: usize,
12 scale: Scalar,
13 weighting: Weighting,
14 preserve_boundary: bool,
15 preserve_interfaces: bool,
16 },
17 Taubin {
18 iterations: usize,
19 pass_band: Scalar,
20 scale: Scalar,
21 weighting: Weighting,
22 preserve_boundary: bool,
23 preserve_interfaces: bool,
24 },
25}
26
27impl<const D: usize> Mesh<D> {
28 pub fn smooth(&mut self, smoothing: Smoothing) {
29 match smoothing {
30 Smoothing::Laplace {
31 iterations,
32 scale,
33 weighting,
34 preserve_boundary,
35 preserve_interfaces,
36 } => self.laplace_smooth(
37 iterations,
38 scale,
39 weighting,
40 preserve_boundary,
41 preserve_interfaces,
42 ),
43 Smoothing::Taubin {
44 iterations,
45 pass_band,
46 scale,
47 weighting,
48 preserve_boundary,
49 preserve_interfaces,
50 } => self.taubin_smooth(
51 iterations,
52 pass_band,
53 scale,
54 weighting,
55 preserve_boundary,
56 preserve_interfaces,
57 ),
58 }
59 }
60 fn constrained_adjacency(
61 &self,
62 preserve_boundary: bool,
63 preserve_interfaces: bool,
64 ) -> Vec<Vec<usize>> {
65 let mut constrained = vec![false; self.number_of_nodes()];
66 if preserve_boundary {
67 self.exterior_faces()
68 .iter()
69 .flatten()
70 .for_each(|&node| constrained[node] = true);
71 }
72 if preserve_interfaces {
73 self.mark_interface_nodes(&mut constrained);
74 }
75 let mut adjacency: Vec<Vec<usize>> = self.node_node_connectivity().to_vec();
76 adjacency
77 .iter_mut()
78 .enumerate()
79 .filter(|(node, _)| constrained[*node])
80 .for_each(|(_, neighbors)| neighbors.retain(|&other| constrained[other]));
81 adjacency
82 }
83 fn mark_interface_nodes(&self, constrained: &mut [bool]) {
84 let mut element_block = Vec::with_capacity(self.number_of_elements());
85 for (block, connectivity) in self.connectivities().iter().enumerate() {
86 element_block.resize(
87 element_block.len() + connectivity.number_of_elements(),
88 block,
89 );
90 }
91 self.node_element_connectivity()
92 .iter()
93 .enumerate()
94 .for_each(|(node, elements)| {
95 let mut blocks = elements.iter().map(|&element| element_block[element]);
96 if let Some(first) = blocks.next()
97 && blocks.any(|block| block != first)
98 {
99 constrained[node] = true;
100 }
101 });
102 }
103}