Point Cloud Library (PCL)  1.7.0
/tmp/buildd/pcl-1.7-1.7.0/filters/include/pcl/filters/conditional_removal.h
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2010, Willow Garage, Inc.
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of the copyright holder(s) nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  *
00034  * $Id$
00035  *
00036  */
00037 
00038 #ifndef PCL_FILTER_FIELD_VAL_CONDITION_H_
00039 #define PCL_FILTER_FIELD_VAL_CONDITION_H_
00040 #include <pcl/common/eigen.h>
00041 #include <pcl/filters/filter.h>
00042 
00043 namespace pcl
00044 {
00045   //////////////////////////////////////////////////////////////////////////////////////////
00046   namespace ComparisonOps
00047   {
00048     /** \brief The kind of comparison operations that are possible within a 
00049       * comparison object
00050       */
00051     typedef enum
00052     {
00053       GT, GE, LT, LE, EQ
00054     } CompareOp;
00055   }
00056 
00057   //////////////////////////////////////////////////////////////////////////////////////////
00058   /** \brief A datatype that enables type-correct comparisons. */
00059   template<typename PointT>
00060   class PointDataAtOffset
00061   {
00062     public:
00063       /** \brief Constructor. */
00064       PointDataAtOffset (uint8_t datatype, uint32_t offset) :
00065         datatype_ (datatype), offset_ (offset)
00066       {
00067       }
00068 
00069       /** \brief Compare function. 
00070         * \param p the point to compare
00071         * \param val the value to compare the point to
00072         */
00073       int
00074       compare (const PointT& p, const double& val);
00075     protected:
00076       /** \brief The type of data. */
00077       uint8_t datatype_;
00078 
00079       /** \brief The data offset. */
00080       uint32_t offset_;
00081     private:
00082       PointDataAtOffset () : datatype_ (), offset_ () {}
00083   };
00084 
00085   //////////////////////////////////////////////////////////////////////////////////////////
00086   /** \brief The (abstract) base class for the comparison object. */
00087   template<typename PointT>
00088   class ComparisonBase
00089   {
00090     public:
00091       typedef boost::shared_ptr< ComparisonBase<PointT> > Ptr;
00092       typedef boost::shared_ptr< const ComparisonBase<PointT> > ConstPtr;
00093 
00094       /** \brief Constructor. */
00095       ComparisonBase () : capable_ (false), field_name_ (), offset_ (), op_ () {}
00096 
00097       /** \brief Destructor. */
00098       virtual ~ComparisonBase () {}
00099 
00100       /** \brief Return if the comparison is capable. */
00101       inline bool
00102       isCapable () const
00103       {
00104         return (capable_);
00105       }
00106 
00107       /** \brief Evaluate function. */
00108       virtual bool
00109       evaluate (const PointT &point) const = 0;
00110 
00111     protected:
00112       /** \brief True if capable. */
00113       bool capable_;
00114 
00115       /** \brief Field name to compare data on. */
00116       std::string field_name_;
00117 
00118       /** \brief The data offset. */
00119       uint32_t offset_;
00120 
00121       /** \brief The comparison operator type. */
00122       ComparisonOps::CompareOp op_;
00123   };
00124 
00125   //////////////////////////////////////////////////////////////////////////////////////////
00126   /** \brief The field-based specialization of the comparison object. */
00127   template<typename PointT>
00128   class FieldComparison : public ComparisonBase<PointT>
00129   {
00130     using ComparisonBase<PointT>::field_name_;
00131     using ComparisonBase<PointT>::op_;
00132     using ComparisonBase<PointT>::capable_;
00133 
00134     public:
00135       typedef boost::shared_ptr< FieldComparison<PointT> > Ptr;
00136       typedef boost::shared_ptr< const FieldComparison<PointT> > ConstPtr;
00137 
00138 
00139       /** \brief Construct a FieldComparison
00140         * \param field_name the name of the field that contains the data we want to compare
00141         * \param op the operator to use when making the comparison
00142         * \param compare_val the constant value to compare the field value too
00143         */
00144       FieldComparison (std::string field_name, ComparisonOps::CompareOp op, double compare_val);
00145 
00146       /** \brief Copy constructor.
00147         * \param[in] src the field comparison object to copy into this
00148         */
00149       FieldComparison (const FieldComparison &src) 
00150         : ComparisonBase<PointT> ()
00151         , compare_val_ (src.compare_val_), point_data_ (src.point_data_)
00152       {
00153       }
00154 
00155       /** \brief Copy operator.
00156         * \param[in] src the field comparison object to copy into this
00157         */
00158       inline FieldComparison&
00159       operator = (const FieldComparison &src)
00160       {
00161         compare_val_ = src.compare_val_;
00162         point_data_  = src.point_data_;
00163         return (*this);
00164       }
00165 
00166       /** \brief Destructor. */
00167       virtual ~FieldComparison ();
00168 
00169       /** \brief Determine the result of this comparison.  
00170         * \param point the point to evaluate
00171         * \return the result of this comparison.
00172         */
00173       virtual bool
00174       evaluate (const PointT &point) const;
00175 
00176     protected:
00177       /** \brief All types (that we care about) can be represented as a double. */
00178       double compare_val_;
00179 
00180       /** \brief The point data to compare. */
00181       PointDataAtOffset<PointT>* point_data_;
00182 
00183     private:
00184       FieldComparison () :
00185         compare_val_ (), point_data_ ()
00186       {
00187       } // not allowed
00188   };
00189 
00190   //////////////////////////////////////////////////////////////////////////////////////////
00191   /** \brief A packed rgb specialization of the comparison object. */
00192   template<typename PointT>
00193   class PackedRGBComparison : public ComparisonBase<PointT>
00194   {
00195     using ComparisonBase<PointT>::capable_;
00196     using ComparisonBase<PointT>::op_;
00197 
00198     public:
00199       typedef boost::shared_ptr< PackedRGBComparison<PointT> > Ptr;
00200       typedef boost::shared_ptr< const PackedRGBComparison<PointT> > ConstPtr;
00201 
00202       /** \brief Construct a PackedRGBComparison
00203         * \param component_name either "r", "g" or "b"
00204         * \param op the operator to use when making the comparison
00205         * \param compare_val the constant value to compare the component value too
00206         */
00207       PackedRGBComparison (std::string component_name, ComparisonOps::CompareOp op, double compare_val);
00208 
00209       /** \brief Destructor. */
00210       virtual ~PackedRGBComparison () {}
00211 
00212       /** \brief Determine the result of this comparison.  
00213         * \param point the point to evaluate
00214         * \return the result of this comparison.
00215         */
00216       virtual bool
00217       evaluate (const PointT &point) const;
00218 
00219     protected:
00220       /** \brief The name of the component. */
00221       std::string component_name_;
00222 
00223       /** \brief The offset of the component */
00224       uint32_t component_offset_;
00225 
00226       /** \brief All types (that we care about) can be represented as a double. */
00227       double compare_val_;
00228 
00229     private:
00230       PackedRGBComparison () :
00231         component_name_ (), component_offset_ (), compare_val_ ()
00232       {
00233       } // not allowed
00234 
00235   };
00236 
00237   //////////////////////////////////////////////////////////////////////////////////////////
00238   /** \brief A packed HSI specialization of the comparison object. */
00239   template<typename PointT>
00240   class PackedHSIComparison : public ComparisonBase<PointT>
00241   {
00242     using ComparisonBase<PointT>::capable_;
00243     using ComparisonBase<PointT>::op_;
00244 
00245     public:
00246       typedef boost::shared_ptr< PackedHSIComparison<PointT> > Ptr;
00247       typedef boost::shared_ptr< const PackedHSIComparison<PointT> > ConstPtr;
00248  
00249       /** \brief Construct a PackedHSIComparison 
00250         * \param component_name either "h", "s" or "i"
00251         * \param op the operator to use when making the comparison
00252         * \param compare_val the constant value to compare the component value too
00253         */
00254       PackedHSIComparison (std::string component_name, ComparisonOps::CompareOp op, double compare_val);
00255 
00256       /** \brief Destructor. */
00257       virtual ~PackedHSIComparison () {}
00258 
00259       /** \brief Determine the result of this comparison.  
00260         * \param point the point to evaluate
00261         * \return the result of this comparison.
00262         */
00263       virtual bool
00264       evaluate (const PointT &point) const;
00265 
00266       typedef enum
00267       {
00268         H, // -128 to 127 corresponds to -pi to pi
00269         S, // 0 to 255
00270         I  // 0 to 255
00271       } ComponentId;
00272 
00273     protected:
00274       /** \brief The name of the component. */
00275       std::string component_name_;
00276 
00277       /** \brief The ID of the component. */
00278       ComponentId component_id_;
00279 
00280       /** \brief All types (that we care about) can be represented as a double. */
00281       double compare_val_;
00282 
00283       /** \brief The offset of the component */
00284       uint32_t rgb_offset_;
00285 
00286     private:
00287       PackedHSIComparison () :
00288         component_name_ (), component_id_ (), compare_val_ (), rgb_offset_ ()
00289       {
00290       } // not allowed
00291   };
00292   
00293   //////////////////////////////////////////////////////////////////////////////////////////
00294   /**\brief A comparison whether the (x,y,z) components of a given point satisfy (p'Ap + 2v'p + c [OP] 0).
00295    * Here [OP] stands for the defined pcl::ComparisonOps, i.e. for GT, GE, LT, LE or EQ;
00296    * p = (x,y,z) is a point of the point cloud; A is 3x3 matrix; v is the 3x1 vector; c is a scalar.
00297    *  
00298    * One can also use TfQuadraticXYZComparison for simpler geometric shapes by defining the
00299    * quadratic parts (i.e. the matrix A) to be zero. By combining different instances of
00300    * TfQuadraticXYZComparison one can get more complex shapes. For example, to have a simple
00301    * cylinder (along the x-axis) of specific length one needs three comparisons combined as AND condition:
00302    *   1. The cylinder: A = [0 0 0, 0 1 0, 0 0 1]; v = [0, 0, 0]; c = radius²; OP = LT (meaning "<")
00303    *   2. X-min limit: A = 0; v = [1, 0, 0]; c = x_min; OP = GT
00304    *   3. X-max ...
00305    *
00306    * \author Julian Löchner
00307    */
00308   template<typename PointT>
00309   class TfQuadraticXYZComparison : public pcl::ComparisonBase<PointT>
00310   {
00311     public:
00312       EIGEN_MAKE_ALIGNED_OPERATOR_NEW     //needed whenever there is a fixed size Eigen:: vector or matrix in a class
00313 
00314       typedef boost::shared_ptr<TfQuadraticXYZComparison<PointT> > Ptr;
00315       typedef boost::shared_ptr<const TfQuadraticXYZComparison<PointT> > ConstPtr;
00316 
00317       /** \brief Constructor.
00318        */
00319       TfQuadraticXYZComparison ();
00320       
00321       /** \brief Empty destructor */
00322       virtual ~TfQuadraticXYZComparison () {}
00323 
00324       /** \brief Constructor.
00325        * \param op the operator "[OP]" of the comparison "p'Ap + 2v'p + c [OP] 0".
00326        * \param comparison_matrix the matrix "A" of the comparison "p'Ap + 2v'p + c [OP] 0".
00327        * \param comparison_vector the vector "v" of the comparison "p'Ap + 2v'p + c [OP] 0".
00328        * \param comparison_scalar the scalar "c" of the comparison "p'Ap + 2v'p + c [OP] 0".
00329        * \param comparison_transform the transformation of the comparison.
00330        */
00331       TfQuadraticXYZComparison (const pcl::ComparisonOps::CompareOp op, const Eigen::Matrix3f &comparison_matrix,
00332                                 const Eigen::Vector3f &comparison_vector, const float &comparison_scalar,
00333                                 const Eigen::Affine3f &comparison_transform = Eigen::Affine3f::Identity ());
00334 
00335       /** \brief set the operator "[OP]" of the comparison "p'Ap + 2v'p + c [OP] 0".
00336        */
00337       inline void
00338       setComparisonOperator (const pcl::ComparisonOps::CompareOp op)
00339       {
00340         op_ = op;
00341       }
00342 
00343       /** \brief set the matrix "A" of the comparison "p'Ap + 2v'p + c [OP] 0".
00344        */
00345       inline void
00346       setComparisonMatrix (const Eigen::Matrix3f &matrix)
00347       {
00348         //define comp_matr_ as an homogeneous matrix of the given matrix
00349         comp_matr_.block<3, 3> (0, 0) = matrix;
00350         comp_matr_.col (3) << 0, 0, 0, 1;
00351         comp_matr_.block<1, 3> (3, 0) << 0, 0, 0;
00352         tf_comp_matr_ = comp_matr_;
00353       }
00354 
00355       /** \brief set the matrix "A" of the comparison "p'Ap + 2v'p + c [OP] 0".
00356        */
00357       inline void
00358       setComparisonMatrix (const Eigen::Matrix4f &homogeneousMatrix)
00359       {
00360         comp_matr_ = homogeneousMatrix;
00361         tf_comp_matr_ = comp_matr_;
00362       }
00363 
00364       /** \brief set the vector "v" of the comparison "p'Ap + 2v'p + c [OP] 0".
00365        */
00366       inline void
00367       setComparisonVector (const Eigen::Vector3f &vector)
00368       {
00369         comp_vect_ = vector.homogeneous ();
00370         tf_comp_vect_ = comp_vect_;
00371       }
00372 
00373       /** \brief set the vector "v" of the comparison "p'Ap + 2v'p + c [OP] 0".
00374        */
00375       inline void
00376       setComparisonVector (const Eigen::Vector4f &homogeneousVector)
00377       {
00378         comp_vect_ = homogeneousVector;
00379         tf_comp_vect_ = comp_vect_;
00380       }
00381 
00382       /** \brief set the scalar "c" of the comparison "p'Ap + 2v'p + c [OP] 0".
00383        */
00384       inline void
00385       setComparisonScalar (const float &scalar)
00386       {
00387         comp_scalar_ = scalar;
00388       }
00389 
00390       /** \brief transform the coordinate system of the comparison. If you think of
00391        * the transformation to be a translation and rotation of the comparison in the
00392        * same coordinate system, you have to provide the inverse transformation.
00393        * This function does not change the original definition of the comparison. Thus,
00394        * each call of this function will assume the original definition of the comparison
00395        * as starting point for the transformation.
00396        *
00397        * @param transform the transformation (rotation and translation) as an affine matrix.
00398        */
00399       inline void
00400       transformComparison (const Eigen::Matrix4f &transform)
00401       {
00402         tf_comp_matr_ = transform.transpose () * comp_matr_ * transform;
00403         tf_comp_vect_ = comp_vect_.transpose () * transform;
00404       }
00405 
00406       /** \brief transform the coordinate system of the comparison. If you think of
00407        * the transformation to be a translation and rotation of the comparison in the
00408        * same coordinate system, you have to provide the inverse transformation.
00409        * This function does not change the original definition of the comparison. Thus,
00410        * each call of this function will assume the original definition of the comparison
00411        * as starting point for the transformation.
00412        *
00413        * @param transform the transformation (rotation and translation) as an affine matrix.
00414        */
00415       inline void
00416       transformComparison (const Eigen::Affine3f &transform)
00417       {
00418         transformComparison (transform.matrix ());
00419       }
00420 
00421       /** \brief Determine the result of this comparison.
00422        * \param point the point to evaluate
00423        * \return the result of this comparison.
00424        */
00425       virtual bool
00426       evaluate (const PointT &point) const;
00427 
00428     protected:
00429       using pcl::ComparisonBase<PointT>::capable_;
00430       using pcl::ComparisonBase<PointT>::op_;
00431 
00432       Eigen::Matrix4f comp_matr_;
00433       Eigen::Vector4f comp_vect_;
00434 
00435       float comp_scalar_;
00436 
00437     private:
00438       Eigen::Matrix4f tf_comp_matr_;
00439       Eigen::Vector4f tf_comp_vect_;
00440   };
00441   
00442   //////////////////////////////////////////////////////////////////////////////////////////
00443   /** \brief Base condition class. */
00444   template<typename PointT>
00445   class ConditionBase
00446   {
00447     public:
00448       typedef typename pcl::ComparisonBase<PointT> ComparisonBase;
00449       typedef typename ComparisonBase::Ptr ComparisonBasePtr;
00450       typedef typename ComparisonBase::ConstPtr ComparisonBaseConstPtr;
00451 
00452       typedef boost::shared_ptr<ConditionBase<PointT> > Ptr;
00453       typedef boost::shared_ptr<const ConditionBase<PointT> > ConstPtr;
00454 
00455       /** \brief Constructor. */
00456       ConditionBase () : capable_ (true), comparisons_ (), conditions_ ()
00457       {
00458       }
00459 
00460       /** \brief Destructor. */
00461       virtual ~ConditionBase ()
00462       {
00463         // comparisons are boost::shared_ptr.will take care of themselves
00464         comparisons_.clear ();
00465 
00466         // conditions are boost::shared_ptr. will take care of themselves
00467         conditions_.clear ();
00468       }
00469 
00470       /** \brief Add a new comparison
00471         * \param comparison the comparison operator to add
00472         */
00473       void
00474       addComparison (ComparisonBaseConstPtr comparison);
00475 
00476       /** \brief Add a nested condition to this condition.  
00477         * \param condition the nested condition to be added
00478         */
00479       void
00480       addCondition (Ptr condition);
00481 
00482       /** \brief Check if evaluation requirements are met. */
00483       inline bool
00484       isCapable () const
00485       {
00486         return (capable_);
00487       }
00488 
00489       /** \brief Determine if a point meets this condition.  
00490         * \return whether the point meets this condition.
00491         */
00492       virtual bool
00493       evaluate (const PointT &point) const = 0;
00494 
00495     protected:
00496       /** \brief True if capable. */
00497       bool capable_;
00498 
00499       /** \brief The collection of all comparisons that need to be verified. */
00500       std::vector<ComparisonBaseConstPtr> comparisons_;
00501 
00502       /** \brief The collection of all conditions that need to be verified. */
00503       std::vector<Ptr> conditions_;
00504   };
00505 
00506   //////////////////////////////////////////////////////////////////////////////////////////
00507   /** \brief AND condition. */
00508   template<typename PointT>
00509   class ConditionAnd : public ConditionBase<PointT>
00510   {
00511     using ConditionBase<PointT>::conditions_;
00512     using ConditionBase<PointT>::comparisons_;
00513 
00514     public:
00515       typedef boost::shared_ptr<ConditionAnd<PointT> > Ptr;
00516       typedef boost::shared_ptr<const ConditionAnd<PointT> > ConstPtr;
00517 
00518       /** \brief Constructor. */
00519       ConditionAnd () :
00520         ConditionBase<PointT> ()
00521       {
00522       }
00523 
00524       /** \brief Determine if a point meets this condition.  
00525         * \return whether the point meets this condition.
00526         *
00527         * The ConditionAnd evaluates to true when ALL
00528         * comparisons and nested conditions evaluate to true
00529         */
00530       virtual bool
00531       evaluate (const PointT &point) const;
00532   };
00533 
00534   //////////////////////////////////////////////////////////////////////////////////////////
00535   /** \brief OR condition. */
00536   template<typename PointT>
00537   class ConditionOr : public ConditionBase<PointT>
00538   {
00539     using ConditionBase<PointT>::conditions_;
00540     using ConditionBase<PointT>::comparisons_;
00541 
00542     public:
00543       typedef boost::shared_ptr<ConditionOr<PointT> > Ptr;
00544       typedef boost::shared_ptr<const ConditionOr<PointT> > ConstPtr;
00545 
00546       /** \brief Constructor. */
00547       ConditionOr () :
00548         ConditionBase<PointT> ()
00549       {
00550       }
00551 
00552       /** \brief Determine if a point meets this condition.  
00553         * \return whether the point meets this condition.
00554         *
00555         * The ConditionOr evaluates to true when ANY
00556         * comparisons or nested conditions evaluate to true
00557         */
00558       virtual bool
00559       evaluate (const PointT &point) const;
00560   };
00561 
00562   //////////////////////////////////////////////////////////////////////////////////////////
00563   /** \brief @b ConditionalRemoval filters data that satisfies certain conditions.
00564     *
00565     * A ConditionalRemoval must be provided a condition. There are two types of
00566     * conditions: ConditionAnd and ConditionOr. Conditions require one or more
00567     * comparisons and/or other conditions. A comparison has a name, a
00568     * comparison operator, and a value.
00569     *
00570     * An ConditionAnd will evaluate to true when ALL of its encapsulated
00571     * comparisons and conditions are true.
00572     *
00573     * An ConditionOr will evaluate to true when ANY of its encapsulated
00574     * comparisons and conditions are true.
00575     *
00576     * Depending on the derived type of the comparison, the name can correspond
00577     * to a PointCloud field name, or a color component in rgb color space or
00578     * hsi color space.
00579     *
00580     * Here is an example usage:
00581     *  // Build the condition
00582     *  pcl::ConditionAnd<PointT>::Ptr range_cond (new pcl::ConditionAnd<PointT> ());
00583     *  range_cond->addComparison (pcl::FieldComparison<PointT>::Ptr (new pcl::FieldComparison<PointT>("z", pcl::ComparisonOps::LT, 2.0)));
00584     *  range_cond->addComparison (pcl::FieldComparison<PointT>::Ptr (new pcl::FieldComparison<PointT>("z", pcl::ComparisonOps::GT, 0.0)));
00585     *  // Build the filter
00586     *  pcl::ConditionalRemoval<PointT> range_filt;
00587     *  range_filt.setCondition (range_cond);
00588     *  range_filt.setKeepOrganized (false);
00589     *
00590     * \author Louis LeGrand, Intel Labs Seattle
00591     * \ingroup filters
00592     */
00593   template<typename PointT>
00594   class ConditionalRemoval : public Filter<PointT>
00595   {
00596     using Filter<PointT>::input_;
00597     using Filter<PointT>::filter_name_;
00598     using Filter<PointT>::getClassName;
00599 
00600     using Filter<PointT>::removed_indices_;
00601     using Filter<PointT>::extract_removed_indices_;
00602 
00603     typedef typename Filter<PointT>::PointCloud PointCloud;
00604     typedef typename PointCloud::Ptr PointCloudPtr;
00605     typedef typename PointCloud::ConstPtr PointCloudConstPtr;
00606 
00607     public:
00608       typedef typename pcl::ConditionBase<PointT> ConditionBase;
00609       typedef typename ConditionBase::Ptr ConditionBasePtr;
00610       typedef typename ConditionBase::ConstPtr ConditionBaseConstPtr;
00611 
00612       /** \brief the default constructor.  
00613         *
00614         * All ConditionalRemovals require a condition which can be set
00615         * using the setCondition method
00616         * \param extract_removed_indices extract filtered indices from indices vector
00617         */
00618       ConditionalRemoval (int extract_removed_indices = false) :
00619         Filter<PointT>::Filter (extract_removed_indices), capable_ (false), keep_organized_ (false), condition_ (),
00620         user_filter_value_ (std::numeric_limits<float>::quiet_NaN ())
00621       {
00622         filter_name_ = "ConditionalRemoval";
00623       }
00624 
00625       /** \brief a constructor that includes the condition.  
00626         * \param condition the condition that each point must satisfy to avoid
00627         * being removed by the filter
00628         * \param extract_removed_indices extract filtered indices from indices vector
00629         */
00630       ConditionalRemoval (ConditionBasePtr condition, bool extract_removed_indices = false) :
00631         Filter<PointT>::Filter (extract_removed_indices), capable_ (false), keep_organized_ (false), condition_ (),
00632         user_filter_value_ (std::numeric_limits<float>::quiet_NaN ())
00633       {
00634         filter_name_ = "ConditionalRemoval";
00635         setCondition (condition);
00636       }
00637 
00638       /** \brief Set whether the filtered points should be kept and set to the
00639         * value given through \a setUserFilterValue (default: NaN), or removed
00640         * from the PointCloud, thus potentially breaking its organized
00641         * structure. By default, points are removed.
00642         *
00643         * \param val set to true whether the filtered points should be kept and
00644         * set to a given user value (default: NaN)
00645         */
00646       inline void
00647       setKeepOrganized (bool val)
00648       {
00649         keep_organized_ = val;
00650       }
00651 
00652       inline bool
00653       getKeepOrganized () const
00654       {
00655         return (keep_organized_);
00656       }
00657 
00658       /** \brief Provide a value that the filtered points should be set to
00659         * instead of removing them.  Used in conjunction with \a
00660         * setKeepOrganized ().
00661         * \param val the user given value that the filtered point dimensions should be set to
00662         */
00663       inline void
00664       setUserFilterValue (float val)
00665       {
00666         user_filter_value_ = val;
00667       }
00668 
00669       /** \brief Set the condition that the filter will use.  
00670         * \param condition each point must satisfy this condition to avoid
00671         * being removed by the filter
00672         *
00673         * All ConditionalRemovals require a condition
00674         */
00675       void
00676       setCondition (ConditionBasePtr condition);
00677 
00678     protected:
00679       /** \brief Filter a Point Cloud.
00680         * \param output the resultant point cloud message
00681         */
00682       void
00683       applyFilter (PointCloud &output);
00684 
00685       typedef typename pcl::traits::fieldList<PointT>::type FieldList;
00686 
00687       /** \brief True if capable. */
00688       bool capable_;
00689 
00690       /** \brief Keep the structure of the data organized, by setting the
00691         * filtered points to the a user given value (NaN by default).
00692         */
00693       bool keep_organized_;
00694 
00695       /** \brief The condition to use for filtering */
00696       ConditionBasePtr condition_;
00697 
00698       /** \brief User given value to be set to any filtered point. Casted to
00699         * the correct field type. 
00700         */
00701       float user_filter_value_;
00702   };
00703 }
00704 
00705 #ifdef PCL_NO_PRECOMPILE
00706 #include <pcl/filters/impl/conditional_removal.hpp>
00707 #endif
00708 
00709 #endif