|
| 1 | +from typing import Tuple |
| 2 | + |
| 3 | +import nifty |
| 4 | +import numpy as np |
| 5 | + |
| 6 | + |
| 7 | +def smooth_mesh( |
| 8 | + verts: np.ndarray, normals: np.ndarray, faces: np.ndarray, iterations: int |
| 9 | +) -> Tuple[np.ndarray, np.ndarray]: |
| 10 | + """Smooth mesh surface via laplacian smoothing. |
| 11 | +
|
| 12 | + Args: |
| 13 | + verts: The mesh vertices. |
| 14 | + normals: The mesh normals. |
| 15 | + faces: The mesh faces. |
| 16 | + iterations: The number of smoothing iterations. |
| 17 | +
|
| 18 | + Returns: |
| 19 | + The vertices after smoothing. |
| 20 | + The normals after smoothing. |
| 21 | + """ |
| 22 | + n_verts = len(verts) |
| 23 | + g = nifty.graph.undirectedGraph(n_verts) |
| 24 | + |
| 25 | + edges = np.concatenate([faces[:, :2], faces[:, 1:], faces[:, ::2]], axis=0) |
| 26 | + g.insertEdges(edges) |
| 27 | + |
| 28 | + current_verts = verts |
| 29 | + current_normals = normals |
| 30 | + new_verts = np.zeros_like(verts, dtype=verts.dtype) |
| 31 | + new_normals = np.zeros_like(normals, dtype=normals.dtype) |
| 32 | + |
| 33 | + # Implement this directly in nifty for speed up? |
| 34 | + for it in range(iterations): |
| 35 | + for vert in range(n_verts): |
| 36 | + nbrs = np.array([vert] + [nbr[0] for nbr in g.nodeAdjacency(vert)], dtype="int") |
| 37 | + new_verts[vert] = np.mean(current_verts[nbrs], axis=0) |
| 38 | + new_normals[vert] = np.mean(current_normals[nbrs], axis=0) |
| 39 | + current_verts = new_verts |
| 40 | + current_normals = new_normals |
| 41 | + |
| 42 | + return new_verts, new_normals |
0 commit comments