Repository navigation
Rewrite from_points as a multi-level grid mesher - #31
Merged
Merged
Conversation
from_points grew triangles from seed fans and border edges and produced overlapping, non-manifold meshes. It now triangulates a grid of XY cells: - Points of a cell are split into levels separated by more than the clearance (min_clearance, default 1 m), so stacked floors are separate vertices. A level's height is a robust plane fit of its upper face at the cell centre; a slab seen from above and below keeps its upper face, and a level that is not a plane (wall, furniture) keeps a high top, as an obstacle. - Sparse upper faces and cells that only saw the lower face of a slab are recovered from the neighbouring cells, without lifting spikes, potholes or boxes. - Small enclosed holes (max_hole_area) are filled from their border. - Neighbouring levels are linked by mutual closest height within the step and slope limits, and every quad gets at most the two triangles of one diagonal per level: no overlap, at most two triangles per edge. - Only used vertices are kept; max_surfaces and min_surface_area drop the triangles and vertices of the removed surfaces. A "support" layer counts the points behind each triangle (0 if interpolated). build_adjacency resets the neighbors, leaves non-manifold edges open and counts them (nonmanifold_edges()). Fixes #30 Signed-off-by: Francisco Martín Rico <fmrico@gmail.com>
This was referenced Oct 14, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #30
from_points(andfrom_pointcloud2) grew triangles from seed fans and border edges and produced overlapping, non-manifold meshes. This replaces it with a deterministic multi-level grid triangulation that is manifold by construction.How it works
Levels. Points are binned in XY cells of
resolution. In each cell, points closer thanmax(min_clearance, max_dz)in z form one level: stacked floors give one vertex per floor.Height of a level. A robust plane fit (two passes, trimming outliers) of its upper face, at the cell centre.
Sparse faces. Two neighbour-consensus passes:
Spikes, potholes and boxes are never lifted.
Holes. Enclosed empty regions up to
max_hole_area(1 m² by default) are filled from the levels around most of their border.Links and triangles.
max_slope_deg.Output.
max_surfacesand the newmin_surface_areadrop the triangles and vertices of the removed surfaces.elevation, plus the newsupport(points behind each triangle, 0 if interpolated).New
BuildParams:min_clearance,min_surface_area,max_hole_area.max_edge_len,neighbor_radius,k_neighbors,use_radiusandmin_angle_degare kept for API compatibility and are now ignored. Voxelized clouds need a resolution of at least twice the voxel size.build_adjacencynow sorts the edge uses instead of hashing, resets the neighbors before rebuilding, leaves non-manifold edges open (no asymmetric links) and counts them (nonmanifold_edges()).The
.navmapfile format and the message are unchanged.Results
Max triangles per edge in brackets.
Tests
test_from_points(30 tests):min_clearance;max_surfaces/min_surface_area,supportlayer, degenerate inputs.test_adjacency(6 tests): non-manifold edges, stale links after a rebuild, copy.navmap_coreandnavmap_rospass under ASan/UBSan.navmap_tools,navmap_examplesand the EasyNav NavMap plugins pass unchanged.