conspire/geometry/mesh/quality/improve/smart_laplace/
mod.rs1#[cfg(test)]
2mod test;
3
4use super::Incidence;
5use crate::{
6 geometry::{Coordinate, mesh::Mesh},
7 math::Scalar,
8};
9
10impl<const D: usize> Mesh<D> {
11 pub fn smart_laplace_smooth(&mut self, iterations: usize, scale: Scalar) {
12 let number_of_nodes = self.number_of_nodes();
13 let neighbors = self.node_node_connectivity().to_vec();
14 let incidence = Incidence::of(self);
15 let coordinates = self.coordinates.members_mut();
16 for _ in 0..iterations {
17 for node in 0..number_of_nodes {
18 if neighbors[node].is_empty() {
19 continue;
20 }
21 let before = incidence.minimum_scaled_jacobian(node, coordinates);
22 let original = coordinates[node].clone();
23 let centroid = neighbors[node]
24 .iter()
25 .map(|&neighbor| &coordinates[neighbor])
26 .sum::<Coordinate<D>>()
27 / (neighbors[node].len() as Scalar);
28 coordinates[node] += (centroid - &original) * scale;
29 let after = incidence.minimum_scaled_jacobian(node, coordinates);
30 if after < before {
31 coordinates[node] = original;
32 }
33 }
34 }
35 }
36}