Skip to main content

conspire/geometry/mesh/quality/improve/smart_laplace/
mod.rs

1#[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}