Skip to main content

conspire/geometry/mesh/smooth/
mod.rs

1mod 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}