Skip to content

Extend BruteForce search to non-XYZ point types - #6457

Open
jeevan6996 wants to merge 4 commits into
PointCloudLibrary:masterfrom
jeevan6996:extend-bruteforce-nonxyz-points
Open

Extend BruteForce search to non-XYZ point types#6457
jeevan6996 wants to merge 4 commits into
PointCloudLibrary:masterfrom
jeevan6996:extend-bruteforce-nonxyz-points

Conversation

@jeevan6996

Copy link
Copy Markdown

Summary

  • add PointRepresentation support to BruteForce search
  • keep the existing fast XYZ distance path when the representation is trivial 3D
  • use full DefaultFeatureRepresentation dimensions for descriptor point types where available
  • allow autoSelectMethod to fall back to BruteForce when FLANN/Nanoflann are unavailable
  • add focused BruteForce tests for custom representations, FPFH descriptors, and sparse invalid descriptors

Fixes #6421.

Validation

  • configured a focused local build with search/tests enabled
  • built target: cmake --build /private/tmp/pcl-bruteforce-build-6 --target test_brute_force_search
  • ran: ctest --test-dir /private/tmp/pcl-bruteforce-build-6/test -R brute_force_search --output-on-failure
  • ran: git diff --check

@jeevan6996

Copy link
Copy Markdown
Author

The CI linker failures were caused by AutoSelectMethod being explicitly instantiated for every PCL_POINT_TYPES, while BruteForce was precompiled only for the XYZ and descriptor subsets. That left symbols undefined for types such as SHOT352, Normal, and PointUV when the fallback was selected.

Updated search/src/brute_force.cpp to instantiate BruteForce for PCL_POINT_TYPES, keeping both instantiation sets aligned. Verified locally with Homebrew LLVM: pcl_search builds, test_brute_force_search links, and all 3 focused tests pass.

Comment thread search/include/pcl/search/brute_force.h Outdated
Comment on lines +66 to +69
if constexpr (!pcl::traits::has_xyz_v<PointT> && has_descriptor_size<PointT>::value)
return (pcl::make_shared<DefaultFeatureRepresentation<PointT>> ());
else
return (pcl::make_shared<DefaultPointRepresentation<PointT>> ());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for this pull request. Could you please explain why you did this condition, since none of the other search methods do it like this?

@jeevan6996

Copy link
Copy Markdown
Author

Thanks. I checked the other search implementations and they default to DefaultPointRepresentation, which is limited to the first three float values unless a type-specific specialization exists.

This condition is intentional for BruteForce’s new non-XYZ descriptor support: types with descriptorSize need DefaultFeatureRepresentation so all descriptor dimensions are included in distance calculations. XYZ and ordinary point types retain the existing default behavior, and callers can still override the representation explicitly. Tests cover both descriptor and custom representations.

template <typename PointT> bool
pcl::search::BruteForce<PointT>::isValidPoint (const PointT& point) const
{
if constexpr (pcl::traits::has_xyz_v<PointT>)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

The new custom-representation path is not used by isValidPoint() for point types with XYZ traits:

if constexpr (pcl::traits::has_xyz_v<PointT>)
  return (pcl::isFinite (point));

This still validates x/y/z even when setPointRepresentation() installs a representation that intentionally uses a different subset of fields. For example, a representation that uses only x/y should be able to search a point whose z is NaN, but this causes the query assertion to fail (and causes sparse searches to skip the point). This also differs from the representation-based validity behavior used by the other search implementations.

Could this use point_representation_->isValid(point) consistently, with a regression test using a custom representation that ignores an invalid XYZ field?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Sounds good to me, then there is even no point in having the isValidPoint function, instead point_representation_->isValid(point) can be checked inline.

@mvieth

mvieth commented Aug 14, 2026

Copy link
Copy Markdown
Member

Thanks. I checked the other search implementations and they default to DefaultPointRepresentation, which is limited to the first three float values unless a type-specific specialization exists.

This condition is intentional for BruteForce’s new non-XYZ descriptor support: types with descriptorSize need DefaultFeatureRepresentation so all descriptor dimensions are included in distance calculations. XYZ and ordinary point types retain the existing default behavior, and callers can still override the representation explicitly. Tests cover both descriptor and custom representations.

I just checked all types for which specializations of descriptorSize exist, and I identified several types where specializations of DefaultPointRepresentation exist and it is thus wrong to use DefaultFeatureRepresentation (e.g. ShapeContext1980). So I would suggest to just use DefaultPointRepresentation, not DefaultFeatureRepresentation, in BruteForce, to stay consistent with KdTree search and others.

But I have also identified four types which are missing a specialization of DefaultPointRepresentation in point_representation.h, so the following should be added to point_representation.h:

  template <>
  class DefaultPointRepresentation<GRSDSignature21> : public DefaultFeatureRepresentation <GRSDSignature21>
  {};

  template <>
  class DefaultPointRepresentation<BRISKSignature512> : public DefaultFeatureRepresentation <BRISKSignature512>
  {};

  template <>
  class DefaultPointRepresentation<ESFSignature640> : public DefaultFeatureRepresentation <ESFSignature640>
  {};

  template <>
  class DefaultPointRepresentation<GFPFHSignature16> : public DefaultFeatureRepresentation <GFPFHSignature16>
  {};

Can you do that? Thanks.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Help wanted: Extend BruteForce search to point types without xyz

2 participants