Point Cloud Library (PCL)  1.7.0
/tmp/buildd/pcl-1.7-1.7.0/octree/include/pcl/octree/octree_pointcloud.h
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Point Cloud Library (PCL) - www.pointclouds.org
00005  *  Copyright (c) 2010-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 #ifndef PCL_OCTREE_POINTCLOUD_H
00040 #define PCL_OCTREE_POINTCLOUD_H
00041 
00042 #include "octree_base.h"
00043 //#include "octree2buf_base.h"
00044 
00045 #include <pcl/point_cloud.h>
00046 #include <pcl/point_types.h>
00047 
00048 #include <queue>
00049 #include <vector>
00050 #include <algorithm>
00051 #include <iostream>
00052 
00053 namespace pcl
00054 {
00055   namespace octree
00056   {
00057 
00058     //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00059     /** \brief @b Octree pointcloud class
00060      *  \note Octree implementation for pointclouds. Only indices are stored by the octree leaf nodes (zero-copy).
00061      *  \note The octree pointcloud class needs to be initialized with its voxel resolution. Its bounding box is automatically adjusted
00062      *  \note according to the pointcloud dimension or it can be predefined.
00063      *  \note Note: The tree depth equates to the resolution and the bounding box dimensions of the octree.
00064      *  \note
00065      *  \note typename: PointT: type of point used in pointcloud
00066      *  \note typename: LeafContainerT:  leaf node container (
00067      *  \note typename: BranchContainerT:  branch node container
00068      *  \note typename: OctreeT: octree implementation ()
00069      *  \ingroup octree
00070      *  \author Julius Kammerl (julius@kammerl.de)
00071      */
00072     //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00073     template<typename PointT, typename LeafContainerT = OctreeContainerPointIndices,
00074         typename BranchContainerT = OctreeContainerEmpty,
00075         typename OctreeT = OctreeBase<LeafContainerT, BranchContainerT> >
00076 
00077     class OctreePointCloud : public OctreeT
00078     {
00079         // iterators are friends
00080         friend class OctreeIteratorBase<OctreeT> ;
00081         friend class OctreeDepthFirstIterator<OctreeT> ;
00082         friend class OctreeBreadthFirstIterator<OctreeT> ;
00083         friend class OctreeLeafNodeIterator<OctreeT> ;
00084 
00085       public:
00086         typedef OctreeT Base;
00087 
00088         typedef typename OctreeT::LeafNode LeafNode;
00089         typedef typename OctreeT::BranchNode BranchNode;
00090 
00091         // Octree default iterators
00092         typedef OctreeDepthFirstIterator<OctreeT> Iterator;
00093         typedef const OctreeDepthFirstIterator<OctreeT> ConstIterator;
00094 
00095         // Octree leaf node iterators
00096         typedef OctreeLeafNodeIterator<OctreeT> LeafNodeIterator;
00097         typedef const OctreeLeafNodeIterator<OctreeT> ConstLeafNodeIterator;
00098 
00099         // Octree depth-first iterators
00100         typedef OctreeDepthFirstIterator<OctreeT> DepthFirstIterator;
00101         typedef const OctreeDepthFirstIterator<OctreeT> ConstDepthFirstIterator;
00102 
00103         // Octree breadth-first iterators
00104         typedef OctreeBreadthFirstIterator<OctreeT> BreadthFirstIterator;
00105         typedef const OctreeBreadthFirstIterator<OctreeT> ConstBreadthFirstIterator;
00106 
00107         /** \brief Octree pointcloud constructor.
00108          * \param[in] resolution_arg octree resolution at lowest octree level
00109          */
00110         OctreePointCloud (const double resolution_arg);
00111 
00112         /** \brief Empty deconstructor. */
00113         virtual
00114         ~OctreePointCloud ();
00115 
00116         // public typedefs
00117         typedef boost::shared_ptr<std::vector<int> > IndicesPtr;
00118         typedef boost::shared_ptr<const std::vector<int> > IndicesConstPtr;
00119 
00120         typedef pcl::PointCloud<PointT> PointCloud;
00121         typedef boost::shared_ptr<PointCloud> PointCloudPtr;
00122         typedef boost::shared_ptr<const PointCloud> PointCloudConstPtr;
00123 
00124         // public typedefs for single/double buffering
00125         typedef OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeBase<LeafContainerT> > SingleBuffer;
00126        // typedef OctreePointCloud<PointT, LeafContainerT, BranchContainerT, Octree2BufBase<LeafContainerT> > DoubleBuffer;
00127 
00128         // Boost shared pointers
00129         typedef boost::shared_ptr<OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeT> > Ptr;
00130         typedef boost::shared_ptr<const OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeT> > ConstPtr;
00131 
00132         // Eigen aligned allocator
00133         typedef std::vector<PointT, Eigen::aligned_allocator<PointT> > AlignedPointTVector;
00134         typedef std::vector<PointXYZ, Eigen::aligned_allocator<PointXYZ> > AlignedPointXYZVector;
00135 
00136         /** \brief Provide a pointer to the input data set.
00137          * \param[in] cloud_arg the const boost shared pointer to a PointCloud message
00138          * \param[in] indices_arg the point indices subset that is to be used from \a cloud - if 0 the whole point cloud is used
00139          */
00140         inline void setInputCloud (const PointCloudConstPtr &cloud_arg,
00141             const IndicesConstPtr &indices_arg = IndicesConstPtr ())
00142         {
00143           input_ = cloud_arg;
00144           indices_ = indices_arg;
00145         }
00146 
00147         /** \brief Get a pointer to the vector of indices used.
00148          * \return pointer to vector of indices used.
00149          */
00150         inline IndicesConstPtr const getIndices () const
00151         {
00152           return (indices_);
00153         }
00154 
00155         /** \brief Get a pointer to the input point cloud dataset.
00156          * \return pointer to pointcloud input class.
00157          */
00158         inline PointCloudConstPtr getInputCloud () const
00159         {
00160           return (input_);
00161         }
00162 
00163         /** \brief Set the search epsilon precision (error bound) for nearest neighbors searches.
00164          * \param[in] eps precision (error bound) for nearest neighbors searches
00165          */
00166         inline void setEpsilon (double eps)
00167         {
00168           epsilon_ = eps;
00169         }
00170 
00171         /** \brief Get the search epsilon precision (error bound) for nearest neighbors searches. */
00172         inline double getEpsilon () const
00173         {
00174           return (epsilon_);
00175         }
00176 
00177         /** \brief Set/change the octree voxel resolution
00178          * \param[in] resolution_arg side length of voxels at lowest tree level
00179          */
00180         inline void setResolution (double resolution_arg)
00181         {
00182           // octree needs to be empty to change its resolution
00183           assert( this->leaf_count_ == 0);
00184 
00185           resolution_ = resolution_arg;
00186 
00187           getKeyBitSize ();
00188         }
00189 
00190         /** \brief Get octree voxel resolution
00191          * \return voxel resolution at lowest tree level
00192          */
00193         inline double getResolution () const
00194         {
00195           return (resolution_);
00196         }
00197 
00198         /** \brief Get the maximum depth of the octree.
00199          *  \return depth_arg: maximum depth of octree
00200          * */
00201         inline unsigned int getTreeDepth () const
00202         {
00203           return this->octree_depth_;
00204         }
00205 
00206         /** \brief Add points from input point cloud to octree. */
00207         void
00208         addPointsFromInputCloud ();
00209 
00210         /** \brief Add point at given index from input point cloud to octree. Index will be also added to indices vector.
00211          * \param[in] point_idx_arg index of point to be added
00212          * \param[in] indices_arg pointer to indices vector of the dataset (given by \a setInputCloud)
00213          */
00214         void
00215         addPointFromCloud (const int point_idx_arg, IndicesPtr indices_arg);
00216 
00217         /** \brief Add point simultaneously to octree and input point cloud.
00218          *  \param[in] point_arg point to be added
00219          *  \param[in] cloud_arg pointer to input point cloud dataset (given by \a setInputCloud)
00220          */
00221         void
00222         addPointToCloud (const PointT& point_arg, PointCloudPtr cloud_arg);
00223 
00224         /** \brief Add point simultaneously to octree and input point cloud. A corresponding index will be added to the indices vector.
00225          * \param[in] point_arg point to be added
00226          * \param[in] cloud_arg pointer to input point cloud dataset (given by \a setInputCloud)
00227          * \param[in] indices_arg pointer to indices vector of the dataset (given by \a setInputCloud)
00228          */
00229         void
00230         addPointToCloud (const PointT& point_arg, PointCloudPtr cloud_arg, IndicesPtr indices_arg);
00231 
00232         /** \brief Check if voxel at given point exist.
00233          * \param[in] point_arg point to be checked
00234          * \return "true" if voxel exist; "false" otherwise
00235          */
00236         bool
00237         isVoxelOccupiedAtPoint (const PointT& point_arg) const;
00238 
00239         /** \brief Delete the octree structure and its leaf nodes.
00240          * */
00241         void deleteTree ()
00242         {
00243           // reset bounding box
00244           min_x_ = min_y_ = max_y_ = min_z_ = max_z_ = 0;
00245           this->bounding_box_defined_ = false;
00246 
00247           OctreeT::deleteTree ();
00248         }
00249 
00250         /** \brief Check if voxel at given point coordinates exist.
00251          * \param[in] point_x_arg X coordinate of point to be checked
00252          * \param[in] point_y_arg Y coordinate of point to be checked
00253          * \param[in] point_z_arg Z coordinate of point to be checked
00254          * \return "true" if voxel exist; "false" otherwise
00255          */
00256         bool
00257         isVoxelOccupiedAtPoint (const double point_x_arg, const double point_y_arg, const double point_z_arg) const;
00258 
00259         /** \brief Check if voxel at given point from input cloud exist.
00260          * \param[in] point_idx_arg point to be checked
00261          * \return "true" if voxel exist; "false" otherwise
00262          */
00263         bool
00264         isVoxelOccupiedAtPoint (const int& point_idx_arg) const;
00265 
00266         /** \brief Get a PointT vector of centers of all occupied voxels.
00267          * \param[out] voxel_center_list_arg results are written to this vector of PointT elements
00268          * \return number of occupied voxels
00269          */
00270         int
00271         getOccupiedVoxelCenters (AlignedPointTVector &voxel_center_list_arg) const;
00272 
00273         /** \brief Get a PointT vector of centers of voxels intersected by a line segment.
00274          * This returns a approximation of the actual intersected voxels by walking
00275          * along the line with small steps. Voxels are ordered, from closest to
00276          * furthest w.r.t. the origin.
00277          * \param[in] origin origin of the line segment
00278          * \param[in] end end of the line segment
00279          * \param[out] voxel_center_list results are written to this vector of PointT elements
00280          * \param[in] precision determines the size of the steps: step_size = octree_resolution x precision
00281          * \return number of intersected voxels
00282          */
00283         int
00284         getApproxIntersectedVoxelCentersBySegment (
00285             const Eigen::Vector3f& origin, const Eigen::Vector3f& end,
00286             AlignedPointTVector &voxel_center_list, float precision = 0.2);
00287 
00288         /** \brief Delete leaf node / voxel at given point
00289          * \param[in] point_arg point addressing the voxel to be deleted.
00290          */
00291         void
00292         deleteVoxelAtPoint (const PointT& point_arg);
00293 
00294         /** \brief Delete leaf node / voxel at given point from input cloud
00295          *  \param[in] point_idx_arg index of point addressing the voxel to be deleted.
00296          */
00297         void
00298         deleteVoxelAtPoint (const int& point_idx_arg);
00299 
00300         //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00301         // Bounding box methods
00302         //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00303 
00304         /** \brief Investigate dimensions of pointcloud data set and define corresponding bounding box for octree. */
00305         void
00306         defineBoundingBox ();
00307 
00308         /** \brief Define bounding box for octree
00309          * \note Bounding box cannot be changed once the octree contains elements.
00310          * \param[in] min_x_arg X coordinate of lower bounding box corner
00311          * \param[in] min_y_arg Y coordinate of lower bounding box corner
00312          * \param[in] min_z_arg Z coordinate of lower bounding box corner
00313          * \param[in] max_x_arg X coordinate of upper bounding box corner
00314          * \param[in] max_y_arg Y coordinate of upper bounding box corner
00315          * \param[in] max_z_arg Z coordinate of upper bounding box corner
00316          */
00317         void
00318         defineBoundingBox (const double min_x_arg, const double min_y_arg, const double min_z_arg,
00319                            const double max_x_arg, const double max_y_arg, const double max_z_arg);
00320 
00321         /** \brief Define bounding box for octree
00322          * \note Lower bounding box point is set to (0, 0, 0)
00323          * \note Bounding box cannot be changed once the octree contains elements.
00324          * \param[in] max_x_arg X coordinate of upper bounding box corner
00325          * \param[in] max_y_arg Y coordinate of upper bounding box corner
00326          * \param[in] max_z_arg Z coordinate of upper bounding box corner
00327          */
00328         void
00329         defineBoundingBox (const double max_x_arg, const double max_y_arg, const double max_z_arg);
00330 
00331         /** \brief Define bounding box cube for octree
00332          * \note Lower bounding box corner is set to (0, 0, 0)
00333          * \note Bounding box cannot be changed once the octree contains elements.
00334          * \param[in] cubeLen_arg side length of bounding box cube.
00335          */
00336         void
00337         defineBoundingBox (const double cubeLen_arg);
00338 
00339         /** \brief Get bounding box for octree
00340          * \note Bounding box cannot be changed once the octree contains elements.
00341          * \param[in] min_x_arg X coordinate of lower bounding box corner
00342          * \param[in] min_y_arg Y coordinate of lower bounding box corner
00343          * \param[in] min_z_arg Z coordinate of lower bounding box corner
00344          * \param[in] max_x_arg X coordinate of upper bounding box corner
00345          * \param[in] max_y_arg Y coordinate of upper bounding box corner
00346          * \param[in] max_z_arg Z coordinate of upper bounding box corner
00347          */
00348         void
00349         getBoundingBox (double& min_x_arg, double& min_y_arg, double& min_z_arg,
00350                         double& max_x_arg, double& max_y_arg, double& max_z_arg) const;
00351 
00352         /** \brief Calculates the squared diameter of a voxel at given tree depth
00353          * \param[in] tree_depth_arg depth/level in octree
00354          * \return squared diameter
00355          */
00356         double
00357         getVoxelSquaredDiameter (unsigned int tree_depth_arg) const;
00358 
00359         /** \brief Calculates the squared diameter of a voxel at leaf depth
00360          * \return squared diameter
00361          */
00362         inline double
00363         getVoxelSquaredDiameter () const
00364         {
00365           return getVoxelSquaredDiameter (this->octree_depth_);
00366         }
00367 
00368         /** \brief Calculates the squared voxel cube side length at given tree depth
00369          * \param[in] tree_depth_arg depth/level in octree
00370          * \return squared voxel cube side length
00371          */
00372         double
00373         getVoxelSquaredSideLen (unsigned int tree_depth_arg) const;
00374 
00375         /** \brief Calculates the squared voxel cube side length at leaf level
00376          * \return squared voxel cube side length
00377          */
00378         inline double getVoxelSquaredSideLen () const
00379         {
00380           return getVoxelSquaredSideLen (this->octree_depth_);
00381         }
00382 
00383         /** \brief Generate bounds of the current voxel of an octree iterator
00384          * \param[in] iterator: octree iterator
00385          * \param[out] min_pt lower bound of voxel
00386          * \param[out] max_pt upper bound of voxel
00387          */
00388         inline void
00389         getVoxelBounds (OctreeIteratorBase<OctreeT>& iterator, Eigen::Vector3f &min_pt, Eigen::Vector3f &max_pt)
00390         {
00391           this->genVoxelBoundsFromOctreeKey (iterator.getCurrentOctreeKey (),
00392               iterator.getCurrentOctreeDepth (), min_pt, max_pt);
00393         }
00394 
00395         /** \brief Enable dynamic octree structure
00396          *  \note Leaf nodes are kept as close to the root as possible and are only expanded if the number of DataT objects within a leaf node exceeds a fixed limit.
00397          *  \param maxObjsPerLeaf: maximum number of DataT objects per leaf
00398          * */
00399         inline void
00400         enableDynamicDepth ( size_t maxObjsPerLeaf )
00401         {
00402           assert(this->leaf_count_==0);
00403           max_objs_per_leaf_ = maxObjsPerLeaf;
00404 
00405           this->dynamic_depth_enabled_ = static_cast<bool> (max_objs_per_leaf_>0);
00406         }
00407 
00408 
00409       protected:
00410 
00411         /** \brief Add point at index from input pointcloud dataset to octree
00412          * \param[in] point_idx_arg the index representing the point in the dataset given by \a setInputCloud to be added
00413          */
00414         virtual void
00415         addPointIdx (const int point_idx_arg);
00416 
00417         /** \brief Add point at index from input pointcloud dataset to octree
00418          * \param[in] leaf_node to be expanded
00419          * \param[in] parent_branch parent of leaf node to be expanded
00420          * \param[in] child_idx child index of leaf node (in parent branch)
00421          * \param[in] depth_mask of leaf node to be expanded
00422          */
00423         void
00424         expandLeafNode (LeafNode* leaf_node, BranchNode* parent_branch, unsigned char child_idx, unsigned int depth_mask);
00425 
00426         /** \brief Get point at index from input pointcloud dataset
00427          * \param[in] index_arg index representing the point in the dataset given by \a setInputCloud
00428          * \return PointT from input pointcloud dataset
00429          */
00430         const PointT&
00431         getPointByIndex (const unsigned int index_arg) const;
00432 
00433         /** \brief Find octree leaf node at a given point
00434          * \param[in] point_arg query point
00435          * \return pointer to leaf node. If leaf node does not exist, pointer is 0.
00436          */
00437         LeafContainerT*
00438         findLeafAtPoint (const PointT& point_arg) const
00439         {
00440           OctreeKey key;
00441 
00442           // generate key for point
00443           this->genOctreeKeyforPoint (point_arg, key);
00444 
00445           return (this->findLeaf (key));
00446         }
00447 
00448         //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00449         // Protected octree methods based on octree keys
00450         //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00451 
00452         /** \brief Define octree key setting and octree depth based on defined bounding box. */
00453         void
00454         getKeyBitSize ();
00455 
00456         /** \brief Grow the bounding box/octree until point fits
00457          * \param[in] point_idx_arg point that should be within bounding box;
00458          */
00459         void
00460         adoptBoundingBoxToPoint (const PointT& point_idx_arg);
00461 
00462         /** \brief Checks if given point is within the bounding box of the octree
00463          * \param[in] point_idx_arg point to be checked for bounding box violations
00464          * \return "true" - no bound violation
00465          */
00466         inline bool isPointWithinBoundingBox (const PointT& point_idx_arg) const
00467         {
00468           return (! ( (point_idx_arg.x < min_x_) || (point_idx_arg.y < min_y_)
00469                    || (point_idx_arg.z < min_z_) || (point_idx_arg.x >= max_x_)
00470                    || (point_idx_arg.y >= max_y_) || (point_idx_arg.z >= max_z_)));
00471         }
00472 
00473         /** \brief Generate octree key for voxel at a given point
00474          * \param[in] point_arg the point addressing a voxel
00475          * \param[out] key_arg write octree key to this reference
00476          */
00477         void
00478         genOctreeKeyforPoint (const PointT & point_arg,
00479             OctreeKey &key_arg) const;
00480 
00481         /** \brief Generate octree key for voxel at a given point
00482          * \param[in] point_x_arg X coordinate of point addressing a voxel
00483          * \param[in] point_y_arg Y coordinate of point addressing a voxel
00484          * \param[in] point_z_arg Z coordinate of point addressing a voxel
00485          * \param[out] key_arg write octree key to this reference
00486          */
00487         void
00488         genOctreeKeyforPoint (const double point_x_arg, const double point_y_arg, const double point_z_arg,
00489                               OctreeKey & key_arg) const;
00490 
00491         /** \brief Virtual method for generating octree key for a given point index.
00492          * \note This method enables to assign indices to leaf nodes during octree deserialization.
00493          * \param[in] data_arg index value representing a point in the dataset given by \a setInputCloud
00494          * \param[out] key_arg write octree key to this reference
00495          * \return "true" - octree keys are assignable
00496          */
00497         virtual bool
00498         genOctreeKeyForDataT (const int& data_arg, OctreeKey & key_arg) const;
00499 
00500         /** \brief Generate a point at center of leaf node voxel
00501          * \param[in] key_arg octree key addressing a leaf node.
00502          * \param[out] point_arg write leaf node voxel center to this point reference
00503          */
00504         void
00505         genLeafNodeCenterFromOctreeKey (const OctreeKey & key_arg,
00506             PointT& point_arg) const;
00507 
00508         /** \brief Generate a point at center of octree voxel at given tree level
00509          * \param[in] key_arg octree key addressing an octree node.
00510          * \param[in] tree_depth_arg octree depth of query voxel
00511          * \param[out] point_arg write leaf node center point to this reference
00512          */
00513         void
00514         genVoxelCenterFromOctreeKey (const OctreeKey & key_arg,
00515             unsigned int tree_depth_arg, PointT& point_arg) const;
00516 
00517         /** \brief Generate bounds of an octree voxel using octree key and tree depth arguments
00518          * \param[in] key_arg octree key addressing an octree node.
00519          * \param[in] tree_depth_arg octree depth of query voxel
00520          * \param[out] min_pt lower bound of voxel
00521          * \param[out] max_pt upper bound of voxel
00522          */
00523         void
00524         genVoxelBoundsFromOctreeKey (const OctreeKey & key_arg,
00525             unsigned int tree_depth_arg, Eigen::Vector3f &min_pt,
00526             Eigen::Vector3f &max_pt) const;
00527 
00528         /** \brief Recursively search the tree for all leaf nodes and return a vector of voxel centers.
00529          * \param[in] node_arg current octree node to be explored
00530          * \param[in] key_arg octree key addressing a leaf node.
00531          * \param[out] voxel_center_list_arg results are written to this vector of PointT elements
00532          * \return number of voxels found
00533          */
00534         int
00535         getOccupiedVoxelCentersRecursive (const BranchNode* node_arg,
00536             const OctreeKey& key_arg,
00537             AlignedPointTVector &voxel_center_list_arg) const;
00538 
00539         //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00540         // Globals
00541         //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00542         /** \brief Pointer to input point cloud dataset. */
00543         PointCloudConstPtr input_;
00544 
00545         /** \brief A pointer to the vector of point indices to use. */
00546         IndicesConstPtr indices_;
00547 
00548         /** \brief Epsilon precision (error bound) for nearest neighbors searches. */
00549         double epsilon_;
00550 
00551         /** \brief Octree resolution. */
00552         double resolution_;
00553 
00554         // Octree bounding box coordinates
00555         double min_x_;
00556         double max_x_;
00557 
00558         double min_y_;
00559         double max_y_;
00560 
00561         double min_z_;
00562         double max_z_;
00563 
00564         /** \brief Flag indicating if octree has defined bounding box. */
00565         bool bounding_box_defined_;
00566 
00567         /** \brief Amount of DataT objects per leafNode before expanding branch
00568          *  \note zero indicates a fixed/maximum depth octree structure
00569          * **/
00570         std::size_t max_objs_per_leaf_;
00571     };
00572 
00573   }
00574 }
00575 
00576 #ifdef PCL_NO_PRECOMPILE
00577 #include <pcl/octree/impl/octree_pointcloud.hpp>
00578 #endif
00579 
00580 #endif
00581