Turn a multi-label .nii.gz segmentation into one clean, closed STL surface per
label — solid, watertight, manifold, self-intersection-free. In csg mode,
adjacent regions share their interface seam bit-identically, so the parts
assemble seamlessly in 3D Slicer / Mimics.
Left → right: naive marching cubes (voxel staircase) · a typical 3D Slicer default export · NiftiMesh (smooth, watertight, seamless).
A multi-label segmentation volume → per-label STL meshes. Two modes:
csg— for one structure split by internal interfaces: lung lobes / segments, Couinaud liver segments. Neighbouring labels share their cut seam exactly (no crack, no black line).independent— for disjoint organs (liver + spleen + kidneys, vessels): each label becomes its own closed, smoothed surface.
You define the output names — nothing is hard-coded to any anatomy.
pip install "niftimesh[csg]" # csg mode (needs meshlib)
pip install niftimesh # independent + naive modes onlyPython ≥ 3.9. NIfTI is read via nibabel (bundled) or SimpleITK if installed.
Prebuilt wheels are also attached to each
GitHub Release.
# names from a JSON file: {"1": "left_lower_lobe", "2": "left_upper_lobe", ...}
niftimesh seg.nii.gz out/ --mode csg --label-names names.json --suffix _3d
# omit --label-names to get label_1.stl, label_2.stl, ...
niftimesh organs.nii.gz out/ --mode independentfrom niftimesh import nifti_to_stl
nifti_to_stl("seg.nii.gz", "out/", mode="csg",
label_names={1: "left_lower_lobe", 2: "left_upper_lobe"})
# in-memory: numpy (z, y, x) label volume -> {label: vtkPolyData}
from niftimesh import reconstruct
meshes = reconstruct(seg, spacing=(0.84, 0.84, 1.0), mode="independent")Apache 2.0 © 2026 Justin


