The functions module provides VTK-friendly wrappers for trueform's algorithms. Pass in tf::vtk::polydata, get back results as VTK objects or trueform primitives. Many functions accept an optional vtkMatrix4x4* transform for operating on meshes in world space without modifying the underlying geometry.
Include the module with:
#include <trueform/vtk/functions.hpp>
These functions wrap trueform's Spatial module queries. They automatically select the appropriate primitive type based on what the polydata contains: polygons first, then lines, then points.
Find the nearest point on a mesh to a query point. Returns neighbor_result, an alias for tf::nearest_neighbor<vtkIdType, float, 3>:
| Member | Type | Description |
|---|---|---|
element | vtkIdType | Cell index of nearest element |
info.point | tf::point<float, 3> | Closest point on the mesh |
info.metric | float | Squared distance |
operator bool() | True if a neighbor was found |
auto result = tf::vtk::neighbor_search(mesh, point);
if (result) {
auto closest = result.info.point; // tf::point<float, 3>
auto dist2 = result.info.metric; // squared distance
auto cell_id = result.element; // vtkIdType
}
// With radius constraint (returns false if nothing within radius)
auto result = tf::vtk::neighbor_search(mesh, point, 10.0f);
// With transform
auto result = tf::vtk::neighbor_search({mesh, matrix}, point);
For mesh-vs-mesh queries, returns neighbor_pair_result, an alias for tf::nearest_neighbor_pair<vtkIdType, vtkIdType, float, 3>:
| Member | Type | Description |
|---|---|---|
elements | std::pair<vtkIdType, vtkIdType> | Cell indices on each mesh |
info.metric | float | Squared distance |
info.first | tf::point<float, 3> | Closest point on first mesh |
info.second | tf::point<float, 3> | Closest point on second mesh |
operator bool() | True if a pair was found |
auto pair = tf::vtk::neighbor_search(mesh0, mesh1);
if (pair) {
auto [dist2, pt0, pt1] = pair.info;
auto [id0, id1] = pair.elements;
}
// With transforms
auto pair = tf::vtk::neighbor_search({mesh0, matrix0}, {mesh1, matrix1});
Find the k nearest points on a mesh. Returns std::vector<neighbor_result> sorted by squared distance. See kNN Queries.
auto results = tf::vtk::neighbor_search_k(mesh, point, 5);
for (const auto& r : results) {
// r.element, r.info.point, r.info.metric
}
// With radius constraint
auto results = tf::vtk::neighbor_search_k(mesh, point, 5, 10.0f);
Find nearest neighbors for multiple query points in parallel. Returns std::vector<neighbor_result>.
auto results = tf::vtk::neighbor_search_batch(mesh, query_points);
// With radius
auto results = tf::vtk::neighbor_search_batch(mesh, query_points, 10.0f);
Find k nearest neighbors for multiple query points. Returns tf::offset_block_vector<std::size_t, neighbor_result> with variable results per query.
auto results = tf::vtk::neighbor_search_k_batch(mesh, query_points, 5);
for (const auto& pt_results : results) {
for (const auto& r : pt_results) {
// r.element, r.info.point, r.info.metric
}
}
// With radius
auto results = tf::vtk::neighbor_search_k_batch(mesh, query_points, 5, 10.f);
Convenience wrappers around neighbor_search that return only the distance.
// Squared distance (faster, avoids sqrt)
float d2 = tf::vtk::distance2(mesh, point);
float d2 = tf::vtk::distance2(mesh0, mesh1);
// Euclidean distance
float d = tf::vtk::distance(mesh, point);
float d = tf::vtk::distance({mesh0, matrix0}, {mesh1, matrix1});
Test whether two meshes intersect. See Distance and Intersection.
if (tf::vtk::intersects(mesh0, mesh1)) {
// meshes overlap
}
// With transforms
if (tf::vtk::intersects({mesh0, matrix0}, {mesh1, matrix1})) {
// meshes overlap in world space
}
Cast rays against meshes for picking and visibility testing. These wrap trueform's Ray Casting with VTK polydata.
Cast a tf::ray and get parametric hit information. Returns ray_cast_result, an alias for tf::tree_ray_info<vtkIdType, tf::ray_cast_info<float>>:
| Member | Type | Description |
|---|---|---|
element | vtkIdType | Cell index of hit element |
info.status | tf::intersect_status | Intersection status |
info.t | float | Parametric distance along ray |
operator bool() | True if intersection found |
auto result = tf::vtk::ray_cast(ray, mesh);
if (result) {
auto t = result.info.t; // parametric distance along ray
auto cell_id = result.element; // hit cell
}
// With ray config (min/max t)
auto result = tf::vtk::ray_cast(ray, mesh, {0.1f, 100.0f});
// With transform
auto result = tf::vtk::ray_cast(ray, {mesh, matrix});
Cast a ray and get the 3D hit position. Returns ray_hit_result, an alias for tf::tree_ray_info<vtkIdType, tf::ray_hit_info<float, 3>>:
| Member | Type | Description |
|---|---|---|
element | vtkIdType | Cell index of hit element |
info.status | tf::intersect_status | Intersection status |
info.t | float | Parametric distance along ray |
info.point | tf::point<float, 3> | Hit position |
operator bool() | True if intersection found |
auto result = tf::vtk::ray_hit(ray, mesh);
if (result) {
auto hit_point = result.info.point; // tf::point<float, 3>
auto t = result.info.t;
auto cell_id = result.element;
}
// With transform
auto result = tf::vtk::ray_hit(ray, {mesh, matrix});
Pick the closest actor along a ray from a collection of actors. Automatically handles actor transforms via GetUserMatrix().
std::vector<vtkActor*> actors = {...};
auto ray = tf::vtk::make_world_ray(renderer, mouse_x, mouse_y);
if (auto result = tf::vtk::pick(ray, actors)) {
vtkActor* hit_actor = result->actor;
vtkIdType cell_id = result->cell_id;
auto position = result->position; // tf::point<float, 3>
float t = result->t;
}
Compute bounding boxes from polydata geometry. See AABB for the underlying types.
Compute the axis-aligned bounding box. Returns tf::aabb<float, 3>.
auto box = tf::vtk::aabb_from(polydata);
auto center = box.center();
auto size = box.size();
Compute the oriented bounding box (minimum-volume enclosing box). Returns tf::obb<float, 3>.
auto box = tf::vtk::obb_from(polydata);
Combine meshes using constructive solid geometry. See the Cut module for details on boolean operations and input requirements.
Compute boolean operations between two meshes. Returns vtkSmartPointer<polydata> with "Labels" cell scalars indicating face origin (positive for mesh0, negative for mesh1).
auto result = tf::vtk::make_boolean(mesh0, mesh1, tf::boolean_op::merge);
auto result = tf::vtk::make_boolean(mesh0, mesh1, tf::boolean_op::intersection);
auto result = tf::vtk::make_boolean(mesh0, mesh1, tf::boolean_op::difference);
// With transforms
auto result = tf::vtk::make_boolean(
{mesh0, matrix0}, {mesh1, matrix1}, tf::boolean_op::merge);
With tf::return_curves, returns std::pair<vtkSmartPointer<polydata>, vtkSmartPointer<polydata>> — the result mesh and intersection curves.
auto [result, curves] = tf::vtk::make_boolean(
mesh0, mesh1, tf::boolean_op::merge, tf::return_curves);
Compute intersection curves between two meshes without performing a boolean operation. Returns vtkSmartPointer<polydata> with line cells. See Intersect module for the underlying algorithm.
auto curves = tf::vtk::make_intersection_curves(mesh0, mesh1);
// With transforms
auto curves = tf::vtk::make_intersection_curves(
{mesh0, matrix0}, {mesh1, matrix1});
Find where a mesh intersects itself and embed the intersection curves as edges. Returns vtkSmartPointer<polydata>. See Embedded Self-Intersection Curves.
auto result = tf::vtk::resolved_self_intersections(mesh);
With tf::return_curves, returns std::tuple<vtkSmartPointer<polydata>, vtkSmartPointer<polydata>> — the resolved mesh and intersection curves.
auto [result, curves] = tf::vtk::resolved_self_intersections(
mesh, tf::return_curves);
Analyze and modify mesh connectivity. See the Topology module for the underlying structures.
Label connected components in a mesh. Returns std::pair<vtkSmartPointer<polydata>, int> — a polydata with "ComponentLabel" cell scalars and the number of components found.
auto [labeled, n_components] = tf::vtk::make_connected_components(
mesh, tf::connectivity_type::edge);
std::cout << "Found " << n_components << " components\n";
Connectivity types:
tf::connectivity_type::manifold_edge — faces sharing a manifold edge are connectedtf::connectivity_type::edge — faces sharing an edge are connectedtf::connectivity_type::vertex — faces sharing a vertex are connectedSplit a labeled polydata into separate meshes, one per unique label. Returns std::pair<std::vector<vtkSmartPointer<polydata>>, std::vector<vtkIdType>> — a vector of polydata objects and their corresponding labels.
auto [labeled, n] = tf::vtk::make_connected_components(
mesh, tf::connectivity_type::edge);
auto [components, labels] = tf::vtk::split_into_components(labeled);
for (const auto &[polydata, label] : tf::zip(components, labels)) {
}
// Split by a named cell data array
auto [components, labels] = tf::vtk::split_into_components(polydata, "RegionId");
Extract boundary edges connected into continuous paths. Returns vtkSmartPointer<polydata> with line cells. The output shares points with the input. See Boundary Detection.
auto boundaries = tf::vtk::make_boundary_paths(mesh);
std::cout << "Found " << boundaries->GetNumberOfLines() << " boundary paths\n";
Extract individual boundary edges (edges belonging to only one face). Returns vtkSmartPointer<polydata> with line cells.
auto edges = tf::vtk::make_boundary_edges(mesh);
Extract edges belonging to more than two faces. Returns vtkSmartPointer<polydata> with line cells. See Non-Manifold Edge Detection.
auto edges = tf::vtk::make_non_manifold_edges(mesh);
Extract both boundary and non-manifold edges. Returns vtkSmartPointer<polydata> with line cells and "EdgeType" cell scalars (0=boundary, 1=non-manifold). See Non-Simple Edge Detection.
auto edges = tf::vtk::make_non_simple_edges(mesh);
Orient face winding so adjacent faces have compatible normals. Modifies the input in place. Uses flood-fill through manifold edges; non-manifold edges act as barriers. See Face Orientation.
tf::vtk::orient_faces_consistently(mesh);
Extract features from scalar fields defined on mesh vertices. See the Cut module for the underlying algorithms.
Extract curves at specified scalar values. Returns vtkSmartPointer<polydata> with line cells representing isocontours.
auto contours = tf::vtk::make_isocontours(mesh, "height", {0.1f, 0.2f, 0.3f});
// nullptr for active scalars
auto contours = tf::vtk::make_isocontours(mesh, nullptr, {0.5f});
Extract regions between scalar values. Returns vtkSmartPointer<polydata> with polygon cells and "BandLabel" cell scalars. See Isobands.
// cut_values define band boundaries
// selected_bands: 0=first band, 1=second, etc.
auto bands = tf::vtk::make_isobands(mesh, "height",
{0.0f, 0.5f, 1.0f}, // cut values
{1, 2}); // select bands 1 and 2
With tf::return_curves, returns std::pair<vtkSmartPointer<polydata>, vtkSmartPointer<polydata>> — the bands and their boundary curves.
auto [bands, curves] = tf::vtk::make_isobands(mesh, "height",
{0.0f, 0.5f, 1.0f}, {1, 2}, tf::return_curves);
Compute and set normal vectors on polydata. See the Geometry module for the underlying algorithms.
Compute face normals and store as "Normals" cell data array. Modifies the input in place. See Polygon Normals.
tf::vtk::compute_cell_normals(polydata);
Compute vertex normals by averaging adjacent face normals and store as "Normals" point data array. Modifies the input in place. Computes cell normals first if not present. See Point Normals.
tf::vtk::compute_point_normals(mesh);
Remove degeneracies and duplicates from mesh data. See the Clean module for the underlying algorithms.
Remove duplicate points and degenerate faces from polygon data. Returns vtkSmartPointer<polydata>. See Polygon Cleaning.
auto clean = tf::vtk::cleaned_polygons(mesh);
// With tolerance for merging nearby points
auto clean = tf::vtk::cleaned_polygons(mesh, 0.001f);
// Without preserving point/cell data
auto clean = tf::vtk::cleaned_polygons(mesh, 0.0f, false);
Clean line data: merge duplicate points, remove degenerate edges, and reconnect edges into continuous paths. Returns vtkSmartPointer<polydata>. See Curve Cleaning.
auto clean = tf::vtk::cleaned_lines(mesh);
auto clean = tf::vtk::cleaned_lines(mesh, 0.001f);
Remove duplicate points. Returns vtkSmartPointer<vtkPoints>. See Point Cleaning.
auto clean = tf::vtk::cleaned_points(points);
auto clean = tf::vtk::cleaned_points(points, 0.001f);
Read and write mesh files directly to/from tf::vtk::polydata. See the I/O module for the underlying algorithms.
Read an STL file. Returns vtkSmartPointer<polydata> with cached acceleration structures ready to use.
auto mesh = tf::vtk::read_stl("model.stl");
Write polydata to binary STL. Returns bool indicating success. Input must contain triangles.
bool ok = tf::vtk::write_stl(polydata, "output.stl");
// With transform applied
bool ok = tf::vtk::write_stl({polydata, matrix}, "output.stl");
Read an OBJ file. Returns vtkSmartPointer<polydata>. Only vertices and faces are read.
auto mesh = tf::vtk::read_obj("model.obj");
Write polydata to OBJ format. Returns bool indicating success.
bool ok = tf::vtk::write_obj(polydata, "output.obj");
// With transform applied
bool ok = tf::vtk::write_obj({polydata, matrix}, "output.obj");