VTK | C++

Overview

VTK integration layer for trueform algorithms.

The tf::vtk library integrates trueform with VTK (Visualization Toolkit). It provides tf::vtk::polydata—an extended vtkPolyData with cached acceleration structures—plus standalone functions and VTK pipeline filters wrapping trueform's algorithms.

Installation

Requirements

  • VTK 9+ with CommonCore and CommonDataModel components

Build & Install

git clone https://github.com/polydera/trueform.git
cd trueform

cmake -B build -DTF_BUILD_VTK_INTEGRATION=ON -DCMAKE_BUILD_TYPE=Release
cmake --build build --parallel
cmake --install build --prefix /usr/local

Usage

CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(my_vtk_app LANGUAGES CXX)

find_package(trueform_vtk REQUIRED CONFIG)

add_executable(my_vtk_app main.cpp)
target_link_libraries(my_vtk_app PRIVATE tf::vtk)
Linking tf::vtk automatically includes tf::trueform and VTK libraries.

Core

Polydata, zero-copy views, and data conversion utilities.

Functions

Standalone mesh operations wrapping trueform algorithms.

Filters

VTK pipeline filters wrapping trueform algorithms.

Examples

Interactive applications: spatial queries, booleans, scalar fields, topology.

Quick Tour

Wrap any vtkPolyData to access trueform's API:

#include <trueform/vtk.hpp>

// Your existing VTK pipeline
vtkNew<vtkSTLReader> reader;
reader->SetFileName("model.stl");
reader->Update();

// Wrap in tf::vtk::polydata (zero-copy)
auto mesh = vtkSmartPointer<tf::vtk::polydata>::New();
mesh->ShallowCopy(reader->GetOutput());

Iterate over geometry as trueform primitive views:

// Points
for (auto pt : mesh->points()) {
    auto [x, y, z] = pt;
}

// Polygons (faces + points) - dynamic size
for (auto polygon : mesh->polygons()) {
    for (auto pt : polygon) {
        // each pt is a tf::point_view<float, 3>
    }
    // Access vertex indices
    for (auto id : polygon.indices()) {
        // id is vtkIdType
    }
}

// Lines/paths
for (auto curve : mesh->curves()) {
    for (auto pt : curve) {
        // each pt is a tf::point_view<float, 3>
    }
    for (auto id : curve.indices()) {
        // point index along the path
    }
}

Use trueform functions directly on the views:

auto polygons = polydata0->polygons();
// segments of lines
auto segments = polydata1->segments();

if(!tf::intersects(segments[0], polygons[10])) {
    auto d2 = tf::distance2(segments[0], polygons[10]);
}

Cached acceleration structures are built lazily and track VTK's MTime:

// First access builds the structure
auto& tree = mesh->poly_tree();           // tf::aabb_tree
auto& point_tree = mesh->point_tree();           // tf::aabb_tree
auto& fm = mesh->face_membership();       // tf::face_membership
auto& mel = mesh->manifold_edge_link();   // tf::manifold_edge_link

// Subsequent accesses reuse cached structures
// Structures rebuild automatically when mesh data changes

Collision detection and distance between meshes:

// Check if two meshes intersect
if (tf::vtk::intersects(mesh0, mesh1)) {
    // handle collision
}

// Get squared distance between meshes
auto d2 = tf::vtk::distance2(mesh0, mesh1);

// Get actual distance
auto d = tf::vtk::distance(mesh0, mesh1);

// Full nearest neighbor info between meshes
auto nearest = tf::vtk::neighbor_search(mesh0, mesh1);
// nearest.elements.first, nearest.elements.second - primitive indices
// nearest.info.metric - squared distance
// nearest.info.first, nearest.info.second - closest points

Spatial queries work directly on polydata:

auto ray = tf::make_ray(origin, direction);
if (auto hit = tf::vtk::ray_hit(ray, mesh)) {
    // hit.element, hit.info.t, hit.info.point
}

auto query_pt = tf::point<float, 3>{1.0f, 2.0f, 3.0f};
if (auto nearest = tf::vtk::neighbor_search(mesh, query_pt)) {
    // nearest.element, nearest.info.metric, nearest.info.point
}

// k nearest neighbors
auto knn = tf::vtk::neighbor_search_k(mesh, query_pt, 5);
for (auto& neighbor : knn) {
    // neighbor.element, neighbor.info.metric, neighbor.info.point
}

Boolean operations between meshes:

auto [result, curves] = tf::vtk::make_boolean(
    mesh1, mesh2, tf::boolean_op::merge, tf::return_curves);

// Result is tf::vtk::polydata with "Labels" cell scalars
for (auto polygon : result->polygons()) {
    // ...
}

VTK pipeline filters integrate with existing pipelines:

// Adapter converts vtkPolyData → tf::vtk::polydata
vtkNew<tf::vtk::adapter> adapter;
adapter->SetInputConnection(reader->GetOutputPort());

// Boolean filter
vtkNew<tf::vtk::boolean> boolean_filter;
boolean_filter->SetInputConnection(0, adapter1->GetOutputPort());
boolean_filter->SetInputConnection(1, adapter2->GetOutputPort());
boolean_filter->set_operation(tf::boolean_op::merge);
boolean_filter->Update();

auto* result = boolean_filter->GetOutput();

This is tf::vtk from a bird's eye view. For detailed API documentation, explore the Core utilities, Functions reference, and Filters guide.