Skip to content

Feat/new-filter-voxel-sor#27

Merged
jlblancoc merged 4 commits intodevelopfrom
feat/new-filter-voxel-sor
Jan 21, 2026
Merged

Feat/new-filter-voxel-sor#27
jlblancoc merged 4 commits intodevelopfrom
feat/new-filter-voxel-sor

Conversation

@jlblancoc
Copy link
Copy Markdown
Member

@jlblancoc jlblancoc commented Jan 21, 2026

Summary by CodeRabbit

  • New Features

    • Voxel-based Statistical Outlier Removal (SOR) filter: configurable per-voxel local k-NN analysis with parallel processing support.
  • Improvements

    • Clearer runtime error reporting during filter pipeline initialization.
    • Added statistical logging of inlier/outlier counts.
    • Minor constructor/api cleanup for existing SOR filter.
  • Documentation

    • Comprehensive usage docs and examples for the new voxel SOR filter.
  • Tests

    • New unit tests and expanded test suite covering the new filter and class factory.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jan 21, 2026

📝 Walkthrough

Walkthrough

Adds a new voxel-based Statistical Outlier Removal filter (FilterVoxelSOR) with implementation, header, docs, tests, CMake registration, MRPT-version guards, minor FilterSOR logging/statistics, and improved dynamic-creation error messaging.

Changes

Cohort / File(s) Summary
New Filter Implementation
mp2p_icp_filters/include/mp2p_icp_filters/FilterVoxelSOR.h, mp2p_icp_filters/src/FilterVoxelSOR.cpp
New FilterVoxelSOR class: voxel grid builder, per-voxel local k-NN analysis (mean_k, std_dev_mul), inlier/outlier classification, optional TBB parallelization, MRPT-version conditional insert semantics, YAML parameter loading.
Build & Registration
mp2p_icp_filters/CMakeLists.txt, mp2p_icp_filters/src/register.cpp
Added public header & source to CMake lists; registered FilterVoxelSOR in RTTI initializer.
FilterBase / FilterSOR tweaks
mp2p_icp_filters/src/FilterBase.cpp, mp2p_icp_filters/src/FilterSOR.cpp, mp2p_icp_filters/include/mp2p_icp_filters/FilterSOR.h
Improved assertion message on dynamic creation failure; moved MRPT version check into FilterSOR::filter(), added inlier/outlier counters and debug logging; FilterSOR() constructor defaulted.
Documentation
docs/source/mp2p_icp_filters.rst
Appended comprehensive FilterVoxelSOR documentation (purpose, parameters, YAML/C++ examples, notes) after existing FilterVoxelSlice section.
Tests & Test CMake
tests/test-mp2p_FilterVoxelSOR.cpp, tests/test-mp2p_class_factory.cpp, tests/CMakeLists.txt
New unit test for FilterVoxelSOR, new class-factory instantiation test, and additional test targets referencing mp2p_icp_filters.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant Filter as "FilterVoxelSOR"
    participant VoxelGrid as "Voxel Grid Builder"
    participant Parallel as "Parallel Worker (TBB / seq)"
    participant KNN as "Per-voxel k-NN Analyzer"
    participant Layers as "Inliers/Outliers Layers"

    User->>Filter: filter(metric_map_t)
    Filter->>Filter: validate input layer & params
    Filter->>VoxelGrid: build voxels (voxel_size)
    VoxelGrid-->>Filter: voxel buckets
    Filter->>Layers: ensure/create output layers
    Filter->>Parallel: dispatch voxel buckets
    loop per voxel (parallel/thread)
        Parallel->>KNN: if size ≤ mean_k -> mark all inliers
        alt size > mean_k
            KNN->>KNN: build local points map
            KNN->>KNN: compute avg dist to k-NN per point
            KNN->>KNN: compute μ, σ and threshold = μ + std_dev_mul·σ
            KNN-->>Parallel: classify points (inlier/outlier)
        end
    end
    Parallel-->>Filter: per-thread results
    Filter->>Layers: merge results into inliers/outliers
    Layers-->>Filter: layers updated
    Filter->>User: return updated metric_map_t (log stats)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Poem

🐇 I hop through voxels, quiet and spry,

I count my neighbors, low and high,
Sigma hums and thresholds pry,
Outliers scatter — watch them fly,
Clean clouds dance beneath my sky.

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Feat/new-filter-voxel-sor' clearly describes the main change: introducing a new FilterVoxelSOR filter component with comprehensive implementation across multiple files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
mp2p_icp_filters/src/FilterSOR.cpp (1)

162-215: Counter increments missing in older MRPT version branches.

The num_inliers and num_outliers counters are only incremented within the #if MRPT_VERSION >= 0x020f03 branch (lines 171 and 180). The other version branches (lines 185-196 for MRPT 2.15.0-2.15.2, and lines 197-209 for older versions) don't increment the counters, so the debug log will always report 0 inliers and 0 outliers for those MRPT versions.

🐛 Proposed fix to add counters in all branches
 `#elif` MRPT_VERSION >= 0x020f00  // 2.15.0
             if (outInliers)
             {
                 outInliers->insertPointFrom(pc, i, *ctxI);
             }
+            ++num_inliers;
         }
         else
         {
+            ++num_outliers;
             if (outOutliers)
             {
                 outOutliers->insertPointFrom(pc, i, *ctxO);
             }
 `#else`
             if (outInliers)
             {
                 outInliers->insertPointFrom(pc, i);
             }
+            ++num_inliers;
         }
         else
         {
+            ++num_outliers;
             if (outOutliers)
             {
                 outOutliers->insertPointFrom(pc, i);
             }
 `#endif`
🤖 Fix all issues with AI agents
In `@mp2p_icp_filters/include/mp2p_icp_filters/FilterVoxelSOR.h`:
- Around line 15-20: Update the file-level documentation date in the header
comment of FilterVoxelSOR.h: change the `@date` value currently "Jan 21, 2025" to
"Jan 21, 2026" so the file header (the block at top of FilterVoxelSOR.h)
reflects the correct year.

In `@mp2p_icp_filters/src/FilterVoxelSOR.cpp`:
- Around line 54-56: After loading params in FilterVoxelSOR::initialize_filter,
add MRPT_START / MRPT_END wrapped assertions to validate parameters: assert
params.voxel_size > 0 with ASSERT_GT_(params.voxel_size, 0.0f), assert
params.mean_k >= 1 with ASSERT_GE_(params.mean_k, 1), and assert
params.parallelization_grain_size >= 1 with
ASSERT_GE_(params.parallelization_grain_size, 1) to prevent divide-by-zero and
invalid ranges as done in FilterMLS.
- Around line 61-85: Add a guard before creating output layers to reject
configurations where params.output_layer_inliers or params.output_layer_outliers
equals params.input_layer or equals each other: detect these name collisions and
return early (or raise) with an error; perform this check prior to calling
GetOrCreatePointLayer so you never obtain aliases to the input map (which would
lead to xs/ys/zs buffer invalidation and duplicate insertions). Ensure the
validation references params.input_layer, params.output_layer_inliers,
params.output_layer_outliers and runs before the GetOrCreatePointLayer calls in
FilterVoxelSOR.

In `@tests/test-mp2p_class_factory.cpp`:
- Around line 15-20: Update the file-level doc comment's `@brief`: replace the
existing "@brief Unit tests for Generator" with a concise description reflecting
this test suite's purpose (e.g., "@brief Unit tests for the class factory
mechanism and registered classes"); locate and edit the top comment block
containing the `@brief` tag in test-mp2p_class_factory.cpp to ensure the
description matches the tests.
- Around line 91-103: The final unconditional "return 0;" in main is unreachable
because both the try block (return test_class_factory()) and the catch block
(return 1) already return; remove the trailing "return 0;" (or alternatively
refactor main to assign test_class_factory() to an int and return it after the
try/catch) so that main no longer contains unreachable code; locate this in the
main function where test_class_factory() is returned.

Comment thread mp2p_icp_filters/include/mp2p_icp_filters/FilterVoxelSOR.h
Comment thread mp2p_icp_filters/src/FilterVoxelSOR.cpp
Comment thread mp2p_icp_filters/src/FilterVoxelSOR.cpp
Comment thread tests/test-mp2p_class_factory.cpp
Comment thread tests/test-mp2p_class_factory.cpp
@jlblancoc jlblancoc enabled auto-merge January 21, 2026 11:33
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@mp2p_icp_filters/src/FilterSOR.cpp`:
- Around line 58-60: Add a direct include for the C++ standard exception header
so the use of std::runtime_error in FilterSOR.cpp is not dependent on transitive
MRPT headers: add an `#include` <stdexcept> near the top of FilterSOR.cpp (before
the preprocessor check/throw) so the throw std::runtime_error("FilterSOR
requires MRPT >= 2.15.4") is valid and self-contained.

Comment thread mp2p_icp_filters/src/FilterSOR.cpp
@jlblancoc jlblancoc merged commit fc3d8bd into develop Jan 21, 2026
10 of 13 checks passed
@jlblancoc jlblancoc deleted the feat/new-filter-voxel-sor branch January 21, 2026 11:43
@codecov
Copy link
Copy Markdown

codecov Bot commented Jan 21, 2026

Codecov Report

❌ Patch coverage is 90.85366% with 15 lines in your changes missing coverage. Please review.
✅ Project coverage is 66.19%. Comparing base (affe457) to head (eb6f4bd).
⚠️ Report is 5 commits behind head on develop.

Files with missing lines Patch % Lines
mp2p_icp_filters/src/FilterVoxelSOR.cpp 94.05% 6 Missing ⚠️
tests/test-mp2p_class_factory.cpp 72.72% 6 Missing ⚠️
tests/test-mp2p_FilterVoxelSOR.cpp 90.62% 3 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop      #27      +/-   ##
===========================================
+ Coverage    65.25%   66.19%   +0.94%     
===========================================
  Files          161      165       +4     
  Lines         7938     8100     +162     
  Branches       858      879      +21     
===========================================
+ Hits          5180     5362     +182     
+ Misses        2758     2738      -20     
Files with missing lines Coverage Δ
...p_icp_filters/include/mp2p_icp_filters/FilterSOR.h 100.00% <100.00%> (ø)
..._filters/include/mp2p_icp_filters/FilterVoxelSOR.h 100.00% <100.00%> (ø)
mp2p_icp_filters/src/FilterBase.cpp 72.50% <100.00%> (ø)
mp2p_icp_filters/src/FilterSOR.cpp 94.11% <100.00%> (+0.36%) ⬆️
mp2p_icp_filters/src/register.cpp 100.00% <100.00%> (ø)
tests/test-mp2p_FilterVoxelSOR.cpp 90.62% <90.62%> (ø)
mp2p_icp_filters/src/FilterVoxelSOR.cpp 94.05% <94.05%> (ø)
tests/test-mp2p_class_factory.cpp 72.72% <72.72%> (ø)

... and 24 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant