Interactive examples demonstrating trueform's VTK integration. Each example shows a focused pipeline—collision detection, boolean operations, isocontours, and more—with draggable meshes and real-time updates.
All examples are available in the GitHub repository.
Enable VTK examples when building trueform:
cmake -DBUILD_VTK=ON -DBUILD_EXAMPLES=ON ..
make vtk_examples -j10
Requires VTK 9+ with rendering components (RenderingOpenGL2, InteractionStyle).
Run an example:
./vtk_example_collision
./vtk_example_boolean
A 5×5 grid of draggable meshes. Drag any mesh and colliding neighbors highlight in real-time using intersects with transforms.
// Check collision between two transformed meshes
bool collision = tf::vtk::intersects(
std::make_pair(poly, selected_matrix),
std::make_pair(poly, other_matrix));
if (collision) {
actor->GetProperty()->SetColor(0.9, 0.7, 0.7);
}
Two draggable meshes with a colored tube showing the closest points between them. Distance updates in real-time using neighbor_search. Tube color interpolates green (close) to red (far).
// Find closest points between two transformed meshes
auto result = tf::vtk::neighbor_search(
std::make_pair(poly, matrices[0].Get()),
std::make_pair(poly, matrices[1].Get()));
// Visualize with a line
line_source->SetPoint1(result.info.first.data());
line_source->SetPoint2(result.info.second.data());
// Color by distance
float t = std::sqrt(result.info.metric) / max_distance;
line_actor->GetProperty()->SetColor(t, 1.0 - t, 0.3);
Two-viewport display: input meshes with intersection curves on the left, boolean result on the right. Drag either mesh to reposition—the boolean result and curves update in real-time. Uses the boolean filter with transforms and curve output. Result mesh colored by "Labels" cell data.
// Boolean filter pipeline
vtkNew<tf::vtk::boolean> boolean_filter;
boolean_filter->SetInputConnection(0, adapter0->GetOutputPort());
boolean_filter->SetInputConnection(1, adapter1->GetOutputPort());
boolean_filter->set_matrix0(matrix0);
boolean_filter->set_matrix1(matrix1);
boolean_filter->set_operation(tf::boolean_op::left_difference);
boolean_filter->set_return_curves(true);
// Visualize curves as tubes
vtkNew<vtkTubeFilter> tube;
tube->SetInputConnection(boolean_filter->GetOutputPort(1));
// Color result by Labels
vtkNew<vtkLookupTable> lut;
lut->SetNumberOfTableValues(2);
lut->SetTableValue(0, 0.8, 0.8, 0.9, 1.0); // mesh 0
lut->SetTableValue(1, 0.9, 0.8, 0.8, 1.0); // mesh 1
result_mapper->SetInputConnection(boolean_filter->GetOutputPort(0));
result_mapper->SetScalarModeToUseCellData();
result_mapper->SetLookupTable(lut);
Two draggable meshes with intersection curves. Drag either mesh—curves update in real-time. Uses the intersection_curves filter with transforms.
// Intersection curves pipeline
vtkNew<tf::vtk::intersection_curves> curves;
curves->SetInputConnection(0, adapter0->GetOutputPort());
curves->SetInputConnection(1, adapter1->GetOutputPort());
curves->set_matrix0(matrix0);
curves->set_matrix1(matrix1);
// Visualize as tubes
vtkNew<vtkTubeFilter> tube;
tube->SetInputConnection(curves->GetOutputPort());
tube->SetRadius(0.0005);
Isocontour curves on a mesh with a distance-from-centroid scalar field. Hold Shift and scroll to animate the cut values—contours sweep across the surface. Uses the isocontours filter.
// Create scalar field
auto points = tf::vtk::make_points(poly);
auto center = tf::centroid(points);
auto scalars_range = tf::vtk::make_range(scalars.Get());
tf::parallel_transform(points, scalars_range, tf::distance_f(center));
// Isocontours pipeline
vtkNew<tf::vtk::isocontours> iso;
iso->SetInputConnection(reader->GetOutputPort());
iso->set_cut_values({0.1f, 0.2f, 0.3f, ...});
// Visualize as tubes
vtkNew<vtkTubeFilter> tube;
tube->SetInputConnection(iso->GetOutputPort());
Alternating isoband regions with boundary curves. Hold Shift and scroll to animate the band selection—creates a marching-stripes effect across the surface. Uses the isobands filter with curve output.
// Isobands pipeline
vtkNew<tf::vtk::isobands> bands;
bands->SetInputConnection(reader->GetOutputPort());
bands->set_cut_values({0.0f, 0.5f, 1.0f, 1.5f, ...});
bands->set_selected_bands({0, 2, 4, ...}); // alternating
bands->set_return_curves(true);
// Color bands by BandLabel
band_mapper->SetInputConnection(bands->GetOutputPort(0));
band_mapper->SetScalarModeToUseCellData();
band_mapper->SetLookupTable(lut);
// Boundary curves
vtkNew<vtkTubeFilter> tube;
tube->SetInputConnection(bands->GetOutputPort(1));
Creates disconnected regions using alternating isobands, then labels and splits them into separate meshes. Uses the connected_components filter and split_into_components function.
// Create disconnected regions with isobands
vtkNew<tf::vtk::isobands> bands;
bands->set_selected_bands({0, 2, 4, 6, 8}); // alternating
// Label components
vtkNew<tf::vtk::connected_components> cc;
cc->SetInputConnection(adapt->GetOutputPort());
cc->set_connectivity(tf::connectivity_type::edge);
cc->Update();
std::cout << "Found " << cc->n_components() << " components\n";
// Split into separate meshes
auto [components, labels] = tf::vtk::split_into_components(cc->GetOutput());
// Color by ComponentLabel
mapper->SetScalarModeToUseCellData();
mapper->SelectColorArray("ComponentLabel");
mapper->SetScalarRange(0, cc->n_components() - 1);
Extracts the boundary of a cut mesh (upper half via isobands) and visualizes it as tubes. Uses the boundary_paths filter.
// Cut mesh with isobands (upper half)
vtkNew<tf::vtk::isobands> bands;
bands->set_cut_values({mid_z, max_z + 1.0f});
bands->set_selected_bands({0});
// Extract boundary
vtkNew<tf::vtk::boundary_paths> boundary;
boundary->SetInputConnection(bands->GetOutputPort(0));
// Visualize as tubes
vtkNew<vtkTubeFilter> tube;
tube->SetInputConnection(boundary->GetOutputPort());
tube->SetRadius(0.0005);