CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-numpy-stl

Library to make reading, writing and modifying both binary and ascii STL files easy.

85

1.39x

Evaluation85%

1.39x

Agent success when using this tile

Overview
Eval results
Files

transformations.mddocs/

Geometric Transformations

Transform meshes through rotation, translation, and general 4x4 transformation matrices with support for rotation around arbitrary axes and points.

Capabilities

Rotation Operations

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
    """

Translation Operations

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)
    """

General Transformations

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
    """

Usage Examples

Basic Rotations

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))

Rotation Around Specific Points

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)

Using Rotation Matrices

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)

Translation Operations

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)

Combined Transformations

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)

Chaining Transformations

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])

Transformation Utilities

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)

Mathematical Notes

Rotation Matrix Properties

  • Rotation matrices are orthogonal with unit determinant
  • The library uses Euler-Rodrigues formula for numerical stability
  • Positive angles produce clockwise rotations (legacy behavior)
  • Rotation matrices preserve distances and angles

Coordinate System

  • Right-handed coordinate system is assumed
  • Z-axis typically points "up" in 3D printing contexts
  • STL files may use different coordinate conventions

Performance Considerations

  • rotate_using_matrix() is more efficient for repeated rotations
  • Pre-compute rotation matrices when applying the same rotation to multiple meshes
  • Large meshes benefit from vectorized NumPy operations

Error Handling

  • AssertionError: Raised for invalid matrix dimensions or non-unit determinants
  • TypeError: Raised for incorrect parameter types (e.g., wrong point format)
  • ValueError: Raised for invalid transformation matrix properties

Install with Tessl CLI

npx tessl i tessl/pypi-numpy-stl

docs

data-access.md

file-operations.md

index.md

mesh-analysis.md

mesh-processing.md

transformations.md

tile.json