Modules | PY

I/O

File I/O operations for reading and writing mesh data.

The I/O module provides functions for reading and writing mesh data in STL format (both ASCII and binary) and OBJ format (ASCII).

Reading

STL Files

Read an STL file and return mesh data:

import trueform as tf
import numpy as np

# Read STL file
faces, points = tf.read_stl("model.stl")
# faces: (N, 3) array with dtype np.int32
# points: (M, 3) array with dtype np.float32

# Create Mesh from loaded data
mesh = tf.Mesh(faces, points)
print(f"Loaded {len(faces)} faces, {len(points)} points")

# For large meshes (> 2 billion vertices), use int64 indices
faces, points = tf.read_stl("large_model.stl", index_dtype=np.int64)

OBJ Files

Read an OBJ file and return mesh data:

import trueform as tf
import numpy as np

# Read triangular mesh
faces, points = tf.read_obj("model.obj", ngon=3)
# faces: (N, 3) array with dtype np.int32
# points: (M, 3) array with dtype np.float32

# Read quad mesh
faces, points = tf.read_obj("quad_model.obj", ngon=4)
# faces: (N, 4) array with dtype np.int32

# Create Mesh from loaded data
mesh = tf.Mesh(faces, points)
print(f"Loaded {len(faces)} faces, {len(points)} points")

# For large meshes, use int64 indices
faces, points = tf.read_obj("large_model.obj", ngon=3, index_dtype=np.int64)
The ngon parameter is required because numpy arrays cannot be ragged (all rows must have the same length).

Writing

STL Files

Write mesh data to binary STL format:

# Write from tuple (faces, points)
faces = np.array([[0, 1, 2]], dtype=np.int32)
points = np.array([[0, 0, 0], [1, 0, 0], [0, 1, 0]], dtype=np.float32)
tf.write_stl((faces, points), "output.stl")

# Write from Mesh object
mesh = tf.Mesh(faces, points)
tf.write_stl(mesh, "output_mesh.stl")

With transformation parameter:

# Apply transformation during write
transform = np.eye(4, dtype=np.float32)
transform[:3, 3] = [10, 0, 5]  # Translate by (10, 0, 5)
tf.write_stl((faces, points), "translated.stl", transformation=transform)

Using mesh transformation property:

# Set transformation on mesh
mesh = tf.Mesh(faces, points)
mesh.transformation = transform
tf.write_stl(mesh, "mesh_with_transform.stl")  # Transformation applied automatically

# Override mesh transformation
override_transform = np.eye(4, dtype=np.float32)
override_transform[2, 3] = 20  # Different Z translation
tf.write_stl(mesh, "overridden.stl", transformation=override_transform)
Transformation Priority: Explicit transformation parameter overrides mesh.transformation property.

OBJ Files

Write mesh data to ASCII OBJ format:

# Write triangular mesh from tuple (faces, points)
faces = np.array([[0, 1, 2]], dtype=np.int32)
points = np.array([[0, 0, 0], [1, 0, 0], [0, 1, 0]], dtype=np.float32)
tf.write_obj((faces, points), "triangle.obj")

# Write quad mesh
faces = np.array([[0, 1, 2, 3]], dtype=np.int32)
points = np.array([[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0]], dtype=np.float32)
tf.write_obj((faces, points), "quad.obj")

# Write from Mesh object
mesh = tf.Mesh(faces, points)
tf.write_obj(mesh, "output_mesh.obj")

With transformation parameter:

# Apply transformation during write
transform = np.eye(4, dtype=np.float32)
transform[:3, 3] = [10, 0, 5]  # Translate by (10, 0, 5)
tf.write_obj((faces, points), "translated.obj", transformation=transform)

Using mesh transformation property:

# Set transformation on mesh
mesh = tf.Mesh(faces, points)
mesh.transformation = transform
tf.write_obj(mesh, "mesh_with_transform.obj")  # Transformation applied automatically

Round-trip Example

import trueform as tf
import numpy as np

# Read STL file
faces, points = tf.read_stl("input.stl")

# Create transformation (translate + rotate)
transform = np.eye(4, dtype=np.float32)
transform[:3, 3] = [5, 0, 0]  # Translation
angle = np.radians(45)
transform[0, 0] = np.cos(angle)
transform[0, 1] = -np.sin(angle)
transform[1, 0] = np.sin(angle)
transform[1, 1] = np.cos(angle)

# Write with transformation
tf.write_stl((faces, points), "transformed.stl", transformation=transform)

# Or via Mesh object
mesh = tf.Mesh(faces, points)
mesh.transformation = transform
tf.write_stl(mesh, "transformed_mesh.stl")
For implementation details, see the C++ I/O documentation.