Library to make reading, writing and modifying both binary and ascii STL files easy.
85
Evaluation — 85%
↑ 1.39xAgent success when using this tile
Access and modify mesh data through convenient properties and array interfaces with support for both vertex-based and coordinate-based operations.
Access mesh triangle data through structured properties for efficient manipulation.
@property
def data(self):
"""
Raw mesh data as NumPy structured array.
Returns:
numpy.array: Structured array with dtype containing:
- normals: (N, 3) float32 - Triangle normal vectors
- vectors: (N, 3, 3) float32 - Triangle vertices
- attr: (N, 1) uint16 - Triangle attributes
Notes:
- Primary data storage for the mesh
- Direct modification affects all derived properties
- Uses little-endian byte order for STL compatibility
"""
@property
def vectors(self):
"""
Triangle vertices as a 3D array.
Returns:
numpy.array: Triangle vertices (N, 3, 3)
- First dimension: triangle index
- Second dimension: vertex index (0, 1, 2)
- Third dimension: coordinate (x, y, z)
"""
@property
def normals(self):
"""
Triangle normal vectors.
Returns:
numpy.array: Normal vectors (N, 3)
Notes:
- Automatically calculated by update_normals()
- Can be manually set but should maintain consistency
"""
@property
def attr(self):
"""
Triangle attributes from STL format.
Returns:
numpy.array: Triangle attributes (N, 1) uint16
Notes:
- Used by binary STL format for additional triangle data
- Typically unused in most applications
"""Access individual vertices of triangles for detailed mesh manipulation.
@property
def v0(self):
"""
First vertex of each triangle.
Returns:
numpy.array: First vertices (N, 3)
Notes:
- Modifying this affects the underlying vectors array
- Equivalent to vectors[:, 0]
"""
@property
def v1(self):
"""
Second vertex of each triangle.
Returns:
numpy.array: Second vertices (N, 3)
Notes:
- Modifying this affects the underlying vectors array
- Equivalent to vectors[:, 1]
"""
@property
def v2(self):
"""
Third vertex of each triangle.
Returns:
numpy.array: Third vertices (N, 3)
Notes:
- Modifying this affects the underlying vectors array
- Equivalent to vectors[:, 2]
"""Access vertex data organized by coordinate axis for spatial operations.
@property
def x(self):
"""
X coordinates of all vertices.
Returns:
numpy.array: X coordinates (N, 3)
- Each row contains x-coordinates of triangle's three vertices
Notes:
- Convenient for coordinate-based transformations
- Modifying affects underlying vertex data
"""
@property
def y(self):
"""
Y coordinates of all vertices.
Returns:
numpy.array: Y coordinates (N, 3)
- Each row contains y-coordinates of triangle's three vertices
"""
@property
def z(self):
"""
Z coordinates of all vertices.
Returns:
numpy.array: Z coordinates (N, 3)
- Each row contains z-coordinates of triangle's three vertices
"""
@property
def points(self):
"""
All vertices flattened into a 2D array.
Returns:
numpy.array: Flattened vertex coordinates (N, 9)
- Each row: [v0_x, v0_y, v0_z, v1_x, v1_y, v1_z, v2_x, v2_y, v2_z]
Notes:
- Useful for operations that need all coordinates in linear format
- Modifying affects underlying vector data
"""Standard Python array interface for mesh manipulation.
def __len__(self):
"""
Number of triangles in the mesh.
Returns:
int: Triangle count
"""
def __getitem__(self, key):
"""
Get triangle data by index.
Parameters:
- key: Index or slice for triangle selection
Returns:
numpy.array: Points data for selected triangles
Notes:
- Returns flattened coordinate data (9 values per triangle)
- Supports standard indexing and slicing
"""
def __setitem__(self, key, value):
"""
Set triangle data by index.
Parameters:
- key: Index or slice for triangle selection
- value: New coordinate data for triangles
Notes:
- Accepts flattened coordinate data (9 values per triangle)
- Updates underlying vector storage
"""
def __iter__(self):
"""
Iterate over triangle point data.
Yields:
numpy.array: Flattened coordinates for each triangle (9 values)
"""Access mesh identification and configuration properties.
@property
def name(self):
"""
Mesh name from STL file or user assignment.
Returns:
str: Mesh name
Notes:
- ASCII STL files can contain named solids
- Binary STL names come from file headers
- Can be manually assigned for identification
"""
@property
def speedups(self):
"""
Whether Cython optimizations are enabled.
Returns:
bool: True if using Cython extensions, False for pure Python
"""import numpy as np
from stl import mesh
# Load a mesh
my_mesh = mesh.Mesh.from_file('model.stl')
# Basic information
print(f"Mesh name: {my_mesh.name}")
print(f"Triangle count: {len(my_mesh)}")
print(f"Using speedups: {my_mesh.speedups}")
# Access triangle data
first_triangle = my_mesh.vectors[0]
print(f"First triangle vertices:\n{first_triangle}")
# Access normal vectors
normals = my_mesh.normals
print(f"Normal vector shape: {normals.shape}")import numpy as np
from stl import mesh
my_mesh = mesh.Mesh.from_file('model.stl')
# Access individual vertices
v0_vertices = my_mesh.v0 # First vertex of each triangle
v1_vertices = my_mesh.v1 # Second vertex of each triangle
v2_vertices = my_mesh.v2 # Third vertex of each triangle
# Modify specific vertices
my_mesh.v0[0] = [1.0, 2.0, 3.0] # Change first vertex of first triangle
# Bulk vertex operations
my_mesh.v0 += [0.1, 0.0, 0.0] # Move all first vertices in X direction
my_mesh.v1[:, 2] += 1.0 # Move all second vertices up in Zimport numpy as np
from stl import mesh
my_mesh = mesh.Mesh.from_file('model.stl')
# Access by coordinate
x_coords = my_mesh.x # All X coordinates (N, 3)
y_coords = my_mesh.y # All Y coordinates (N, 3)
z_coords = my_mesh.z # All Z coordinates (N, 3)
# Find bounding box
min_x, max_x = np.min(my_mesh.x), np.max(my_mesh.x)
min_y, max_y = np.min(my_mesh.y), np.max(my_mesh.y)
min_z, max_z = np.min(my_mesh.z), np.max(my_mesh.z)
print(f"Bounding box: X[{min_x:.2f}, {max_x:.2f}] "
f"Y[{min_y:.2f}, {max_y:.2f}] Z[{min_z:.2f}, {max_z:.2f}]")
# Coordinate transformations
my_mesh.z += 10.0 # Move entire mesh up by 10 units
my_mesh.x *= 2.0 # Scale X coordinates by factor of 2import numpy as np
from stl import mesh
my_mesh = mesh.Mesh.from_file('model.stl')
# Iterate over triangles
for i, triangle_points in enumerate(my_mesh):
if i < 3: # Print first 3 triangles
print(f"Triangle {i}: {triangle_points}")
# Index-based access
first_triangle = my_mesh[0] # Get first triangle points (9 values)
last_triangle = my_mesh[-1] # Get last triangle points
# Slice access
first_ten = my_mesh[:10] # First 10 triangles
middle_range = my_mesh[5:15] # Triangles 5-14
# Modify triangles
my_mesh[0] = np.array([0, 0, 0, 1, 0, 0, 0, 1, 0]) # Set first triangleimport numpy as np
from stl import mesh
my_mesh = mesh.Mesh.from_file('model.stl')
# Get flattened points (N, 9)
points = my_mesh.points
print(f"Points shape: {points.shape}")
# Reshape to work with individual coordinates
reshaped = points.reshape(-1, 3) # All vertices as (N*3, 3)
print(f"Individual vertex coordinates: {reshaped.shape}")
# Statistical analysis on all vertices
mean_vertex = np.mean(reshaped, axis=0)
std_vertex = np.std(reshaped, axis=0)
print(f"Mean vertex position: {mean_vertex}")
print(f"Standard deviation: {std_vertex}")import numpy as np
from stl import mesh
my_mesh = mesh.Mesh.from_file('model.stl')
# Access raw structured array
raw_data = my_mesh.data
print(f"Data dtype: {raw_data.dtype}")
# Direct field access
triangles = raw_data['vectors']
normals = raw_data['normals']
attributes = raw_data['attr']
# Modify raw data (advanced usage)
raw_data['vectors'][0, 0, :] = [1, 2, 3] # Set first vertex of first triangle
raw_data['attr'][:] = 42 # Set all attributes to 42# Efficient: Vectorized operations
my_mesh.vectors += offset # Fast batch translation
# Less efficient: Loop-based operations
for i in range(len(my_mesh)):
my_mesh.vectors[i] += offset # Slower individual updates# NumPy dtype for mesh data
dtype = np.dtype([
('normals', np.float32, (3,)), # Triangle normals (N, 3)
('vectors', np.float32, (3, 3)), # Triangle vertices (N, 3, 3)
('attr', np.uint16, (1,)), # Triangle attributes (N, 1)
])Install 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