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

data-access.mddocs/

Mesh Data Access

Access and modify mesh data through convenient properties and array interfaces with support for both vertex-based and coordinate-based operations.

Capabilities

Triangle Data Properties

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

Individual Vertex Access

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

Coordinate-Based Access

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

Array Interface Methods

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

Mesh Metadata

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

Usage Examples

Basic Data Access

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

Vertex Manipulation

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 Z

Coordinate-Based Operations

import 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 2

Array Interface Usage

import 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 triangle

Working with Points Array

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

Direct Data Array Manipulation

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

Performance Considerations

Memory Layout

  • NumPy structured arrays provide efficient memory usage
  • Contiguous memory layout enables fast vectorized operations
  • Direct property access avoids unnecessary copying

Efficient Operations

# 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

Property Caching

  • Computed properties (areas, centroids) are cached
  • Modifying vertex data invalidates cached properties
  • Call update methods to refresh computed values

Data Type Information

Structured Array Format

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

Coordinate System

  • Right-handed coordinate system
  • Units depend on source STL file (typically millimeters)
  • Z-axis often represents vertical direction in 3D printing

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