Getting Started | PY

Introduction

Real-time geometric processing on NumPy arrays. Easy to use, robust on real-world data.

trueform is a Python library for real-time geometric processing. Spatial queries, mesh booleans, isocontours, topology — at interactive speed on million-polygon meshes. Robust to non-manifold flaps, inconsistent winding, and pipeline artifacts. NumPy in, NumPy out.

Try it in your browser

Interactive mesh booleans, collisions, isobands and more. No install needed.

Simple code just works. Forms cache structures on demand. Algorithms process forms and return NumPy arrays.

facesnp.arraypointsnp.arrayFormmesh = tf.Mesh(faces, points)Properties (cached on demand).normals.vertex_link.face_link...Shared Viewmesh0 = mesh.shared_view()mesh0.transformation = t0Shared Viewmesh1 = mesh.shared_view()mesh1.transformation = t1Algorithmstf.boolean_union(mesh0, mesh1)...tf.intersection_curves(mesh0, mesh1)Resultnp.array, ...

NumPy in, NumPy out. Forms cache properties on demand.

Installation

Requirements and installation via pip.

Modules

Learn how trueform works — data structures, spatial queries, topology, and the algorithms that connect them.

Benchmarks

Benchmarked against VTK, CGAL, libigl, Coal, FCL, and nanoflann.

Blender

Bring trueform performance to Blender add-ons.

Examples

Core functionality and VTK integration demos.

Research

Theory, publications, and citation.

Quick Tour

Here's how trueform enables complex geometric workflows — NumPy arrays in, NumPy arrays out:

import numpy as np
import trueform as tf

# Start with numpy arrays
points = np.array([
    [0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1]
], dtype=np.float32)
faces = np.array([
    [0, 1, 2], [0, 2, 3], [0, 3, 1], [1, 3, 2]
], dtype=np.int32)

# Create a mesh
mesh = tf.Mesh(faces, points)

# Or with variable-sized faces (n-gons)
offsets = np.array([0, 3, 7], dtype=np.int64)
data = np.array([0, 1, 2, 0, 2, 3, 1], dtype=np.int32)
ngon_faces = tf.OffsetBlockedArray(offsets, data)
ngon_mesh = tf.Mesh(ngon_faces, points)

# Or read from file
mesh = tf.read_stl("model.stl")

Primitive queries work directly on geometry:

triangle = tf.Polygon([[0, 0, 0], [1, 0, 0], [0, 1, 0]])
segment = tf.Segment([[0, 0, 0], [1, 1, 1]])
ray = tf.Ray(origin=[0.2, 0.2, -1], direction=[0, 0, 1])

dist2, pt_on_tri, pt_on_seg = tf.closest_metric_point_pair(triangle, segment)

if (t := tf.ray_cast(ray, triangle)) is not None:
    hit_point = ray.origin + t * np.array(ray.direction)

Mesh analysis reveals structure and defects:

# Connected components
num_components, labels = tf.label_connected_components(mesh.face_link)
components, component_ids = tf.split_into_components(mesh, labels)

# Vertex neighborhoods
v_link = mesh.vertex_link
k2_ring = tf.k_rings(v_link, k=2)
neighs = tf.neighborhoods(v_link, mesh.points, radius=0.5)

# Principal curvatures and directions
k0, k1, d0, d1 = tf.principal_curvatures(mesh, directions=True)

# Boundary curves (open edges)
paths, boundary_points = tf.boundary_curves(mesh)

# Non-manifold edges (shared by >2 faces)
bad_edges = tf.non_manifold_edges(mesh)

Spatial acceleration enables queries on transformed geometry:

static_mesh = tf.Mesh(faces0, points0)
dynamic_mesh = tf.Mesh(faces1, points1)
dynamic_mesh.transformation = rotation_matrix

# Collision detection
does_intersect = tf.intersects(static_mesh, dynamic_mesh)
distance = tf.distance(static_mesh, dynamic_mesh)

# Collect all intersecting primitive pairs
pairs = tf.gather_intersecting_ids(static_mesh, dynamic_mesh)

# Compute intersection curves
paths, curve_points = tf.intersection_curves(static_mesh, dynamic_mesh)

Boolean operations combine meshes:

(result_faces, result_points), labels = tf.boolean_union(mesh0, mesh1)

# With intersection curves
(result_faces, result_points), labels, (paths, curve_points) = tf.boolean_union(
    mesh0, mesh1, return_curves=True
)

Scalar fields and isocontours:

# Compute distance field from a plane
plane = tf.Plane(normal=[0, 0, 1], offset=0.0)
scalars = tf.distance_field(mesh.points, plane)

# Extract isobands with boundary curves
(band_faces, band_points), labels, (paths, curve_points) = tf.isobands(
    mesh, scalars, [-1.0, 0.0, 1.0], return_curves=True
)

Mesh cleanup prepares geometry for processing:

# Merge coincident vertices, remove degenerates and duplicates
clean_faces, clean_points = tf.cleaned((faces, points))

# Triangulate n-gons
tri_faces, tri_points = tf.triangulated((quad_faces, points))

# Ensure outward-facing normals on closed meshes
new_faces = tf.ensure_positive_orientation(mesh)

Continue Learning

The Quick Tour above shows trueform's syntax. To build intuition for real workflows, start with the Core Functionality examples — complete scripts covering common tasks. Then explore the Modules to understand the underlying patterns.

Core Functionality

Self-contained examples from primitive queries through booleans and isobands. See the library in action.

Modules

Learn how trueform works — data structures, spatial queries, topology, and the algorithms that connect them.