The Clean module removes duplicate, degenerate, and unreferenced elements from geometric data. It operates on trueform's primitive ranges, maintains referential integrity, and provides optional index maps for reindexing associated data.
Include the module with:
#include <trueform/clean.hpp>
| Geometry | Removes |
|---|---|
| Points | Duplicate vertices |
| Segments | Duplicate vertices, duplicate edges, degenerate edges, unreferenced vertices |
| Polygons | Duplicate vertices, duplicate faces, degenerate faces, unreferenced vertices |
| Curves | Duplicate vertices, degenerate edges, unreferenced vertices |
Definitions:
When duplicates are removed, the element with the smallest index is kept.
Remove duplicate points from point collections:
// Exact duplicate removal
auto clean_points = tf::cleaned(points);
// Tolerance-based: merge points within distance
auto clean_points = tf::cleaned(points, 1e-6f);
// Get index map for reindexing associated data
auto [clean_points, point_map] = tf::cleaned(points, tolerance, tf::return_index_map);
auto clean_normals = tf::reindexed(point_normals, point_map);
For points (and soups), the index type defaults to int. Specify explicitly for large data:
auto clean_points = tf::cleaned<int64_t>(points);
Clean segment collections:
// Clean segments
auto clean_segments = tf::cleaned(segments);
// With tolerance
auto clean_segments = tf::cleaned(segments, 1e-5f);
// Get both edge and point index maps
auto [clean_segments, edge_map, point_map] =
tf::cleaned(segments, tolerance, tf::return_index_map);
// Reindex associated data
auto clean_edge_attrs = tf::reindexed(tf::make_edges(edge_attrs), edge_map);
auto clean_point_attrs = tf::reindexed(point_attrs, point_map);
The index type is deduced from segments.edges()[0][0].
Clean polygon meshes:
// Clean polygons
auto clean_polygons = tf::cleaned(polygons);
// With tolerance
auto clean_polygons = tf::cleaned(polygons, 1e-8);
// Get both face and point index maps
auto [clean_polygons, face_map, point_map] =
tf::cleaned(polygons, tolerance, tf::return_index_map);
// Reindex associated data
auto clean_face_normals = tf::reindexed(face_normals, face_map);
auto clean_vertex_attrs = tf::reindexed(vertex_attrs, point_map);
The index type is deduced from polygons.faces()[0][0]. Specify explicitly for large meshes:
auto clean_polygons = tf::cleaned<int64_t>(polygons);
Clean curve collections (connected paths):
// Clean curves
auto clean_curves = tf::cleaned(curves);
// With tolerance
auto clean_curves = tf::cleaned(curves, 1e-5f);
// Get point index map (edge map not available since paths are reconnected)
auto [clean_curves, point_map] = tf::cleaned(curves, tolerance, tf::return_index_map);
Polygon and segment soups (unindexed geometry) can be cleaned, converting them to indexed geometry:
// Triangle soup: each element stores its own vertices
auto soup = tf::make_polygons(tf::make_blocked_range<3>(raw_points));
// Clean converts to indexed geometry with shared vertices
auto clean_mesh = tf::cleaned(soup);
// With tolerance
auto clean_mesh = tf::cleaned(soup, 1e-6f);
All cleaning operations can return index maps for tracking how elements were remapped:
auto [clean_polygons, face_map, point_map] =
tf::cleaned(polygons, tf::return_index_map);
// Use maps to reindex associated data
auto clean_face_colors = tf::reindexed(face_colors, face_map);
auto clean_vertex_uvs = tf::reindexed(vertex_uvs, point_map);
For more control, use tf::make_clean_index_map directly:
// Points
auto point_map = tf::make_clean_index_map(points);
auto point_map = tf::make_clean_index_map(points, tolerance);
// Segments
auto [edge_map, point_map] = tf::make_clean_index_map(segments);
auto [edge_map, point_map] = tf::make_clean_index_map(segments, tolerance);
// Polygons
auto [face_map, point_map] = tf::make_clean_index_map(polygons);
auto [face_map, point_map] = tf::make_clean_index_map(polygons, tolerance);
// Explicit index type
auto [face_map, point_map] = tf::make_clean_index_map<int64_t>(polygons);