Library to make reading, writing and modifying both binary and ascii STL files easy.
85
Evaluation — 85%
↑ 1.39xAgent success when using this tile
Transform meshes through rotation, translation, and general 4x4 transformation matrices with support for rotation around arbitrary axes and points.
Rotate meshes around arbitrary axes with optional rotation points and pre-computed rotation matrices.
def rotate(self, axis, theta=0, point=None):
"""
Rotate the mesh around an axis by a given angle.
Parameters:
- axis (array-like): Rotation axis vector [x, y, z]
- theta (float): Rotation angle in radians (use math.radians() for degrees)
- point (array-like, optional): Rotation point [x, y, z]
Defaults to origin [0, 0, 0]
Notes:
- Uses Euler-Rodrigues formula for efficient rotation
- Rotates both vertices and normal vectors
- Point parameter allows rotation around arbitrary points
- Positive angles produce clockwise rotation (legacy behavior)
"""
def rotate_using_matrix(self, rotation_matrix, point=None):
"""
Rotate using a pre-computed rotation matrix.
Parameters:
- rotation_matrix (numpy.array): 3x3 or 4x4 rotation matrix
- point (array-like, optional): Rotation point [x, y, z]
Notes:
- More efficient when applying same rotation to multiple meshes
- Matrix must have unit determinant for valid rotation
- Supports both 3x3 rotation and 4x4 transformation matrices
"""
@classmethod
def rotation_matrix(cls, axis, theta):
"""
Generate a rotation matrix for the given axis and angle.
Parameters:
- axis (array-like): Rotation axis vector [x, y, z]
- theta (float): Rotation angle in radians
Returns:
numpy.array: 3x3 rotation matrix
Notes:
- Uses Euler-Rodrigues formula for numerical stability
- Returns identity matrix if axis is zero vector
- Axis vector is automatically normalized
"""Move meshes through 3D space with vector-based translation.
def translate(self, translation):
"""
Translate the mesh by a given vector.
Parameters:
- translation (array-like): Translation vector [dx, dy, dz]
Notes:
- Translation vector must be length 3
- Adds translation to all vertex coordinates
- Does not affect normal vectors (translation-invariant)
"""Apply combined rotation and translation using 4x4 transformation matrices.
def transform(self, matrix):
"""
Apply a 4x4 transformation matrix to the mesh.
Parameters:
- matrix (numpy.array): 4x4 transformation matrix
[R | t]
[0 | 1]
where R is 3x3 rotation, t is 3x1 translation
Notes:
- Matrix must be exactly 4x4 shape
- Rotation part (matrix[0:3, 0:3]) must have unit determinant
- Translation part is matrix[0:3, 3]
- Applies rotation to vertices and normals, translation only to vertices
"""import math
import numpy as np
from stl import mesh
# Load a mesh
my_mesh = mesh.Mesh.from_file('model.stl')
# Rotate 45 degrees around Z-axis
my_mesh.rotate([0, 0, 1], math.radians(45))
# Rotate around X-axis
my_mesh.rotate([1, 0, 0], math.pi/2) # 90 degrees
# Rotate around arbitrary axis
axis = [1, 1, 0] # Diagonal axis
my_mesh.rotate(axis, math.radians(30))import math
import numpy as np
from stl import mesh
my_mesh = mesh.Mesh.from_file('model.stl')
# Find the center of the mesh
center = (my_mesh.max_ + my_mesh.min_) / 2
# Rotate around the mesh center
my_mesh.rotate([0, 0, 1], math.radians(45), point=center)
# Rotate around a specific point
rotation_point = [10, 20, 30]
my_mesh.rotate([1, 0, 0], math.radians(90), point=rotation_point)import math
import numpy as np
from stl import mesh
my_mesh = mesh.Mesh.from_file('model.stl')
# Create a rotation matrix
axis = [0, 1, 0] # Y-axis
angle = math.radians(60)
rot_matrix = mesh.Mesh.rotation_matrix(axis, angle)
# Apply to multiple meshes efficiently
my_mesh.rotate_using_matrix(rot_matrix)
# Can also create custom rotation matrices
theta = math.radians(45)
cos_t, sin_t = math.cos(theta), math.sin(theta)
z_rotation = np.array([
[cos_t, -sin_t, 0],
[sin_t, cos_t, 0],
[0, 0, 1]
])
my_mesh.rotate_using_matrix(z_rotation)import numpy as np
from stl import mesh
my_mesh = mesh.Mesh.from_file('model.stl')
# Simple translation
my_mesh.translate([5, 10, -2])
# Move to origin (center the mesh)
center = (my_mesh.max_ + my_mesh.min_) / 2
my_mesh.translate(-center)
# Move to specific position
target_position = [100, 200, 50]
current_center = (my_mesh.max_ + my_mesh.min_) / 2
offset = target_position - current_center
my_mesh.translate(offset)import math
import numpy as np
from stl import mesh
my_mesh = mesh.Mesh.from_file('model.stl')
# Create a 4x4 transformation matrix
# Combine 45-degree Z rotation with translation
angle = math.radians(45)
cos_a, sin_a = math.cos(angle), math.sin(angle)
transform_matrix = np.array([
[cos_a, -sin_a, 0, 10], # Rotation + X translation
[sin_a, cos_a, 0, 20], # Rotation + Y translation
[0, 0, 1, 5 ], # Z translation
[0, 0, 0, 1 ] # Homogeneous coordinate
])
my_mesh.transform(transform_matrix)import math
import numpy as np
from stl import mesh
my_mesh = mesh.Mesh.from_file('model.stl')
# Center the mesh at origin
center = (my_mesh.max_ + my_mesh.min_) / 2
my_mesh.translate(-center)
# Scale (simulate by creating scaled copy of vertices)
# Note: NumPy STL doesn't have direct scaling, but you can modify vectors
scale_factor = 2.0
my_mesh.vectors *= scale_factor
# Rotate around origin
my_mesh.rotate([0, 0, 1], math.radians(45))
# Move to final position
my_mesh.translate([100, 200, 50])import math
import numpy as np
from stl import mesh
def create_transform_matrix(rotation_axis, rotation_angle, translation):
"""Create a 4x4 transformation matrix."""
# Get 3x3 rotation matrix
rot_3x3 = mesh.Mesh.rotation_matrix(rotation_axis, rotation_angle)
# Create 4x4 matrix
transform = np.eye(4)
transform[0:3, 0:3] = rot_3x3
transform[0:3, 3] = translation
return transform
# Usage
my_mesh = mesh.Mesh.from_file('model.stl')
transform = create_transform_matrix(
rotation_axis=[0, 0, 1],
rotation_angle=math.radians(30),
translation=[5, 10, 0]
)
my_mesh.transform(transform)rotate_using_matrix() is more efficient for repeated rotationsInstall with Tessl CLI
npx tessl i tessl/pypi-numpy-stlevals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10