Point Cloud Library (PCL)  1.7.0
/tmp/buildd/pcl-1.7-1.7.0/filters/include/pcl/filters/crop_hull.h
00001  /*
00002   * Software License Agreement (BSD License)
00003   *
00004   *  Point Cloud Library (PCL) - www.pointclouds.org
00005   *  Copyright (c) 2011, Willow Garage, Inc.
00006   *
00007   *  All rights reserved.
00008   *
00009   *  Redistribution and use in source and binary forms, with or without
00010   *  modification, are permitted provided that the following conditions
00011   *  are met:
00012   *
00013   *   * Redistributions of source code must retain the above copyright
00014   *     notice, this list of conditions and the following disclaimer.
00015   *   * Redistributions in binary form must reproduce the above
00016   *     copyright notice, this list of conditions and the following
00017   *     disclaimer in the documentation and/or other materials provided
00018   *     with the distribution.
00019   *   * Neither the name of the copyright holder(s) nor the names of its
00020   *     contributors may be used to endorse or promote products derived
00021   *     from this software without specific prior written permission.
00022   *
00023   *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00024   *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00025   *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00026   *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00027   *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00028   *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00029   *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030   *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00031   *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032   *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00033   *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00034   *  POSSIBILITY OF SUCH DAMAGE.
00035   *
00036   */
00037 
00038 #ifndef PCL_FILTERS_CROP_HULL_H_
00039 #define PCL_FILTERS_CROP_HULL_H_
00040 
00041 #include <pcl/point_types.h>
00042 #include <pcl/Vertices.h>
00043 #include <pcl/filters/filter_indices.h>
00044 
00045 namespace pcl
00046 {
00047   /** \brief Filter points that lie inside or outside a 3D closed surface or 2D
00048     * closed polygon, as generated by the ConvexHull or ConcaveHull classes.
00049     * \author James Crosby
00050     * \ingroup filters
00051     */
00052   template<typename PointT>
00053   class CropHull: public FilterIndices<PointT>
00054   {
00055     using Filter<PointT>::filter_name_;
00056     using Filter<PointT>::indices_;
00057     using Filter<PointT>::input_;
00058     
00059     typedef typename Filter<PointT>::PointCloud PointCloud;
00060     typedef typename PointCloud::Ptr PointCloudPtr;
00061     typedef typename PointCloud::ConstPtr PointCloudConstPtr;
00062 
00063     public:
00064 
00065       typedef boost::shared_ptr< CropHull<PointT> > Ptr;
00066       typedef boost::shared_ptr< const CropHull<PointT> > ConstPtr;
00067 
00068       /** \brief Empty Constructor. */
00069       CropHull () :
00070         hull_polygons_(),
00071         hull_cloud_(),
00072         dim_(3),
00073         crop_outside_(true)
00074       {
00075         filter_name_ = "CropHull";
00076       }
00077 
00078       /** \brief Set the vertices of the hull used to filter points.
00079         * \param[in] polygons Vector of polygons (Vertices structures) forming
00080         * the hull used for filtering points.
00081         */
00082       inline void
00083       setHullIndices (const std::vector<Vertices>& polygons)
00084       {
00085         hull_polygons_ = polygons;
00086       }
00087 
00088       /** \brief Get the vertices of the hull used to filter points.
00089         */
00090       std::vector<Vertices>
00091       getHullIndices () const
00092       {
00093         return (hull_polygons_);
00094       }
00095       
00096       /** \brief Set the point cloud that the hull indices refer to
00097         * \param[in] points the point cloud that the hull indices refer to
00098         */
00099       inline void
00100       setHullCloud (PointCloudPtr points)
00101       {
00102         hull_cloud_ = points;
00103       }
00104 
00105       /** \brief Get the point cloud that the hull indices refer to. */
00106       PointCloudPtr
00107       getHullCloud () const
00108       {
00109         return (hull_cloud_);
00110       }
00111     
00112       /** \brief Set the dimensionality of the hull to be used.
00113         * This should be set to correspond to the dimensionality of the
00114         * convex/concave hull produced by the pcl::ConvexHull and
00115         * pcl::ConcaveHull classes.
00116         * \param[in] dim Dimensionailty of the hull used to filter points.
00117         */
00118       inline void
00119       setDim (int dim)
00120       {
00121         dim_ = dim;
00122       }
00123       
00124       /** \brief Remove points outside the hull (default), or those inside the hull.
00125         * \param[in] crop_outside If true, the filter will remove points
00126         * outside the hull. If false, those inside will be removed.
00127         */
00128       inline void
00129       setCropOutside(bool crop_outside)
00130       {
00131         crop_outside_ = crop_outside;
00132       }
00133 
00134     protected:
00135       /** \brief Filter the input points using the 2D or 3D polygon hull.
00136         * \param[out] output The set of points that passed the filter
00137         */
00138       void
00139       applyFilter (PointCloud &output);
00140 
00141       /** \brief Filter the input points using the 2D or 3D polygon hull.
00142         * \param[out] indices the indices of the set of points that passed the filter.
00143         */
00144       void        
00145       applyFilter (std::vector<int> &indices);
00146 
00147     private:  
00148       /** \brief Return the size of the hull point cloud in line with coordinate axes.
00149         * This is used to choose the 2D projection to use when cropping to a 2d
00150         * polygon.
00151         */
00152       Eigen::Vector3f
00153       getHullCloudRange ();
00154       
00155       /** \brief Apply the two-dimensional hull filter.
00156         * All points are assumed to lie in the same plane as the 2D hull, an
00157         * axis-aligned 2D coordinate system using the two dimensions specified
00158         * (PlaneDim1, PlaneDim2) is used for calculations.
00159         * \param[out] output The set of points that pass the 2D polygon filter.
00160         */
00161       template<unsigned PlaneDim1, unsigned PlaneDim2> void
00162       applyFilter2D (PointCloud &output); 
00163 
00164       /** \brief Apply the two-dimensional hull filter.
00165         * All points are assumed to lie in the same plane as the 2D hull, an
00166         * axis-aligned 2D coordinate system using the two dimensions specified
00167         * (PlaneDim1, PlaneDim2) is used for calculations.
00168         * \param[out] indices The indices of the set of points that pass the
00169         *                     2D polygon filter.
00170         */
00171       template<unsigned PlaneDim1, unsigned PlaneDim2> void
00172       applyFilter2D (std::vector<int> &indices);
00173 
00174        /** \brief Apply the three-dimensional hull filter.
00175          * Polygon-ray crossings are used for three rays cast from each point
00176          * being tested, and a  majority vote of the resulting
00177          * polygon-crossings is used to decide  whether the point lies inside
00178          * or outside the hull.
00179          * \param[out] output The set of points that pass the 3D polygon hull
00180          *                    filter.
00181          */
00182       void
00183       applyFilter3D (PointCloud &output);
00184 
00185       /** \brief Apply the three-dimensional hull filter.
00186         *  Polygon-ray crossings are used for three rays cast from each point
00187         *  being tested, and a  majority vote of the resulting
00188         *  polygon-crossings is used to decide  whether the point lies inside
00189         *  or outside the hull.
00190         * \param[out] indices The indices of the set of points that pass the 3D
00191         *                     polygon hull filter.
00192         */
00193       void
00194       applyFilter3D (std::vector<int> &indices);
00195 
00196       /** \brief Test an individual point against a 2D polygon.
00197         * PlaneDim1 and PlaneDim2 specify the x/y/z coordinate axes to use.
00198         * \param[in] point Point to test against the polygon.
00199         * \param[in] verts Vertex indices of polygon.
00200         * \param[in] cloud Cloud from which the vertex indices are drawn.
00201         */
00202       template<unsigned PlaneDim1, unsigned PlaneDim2> inline static bool
00203       isPointIn2DPolyWithVertIndices (const PointT& point,
00204                                       const Vertices& verts,
00205                                       const PointCloud& cloud);
00206 
00207       /** \brief Does a ray cast from a point intersect with an arbitrary
00208         * triangle in 3D?
00209         * See: http://softsurfer.com/Archive/algorithm_0105/algorithm_0105.htm#intersect_RayTriangle()
00210         * \param[in] point Point from which the ray is cast.
00211         * \param[in] ray   Vector in direction of ray.
00212         * \param[in] verts Indices of vertices making the polygon.
00213         * \param[in] cloud Cloud from which the vertex indices are drawn.
00214         */
00215       inline static bool
00216       rayTriangleIntersect (const PointT& point,
00217                             const Eigen::Vector3f& ray,
00218                             const Vertices& verts,
00219                             const PointCloud& cloud);
00220 
00221 
00222       /** \brief The vertices of the hull used to filter points. */
00223       std::vector<pcl::Vertices> hull_polygons_;
00224 
00225       /** \brief The point cloud that the hull indices refer to. */
00226       PointCloudPtr hull_cloud_;
00227 
00228       /** \brief The dimensionality of the hull to be used. */
00229       int dim_;
00230 
00231       /** \brief If true, the filter will remove points outside the hull. If
00232        * false, those inside will be removed.
00233        */
00234       bool crop_outside_;
00235   };
00236 
00237 } // namespace pcl
00238 
00239 #ifdef PCL_NO_PRECOMPILE
00240 #include <pcl/filters/impl/crop_hull.hpp>
00241 #endif
00242 
00243 #endif // ifndef PCL_FILTERS_CROP_HULL_H_