from zmesh import Mesher
labels = ... # some dense volumetric labeled image
mesher = Mesher( (4,4,40) ) # anisotropy of image
# initial marching cubes pass
# close controls whether meshes touching
# the image boundary are left open or closed
mesher.mesh(labels, close=False)
meshes = []
for obj_id in mesher.ids():
meshes.append(
mesher.get(
obj_id,
normals=False, # whether to calculate normals or not
# tries to reduce triangles by this factor
# 0 disables simplification
reduction_factor=100,
# Max tolerable error in physical distance
# note: if max_error is not set, the max error
# will be set equivalent to one voxel along the
# smallest dimension.
max_error=8,
# whether meshes should be centered in the voxel
# on (0,0,0) [False] or (0.5,0.5,0.5) [True]
voxel_centered=False,
)
)
mesher.erase(obj_id) # delete high res mesh
mesher.clear() # clear memory retained by mesher
mesh = meshes[0]
mesh = mesher.simplify(
mesh,
# same as reduction_factor in get
reduction_factor=100,
# same as max_error in get
max_error=40,
compute_normals=False, # whether to also compute face normals
) # apply simplifier to a pre-existing mesh
# compute normals without simplifying
mesh = mesher.compute_normals(mesh)
mesh.vertices
mesh.faces
mesh.normals
mesh.triangles() # compute triangles from vertices and faces
# Extremely common obj format
with open('iconic_doge.obj', 'wb') as f:
f.write(mesh.to_obj())
# Common binary format
with open('iconic_doge.ply', 'wb') as f:
f.write(mesh.to_ply())
# Neuroglancer Precomputed format
with open('10001001:0', 'wb') as f:
f.write(mesh.to_precomputed())
Note: As of the latest version, mesher.get_mesh
has been deprecated in favor of mesher.get
which fixes a long standing bug where you needed to transpose your data in order to get a mesh in the correct orientation.
If binaries are not available for your system, ensure you have a C++ compiler installed.
pip install zmesh
.simplify
after converting to voxel space is 220 (appx. 1M) due to the packed 64-bit vertex format.Thanks to Aleks Zlateski for creating and sharing this beautiful mesher.
Later changes by Will Silversmith, Nico Kemnitz, and Jingpeng Wu.