Skip to content

FilterRemovePointCloudField now accepts multiple fields#42

Merged
jlblancoc merged 1 commit intodevelopfrom
feat/filter-remove-several-point-fields
Feb 16, 2026
Merged

FilterRemovePointCloudField now accepts multiple fields#42
jlblancoc merged 1 commit intodevelopfrom
feat/filter-remove-several-point-fields

Conversation

@jlblancoc
Copy link
Copy Markdown
Member

@jlblancoc jlblancoc commented Feb 16, 2026

Summary by CodeRabbit

  • New Features

    • Point cloud filtering now supports removing one or more fields in a single operation; configuration accepts a single field or a list.
  • Behavior Changes

    • Missing-field handling now applies across the specified fields: the configured missing-field policy is enforced if any listed field is absent.
  • Tests

    • Test coverage expanded to validate single- and multi-field removal scenarios and missing-field behavior.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 16, 2026

📝 Walkthrough

Walkthrough

Replaced the singular field_name parameter with field_names (accepting a string or a sequence of strings) across header, implementation, documentation, and tests; YAML parsing and filter logic now accept and iterate over one or more field names and apply per-field error handling.

Changes

Cohort / File(s) Summary
Documentation
docs/source/mp2p_icp_filters.rst
YAML examples and descriptive text updated to use field_names (scalar or sequence) and reflect removal of one or more fields.
Header Definition
mp2p_icp_filters/include/mp2p_icp_filters/FilterRemovePointCloudField.h
Replaced std::string field_name with std::vector<std::string> field_names in Parameters; updated comments/documentation to reference multiple fields.
Implementation Logic
mp2p_icp_filters/src/FilterRemovePointCloudField.cpp
YAML loader now accepts field_names as scalar or sequence, validates non-empty list, and filter logic iterates over field_names removing each with per-field error handling/logging governed by throw_on_missing_field.
Tests
tests/test-mp2p_FilterRemovePointCloudField.cpp
Replaced field_name keys with field_names (scalar or sequence); added test case for removing multiple fields in one call and adjusted expectations/logging where applicable.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 I hopped through code with a curious cheer,
From single to many, the fields disappear,
YAML and tests now sing in a line,
field_names in sequence — tidy and fine,
Hooray for clean clouds, one hop at a time! 🎉

🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: FilterRemovePointCloudField now accepts multiple fields instead of a single field, which is the primary objective across all modified files.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into develop

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/filter-remove-several-point-fields

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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: 1

🤖 Fix all issues with AI agents
Verify each finding against the current code and only fix it if needed.


In `@mp2p_icp_filters/src/FilterRemovePointCloudField.cpp`:
- Around line 103-110: Reformat the THROW_EXCEPTION call to satisfy
clang-format: adjust the indentation and line breaks in the block where you
check (!removed && params.throw_on_missing_field) so the THROW_EXCEPTION(
mrpt::format( "Field '%s' does not exist in layer '%s'", field_name.c_str(),
params.pointcloud_layer.c_str() ) ); call is split/formatted per project style
(preserve use of THROW_EXCEPTION and mrpt::format and the field_name /
params.pointcloud_layer arguments) — run clang-format on
FilterRemovePointCloudField.cpp to apply the exact spacing and line breaks.
- Around line 98-124: The loop currently calls pc->unregisterField(...) and may
remove earlier fields before THROW_EXCEPTION is raised, causing partial
modification; modify RemovePointCloudField logic to perform a pre-validation
pass when params.throw_on_missing_field is true: iterate params.field_names and
check existence (e.g., via an existence API on pc or by querying fields) and
throw via the same THROW_EXCEPTION if any are missing, before performing any
pc->unregisterField calls; otherwise (when not throwing) keep the current
single-pass behavior and the MRPT_LOG_DEBUG_STREAM messages for removed/ignored
fields.
🧹 Nitpick comments (1)
🤖 Fix all nitpicks with AI agents
Verify each finding against the current code and only fix it if needed.


In `@mp2p_icp_filters/src/FilterRemovePointCloudField.cpp`:
- Around line 98-124: The loop currently calls pc->unregisterField(...) and may
remove earlier fields before THROW_EXCEPTION is raised, causing partial
modification; modify RemovePointCloudField logic to perform a pre-validation
pass when params.throw_on_missing_field is true: iterate params.field_names and
check existence (e.g., via an existence API on pc or by querying fields) and
throw via the same THROW_EXCEPTION if any are missing, before performing any
pc->unregisterField calls; otherwise (when not throwing) keep the current
single-pass behavior and the MRPT_LOG_DEBUG_STREAM messages for removed/ignored
fields.
mp2p_icp_filters/src/FilterRemovePointCloudField.cpp (1)

98-124: Partial removal on failure when throw_on_missing_field is true.

If field_names contains e.g. ["a", "b", "c"] and field "b" is missing, "a" will have already been removed before the exception is thrown. This leaves the point cloud in a partially modified state. If this is intentional "fail-fast" behavior, consider documenting it. Otherwise, a two-pass approach (validate all fields exist first, then remove) would be safer.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mp2p_icp_filters/src/FilterRemovePointCloudField.cpp` around lines 98 - 124,
The loop currently calls pc->unregisterField(...) and may remove earlier fields
before THROW_EXCEPTION is raised, causing partial modification; modify
RemovePointCloudField logic to perform a pre-validation pass when
params.throw_on_missing_field is true: iterate params.field_names and check
existence (e.g., via an existence API on pc or by querying fields) and throw via
the same THROW_EXCEPTION if any are missing, before performing any
pc->unregisterField calls; otherwise (when not throwing) keep the current
single-pass behavior and the MRPT_LOG_DEBUG_STREAM messages for removed/ignored
fields.

Comment thread mp2p_icp_filters/src/FilterRemovePointCloudField.cpp
@jlblancoc jlblancoc force-pushed the feat/filter-remove-several-point-fields branch from 6c2deae to df9eeca Compare February 16, 2026 21:25
@jlblancoc jlblancoc enabled auto-merge February 16, 2026 21:25
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.

🤖 Fix all issues with AI agents
Verify each finding against the current code and only fix it if needed.


In `@mp2p_icp_filters/src/FilterRemovePointCloudField.cpp`:
- Around line 98-123: The loop in FilterRemovePointCloudField.cpp that calls
pc->unregisterField for each entry in params.field_names can leave the
point-cloud layer partially modified when params.throw_on_missing_field is true;
change the logic so that when params.throw_on_missing_field is true you first
iterate over params.field_names to check existence (e.g., call pc->hasField or a
non-mutating check) and throw if any are missing, and only after that perform
the removals with pc->unregisterField; alternatively implement a rollback on
failure by recording removed fields and re-registering them, but prefer the
pre-validation approach for simplicity and atomic semantics.

In `@tests/test-mp2p_FilterRemovePointCloudField.cpp`:
- Around line 270-311: Add a new unit test that exercises
FilterRemovePointCloudField when throw_on_missing_field is true and the provided
sequence in p["field_names"] contains both existing and non-existing field
names: create a points map (like the existing case 10), register a subset of
fields (e.g., "field1" and "field2"), build p with p["pointcloud_layer"]="raw",
p["field_names"] as a sequence including "field1" and a nonexistent name (e.g.,
"missing_field"), set p["throw_on_missing_field"]=true, call
filter.initialize(p) and then filter.filter(map), and assert that the filter
throws (or the behavior matches the documented partial-removal behavior) and
that existing fields were removed or preserved per the expected contract;
reference FilterRemovePointCloudField, initialize(p), filter(map), and
p["field_names"]/p["throw_on_missing_field"] when adding the test.
🧹 Nitpick comments (2)
🤖 Fix all nitpicks with AI agents
Verify each finding against the current code and only fix it if needed.


In `@mp2p_icp_filters/src/FilterRemovePointCloudField.cpp`:
- Around line 98-123: The loop in FilterRemovePointCloudField.cpp that calls
pc->unregisterField for each entry in params.field_names can leave the
point-cloud layer partially modified when params.throw_on_missing_field is true;
change the logic so that when params.throw_on_missing_field is true you first
iterate over params.field_names to check existence (e.g., call pc->hasField or a
non-mutating check) and throw if any are missing, and only after that perform
the removals with pc->unregisterField; alternatively implement a rollback on
failure by recording removed fields and re-registering them, but prefer the
pre-validation approach for simplicity and atomic semantics.

In `@tests/test-mp2p_FilterRemovePointCloudField.cpp`:
- Around line 270-311: Add a new unit test that exercises
FilterRemovePointCloudField when throw_on_missing_field is true and the provided
sequence in p["field_names"] contains both existing and non-existing field
names: create a points map (like the existing case 10), register a subset of
fields (e.g., "field1" and "field2"), build p with p["pointcloud_layer"]="raw",
p["field_names"] as a sequence including "field1" and a nonexistent name (e.g.,
"missing_field"), set p["throw_on_missing_field"]=true, call
filter.initialize(p) and then filter.filter(map), and assert that the filter
throws (or the behavior matches the documented partial-removal behavior) and
that existing fields were removed or preserved per the expected contract;
reference FilterRemovePointCloudField, initialize(p), filter(map), and
p["field_names"]/p["throw_on_missing_field"] when adding the test.
mp2p_icp_filters/src/FilterRemovePointCloudField.cpp (1)

98-123: Partial removal on throw: early exception leaves map in an inconsistent state.

When throw_on_missing_field is true and multiple fields are provided, if the second field is missing but the first was already successfully removed, the exception leaves the map partially modified. Depending on whether callers expect atomic all-or-nothing semantics, this could be surprising.

Consider either:

  1. Validating all field names exist before removing any, or
  2. Documenting that removal is best-effort and fields are removed in order until an error occurs.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mp2p_icp_filters/src/FilterRemovePointCloudField.cpp` around lines 98 - 123,
The loop in FilterRemovePointCloudField.cpp that calls pc->unregisterField for
each entry in params.field_names can leave the point-cloud layer partially
modified when params.throw_on_missing_field is true; change the logic so that
when params.throw_on_missing_field is true you first iterate over
params.field_names to check existence (e.g., call pc->hasField or a non-mutating
check) and throw if any are missing, and only after that perform the removals
with pc->unregisterField; alternatively implement a rollback on failure by
recording removed fields and re-registering them, but prefer the pre-validation
approach for simplicity and atomic semantics.
tests/test-mp2p_FilterRemovePointCloudField.cpp (1)

270-311: Good addition of multi-field removal test.

Case 10 properly exercises the sequence path with mixed field types. Consider also adding a test case where throw_on_missing_field=true and a sequence contains a mix of existing and non-existing field names, to document/verify the partial-removal behavior.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/test-mp2p_FilterRemovePointCloudField.cpp` around lines 270 - 311, Add
a new unit test that exercises FilterRemovePointCloudField when
throw_on_missing_field is true and the provided sequence in p["field_names"]
contains both existing and non-existing field names: create a points map (like
the existing case 10), register a subset of fields (e.g., "field1" and
"field2"), build p with p["pointcloud_layer"]="raw", p["field_names"] as a
sequence including "field1" and a nonexistent name (e.g., "missing_field"), set
p["throw_on_missing_field"]=true, call filter.initialize(p) and then
filter.filter(map), and assert that the filter throws (or the behavior matches
the documented partial-removal behavior) and that existing fields were removed
or preserved per the expected contract; reference FilterRemovePointCloudField,
initialize(p), filter(map), and p["field_names"]/p["throw_on_missing_field"]
when adding the test.

@jlblancoc jlblancoc merged commit 2b663f5 into develop Feb 16, 2026
13 checks passed
@jlblancoc jlblancoc deleted the feat/filter-remove-several-point-fields branch February 16, 2026 21:40
@codecov
Copy link
Copy Markdown

codecov Bot commented Feb 16, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 77.49%. Comparing base (2ced976) to head (df9eeca).
⚠️ Report is 2 commits behind head on develop.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop      #42      +/-   ##
===========================================
+ Coverage    77.41%   77.49%   +0.07%     
===========================================
  Files          185      185              
  Lines         9848     9883      +35     
  Branches       931      934       +3     
===========================================
+ Hits          7624     7659      +35     
  Misses        2224     2224              
Files with missing lines Coverage Δ
...ude/mp2p_icp_filters/FilterRemovePointCloudField.h 100.00% <ø> (ø)
...2p_icp_filters/src/FilterRemovePointCloudField.cpp 97.50% <100.00%> (+0.72%) ⬆️
tests/test-mp2p_FilterRemovePointCloudField.cpp 97.57% <100.00%> (+0.45%) ⬆️
🚀 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