Point Cloud Library (PCL)  1.14.0-dev
functor_filter.h
1 /*
2  * SPDX-License-Identifier: BSD-3-Clause
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (c) 2020-, Open Perception
6  *
7  * All rights reserved
8  */
9 
10 #pragma once
11 
12 #include <pcl/filters/filter_indices.h>
13 #include <pcl/type_traits.h> // for is_invocable
14 
15 namespace pcl {
16 namespace experimental {
17 /**
18  * \brief Checks if the function object meets the usage in `FunctorFilter` class
19  * \details `Function` needs to be callable with a const reference to a PointCloud
20  * and an index value. The return type should be implicitly convertible to a boolean
21  */
22 template <typename PointT, typename Function>
23 constexpr static bool is_function_object_for_filter_v =
24  is_invocable_r_v<bool, Function, const PointCloud<PointT>&, index_t>;
25 
26 namespace advanced {
27 /**
28  * \brief Filter point clouds and indices based on a function object passed in the ctor
29  * \details The function object can be anything (lambda, std::function, invocable class,
30  * etc.) that can be moved into the class. Additionally, it must satisfy the condition
31  * `is_function_object_for_filter_v`
32  * \ingroup filters
33  */
34 template <typename PointT, typename FunctionObject>
35 class FunctorFilter : public FilterIndices<PointT> {
37  using PCL_Base = PCLBase<PointT>;
38 
39 public:
40  using FunctionObjectT = FunctionObject;
41  // using in type would complicate signature
42  static_assert(is_function_object_for_filter_v<PointT, FunctionObjectT>,
43  "Function object signature must be similar to `bool(const "
44  "PointCloud<PointT>&, index_t)`");
45 
46 protected:
48  using Base::filter_name_;
49  using Base::negative_;
51  using PCL_Base::indices_;
52  using PCL_Base::input_;
53 
54 private:
55  // need to hold a value because lambdas can only be copy or move constructed in C++14
56  FunctionObjectT functionObject_;
57 
58 public:
59  /** \brief Constructor.
60  * \param[in] function_object Object of effective type `FilterFunction` in order to
61  * filter out the indices for which it returns false
62  * \param[in] extract_removed_indices Set to true if you want to be able to
63  * extract the indices of points being removed (default = false).
64  */
65  FunctorFilter(FunctionObjectT function_object, bool extract_removed_indices = false)
66  : Base(extract_removed_indices), functionObject_(std::move(function_object))
67  {
68  filter_name_ = "functor_filter";
69  }
70 
71  const FunctionObjectT&
72  getFunctionObject() const noexcept
73  {
74  return functionObject_;
75  }
76 
78  getFunctionObject() noexcept
79  {
80  return functionObject_;
81  }
82 
83  /**
84  * \brief Filtered results are indexed by an indices array.
85  * \param[out] indices The resultant indices.
86  */
87  void
88  applyFilter(Indices& indices) override
89  {
90  indices.clear();
91  indices.reserve(indices_->size());
93  removed_indices_->clear();
94  removed_indices_->reserve(indices_->size());
95  }
96 
97  for (const auto index : *indices_) {
98  // function object returns true for points that should be selected
99  if (negative_ != functionObject_(*input_, index)) {
100  indices.push_back(index);
101  }
102  else if (extract_removed_indices_) {
103  removed_indices_->push_back(index);
104  }
105  }
106  }
107 
108 protected:
109  /**
110  * \brief ctor to be used by derived classes with member function as FilterFunction
111  * \param[in] extract_removed_indices Set to true if you want to be able to
112  * extract the indices of points being removed (default = false).
113  * \note The class would be ill-defined until `setFunctionObject` has been called
114  * Do not call any filter routine until then
115  */
116  FunctorFilter(bool extract_removed_indices = false) : Base(extract_removed_indices)
117  {
118  filter_name_ = "functor_filter";
119  }
120 
121  /**
122  * \brief utility function for derived class
123  * \param[in] function_object Object of effective type `FilterFunction` in order to
124  * filter out the indices for which it returns false
125  */
126  void
127  setFunctionObject(FunctionObjectT function_object) const noexcept
128  {
129  functionObject_ = std::move(function_object);
130  }
131 };
132 } // namespace advanced
133 
134 template <class PointT>
135 using FilterFunction = std::function<bool(const PointCloud<PointT>&, index_t)>;
136 
137 template <class PointT>
139 } // namespace experimental
140 } // namespace pcl
bool extract_removed_indices_
Set to true if we want to return the indices of the removed points.
Definition: filter.h:161
std::string filter_name_
The filter name.
Definition: filter.h:158
IndicesPtr removed_indices_
Indices of the points that are removed.
Definition: filter.h:155
FilterIndices represents the base class for filters that are about binary point removal.
bool negative_
False = normal filter behavior (default), true = inverted behavior.
PCL base class.
Definition: pcl_base.h:70
PointCloudConstPtr input_
The input point cloud dataset.
Definition: pcl_base.h:147
IndicesPtr indices_
A pointer to the vector of point indices to use.
Definition: pcl_base.h:150
PointCloud represents the base class in PCL for storing collections of 3D points.
Definition: point_cloud.h:173
Filter point clouds and indices based on a function object passed in the ctor.
void applyFilter(Indices &indices) override
Filtered results are indexed by an indices array.
PointCloudConstPtr input_
The input point cloud dataset.
Definition: pcl_base.h:147
FunctorFilter(FunctionObjectT function_object, bool extract_removed_indices=false)
Constructor.
FunctorFilter(bool extract_removed_indices=false)
ctor to be used by derived classes with member function as FilterFunction
bool negative_
False = normal filter behavior (default), true = inverted behavior.
const FunctionObjectT & getFunctionObject() const noexcept
IndicesPtr indices_
A pointer to the vector of point indices to use.
Definition: pcl_base.h:150
void setFunctionObject(FunctionObjectT function_object) const noexcept
utility function for derived class
FunctionObjectT & getFunctionObject() noexcept
std::function< bool(const PointCloud< PointT > &, index_t)> FilterFunction
constexpr static bool is_function_object_for_filter_v
Checks if the function object meets the usage in FunctorFilter class.
detail::int_type_t< detail::index_type_size, detail::index_type_signed > index_t
Type used for an index in PCL.
Definition: types.h:112
IndicesAllocator<> Indices
Type used for indices in PCL.
Definition: types.h:133