Introduction
trueform is a C++ library for real-time geometric processing. Mesh booleans, registration, remeshing and queries — at interactive speed on million-polygon meshes. Robust to non-manifold flaps, inconsistent winding, and pipeline artifacts. Header-only; works directly on your data with zero-copy views.
Try it in your browser
Interactive mesh booleans, registration, isobands, and more. No install needed.
You control the complexity. Simple code just works. Algorithms compute what they need internally. In performance-critical paths, precompute structures and tag them. The compiler detects and reuses them.
You choose the complexity; trueform adapts.
Quick Tour
Here's how trueform enables complex geometric workflows with minimal code:
#include <trueform/trueform.hpp>
// Start with your raw data—no copies, no conversions
std::vector<float> raw_points = {0, 0, 0, 1, 0, 0, 0, 1, 0};
std::vector<int> indices = {0, 1, 2};
auto points = tf::make_points<3>(raw_points);
auto faces = tf::make_faces<3>(indices);
auto triangles = tf::make_polygons(faces, points);
// or maybe faces are variable
std::vector<int> offsets = {0, 3};
auto d_faces = tf::make_faces(offsets, indices);
auto d_polygons = tf::make_polygons(d_faces, points);
auto polygons_buffer = tf::read_stl("file.stl");
auto polygons = polygons_buffer.polygons();
Primitive queries work directly on geometry:
auto polygon = polygons.front();
auto segment = tf::make_segment_between_points(points[0], points[1]);
auto ray = tf::make_ray_between_points(
tf::make_point(0.2f, 0.2f, -1.0f),
tf::make_point(0.2f, 0.2f, 1.0f));
auto [dist2, pt_on_poly, pt_on_seg] = tf::closest_metric_point_pair(polygon, segment);
bool contains = tf::contains_point(polygon, points[0]);
if (auto hit = tf::ray_hit(ray, polygon)) {
auto [status, t, hit_point] = hit;
}
Mesh analysis reveals structure and defects:
// Connected components
auto [n_components, labels] = tf::make_manifold_edge_connected_component_labels(polygons);
auto [components, component_ids] = tf::split_into_components(polygons, labels);
// Vertex neighborhoods
auto v_link = tf::make_vertex_link(polygons);
auto k2_ring = tf::make_k_rings(v_link, 2);
auto neighs = tf::make_neighborhoods(polygons.points() | tf::tag(v_link), 0.5f);
// Principal curvatures and directions
auto [k0, k1, d0, d1] = tf::make_principal_directions(polygons);
// Boundary curves (open edges)
auto boundary_paths = tf::make_boundary_paths(polygons);
auto boundary_curves = tf::make_curves(boundary_paths, polygons.points());
// Non-manifold edges (shared by >2 faces)
auto bad_edges = tf::make_non_manifold_edges(polygons);
auto bad_segments = tf::make_segments(bad_edges, polygons.points());
// Fix inconsistent face winding
tf::orient_faces_consistently(polygons);
Spatial acceleration enables queries on transformed geometry:
tf::aabb_tree<int, float, 3> tree(polygons, tf::config_tree(4, 4));
auto dynamic_form = polygons | tf::tag(tree)
| tf::tag(tf::random_transformation<float, 3>());
auto static_form = polygons | tf::tag(tree);
// Collision detection
bool does_intersect = tf::intersects(static_form, dynamic_form);
float distance2 = tf::distance2(static_form, dynamic_form);
// Collect all intersecting primitive pairs
std::vector<std::pair<int, int>> collisions;
tf::gather_ids(static_form, dynamic_form, tf::intersects_f,
std::back_inserter(collisions));
// Compute intersection curves
auto curves = tf::make_intersection_curves(static_form, dynamic_form);
Boolean operations combine meshes:
auto [result_mesh, labels] = tf::make_boolean(
polygons0,
polygons1 | tf::tag(tf::make_rotation(tf::deg(45.f), tf::axis<2>)),
tf::boolean_op::merge);
// With intersection curves
auto [result, labels, curves] = tf::make_boolean(
polygons0, polygons1, tf::boolean_op::intersection, tf::return_curves);
Scalar fields and isocontours:
// Compute distance field from a plane
auto plane = tf::make_plane(polygons.front());
tf::buffer<float> scalars;
scalars.allocate(polygons.points().size());
tf::parallel_transform(polygons.points(), scalars, tf::distance_f(plane));
// Extract isocontours embedded into the mesh
std::vector<float> cut_values = {-0.5f, 0.0f, 0.5f};
auto [contour_mesh, contour_labels, isocontours] = tf::embedded_isocurves(
polygons, scalars, tf::make_range(cut_values), tf::return_curves);
Mesh cleanup prepares geometry for processing:
// Merge coincident vertices, remove degenerates and duplicates
auto clean_mesh = tf::cleaned(polygons, tf::epsilon<float>);
// Triangulate n-gons
auto tri_mesh = tf::triangulated(polygons);
// Ensure outward-facing normals on closed meshes
tf::ensure_positive_orientation(polygons);
Continue Learning
The Quick Tour above shows trueform's syntax. To build intuition for real workflows, start with the Geometry Walkthrough — a complete example from raw data to final output. Then explore the Modules to understand the underlying patterns.
