| name | numpy-stl-processing |
| description | Read, write, and manipulate STL mesh files using numpy-stl library. Use for 3D printing preparation, mesh analysis, transformations, and combining multiple meshes. Fast numpy-based operations on triangular meshes. |
NumPy-STL Processing
Process STL files with numpy-based mesh operations.
Installation
pip install numpy-stl
Reading and Writing STL
from stl import mesh
import numpy as np
# Load STL file
your_mesh = mesh.Mesh.from_file('model.stl')
# Save STL file
your_mesh.save('output.stl')
# Save as ASCII STL
your_mesh.save('output.stl', mode=mesh.Mode.ASCII)
Creating Meshes from Scratch
from stl import mesh
import numpy as np
# Define vertices of a cube
vertices = np.array([
[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0],
[0, 0, 1], [1, 0, 1], [1, 1, 1], [0, 1, 1]
])
# Define 12 triangles (2 per face)
faces = np.array([
[0,3,1], [1,3,2], # bottom
[4,5,7], [5,6,7], # top
[0,1,5], [0,5,4], # front
[2,3,7], [2,7,6], # back
[0,4,7], [0,7,3], # left
[1,2,6], [1,6,5], # right
])
# Create mesh
cube = mesh.Mesh(np.zeros(faces.shape[0], dtype=mesh.Mesh.dtype))
for i, f in enumerate(faces):
for j in range(3):
cube.vectors[i][j] = vertices[f[j]]
cube.save('cube.stl')
Mesh Transformations
from stl import mesh
import numpy as np
m = mesh.Mesh.from_file('model.stl')
# Translation
m.translate([10, 0, 0])
# Rotation (around Z axis, 45 degrees)
m.rotate([0, 0, 1], np.radians(45))
# Uniform scaling
m.vectors *= 2.0
# Non-uniform scaling
m.x *= 2.0
m.y *= 1.5
Mesh Analysis
from stl import mesh
m = mesh.Mesh.from_file('model.stl')
# Volume and center of mass
volume, cog, inertia = m.get_mass_properties()
print(f"Volume: {volume}")
print(f"Center of mass: {cog}")
# Bounding box
minx, maxx = m.x.min(), m.x.max()
miny, maxy = m.y.min(), m.y.max()
minz, maxz = m.z.min(), m.z.max()
# Surface area
areas = m.areas
total_area = np.sum(areas)
# Number of triangles
num_triangles = len(m.vectors)
Combining Meshes
from stl import mesh
import numpy as np
mesh1 = mesh.Mesh.from_file('part1.stl')
mesh2 = mesh.Mesh.from_file('part2.stl')
# Translate second mesh
mesh2.translate([20, 0, 0])
# Combine
combined = mesh.Mesh(np.concatenate([mesh1.data, mesh2.data]))
combined.save('combined.stl')
Mesh Repair Checks
from stl import mesh
m = mesh.Mesh.from_file('model.stl')
# Check normals
m.update_normals()
# Check if mesh is closed (watertight)
# Count edges that appear only once
from collections import Counter
def get_edges(m):
edges = []
for triangle in m.vectors:
for i in range(3):
edge = tuple(sorted([tuple(triangle[i]), tuple(triangle[(i+1)%3])]))
edges.append(edge)
return edges
edge_counts = Counter(get_edges(m))
open_edges = [e for e, c in edge_counts.items() if c == 1]
is_watertight = len(open_edges) == 0