Point Cloud Library (PCL)  1.7.0
/tmp/buildd/pcl-1.7-1.7.0/outofcore/include/pcl/outofcore/octree_base_node.h
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Point Cloud Library (PCL) - www.pointclouds.org
00005  *  Copyright (c) 2010-2012, Willow Garage, Inc.
00006  *  Copyright (c) 2012, Urban Robotics, Inc.
00007  *
00008  *  All rights reserved.
00009  *
00010  *  Redistribution and use in source and binary forms, with or without
00011  *  modification, are permitted provided that the following conditions
00012  *  are met:
00013  *
00014  *   * Redistributions of source code must retain the above copyright
00015  *     notice, this list of conditions and the following disclaimer.
00016  *   * Redistributions in binary form must reproduce the above
00017  *     copyright notice, this list of conditions and the following
00018  *     disclaimer in the documentation and/or other materials provided
00019  *     with the distribution.
00020  *   * Neither the name of Willow Garage, Inc. nor the names of its
00021  *     contributors may be used to endorse or promote products derived
00022  *     from this software without specific prior written permission.
00023  *
00024  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00025  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00026  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00027  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00028  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00029  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00030  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00031  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00032  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00034  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00035  *  POSSIBILITY OF SUCH DAMAGE.
00036  *
00037  *  $Id$
00038  */
00039 
00040 #ifndef PCL_OUTOFCORE_OCTREE_BASE_NODE_H_
00041 #define PCL_OUTOFCORE_OCTREE_BASE_NODE_H_
00042 
00043 #include <pcl/common/io.h>
00044 #include <pcl/PCLPointCloud2.h>
00045 
00046 #include <pcl/outofcore/boost.h>
00047 #include <pcl/outofcore/octree_base.h>
00048 #include <pcl/outofcore/octree_disk_container.h>
00049 #include <pcl/outofcore/outofcore_node_data.h>
00050 
00051 #include <pcl/octree/octree_nodes.h>
00052 
00053 namespace pcl
00054 {
00055   namespace outofcore
00056   {
00057     // Forward Declarations
00058     template<typename ContainerT, typename PointT>
00059     class OutofcoreOctreeBaseNode;
00060 
00061     template<typename ContainerT, typename PointT>
00062     class OutofcoreOctreeBase;
00063 
00064     /** \brief Non-class function which creates a single child leaf; used with \ref queryBBIntersects_noload to avoid loading the data from disk */
00065     template<typename ContainerT, typename PointT> OutofcoreOctreeBaseNode<ContainerT, PointT>*
00066     makenode_norec (const boost::filesystem::path &path, OutofcoreOctreeBaseNode<ContainerT, PointT>* super);
00067 
00068     /** \brief Non-class method which performs a bounding box query without loading any of the point cloud data from disk */
00069     template<typename ContainerT, typename PointT> void
00070     queryBBIntersects_noload (const boost::filesystem::path &root_node, const Eigen::Vector3d &min, const Eigen::Vector3d &max, const boost::uint32_t query_depth, std::list<std::string> &bin_name);
00071 
00072     /** \brief Non-class method overload */
00073     template<typename ContainerT, typename PointT> void
00074     queryBBIntersects_noload (OutofcoreOctreeBaseNode<ContainerT, PointT>* current, const Eigen::Vector3d&, const Eigen::Vector3d &max, const boost::uint32_t query_depth, std::list<std::string> &bin_name);
00075 
00076     /** \class OutofcoreOctreeBaseNode 
00077      *
00078      *  \note Code was adapted from the Urban Robotics out of core octree implementation. 
00079      *  Contact Jacob Schloss <jacob.schloss@urbanrobotics.net> with any questions. 
00080      *  http://www.urbanrobotics.net/
00081      *
00082      *  \brief OutofcoreOctreeBaseNode Class internally representing nodes of an
00083      *  outofcore octree, with accessors to its data via the \ref
00084      *  octree_disk_container class or \ref octree_ram_container class,
00085      *  whichever it is templated against.  
00086      * 
00087      *  \ingroup outofcore
00088      *  \author Jacob Schloss (jacob.schloss@urbanrobotics.net)
00089      *
00090      */
00091     template<typename ContainerT = OutofcoreOctreeDiskContainer<pcl::PointXYZ>, typename PointT = pcl::PointXYZ>
00092     class OutofcoreOctreeBaseNode : public pcl::octree::OctreeNode
00093     {
00094       friend class OutofcoreOctreeBase<ContainerT, PointT> ;
00095 
00096       //these methods can be rewritten with the iterators. 
00097       friend OutofcoreOctreeBaseNode<ContainerT, PointT>*
00098       makenode_norec<ContainerT, PointT> (const boost::filesystem::path &path, OutofcoreOctreeBaseNode<ContainerT, PointT>* super);
00099   
00100       friend void
00101       queryBBIntersects_noload<ContainerT, PointT> (const boost::filesystem::path &rootnode, const Eigen::Vector3d &min, const Eigen::Vector3d &max, const boost::uint32_t query_depth, std::list<std::string> &bin_name);
00102 
00103       friend void
00104       queryBBIntersects_noload<ContainerT, PointT> (OutofcoreOctreeBaseNode<ContainerT, PointT>* current, const Eigen::Vector3d &min, const Eigen::Vector3d &max, const boost::uint32_t query_depth, std::list<std::string> &bin_name);
00105   
00106       public:
00107         typedef OutofcoreOctreeBase<OutofcoreOctreeDiskContainer < PointT > , PointT > octree_disk;
00108         typedef OutofcoreOctreeBaseNode<OutofcoreOctreeDiskContainer < PointT > , PointT > octree_disk_node;
00109 
00110         typedef std::vector<PointT, Eigen::aligned_allocator<PointT> > AlignedPointTVector;
00111 
00112         typedef pcl::octree::node_type_t node_type_t;
00113 
00114         const static std::string node_index_basename;
00115         const static std::string node_container_basename;
00116         const static std::string node_index_extension;
00117         const static std::string node_container_extension;
00118         const static double sample_percent_;
00119 
00120         /** \brief Empty constructor; sets pointers for children and for bounding boxes to 0
00121          */
00122         OutofcoreOctreeBaseNode ();
00123 
00124         /** \brief Create root node and directory */
00125         OutofcoreOctreeBaseNode (const Eigen::Vector3d &bb_min, const Eigen::Vector3d &bb_max, OutofcoreOctreeBase<ContainerT, PointT> * const tree, const boost::filesystem::path &root_name);
00126 
00127         /** \brief Will recursively delete all children calling recFreeChildrein */
00128         virtual
00129         ~OutofcoreOctreeBaseNode ();
00130 
00131         //query
00132         /** \brief gets the minimum and maximum corner of the bounding box represented by this node
00133          * \param[out] minCoord returns the minimum corner of the bounding box indexed by 0-->X, 1-->Y, 2-->Z 
00134          * \param[out] maxCoord returns the maximum corner of the bounding box indexed by 0-->X, 1-->Y, 2-->Z 
00135          */
00136         virtual inline void
00137         getBoundingBox (Eigen::Vector3d &min_bb, Eigen::Vector3d &max_bb) const
00138         {
00139           node_metadata_->getBoundingBox (min_bb, max_bb);
00140         }
00141 
00142 
00143         const boost::filesystem::path&
00144         getPCDFilename () const
00145         {
00146           return node_metadata_->getPCDFilename ();
00147         }
00148 
00149         const boost::filesystem::path&
00150         getMetadataFilename () const
00151         {
00152           return node_metadata_->getMetadataFilename ();
00153         }
00154 
00155         void
00156         queryFrustum (const double planes[24], std::list<std::string>& file_names);
00157 
00158         void
00159         queryFrustum (const double planes[24], std::list<std::string>& file_names, const boost::uint32_t query_depth, const bool skip_vfc_check = false);
00160 
00161         void
00162         queryFrustum (const double planes[24], const Eigen::Vector3d &eye, const Eigen::Matrix4d &view_projection_matrix, std::list<std::string>& file_names, const boost::uint32_t query_depth, const bool skip_vfc_check = false);
00163 
00164         //point extraction
00165         /** \brief Recursively add points that fall into the queried bounding box up to the \b query_depth 
00166          *
00167          *  \param[in] min_bb the minimum corner of the bounding box, indexed by X,Y,Z coordinates
00168          *  \param[in] max_bb the maximum corner of the bounding box, indexed by X,Y,Z coordinates
00169          *  \param[in] query_depth the maximum depth to query in the octree for points within the bounding box
00170          *  \param[out] dst destion of points returned by the queries
00171          */
00172         virtual void
00173         queryBBIncludes (const Eigen::Vector3d &min_bb, const Eigen::Vector3d &max_bb, size_t query_depth, AlignedPointTVector &dst);
00174 
00175         /** \brief Recursively add points that fall into the queried bounding box up to the \b query_depth
00176          *
00177          *  \param[in] min_bb the minimum corner of the bounding box, indexed by X,Y,Z coordinates
00178          *  \param[in] max_bb the maximum corner of the bounding box, indexed by X,Y,Z coordinates
00179          *  \param[in] query_depth the maximum depth to query in the octree for points within the bounding box
00180          *  \param[out] dst_blob destion of points returned by the queries
00181          */
00182         virtual void
00183         queryBBIncludes (const Eigen::Vector3d &min_bb, const Eigen::Vector3d &max_bb, size_t query_depth, const pcl::PCLPointCloud2::Ptr &dst_blob);
00184 
00185         /** \brief Recursively add points that fall into the queried bounding box up to the \b query_depth 
00186          *
00187          *  \param[in] min_bb the minimum corner of the bounding box, indexed by X,Y,Z coordinates
00188          *  \param[in] max_bb the maximum corner of the bounding box, indexed by X,Y,Z coordinates
00189          *  \param[in] query_depth
00190          *  \param[out] v std::list of points returned by the query
00191          */
00192         virtual void
00193         queryBBIncludes_subsample (const Eigen::Vector3d &min_bb, const Eigen::Vector3d &max_bb, boost::uint64_t query_depth, const double percent, AlignedPointTVector &v);
00194 
00195         virtual void
00196         queryBBIncludes_subsample (const Eigen::Vector3d &min_bb, const Eigen::Vector3d &max_bb, boost::uint64_t query_depth, const pcl::PCLPointCloud2::Ptr& dst_blob, double percent = 1.0);
00197 
00198         /** \brief Recursive acquires PCD paths to any node with which the queried bounding box intersects (at query_depth only).
00199          */
00200         virtual void
00201         queryBBIntersects (const Eigen::Vector3d &min_bb, const Eigen::Vector3d &max_bb, const boost::uint32_t query_depth, std::list<std::string> &file_names);
00202 
00203         /** \brief Write the voxel size to stdout at \ref query_depth 
00204          * \param[in] query_depth The depth at which to print the size of the voxel/bounding boxes
00205          */
00206         virtual void
00207         printBoundingBox (const size_t query_depth) const;
00208 
00209         /** \brief add point to this node if we are a leaf, or find the leaf below us that is supposed to take the point 
00210          *  \param[in] p vector of points to add to the leaf
00211          *  \param[in] skipBBCheck whether to check if the point's coordinates fall within the bounding box
00212          */
00213         virtual boost::uint64_t
00214         addDataToLeaf (const AlignedPointTVector &p, const bool skip_bb_check = true);
00215 
00216         virtual boost::uint64_t
00217         addDataToLeaf (const std::vector<const PointT*> &p, const bool skip_bb_check = true);
00218 
00219         /** \brief Add a single PCLPointCloud2 object into the octree.
00220          *
00221          * \param[in] input_cloud
00222          * \param[in] skip_bb_check (default = false)
00223          */
00224         virtual boost::uint64_t
00225         addPointCloud (const pcl::PCLPointCloud2::Ptr &input_cloud, const bool skip_bb_check = false);
00226 
00227         /** \brief Add a single PCLPointCloud2 into the octree and build the subsampled LOD during construction; this method of LOD construction is <b>not</b> multiresolution. Rather, there are no redundant data. */
00228         virtual boost::uint64_t
00229         addPointCloud_and_genLOD (const pcl::PCLPointCloud2::Ptr input_cloud); //, const bool skip_bb_check);
00230         
00231         /** \brief Recursively add points to the leaf and children subsampling LODs
00232          * on the way down.
00233          *
00234          * \note rng_mutex_ lock occurs
00235          */
00236         virtual boost::uint64_t
00237         addDataToLeaf_and_genLOD (const AlignedPointTVector &p, const bool skip_bb_check);
00238 
00239         /** \brief Write a python visual script to @b file
00240          * \param[in] file output file stream to write the python visual script
00241          */
00242         void
00243         writeVPythonVisual (std::ofstream &file);
00244 
00245         virtual int
00246         read (pcl::PCLPointCloud2::Ptr &output_cloud);
00247 
00248         virtual inline node_type_t
00249         getNodeType () const
00250         {
00251           if(this->getNumChildren () > 0)
00252           {
00253             return (pcl::octree::BRANCH_NODE);
00254           }
00255           else
00256           {
00257             return (pcl::octree::LEAF_NODE);
00258           }
00259         }
00260         
00261         virtual
00262         OutofcoreOctreeBaseNode* 
00263         deepCopy () const
00264         {
00265           OutofcoreOctreeBaseNode* res = NULL;
00266           PCL_THROW_EXCEPTION (PCLException, "Not implemented\n");
00267           return (res);
00268         }
00269 
00270         virtual inline size_t
00271         getDepth () const
00272         {
00273           return (this->depth_);
00274         }
00275 
00276         /** \brief Returns the total number of children on disk */
00277         virtual size_t
00278         getNumChildren () const 
00279         {
00280           size_t res = this->countNumChildren ();
00281           return (res);
00282         }
00283 
00284         /** \brief Count loaded chilren */
00285         virtual size_t
00286         getNumLoadedChildren ()  const
00287         {
00288           size_t res = this->countNumLoadedChildren ();
00289           return (res);
00290         }        
00291         
00292         /** \brief Returns a pointer to the child in octant index_arg */
00293         virtual OutofcoreOctreeBaseNode*
00294         getChildPtr (size_t index_arg) const;
00295 
00296         /** \brief Gets the number of points available in the PCD file */
00297         virtual boost::uint64_t
00298         getDataSize () const;
00299 
00300         inline virtual void
00301         clearData ()
00302         {
00303           //clears write cache and removes PCD file from disk
00304           this->payload_->clear ();
00305         }
00306 
00307       ///////////////////////////////////////////////////////////////////////////////
00308       // PROTECTED METHODS
00309       ////////////////////////////////////////////////////////////////////////////////
00310       protected:
00311         /** \brief Load from disk 
00312          * If creating root, path is full name. If creating any other
00313          * node, path is dir; throws exception if directory or metadata not found
00314          *
00315          * \param[in] Directory pathname
00316          * \param[in] super
00317          * \param[in] loadAll
00318          * \throws PCLException if directory is missing
00319          * \throws PCLException if node index is missing
00320          */
00321         OutofcoreOctreeBaseNode (const boost::filesystem::path &directory_path, OutofcoreOctreeBaseNode<ContainerT, PointT>* super, bool load_all);
00322 
00323         /** \brief Create root node and directory
00324          *
00325          * Initializes the root node and performs initial filesystem checks for the octree; 
00326          * throws OctreeException::OCT_BAD_PATH if root directory is an existing file
00327          *
00328          * \param bb_min triple of x,y,z minima for bounding box
00329          * \param bb_max triple of x,y,z maxima for bounding box
00330          * \param tree adress of the tree data structure that will hold this initial root node
00331          * \param rootname Root directory for location of on-disk octree storage; if directory 
00332          * doesn't exist, it is created; if "rootname" is an existing file, 
00333          * 
00334          * \throws PCLException if the specified path already exists
00335          */
00336         void init_root_node (const Eigen::Vector3d &bb_min, const Eigen::Vector3d &bb_max, OutofcoreOctreeBase<ContainerT, PointT> * const tree, const boost::filesystem::path &rootname);
00337 
00338         /** \brief no copy construction right now */
00339         OutofcoreOctreeBaseNode (const OutofcoreOctreeBaseNode &rval);
00340 
00341         /** \brief Operator= is not implemented */
00342         OutofcoreOctreeBaseNode&
00343         operator= (const OutofcoreOctreeBaseNode &rval);
00344 
00345         /** \brief Counts the number of child directories on disk; used to update num_children_ */
00346         virtual size_t
00347         countNumChildren () const;
00348 
00349         /** \brief Counts the number of loaded chilren by testing the \ref children_ array; 
00350          *  used to update num_loaded_chilren_ internally 
00351          */
00352         virtual size_t
00353         countNumLoadedChildren () const;
00354         
00355         /** \brief Save node's metadata to file
00356          * \param[in] recursive: if false, save only this node's metadata to file; if true, recursively
00357          * save all children's metadata to files as well
00358          */
00359         void
00360         saveIdx (bool recursive);
00361 
00362         /** \brief Randomly sample point data 
00363          */
00364         void
00365         randomSample (const AlignedPointTVector &p, AlignedPointTVector &insertBuff, const bool skip_bb_check);
00366 
00367         /** \brief Subdivide points to pass to child nodes */
00368         void
00369         subdividePoints (const AlignedPointTVector &p, std::vector< AlignedPointTVector > &c, const bool skip_bb_check);
00370         /** \brief Subdivide a single point into a specific child node */
00371         void
00372         subdividePoint (const PointT &point, std::vector< AlignedPointTVector > &c);
00373 
00374         /** \brief Add data to the leaf when at max depth of tree. If
00375          *   skip_bb_check is true, adds to the node regardless of the
00376          *   bounding box it represents; otherwise only adds points that
00377          *   fall within the bounding box 
00378          *
00379          *  \param[in] p vector of points to attempt to add to the tree
00380          *  \param[in] skip_bb_check if @b true, doesn't check that points
00381          *  are in the proper bounding box; if @b false, only adds the
00382          *  points that fall into the bounding box to this node 
00383          *  \return number of points successfully added
00384          */
00385         boost::uint64_t
00386         addDataAtMaxDepth (const AlignedPointTVector &p, const bool skip_bb_check = true);
00387 
00388         /** \brief Add data to the leaf when at max depth of tree. If
00389          *   \ref skip_bb_check is true, adds to the node regardless of the
00390          *   bounding box it represents; otherwise only adds points that
00391          *   fall within the bounding box 
00392          *
00393          *  \param[in] input_cloud PCLPointCloud2 points to attempt to add to the tree;
00394          *  \warning PCLPointCloud2 inserted into the tree must have x,y,z fields, and must be of same type of any other points inserted in the tree
00395          *  \param[in] skip_bb_check (default true) if @b true, doesn't check that points
00396          *  are in the proper bounding box; if @b false, only adds the
00397          *  points that fall into the bounding box to this node 
00398          *  \return number of points successfully added
00399          */
00400         boost::uint64_t
00401         addDataAtMaxDepth (const pcl::PCLPointCloud2::Ptr input_cloud, const bool skip_bb_check = true);
00402         
00403         /** \brief Tests whether the input bounding box intersects with the current node's bounding box 
00404          *  \param[in] min_bb The minimum corner of the input bounding box
00405          *  \param[in] min_bb The maximum corner of the input bounding box
00406          *  \return bool True if any portion of the bounding box intersects with this node's bounding box; false otherwise
00407          */
00408         inline bool
00409         intersectsWithBoundingBox (const Eigen::Vector3d &min_bb, const Eigen::Vector3d &max_bb) const;
00410 
00411         /** \brief Tests whether the input bounding box falls inclusively within this node's bounding box
00412          *  \param[in] min_bb The minimum corner of the input bounding box
00413          *  \param[in] max_bb The maximum corner of the input bounding box
00414          *  \return bool True if the input bounding box falls inclusively within the boundaries of this node's bounding box
00415          **/
00416         inline bool
00417         inBoundingBox (const Eigen::Vector3d &min_bb, const Eigen::Vector3d &max_bb) const;
00418 
00419         /** \brief Tests whether \ref point falls within the input bounding box
00420          *  \param[in] min_bb The minimum corner of the input bounding box
00421          *  \param[in] max_bb The maximum corner of the input bounding box
00422          *  \param[in] point The test point
00423          */
00424         bool
00425         pointInBoundingBox (const Eigen::Vector3d &min_bb, const Eigen::Vector3d &max_bb, const Eigen::Vector3d &point);
00426 
00427         /** \brief Tests whether \ref p falls within the input bounding box
00428          *  \param[in] min_bb The minimum corner of the input bounding box
00429          *  \param[in] max_bb The maximum corner of the input bounding box
00430          *  \param[in] p The point to be tested
00431          **/
00432         static bool
00433         pointInBoundingBox (const Eigen::Vector3d &min_bb, const Eigen::Vector3d &max_bb, const PointT &p);
00434 
00435         /** \brief Tests whether \ref x, \ref y, and \ref z fall within the input bounding box
00436          *  \param[in] min_bb The minimum corner of the input bounding box
00437          *  \param[in] max_bb The maximum corner of the input bounding box
00438          **/
00439         static bool
00440         pointInBoundingBox (const Eigen::Vector3d &min_bb, const Eigen::Vector3d &max_bb, const double x, const double y, const double z);
00441 
00442         /** \brief Tests if specified point is within bounds of current node's bounding box */
00443         inline bool
00444         pointInBoundingBox (const PointT &p) const;
00445 
00446         /** \brief Creates child node \ref idx
00447          *  \param[in] idx Index (0-7) of the child node
00448          */
00449         void
00450         createChild (const std::size_t idx);
00451 
00452         /** \brief Write JSON metadata for this node to file */
00453         void
00454         saveMetadataToFile (const boost::filesystem::path &path);
00455 
00456         /** \brief Method which recursively free children of this node 
00457          */
00458         void
00459         recFreeChildren ();
00460 
00461         /** \brief Number of points in the payload */
00462         inline boost::uint64_t
00463         size () const
00464         {
00465           return (payload_->size ());
00466         }
00467 
00468         void
00469         flushToDiskRecursive ();
00470 
00471         /** \brief Loads the nodes metadata from the JSON file 
00472          */
00473         void
00474         loadFromFile (const boost::filesystem::path &path, OutofcoreOctreeBaseNode* super);
00475 
00476         /** \brief Recursively converts data files to ascii XZY files
00477          *  \note This will be deprecated soon
00478          */
00479         void
00480         convertToXYZRecursive ();
00481 
00482         /** \brief Private constructor used for children 
00483          */
00484         OutofcoreOctreeBaseNode (const Eigen::Vector3d &bb_min, const Eigen::Vector3d &bb_max, const char* dir, OutofcoreOctreeBaseNode<ContainerT, PointT>* super);
00485 
00486         /** \brief Copies points from this and all children into a single point container (std::list)
00487          */
00488         void
00489         copyAllCurrentAndChildPointsRec (std::list<PointT> &v);
00490 
00491         void
00492         copyAllCurrentAndChildPointsRec_sub (std::list<PointT> &v, const double percent);
00493 
00494         /** \brief Returns whether or not a node has unloaded children data */
00495         bool
00496         hasUnloadedChildren () const;
00497 
00498         /** \brief Load nodes child data creating new nodes for each */
00499         virtual void
00500         loadChildren (bool recursive);
00501 
00502         /** \brief Gets a vector of occupied voxel centers
00503          * \param[out] voxel_centers
00504          * \param[in] query_depth
00505          */
00506         void
00507         getOccupiedVoxelCentersRecursive (AlignedPointTVector &voxel_centers, const size_t query_depth);
00508 
00509         /** \brief Gets a vector of occupied voxel centers
00510          * \param[out] voxel_centers
00511          * \param[in] query_depth
00512          */
00513         void
00514         getOccupiedVoxelCentersRecursive (std::vector<Eigen::Vector3d, Eigen::aligned_allocator<Eigen::Vector3d> > &voxel_centers, const size_t query_depth);
00515 
00516         /** \brief Sorts the indices based on x,y,z fields and pushes the index into the proper octant's vector;
00517          *  This could be overloaded with a parallelized implementation
00518          */
00519         void
00520         sortOctantIndices (const pcl::PCLPointCloud2::Ptr &input_cloud, std::vector< std::vector<int> > &indices, const Eigen::Vector3d &mid_xyz);
00521 
00522         /** \brief Enlarges the shortest two sidelengths of the
00523          *  bounding box to a cubic shape; operation is done in
00524          *  place.
00525         */
00526         void
00527         enlargeToCube (Eigen::Vector3d &bb_min, Eigen::Vector3d &bb_max);
00528 
00529         /** \brief The tree we belong to */
00530         OutofcoreOctreeBase<ContainerT, PointT>* m_tree_;//
00531         /** \brief The root node of the tree we belong to */
00532         OutofcoreOctreeBaseNode* root_node_;//
00533         /** \brief super-node */
00534         OutofcoreOctreeBaseNode* parent_;
00535         /** \brief Depth in the tree, root is 0, root's children are 1, ... */
00536         size_t depth_;
00537         /** \brief The children of this node */
00538         std::vector<OutofcoreOctreeBaseNode*> children_;
00539 
00540         /** \brief Number of children on disk. This is only changed when a new node is created */
00541         uint64_t num_children_;
00542 
00543         /** \brief Number of loaded children this node has
00544          *
00545          *  "Loaded" means child OctreeBaseNodes have been allocated,
00546          *  and their metadata files have been loaded into
00547          *  memory. num_loaded_children_ <= num_children_
00548          */
00549         uint64_t num_loaded_children_;
00550 
00551         /** \brief what holds the points. currently a custom class, but in theory
00552          * you could use an stl container if you rewrote some of this class. I used
00553          * to use deques for this... */
00554         boost::shared_ptr<ContainerT> payload_;
00555 
00556         /** \brief Random number generator mutex */
00557         static boost::mutex rng_mutex_;
00558 
00559         /** \brief Mersenne Twister: A 623-dimensionally equidistributed uniform
00560          * pseudo-random number generator */
00561         static boost::mt19937 rand_gen_;
00562 
00563         /** \brief Random number generator seed */
00564         const static boost::uint32_t rngseed = 0xAABBCCDD;
00565         /** \brief Extension for this class to find the pcd files on disk */
00566         const static std::string pcd_extension;
00567 
00568         OutofcoreOctreeNodeMetadata::Ptr node_metadata_;
00569     };
00570   }//namespace outofcore
00571 }//namespace pcl
00572 
00573 #endif //PCL_OUTOFCORE_OCTREE_BASE_NODE_H_