1 /*
2  * Software License Agreement (BSD License)
3  *
4  *  Point Cloud Library (PCL) - www.pointclouds.org
5  *  Copyright (c) 2010-2012, Willow Garage, Inc.
6  *
7  *  All rights reserved.
8  *
9  *  Redistribution and use in source and binary forms, with or without
10  *  modification, are permitted provided that the following conditions
11  *  are met:
12  *
13  *   * Redistributions of source code must retain the above copyright
14  *     notice, this list of conditions and the following disclaimer.
15  *   * Redistributions in binary form must reproduce the above
16  *     copyright notice, this list of conditions and the following
17  *     disclaimer in the documentation and/or other materials provided
18  *     with the distribution.
19  *   * Neither the name of the copyright holder(s) nor the names of its
20  *     contributors may be used to endorse or promote products derived
21  *     from this software without specific prior written permission.
22  *
23  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  *  POSSIBILITY OF SUCH DAMAGE.
35  *
36  * $Id$
37  *
38  */
39 
40 #pragma once
41 
42 #include <pcl/filters/filter_indices.h>
43 
44 namespace pcl
45 {
46   /** \brief @b ExtractIndices extracts a set of indices from a point cloud.
47     * \details Usage example:
48     * \code
49     * pcl::ExtractIndices<PointType> eifilter (true); // Initializing with true will allow us to extract the removed indices
50     * eifilter.setInputCloud (cloud_in);
51     * eifilter.setIndices (indices_in);
52     * eifilter.filter (*cloud_out);
53     * // The resulting cloud_out contains all points of cloud_in that are indexed by indices_in
54     * indices_rem = eifilter.getRemovedIndices ();
55     * // The indices_rem array indexes all points of cloud_in that are not indexed by indices_in
56     * eifilter.setNegative (true);
57     * eifilter.filter (*indices_out);
58     * // Alternatively: the indices_out array is identical to indices_rem
59     * eifilter.setNegative (false);
60     * eifilter.setUserFilterValue (1337.0);
61     * eifilter.filterDirectly (cloud_in);
62     * // This will directly modify cloud_in instead of creating a copy of the cloud
63     * // It will overwrite all fields of the filtered points by the user value: 1337
64     * \endcode
65     * \author Radu Bogdan Rusu
66     * \ingroup filters
67     */
68   template<typename PointT>
69   class ExtractIndices : public FilterIndices<PointT>
70   {
71     protected:
72       using PointCloud = typename FilterIndices<PointT>::PointCloud;
73       using PointCloudPtr = typename PointCloud::Ptr;
74       using PointCloudConstPtr = typename PointCloud::ConstPtr;
75       using FieldList = typename pcl::traits::fieldList<PointT>::type;
76 
77     public:
78 
79       using Ptr = shared_ptr<ExtractIndices<PointT> >;
80       using ConstPtr = shared_ptr<const ExtractIndices<PointT> >;
81 
82       /** \brief Constructor.
83         * \param[in] extract_removed_indices Set to true if you want to be able to extract the indices of points being removed (default = false).
84         */
85       ExtractIndices (bool extract_removed_indices = false) :
FilterIndices(extract_removed_indices)86         FilterIndices<PointT>::FilterIndices (extract_removed_indices)
87       {
88         use_indices_ = true;
89         filter_name_ = "ExtractIndices";
90       }
91 
92       /** \brief Apply the filter and store the results directly in the input cloud.
93         * \details This method will save the time and memory copy of an output cloud but can not alter the original size of the input cloud:
94         * It operates as though setKeepOrganized() is true and will overwrite the filtered points instead of remove them.
95         * All fields of filtered points are replaced with the value set by setUserFilterValue() (default = NaN).
96         * This method also automatically alters the input cloud set via setInputCloud().
97         * It does not alter the value of the internal keep organized boolean as set by setKeepOrganized().
98         * \param cloud The point cloud used for input and output.
99         */
100       void
101       filterDirectly (PointCloudPtr &cloud);
102 
103     protected:
104       using PCLBase<PointT>::input_;
105       using PCLBase<PointT>::indices_;
106       using PCLBase<PointT>::use_indices_;
107       using Filter<PointT>::filter_name_;
108       using Filter<PointT>::getClassName;
109       using FilterIndices<PointT>::negative_;
110       using FilterIndices<PointT>::keep_organized_;
111       using FilterIndices<PointT>::user_filter_value_;
112       using FilterIndices<PointT>::extract_removed_indices_;
113       using FilterIndices<PointT>::removed_indices_;
114 
115       /** \brief Filtered results are stored in a separate point cloud.
116         * \param[out] output The resultant point cloud.
117         */
118       void
119       applyFilter (PointCloud &output) override;
120 
121       /** \brief Filtered results are indexed by an indices array.
122         * \param[out] indices The resultant indices.
123         */
124       void
applyFilter(Indices & indices)125       applyFilter (Indices &indices) override
126       {
127         applyFilterIndices (indices);
128       }
129 
130       /** \brief Filtered results are indexed by an indices array.
131         * \param[out] indices The resultant indices.
132         */
133       void
134       applyFilterIndices (Indices &indices);
135   };
136 
137   //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
138   /** \brief @b ExtractIndices extracts a set of indices from a point cloud.
139     * <br>
140     * Usage examples:
141     * \code
142     * pcl::ExtractIndices<PointType> filter;
143     * filter.setInputCloud (cloud_in);
144     * filter.setIndices (indices_in);
145     * // Extract the points in cloud_in referenced by indices_in as a separate point cloud:
146     * filter.filter (*cloud_out);
147     * // Retrieve indices to all points in cloud_in except those referenced by indices_in:
148     * filter.setNegative (true);
149     * filter.filter (*indices_out);
150     * // The resulting cloud_out is identical to cloud_in, but all points referenced by indices_in are made NaN:
151     * filter.setNegative (true);
152     * filter.setKeepOrganized (true);
153     * filter.filter (*cloud_out);
154     * \endcode
155     * \note Does not inherently remove NaNs from results, hence the \a extract_removed_indices_ system is not used.
156     * \author Radu Bogdan Rusu
157     * \ingroup filters
158     */
159   template<>
160   class PCL_EXPORTS ExtractIndices<pcl::PCLPointCloud2> : public FilterIndices<pcl::PCLPointCloud2>
161   {
162     public:
163       using PCLPointCloud2 = pcl::PCLPointCloud2;
164       using PCLPointCloud2Ptr = PCLPointCloud2::Ptr;
165       using PCLPointCloud2ConstPtr = PCLPointCloud2::ConstPtr;
166 
167       /** \brief Empty constructor. */
ExtractIndices()168       ExtractIndices ()
169       {
170         use_indices_ = true;
171         filter_name_ = "ExtractIndices";
172       }
173 
174     protected:
175       using PCLBase<PCLPointCloud2>::input_;
176       using PCLBase<PCLPointCloud2>::indices_;
177       using PCLBase<PCLPointCloud2>::use_indices_;
178       using Filter<PCLPointCloud2>::filter_name_;
179       using Filter<PCLPointCloud2>::getClassName;
180       using FilterIndices<PCLPointCloud2>::negative_;
181       using FilterIndices<PCLPointCloud2>::keep_organized_;
182       using FilterIndices<PCLPointCloud2>::user_filter_value_;
183 
184       /** \brief Extract point indices into a separate PointCloud
185         * \param[out] output the resultant point cloud
186         */
187       void
188       applyFilter (PCLPointCloud2 &output) override;
189 
190       /** \brief Extract point indices
191         * \param indices the resultant indices
192         */
193       void
194       applyFilter (Indices &indices) override;
195   };
196 }
197 
198 #ifdef PCL_NO_PRECOMPILE
199 #include <pcl/filters/impl/extract_indices.hpp>
200 #endif
201