Point Cloud Library (PCL)  1.7.0
/tmp/buildd/pcl-1.7-1.7.0/surface/include/pcl/surface/mls.h
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  * Point Cloud Library (PCL) - www.pointclouds.org
00005  * Copyright (c) 2009-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 Willow Garage, Inc. 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  * $Id$
00037  *
00038  */
00039 
00040 #ifndef PCL_MLS_H_
00041 #define PCL_MLS_H_
00042 
00043 // PCL includes
00044 #include <pcl/pcl_base.h>
00045 #include <pcl/search/pcl_search.h>
00046 #include <pcl/common/common.h>
00047 
00048 #include <pcl/surface/boost.h>
00049 #include <pcl/surface/eigen.h>
00050 #include <pcl/surface/processing.h>
00051 #include <map>
00052 
00053 namespace pcl
00054 {
00055   /** \brief MovingLeastSquares represent an implementation of the MLS (Moving Least Squares) algorithm 
00056     * for data smoothing and improved normal estimation. It also contains methods for upsampling the 
00057     * resulting cloud based on the parametric fit.
00058     * Reference paper: "Computing and Rendering Point Set Surfaces" by Marc Alexa, Johannes Behr, 
00059     * Daniel Cohen-Or, Shachar Fleishman, David Levin and Claudio T. Silva
00060     * www.sci.utah.edu/~shachar/Publications/crpss.pdf
00061     * \author Zoltan Csaba Marton, Radu B. Rusu, Alexandru E. Ichim, Suat Gedikli
00062     * \ingroup surface
00063     */
00064   template <typename PointInT, typename PointOutT>
00065   class MovingLeastSquares: public CloudSurfaceProcessing<PointInT, PointOutT>
00066   {
00067     public:
00068       typedef boost::shared_ptr<MovingLeastSquares<PointInT, PointOutT> > Ptr;
00069       typedef boost::shared_ptr<const MovingLeastSquares<PointInT, PointOutT> > ConstPtr;
00070 
00071       using PCLBase<PointInT>::input_;
00072       using PCLBase<PointInT>::indices_;
00073       using PCLBase<PointInT>::fake_indices_;
00074       using PCLBase<PointInT>::initCompute;
00075       using PCLBase<PointInT>::deinitCompute;
00076 
00077       typedef typename pcl::search::Search<PointInT> KdTree;
00078       typedef typename pcl::search::Search<PointInT>::Ptr KdTreePtr;
00079       typedef pcl::PointCloud<pcl::Normal> NormalCloud;
00080       typedef pcl::PointCloud<pcl::Normal>::Ptr NormalCloudPtr;
00081 
00082       typedef pcl::PointCloud<PointOutT> PointCloudOut;
00083       typedef typename PointCloudOut::Ptr PointCloudOutPtr;
00084       typedef typename PointCloudOut::ConstPtr PointCloudOutConstPtr;
00085 
00086       typedef pcl::PointCloud<PointInT> PointCloudIn;
00087       typedef typename PointCloudIn::Ptr PointCloudInPtr;
00088       typedef typename PointCloudIn::ConstPtr PointCloudInConstPtr;
00089 
00090       typedef boost::function<int (int, double, std::vector<int> &, std::vector<float> &)> SearchMethod;
00091 
00092       enum UpsamplingMethod {NONE, DISTINCT_CLOUD, SAMPLE_LOCAL_PLANE, RANDOM_UNIFORM_DENSITY, VOXEL_GRID_DILATION};
00093 
00094       /** \brief Empty constructor. */
00095       MovingLeastSquares () : CloudSurfaceProcessing<PointInT, PointOutT> (),
00096                               normals_ (),
00097                               distinct_cloud_ (),
00098                               search_method_ (),
00099                               tree_ (),
00100                               order_ (2),
00101                               polynomial_fit_ (true),
00102                               search_radius_ (0.0),
00103                               sqr_gauss_param_ (0.0),
00104                               compute_normals_ (false),
00105                               upsample_method_ (NONE),
00106                               upsampling_radius_ (0.0),
00107                               upsampling_step_ (0.0),
00108                               desired_num_points_in_radius_ (0),
00109                               mls_results_ (),
00110                               voxel_size_ (1.0),
00111                               dilation_iteration_num_ (0),
00112                               nr_coeff_ (),
00113                               corresponding_input_indices_ (),
00114                               rng_alg_ (),
00115                               rng_uniform_distribution_ ()
00116                               {};
00117       
00118       /** \brief Empty destructor */
00119       virtual ~MovingLeastSquares () {}
00120 
00121 
00122       /** \brief Set whether the algorithm should also store the normals computed
00123         * \note This is optional, but need a proper output cloud type
00124         */
00125       inline void
00126       setComputeNormals (bool compute_normals) { compute_normals_ = compute_normals; }
00127 
00128       /** \brief Provide a pointer to the search object.
00129         * \param[in] tree a pointer to the spatial search object.
00130         */
00131       inline void
00132       setSearchMethod (const KdTreePtr &tree)
00133       {
00134         tree_ = tree;
00135         // Declare the search locator definition
00136         int (KdTree::*radiusSearch)(int index, double radius, std::vector<int> &k_indices, std::vector<float> &k_sqr_distances, unsigned int max_nn) const = &KdTree::radiusSearch;
00137         search_method_ = boost::bind (radiusSearch, boost::ref (tree_), _1, _2, _3, _4, 0);
00138       }
00139 
00140       /** \brief Get a pointer to the search method used. */
00141       inline KdTreePtr 
00142       getSearchMethod () { return (tree_); }
00143 
00144       /** \brief Set the order of the polynomial to be fit.
00145         * \param[in] order the order of the polynomial
00146         */
00147       inline void 
00148       setPolynomialOrder (int order) { order_ = order; }
00149 
00150       /** \brief Get the order of the polynomial to be fit. */
00151       inline int 
00152       getPolynomialOrder () { return (order_); }
00153 
00154       /** \brief Sets whether the surface and normal are approximated using a polynomial, or only via tangent estimation.
00155         * \param[in] polynomial_fit set to true for polynomial fit
00156         */
00157       inline void 
00158       setPolynomialFit (bool polynomial_fit) { polynomial_fit_ = polynomial_fit; }
00159 
00160       /** \brief Get the polynomial_fit value (true if the surface and normal are approximated using a polynomial). */
00161       inline bool 
00162       getPolynomialFit () { return (polynomial_fit_); }
00163 
00164       /** \brief Set the sphere radius that is to be used for determining the k-nearest neighbors used for fitting.
00165         * \param[in] radius the sphere radius that is to contain all k-nearest neighbors
00166         * \note Calling this method resets the squared Gaussian parameter to radius * radius !
00167         */
00168       inline void 
00169       setSearchRadius (double radius) { search_radius_ = radius; sqr_gauss_param_ = search_radius_ * search_radius_; }
00170 
00171       /** \brief Get the sphere radius used for determining the k-nearest neighbors. */
00172       inline double 
00173       getSearchRadius () { return (search_radius_); }
00174 
00175       /** \brief Set the parameter used for distance based weighting of neighbors (the square of the search radius works
00176         * best in general).
00177         * \param[in] sqr_gauss_param the squared Gaussian parameter
00178         */
00179       inline void 
00180       setSqrGaussParam (double sqr_gauss_param) { sqr_gauss_param_ = sqr_gauss_param; }
00181 
00182       /** \brief Get the parameter for distance based weighting of neighbors. */
00183       inline double 
00184       getSqrGaussParam () const { return (sqr_gauss_param_); }
00185 
00186       /** \brief Set the upsampling method to be used
00187         * \note Options are: * NONE - no upsampling will be done, only the input points will be projected to their own
00188         *                             MLS surfaces
00189         *                    * DISTINCT_CLOUD - will project the points of the distinct cloud to the closest point on
00190         *                                       the MLS surface
00191         *                    * SAMPLE_LOCAL_PLANE - the local plane of each input point will be sampled in a circular
00192         *                                           fashion using the \ref upsampling_radius_ and the \ref upsampling_step_
00193         *                                           parameters
00194         *                    * RANDOM_UNIFORM_DENSITY - the local plane of each input point will be sampled using an
00195         *                                               uniform random distribution such that the density of points is
00196         *                                               constant throughout the cloud - given by the \ref \ref desired_num_points_in_radius_
00197         *                                               parameter
00198         *                    * VOXEL_GRID_DILATION - the input cloud will be inserted into a voxel grid with voxels of
00199         *                                            size \ref voxel_size_; this voxel grid will be dilated \ref dilation_iteration_num_
00200         *                                            times and the resulting points will be projected to the MLS surface
00201         *                                            of the closest point in the input cloud; the result is a point cloud
00202         *                                            with filled holes and a constant point density
00203         */
00204       inline void
00205       setUpsamplingMethod (UpsamplingMethod method) { upsample_method_ = method; }
00206 
00207       /** \brief Set the distinct cloud used for the DISTINCT_CLOUD upsampling method. */
00208       inline void
00209       setDistinctCloud (PointCloudInConstPtr distinct_cloud) { distinct_cloud_ = distinct_cloud; }
00210 
00211       /** \brief Get the distinct cloud used for the DISTINCT_CLOUD upsampling method. */
00212       inline PointCloudInConstPtr
00213       getDistinctCloud () { return distinct_cloud_; }
00214 
00215 
00216       /** \brief Set the radius of the circle in the local point plane that will be sampled
00217         * \note Used only in the case of SAMPLE_LOCAL_PLANE upsampling
00218         * \param[in] radius the radius of the circle
00219         */
00220       inline void
00221       setUpsamplingRadius (double radius) { upsampling_radius_ = radius; }
00222 
00223       /** \brief Get the radius of the circle in the local point plane that will be sampled
00224         * \note Used only in the case of SAMPLE_LOCAL_PLANE upsampling
00225         */
00226       inline double
00227       getUpsamplingRadius () { return upsampling_radius_; }
00228 
00229       /** \brief Set the step size for the local plane sampling
00230         * \note Used only in the case of SAMPLE_LOCAL_PLANE upsampling
00231         * \param[in] step_size the step size
00232         */
00233       inline void
00234       setUpsamplingStepSize (double step_size) { upsampling_step_ = step_size; }
00235 
00236 
00237       /** \brief Get the step size for the local plane sampling
00238         * \note Used only in the case of SAMPLE_LOCAL_PLANE upsampling
00239         */
00240       inline double
00241       getUpsamplingStepSize () { return upsampling_step_; }
00242 
00243       /** \brief Set the parameter that specifies the desired number of points within the search radius
00244         * \note Used only in the case of RANDOM_UNIFORM_DENSITY upsampling
00245         * \param[in] desired_num_points_in_radius the desired number of points in the output cloud in a sphere of
00246         * radius \ref search_radius_ around each point
00247         */
00248       inline void
00249       setPointDensity (int desired_num_points_in_radius) { desired_num_points_in_radius_ = desired_num_points_in_radius; }
00250 
00251 
00252       /** \brief Get the parameter that specifies the desired number of points within the search radius
00253         * \note Used only in the case of RANDOM_UNIFORM_DENSITY upsampling
00254         */
00255       inline int
00256       getPointDensity () { return desired_num_points_in_radius_; }
00257 
00258       /** \brief Set the voxel size for the voxel grid
00259         * \note Used only in the VOXEL_GRID_DILATION upsampling method
00260         * \param[in] voxel_size the edge length of a cubic voxel in the voxel grid
00261         */
00262       inline void
00263       setDilationVoxelSize (float voxel_size) { voxel_size_ = voxel_size; }
00264 
00265 
00266       /** \brief Get the voxel size for the voxel grid
00267         * \note Used only in the VOXEL_GRID_DILATION upsampling method
00268         */
00269       inline float
00270       getDilationVoxelSize () { return voxel_size_; }
00271 
00272       /** \brief Set the number of dilation steps of the voxel grid
00273         * \note Used only in the VOXEL_GRID_DILATION upsampling method
00274         * \param[in] iterations the number of dilation iterations
00275         */
00276       inline void
00277       setDilationIterations (int iterations) { dilation_iteration_num_ = iterations; }
00278 
00279       /** \brief Get the number of dilation steps of the voxel grid
00280         * \note Used only in the VOXEL_GRID_DILATION upsampling method
00281         */
00282       inline int
00283       getDilationIterations () { return dilation_iteration_num_; }
00284 
00285       /** \brief Base method for surface reconstruction for all points given in <setInputCloud (), setIndices ()>
00286         * \param[out] output the resultant reconstructed surface model
00287         */
00288       void 
00289       process (PointCloudOut &output);
00290 
00291 
00292       /** \brief Get the set of indices with each point in output having the 
00293         * corresponding point in input */
00294       inline PointIndicesPtr
00295       getCorrespondingIndices () { return (corresponding_input_indices_); }
00296 
00297     protected:
00298       /** \brief The point cloud that will hold the estimated normals, if set. */
00299       NormalCloudPtr normals_;
00300 
00301       /** \brief The distinct point cloud that will be projected to the MLS surface. */
00302       PointCloudInConstPtr distinct_cloud_;
00303 
00304       /** \brief The search method template for indices. */
00305       SearchMethod search_method_;
00306 
00307       /** \brief A pointer to the spatial search object. */
00308       KdTreePtr tree_;
00309 
00310       /** \brief The order of the polynomial to be fit. */
00311       int order_;
00312 
00313       /** True if the surface and normal be approximated using a polynomial, false if tangent estimation is sufficient. */
00314       bool polynomial_fit_;
00315 
00316       /** \brief The nearest neighbors search radius for each point. */
00317       double search_radius_;
00318 
00319       /** \brief Parameter for distance based weighting of neighbors (search_radius_ * search_radius_ works fine) */
00320       double sqr_gauss_param_;
00321 
00322       /** \brief Parameter that specifies whether the normals should be computed for the input cloud or not */
00323       bool compute_normals_;
00324 
00325       /** \brief Parameter that specifies the upsampling method to be used */
00326       UpsamplingMethod upsample_method_;
00327 
00328       /** \brief Radius of the circle in the local point plane that will be sampled
00329         * \note Used only in the case of SAMPLE_LOCAL_PLANE upsampling
00330         */
00331       double upsampling_radius_;
00332 
00333       /** \brief Step size for the local plane sampling
00334         * \note Used only in the case of SAMPLE_LOCAL_PLANE upsampling
00335         */
00336       double upsampling_step_;
00337 
00338       /** \brief Parameter that specifies the desired number of points within the search radius
00339         * \note Used only in the case of RANDOM_UNIFORM_DENSITY upsampling
00340         */
00341       int desired_num_points_in_radius_;
00342 
00343       
00344       /** \brief Data structure used to store the results of the MLS fitting
00345         * \note Used only in the case of VOXEL_GRID_DILATION or DISTINCT_CLOUD upsampling
00346         */
00347       struct MLSResult
00348       {
00349         MLSResult () : mean (), plane_normal (), u_axis (), v_axis (), c_vec (), num_neighbors (), curvature (), valid (false) {}
00350 
00351         MLSResult (const Eigen::Vector3d &a_mean,
00352                    const Eigen::Vector3d &a_plane_normal,
00353                    const Eigen::Vector3d &a_u,
00354                    const Eigen::Vector3d &a_v,
00355                    const Eigen::VectorXd a_c_vec,
00356                    const int a_num_neighbors,
00357                    const float &a_curvature);
00358 
00359         Eigen::Vector3d mean, plane_normal, u_axis, v_axis;
00360         Eigen::VectorXd c_vec;
00361         int num_neighbors;
00362         float curvature;
00363         bool valid;
00364       };
00365 
00366       /** \brief Stores the MLS result for each point in the input cloud
00367         * \note Used only in the case of VOXEL_GRID_DILATION or DISTINCT_CLOUD upsampling
00368         */
00369       std::vector<MLSResult> mls_results_;
00370 
00371       
00372       /** \brief A minimalistic implementation of a voxel grid, necessary for the point cloud upsampling
00373         * \note Used only in the case of VOXEL_GRID_DILATION upsampling
00374         */
00375       class MLSVoxelGrid
00376       {
00377         public:
00378           struct Leaf { Leaf () : valid (true) {} bool valid; };
00379 
00380           MLSVoxelGrid (PointCloudInConstPtr& cloud,
00381                         IndicesPtr &indices,
00382                         float voxel_size);
00383 
00384           void
00385           dilate ();
00386 
00387           inline void
00388           getIndexIn1D (const Eigen::Vector3i &index, uint64_t &index_1d) const
00389           {
00390             index_1d = index[0] * data_size_ * data_size_ +
00391                        index[1] * data_size_ + index[2];
00392           }
00393 
00394           inline void
00395           getIndexIn3D (uint64_t index_1d, Eigen::Vector3i& index_3d) const
00396           {
00397             index_3d[0] = static_cast<Eigen::Vector3i::Scalar> (index_1d / (data_size_ * data_size_));
00398             index_1d -= index_3d[0] * data_size_ * data_size_;
00399             index_3d[1] = static_cast<Eigen::Vector3i::Scalar> (index_1d / data_size_);
00400             index_1d -= index_3d[1] * data_size_;
00401             index_3d[2] = static_cast<Eigen::Vector3i::Scalar> (index_1d);
00402           }
00403 
00404           inline void
00405           getCellIndex (const Eigen::Vector3f &p, Eigen::Vector3i& index) const
00406           {
00407             for (int i = 0; i < 3; ++i)
00408               index[i] = static_cast<Eigen::Vector3i::Scalar> ((p[i] - bounding_min_(i)) / voxel_size_);
00409           }
00410 
00411           inline void
00412           getPosition (const uint64_t &index_1d, Eigen::Vector3f &point) const
00413           {
00414             Eigen::Vector3i index_3d;
00415             getIndexIn3D (index_1d, index_3d);
00416             for (int i = 0; i < 3; ++i)
00417               point[i] = static_cast<Eigen::Vector3f::Scalar> (index_3d[i]) * voxel_size_ + bounding_min_[i];
00418           }
00419 
00420           typedef std::map<uint64_t, Leaf> HashMap;
00421           HashMap voxel_grid_;
00422           Eigen::Vector4f bounding_min_, bounding_max_;
00423           uint64_t data_size_;
00424           float voxel_size_;
00425       };
00426 
00427 
00428       /** \brief Voxel size for the VOXEL_GRID_DILATION upsampling method */
00429       float voxel_size_;
00430 
00431       /** \brief Number of dilation steps for the VOXEL_GRID_DILATION upsampling method */
00432       int dilation_iteration_num_; 
00433 
00434       /** \brief Number of coefficients, to be computed from the requested order.*/
00435       int nr_coeff_;
00436 
00437       /** \brief Collects for each point in output the corrseponding point in the input. */
00438       PointIndicesPtr corresponding_input_indices_;
00439 
00440       /** \brief Search for the closest nearest neighbors of a given point using a radius search
00441         * \param[in] index the index of the query point
00442         * \param[out] indices the resultant vector of indices representing the k-nearest neighbors
00443         * \param[out] sqr_distances the resultant squared distances from the query point to the k-nearest neighbors
00444         */
00445       inline int
00446       searchForNeighbors (int index, std::vector<int> &indices, std::vector<float> &sqr_distances) const
00447       {
00448         return (search_method_ (index, search_radius_, indices, sqr_distances));
00449       }
00450 
00451       /** \brief Smooth a given point and its neighborghood using Moving Least Squares.
00452         * \param[in] index the inex of the query point in the \ref input cloud
00453         * \param[in] nn_indices the set of nearest neighbors indices for \ref pt
00454         * \param[in] nn_sqr_dists the set of nearest neighbors squared distances for \ref pt
00455         * \param[out] projected_points the set of points projected points around the query point
00456         * (in the case of upsampling method NONE, only the query point projected to its own fitted surface will be returned,
00457         * in the case of the other upsampling methods, multiple points will be returned)
00458         * \param[out] projected_points_normals the normals corresponding to the projected points
00459         * \param[out] corresponding_input_indices the set of indices with each point in output having the corresponding point in input
00460         * \param[out] mls_result stores the MLS result for each point in the input cloud
00461         * (used only in the case of VOXEL_GRID_DILATION or DISTINCT_CLOUD upsampling)
00462         */
00463       void
00464       computeMLSPointNormal (int index,
00465                              const std::vector<int> &nn_indices,
00466                              std::vector<float> &nn_sqr_dists,
00467                              PointCloudOut &projected_points,
00468                              NormalCloud &projected_points_normals,
00469                              PointIndices &corresponding_input_indices,
00470                              MLSResult &mls_result) const;
00471 
00472       /** \brief Fits a point (sample point) given in the local plane coordinates of an input point (query point) to
00473         * the MLS surface of the input point
00474         * \param[in] u_disp the u coordinate of the sample point in the local plane of the query point
00475         * \param[in] v_disp the v coordinate of the sample point in the local plane of the query point
00476         * \param[in] u the axis corresponding to the u-coordinates of the local plane of the query point
00477         * \param[in] v the axis corresponding to the v-coordinates of the local plane of the query point
00478         * \param[in] plane_normal the normal to the local plane of the query point
00479         * \param[in] curvature the curvature of the surface at the query point
00480         * \param[in] query_point the absolute 3D position of the query point
00481         * \param[in] c_vec the coefficients of the polynomial fit on the MLS surface of the query point
00482         * \param[in] num_neighbors the number of neighbors of the query point in the input cloud
00483         * \param[out] result_point the absolute 3D position of the resulting projected point
00484         * \param[out] result_normal the normal of the resulting projected point
00485         */
00486       void
00487       projectPointToMLSSurface (float &u_disp, float &v_disp,
00488                                 Eigen::Vector3d &u_axis, Eigen::Vector3d &v_axis,
00489                                 Eigen::Vector3d &n_axis,
00490                                 Eigen::Vector3d &mean,
00491                                 float &curvature,
00492                                 Eigen::VectorXd &c_vec,
00493                                 int num_neighbors,
00494                                 PointOutT &result_point,
00495                                 pcl::Normal &result_normal) const;
00496 
00497       void
00498       copyMissingFields (const PointInT &point_in,
00499                          PointOutT &point_out) const;
00500 
00501       /** \brief Abstract surface reconstruction method. 
00502         * \param[out] output the result of the reconstruction 
00503         */
00504       virtual void performProcessing (PointCloudOut &output);
00505 
00506       /** \brief Perform upsampling for the distinct-cloud and voxel-grid methods
00507         * \param[out] output the result of the reconstruction
00508        */
00509       void performUpsampling (PointCloudOut &output);
00510 
00511     private:
00512       /** \brief Boost-based random number generator algorithm. */
00513       boost::mt19937 rng_alg_;
00514 
00515       /** \brief Random number generator using an uniform distribution of floats
00516         * \note Used only in the case of RANDOM_UNIFORM_DENSITY upsampling
00517         */
00518       boost::shared_ptr<boost::variate_generator<boost::mt19937&, 
00519                                                  boost::uniform_real<float> > 
00520                        > rng_uniform_distribution_;
00521 
00522       /** \brief Abstract class get name method. */
00523       std::string getClassName () const { return ("MovingLeastSquares"); }
00524       
00525     public:
00526         EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00527   };
00528 
00529 #ifdef _OPENMP
00530   /** \brief MovingLeastSquaresOMP is a parallelized version of MovingLeastSquares, using the OpenMP standard.
00531    * \note Compared to MovingLeastSquares, an overhead is incurred in terms of runtime and memory usage.
00532    * \note The upsampling methods DISTINCT_CLOUD and VOXEL_GRID_DILATION are not parallelized completely, i.e. parts of the algorithm run on a single thread only.
00533    * \author Robert Huitl
00534    * \ingroup surface
00535    */
00536   template <typename PointInT, typename PointOutT>
00537   class MovingLeastSquaresOMP: public MovingLeastSquares<PointInT, PointOutT>
00538   {
00539     public:
00540       typedef boost::shared_ptr<MovingLeastSquares<PointInT, PointOutT> > Ptr;
00541       typedef boost::shared_ptr<const MovingLeastSquares<PointInT, PointOutT> > ConstPtr;
00542 
00543       using PCLBase<PointInT>::input_;
00544       using PCLBase<PointInT>::indices_;
00545       using MovingLeastSquares<PointInT, PointOutT>::normals_;
00546       using MovingLeastSquares<PointInT, PointOutT>::corresponding_input_indices_;
00547       using MovingLeastSquares<PointInT, PointOutT>::nr_coeff_;
00548       using MovingLeastSquares<PointInT, PointOutT>::order_;
00549       using MovingLeastSquares<PointInT, PointOutT>::compute_normals_;
00550 
00551       typedef pcl::PointCloud<pcl::Normal> NormalCloud;
00552       typedef pcl::PointCloud<pcl::Normal>::Ptr NormalCloudPtr;
00553 
00554       typedef pcl::PointCloud<PointOutT> PointCloudOut;
00555       typedef typename PointCloudOut::Ptr PointCloudOutPtr;
00556       typedef typename PointCloudOut::ConstPtr PointCloudOutConstPtr;
00557 
00558       /** \brief Constructor for parallelized Moving Least Squares
00559         * \param threads the maximum number of hardware threads to use (0 sets the value to 1)
00560         */
00561       MovingLeastSquaresOMP (unsigned int threads = 0) : threads_ (threads)
00562       {
00563 
00564       }
00565 
00566       /** \brief Set the maximum number of threads to use
00567         * \param threads the maximum number of hardware threads to use (0 sets the value to 1)
00568         */
00569       inline void
00570       setNumberOfThreads (unsigned int threads = 0)
00571       {
00572         threads_ = threads;
00573       }
00574 
00575     protected:
00576       /** \brief Abstract surface reconstruction method.
00577         * \param[out] output the result of the reconstruction
00578         */
00579       virtual void performProcessing (PointCloudOut &output);
00580 
00581       /** \brief The maximum number of threads the scheduler should use. */
00582       unsigned int threads_;
00583   };
00584 #endif
00585 }
00586 
00587 #ifdef PCL_NO_PRECOMPILE
00588 #include <pcl/surface/impl/mls.hpp>
00589 #endif
00590 
00591 #endif  /* #ifndef PCL_MLS_H_ */