Skip to content

Instantly share code, notes, and snippets.

@whateverforever
Last active April 3, 2023 08:18
Show Gist options
  • Save whateverforever/d7c12573f2fafed0ea7855408bb77e06 to your computer and use it in GitHub Desktop.
Save whateverforever/d7c12573f2fafed0ea7855408bb77e06 to your computer and use it in GitHub Desktop.
Trimesh STL loading can lead to vertex indices varying from other programs such as blender or meshlab. Use this function instead to preserve the vertex order. Note: This has been integrated into trimesh since https://github.com/mikedh/trimesh/pull/1546
import trimesh as tm
import numpy as np
def sorted_uniques(arr):
"""
np.unique mangles the order of the original array, so that the resulting
unique values are sorted. To keep them in the order of the original data,
use this function.
"""
uniques, uidxs, inverse = np.unique(arr, return_index=True, return_inverse=True)
sorted2ordered = np.argsort(uidxs)
uniques_ordered = uniques[sorted2ordered]
ordered2sorted = np.argsort(sorted2ordered)
inv_ordered = ordered2sorted[inverse]
return uniques_ordered, uidxs[sorted2ordered], inv_ordered
def load_stl_fixed(path):
"""
Fast, correct STL preprocessing. Takes care that the vertex order is not mangled.
"""
with open(path, "rb") as fh:
mesh = tm.exchange.stl.load_stl(fh)
faces_flat = mesh["faces"].reshape(-1)
tris = mesh["vertices"][faces_flat]
stacked = [tris * (10 ** 8)]
stacked = np.column_stack(stacked).round().astype(np.int64)
dtype = np.dtype((np.void, stacked.dtype.itemsize * stacked.shape[1]))
hashable = np.ascontiguousarray(stacked).view(dtype).reshape(-1)
_, unique, inverse = sorted_uniques(hashable)
verts = tris[unique]
faces = faces_flat[inverse].reshape(-1, 3)
return tm.Trimesh(verts, faces, process=False)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment