Point Cloud Library (PCL)  1.7.2
octree_base.h
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (c) 2010-2012, Willow Garage, Inc.
6  * Copyright (c) 2012, Urban Robotics, Inc.
7  *
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  *
14  * * Redistributions of source code must retain the above copyright
15  * notice, this list of conditions and the following disclaimer.
16  * * Redistributions in binary form must reproduce the above
17  * copyright notice, this list of conditions and the following
18  * disclaimer in the documentation and/or other materials provided
19  * with the distribution.
20  * * Neither the name of Willow Garage, Inc. nor the names of its
21  * contributors may be used to endorse or promote products derived
22  * from this software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  * POSSIBILITY OF SUCH DAMAGE.
36  *
37  * $Id$
38  */
39 
40 #ifndef PCL_OUTOFCORE_OUTOFCOREOCTREEBASE_H_
41 #define PCL_OUTOFCORE_OUTOFCOREOCTREEBASE_H_
42 
43 #include <pcl/outofcore/boost.h>
44 #include <pcl/common/io.h>
45 
46 //outofcore classes
47 #include <pcl/outofcore/octree_base_node.h>
48 #include <pcl/outofcore/octree_disk_container.h>
49 #include <pcl/outofcore/octree_ram_container.h>
50 
51 //outofcore iterators
52 #include <pcl/outofcore/outofcore_iterator_base.h>
53 #include <pcl/outofcore/outofcore_breadth_first_iterator.h>
54 #include <pcl/outofcore/outofcore_depth_first_iterator.h>
55 #include <pcl/outofcore/impl/outofcore_breadth_first_iterator.hpp>
56 #include <pcl/outofcore/impl/outofcore_depth_first_iterator.hpp>
57 
58 //outofcore metadata
59 #include <pcl/outofcore/metadata.h>
60 #include <pcl/outofcore/outofcore_base_data.h>
61 
62 #include <pcl/filters/filter.h>
63 #include <pcl/filters/random_sample.h>
64 
65 #include <pcl/PCLPointCloud2.h>
66 
67 namespace pcl
68 {
69  namespace outofcore
70  {
72  {
73  std::string node_index_basename_;
75  std::string node_index_extension_;
78  };
79 
80  /** \class OutofcoreOctreeBase
81  * \brief This code defines the octree used for point storage at Urban Robotics.
82  *
83  * \note Code was adapted from the Urban Robotics out of core octree implementation.
84  * Contact Jacob Schloss <jacob.schloss@urbanrobotics.net> with any questions.
85  * http://www.urbanrobotics.net/. This code was integrated for the Urban Robotics
86  * Code Sprint (URCS) by Stephen Fox (foxstephend@gmail.com). Additional development notes can be found at
87  * http://www.pointclouds.org/blog/urcs/.
88  *
89  * The primary purpose of this class is an interface to the
90  * recursive traversal (recursion handled by \ref pcl::outofcore::OutofcoreOctreeBaseNode) of the
91  * in-memory/top-level octree structure. The metadata in each node
92  * can be loaded entirely into main memory, from which the tree can be traversed
93  * recursively in this state. This class provides an the interface
94  * for:
95  * -# Point/Region insertion methods
96  * -# Frustrum/box/region queries
97  * -# Parameterization of resolution, container type, etc...
98  *
99  * For lower-level node access, there is a Depth-First iterator
100  * for traversing the trees with direct access to the nodes. This
101  * can be used for implementing other algorithms, and other
102  * iterators can be written in a similar fashion.
103  *
104  * The format of the octree is stored on disk in a hierarchical
105  * octree structure, where .oct_idx are the JSON-based node
106  * metadata files managed by \ref pcl::outofcore::OutofcoreOctreeNodeMetadata,
107  * and .octree is the JSON-based octree metadata file managed by
108  * \ref pcl::outofcore::OutofcoreOctreeBaseMetadata. Children of each node live
109  * in up to eight subdirectories named from 0 to 7, where a
110  * metadata and optionally a pcd file will exist. The PCD files
111  * are stored in compressed binary PCD format, containing all of
112  * the fields existing in the PCLPointCloud2 objects originally
113  * inserted into the out of core object.
114  *
115  * A brief outline of the out of core octree can be seen
116  * below. The files in [brackets] exist only when the LOD are
117  * built.
118  *
119  * At this point in time, there is not support for multiple trees
120  * existing in a single directory hierarchy.
121  *
122  * \verbatim
123  tree_name/
124  tree_name.oct_idx
125  tree_name.octree
126  [tree_name-uuid.pcd]
127  0/
128  tree_name.oct_idx
129  [tree_name-uuid.pcd]
130  0/
131  ...
132  1/
133  ...
134  ...
135  0/
136  tree_name.oct_idx
137  tree_name.pcd
138  1/
139  ...
140  7/
141  \endverbatim
142  *
143  * \ingroup outofcore
144  * \author Jacob Schloss (jacob.schloss@urbanrobotics.net)
145  * \author Stephen Fox, Urban Robotics Code Sprint (foxstephend@gmail.com)
146  *
147  */
148  template<typename ContainerT = OutofcoreOctreeDiskContainer<pcl::PointXYZ>, typename PointT = pcl::PointXYZ>
150  {
151  friend class OutofcoreOctreeBaseNode<ContainerT, PointT>;
153 
154  public:
155 
156  // public typedefs
159 
162 
164 
167 
170 
173 
176 
177  typedef boost::shared_ptr<OutofcoreOctreeBase<ContainerT, PointT> > Ptr;
178  typedef boost::shared_ptr<const OutofcoreOctreeBase<ContainerT, PointT> > ConstPtr;
179 
181 
182  typedef boost::shared_ptr<std::vector<int> > IndicesPtr;
183  typedef boost::shared_ptr<const std::vector<int> > IndicesConstPtr;
184 
185  typedef boost::shared_ptr<PointCloud> PointCloudPtr;
186  typedef boost::shared_ptr<const PointCloud> PointCloudConstPtr;
187 
188  typedef std::vector<PointT, Eigen::aligned_allocator<PointT> > AlignedPointTVector;
189 
190  // Constructors
191  // -----------------------------------------------------------------------
192 
193  /** \brief Load an existing tree
194  *
195  * If load_all is set, the BB and point count for every node is loaded,
196  * otherwise only the root node is actually created, and the rest will be
197  * generated on insertion or query.
198  *
199  * \param root_node_name Path to the top-level tree/tree.oct_idx metadata file
200  * \param load_all Load entire tree metadata (does not load any points from disk)
201  * \throws PCLException for bad extension (root node metadata must be .oct_idx extension)
202  */
203  OutofcoreOctreeBase (const boost::filesystem::path &root_node_name, const bool load_all);
204 
205  /** \brief Create a new tree
206  *
207  * Create a new tree rootname with specified bounding box; will remove and overwrite existing tree with the same name
208  *
209  * Computes the depth of the tree based on desired leaf , then calls the other constructor.
210  *
211  * \param min Bounding box min
212  * \param max Bounding box max
213  * \param resolution_arg Node dimension in meters (assuming your point data is in meters)
214  * \param root_node_name must end in ".oct_idx"
215  * \param coord_sys Coordinate system which is stored in the JSON metadata
216  * \throws PCLException if root file extension does not match \ref pcl::outofcore::OutofcoreOctreeBaseNode::node_index_extension
217  */
218  OutofcoreOctreeBase (const Eigen::Vector3d& min, const Eigen::Vector3d& max, const double resolution_arg, const boost::filesystem::path &root_node_name, const std::string &coord_sys);
219 
220  /** \brief Create a new tree; will not overwrite existing tree of same name
221  *
222  * Create a new tree rootname with specified bounding box; will not overwrite an existing tree
223  *
224  * \param max_depth Specifies a fixed number of LODs to generate, which is the depth of the tree
225  * \param min Bounding box min
226  * \param max Bounding box max
227  * \note Bounding box of the tree must be set before inserting any points. The tree \b cannot be resized at this time.
228  * \param root_node_name must end in ".oct_idx"
229  * \param coord_sys Coordinate system which is stored in the JSON metadata
230  * \throws PCLException if the parent directory has existing children (detects an existing tree)
231  * \throws PCLException if file extension is not ".oct_idx"
232  */
233  OutofcoreOctreeBase (const boost::uint64_t max_depth, const Eigen::Vector3d &min, const Eigen::Vector3d &max, const boost::filesystem::path &root_node_name, const std::string &coord_sys);
234 
235  virtual
237 
238  // Point/Region INSERTION methods
239  // --------------------------------------------------------------------------------
240  /** \brief Recursively add points to the tree
241  * \note shared read_write_mutex lock occurs
242  */
243  boost::uint64_t
244  addDataToLeaf (const AlignedPointTVector &p);
245 
246  /** \brief Copies the points from the point_cloud falling within the bounding box of the octree to the
247  * out-of-core octree; this is an interface to addDataToLeaf and can be used multiple times.
248  * \param point_cloud Pointer to the point cloud data to copy to the outofcore octree; Assumes templated
249  * PointT matches for each.
250  * \return Number of points successfully copied from the point cloud to the octree.
251  */
252  boost::uint64_t
253  addPointCloud (PointCloudConstPtr point_cloud);
254 
255  /** \brief Recursively copies points from input_cloud into the leaf nodes of the out-of-core octree, and stores them to disk.
256  *
257  * \param[in] input_cloud The cloud of points to be inserted into the out-of-core octree. Note if multiple PCLPointCloud2 objects are added to the tree, this assumes that they all have exactly the same fields.
258  * \param[in] skip_bb_check (default=false) whether to skip the bounding box check on insertion. Note the bounding box check is never skipped in the current implementation.
259  * \return Number of poitns successfully copied from the point cloud to the octree
260  */
261  boost::uint64_t
262  addPointCloud (pcl::PCLPointCloud2::Ptr &input_cloud, const bool skip_bb_check = false);
263 
264  /** \brief Recursively add points to the tree.
265  *
266  * Recursively add points to the tree. 1/8 of the remaining
267  * points at each LOD are stored at each internal node of the
268  * octree until either (a) runs out of points, in which case
269  * the leaf is not at the maximum depth of the tree, or (b)
270  * a larger set of points falls in the leaf at the maximum depth.
271  * Note unlike the old implementation, multiple
272  * copies of the same point will \b not be added at multiple
273  * LODs as it walks the tree. Once the point is added to the
274  * octree, it is no longer propagated further down the tree.
275  *
276  *\param[in] input_cloud The input cloud of points which will
277  * be copied into the sorted nodes of the out-of-core octree
278  * \return The total number of points added to the out-of-core
279  * octree.
280  */
281  boost::uint64_t
283 
284  boost::uint64_t
286 
287  boost::uint64_t
288  addPointCloud_and_genLOD (PointCloudConstPtr point_cloud);
289 
290  /** \brief Recursively add points to the tree subsampling LODs on the way.
291  *
292  * shared read_write_mutex lock occurs
293  */
294  boost::uint64_t
295  addDataToLeaf_and_genLOD (AlignedPointTVector &p);
296 
297  // Frustrum/Box/Region REQUESTS/QUERIES: DB Accessors
298  // -----------------------------------------------------------------------
299  void
300  queryFrustum (const double *planes, std::list<std::string>& file_names) const;
301 
302  void
303  queryFrustum (const double *planes, std::list<std::string>& file_names, const boost::uint32_t query_depth) const;
304 
305  void
306  queryFrustum (const double *planes, const Eigen::Vector3d &eye, const Eigen::Matrix4d &view_projection_matrix,
307  std::list<std::string>& file_names, const boost::uint32_t query_depth) const;
308 
309  //--------------------------------------------------------------------------------
310  //templated PointT methods
311  //--------------------------------------------------------------------------------
312 
313  /** \brief Get a list of file paths at query_depth that intersect with your bounding box specified by \c min and \c max.
314  * When querying with this method, you may be stuck with extra data (some outside of your query bounds) that reside in the files.
315  *
316  * \param[in] min The minimum corner of the bounding box
317  * \param[in] max The maximum corner of the bounding box
318  * \param[in] query_depth 0 is root, (this->depth) is full
319  * \param[out] bin_name List of paths to point data files (PCD currently) which satisfy the query
320  */
321  void
322  queryBBIntersects (const Eigen::Vector3d &min, const Eigen::Vector3d &max, const boost::uint32_t query_depth, std::list<std::string> &bin_name) const;
323 
324  /** \brief Get Points in BB, only points inside BB. The query
325  * processes the data at each node, filtering points that fall
326  * out of the query bounds, and returns a single, concatenated
327  * point cloud.
328  *
329  * \param[in] min The minimum corner of the bounding box for querying
330  * \param[in] max The maximum corner of the bounding box for querying
331  * \param[in] query_depth The depth from which point data will be taken
332  * \note If the LODs of the tree have not been built, you must specify the maximum depth in order to retrieve any data
333  * \param[out] dst The destination vector of points
334  */
335  void
336  queryBBIncludes (const Eigen::Vector3d &min, const Eigen::Vector3d &max, const boost::uint64_t query_depth, AlignedPointTVector &dst) const;
337 
338  /** \brief Query all points falling within the input bounding box at \c query_depth and return a PCLPointCloud2 object in \c dst_blob.
339  *
340  * \param[in] min The minimum corner of the input bounding box.
341  * \param[in] max The maximum corner of the input bounding box.
342  * \param[in] query_depth The query depth at which to search for points; only points at this depth are returned
343  * \param[out] dst_blob Storage location for the points satisfying the query.
344  **/
345  void
346  queryBBIncludes (const Eigen::Vector3d &min, const Eigen::Vector3d &max, const boost::uint64_t query_depth, const pcl::PCLPointCloud2::Ptr &dst_blob) const;
347 
348  /** \brief Returns a random subsample of points within the given bounding box at \c query_depth.
349  *
350  * \param[in] min The minimum corner of the boudning box to query.
351  * \param[out] max The maximum corner of the bounding box to query.
352  * \param[in] query_depth The depth in the tree at which to look for the points. Only returns points within the given bounding box at the specified \c query_depth.
353  * \param[out] dst The destination in which to return the points.
354  *
355  */
356  void
357  queryBBIncludes_subsample (const Eigen::Vector3d &min, const Eigen::Vector3d &max, uint64_t query_depth, const double percent, AlignedPointTVector &dst) const;
358 
359  //--------------------------------------------------------------------------------
360  //PCLPointCloud2 methods
361  //--------------------------------------------------------------------------------
362 
363  /** \brief Query all points falling within the input bounding box at \c query_depth and return a PCLPointCloud2 object in \c dst_blob.
364  * If the optional argument for filter is given, points are processed by that filter before returning.
365  * \param[in] min The minimum corner of the input bounding box.
366  * \param[in] max The maximum corner of the input bounding box.
367  * \param[in] query_depth The depth of tree at which to query; only points at this depth are returned
368  * \param[out] dst_blob The destination in which points within the bounding box are stored.
369  * \param[in] percent optional sampling percentage which is applied after each time data are read from disk
370  */
371  virtual void
372  queryBoundingBox (const Eigen::Vector3d &min, const Eigen::Vector3d &max, const int query_depth, const pcl::PCLPointCloud2::Ptr &dst_blob, double percent = 1.0);
373 
374  /** \brief Returns list of pcd files from nodes whose bounding boxes intersect with the input bounding box.
375  * \param[in] min The minimum corner of the input bounding box.
376  * \param[in] max The maximum corner of the input bounding box.
377  * \param query_depth
378  * \param[out] filenames The list of paths to the PCD files which can be loaded and processed.
379  */
380  inline virtual void
381  queryBoundingBox (const Eigen::Vector3d &min, const Eigen::Vector3d &max, const int query_depth, std::list<std::string> &filenames) const
382  {
383  boost::shared_lock < boost::shared_mutex > lock (read_write_mutex_);
384  filenames.clear ();
385  this->root_node_->queryBBIntersects (min, max, query_depth, filenames);
386  }
387 
388  // Parameterization: getters and setters
389  // --------------------------------------------------------------------------------
390 
391  /** \brief Get the overall bounding box of the outofcore
392  * octree; this is the same as the bounding box of the \c root_node_ node
393  * \param min
394  * \param max
395  */
396  bool
397  getBoundingBox (Eigen::Vector3d &min, Eigen::Vector3d &max) const;
398 
399  /** \brief Get number of points at specified LOD
400  * \param[in] depth_index the level of detail at which we want the number of points (0 is root, 1, 2,...)
401  * \return number of points in the tree at \b depth
402  */
403  inline boost::uint64_t
404  getNumPointsAtDepth (const boost::uint64_t& depth_index) const
405  {
406  return (metadata_->getLODPoints (depth_index));
407  }
408 
409  /** \brief Queries the number of points in a bounding box
410  *
411  * \param[in] min The minimum corner of the input bounding box
412  * \param[out] max The maximum corner of the input bounding box
413  * \param[in] query_depth The depth of the nodes to restrict the search to (only this depth is searched)
414  * \param[in] load_from_disk (default true) Whether to load PCD files to count exactly the number of points within the bounding box; setting this to false will return an upper bound by just reading the number of points from the PCD header, even if there may be some points in that node do not fall within the query bounding box.
415  * \return Number of points in the bounding box at depth \b query_depth
416  **/
417  boost::uint64_t
418  queryBoundingBoxNumPoints (const Eigen::Vector3d& min, const Eigen::Vector3d& max, const int query_depth, bool load_from_disk = true);
419 
420 
421  /** \brief Get number of points at each LOD
422  * \return vector of number of points in each LOD indexed by each level of depth, 0 to the depth of the tree.
423  */
424  inline const std::vector<boost::uint64_t>&
426  {
427  return (metadata_->getLODPoints ());
428  }
429 
430  /** \brief Get number of LODs, which is the height of the tree
431  */
432  inline boost::uint64_t
433  getDepth () const
434  {
435  return (metadata_->getDepth ());
436  }
437 
438  inline boost::uint64_t
439  getTreeDepth () const
440  {
441  return (this->getDepth ());
442  }
443 
444  /** \brief Computes the expected voxel dimensions at the leaves
445  */
446  bool
447  getBinDimension (double &x, double &y) const;
448 
449  /** \brief gets the side length of an (assumed) perfect cubic voxel.
450  * \note If the initial bounding box specified in constructing the octree is not square, then this method does not return a sensible value
451  * \return the side length of the cubic voxel size at the specified depth
452  */
453  double
454  getVoxelSideLength (const boost::uint64_t& depth) const;
455 
456  /** \brief Gets the smallest (assumed) cubic voxel side lengths. The smallest voxels are located at the max depth of the tree.
457  * \return The side length of a the cubic voxel located at the leaves
458  */
459  double
461  {
462  return (this->getVoxelSideLength (metadata_->getDepth ()));
463  }
464 
465  /** \brief Get coordinate system tag from the JSON metadata file
466  */
467  const std::string&
468  getCoordSystem () const
469  {
470  return (metadata_->getCoordinateSystem ());
471  }
472 
473  // Mutators
474  // -----------------------------------------------------------------------
475 
476  /** \brief Generate multi-resolution LODs for the tree, which are a uniform random sampling all child leafs below the node.
477  */
478  void
479  buildLOD ();
480 
481  /** \brief Prints size of BBox to stdout
482  */
483  void
484  printBoundingBox (const size_t query_depth) const;
485 
486  /** \brief Prints the coordinates of the bounding box of the node to stdout */
487  void
488  printBoundingBox (OutofcoreNodeType& node) const;
489 
490  /** \brief Prints size of the bounding boxes to stdou
491  */
492  inline void
494  {
495  this->printBoundingBox (metadata_->getDepth ());
496  }
497 
498  /** \brief Returns the voxel centers of all existing voxels at \c query_depth
499  \param[out] voxel_centers Vector of PointXYZ voxel centers for nodes that exist at that depth
500  \param[in] query_depth the depth of the tree at which to retrieve occupied/existing voxels
501  */
502  void
503  getOccupiedVoxelCenters(AlignedPointTVector &voxel_centers, size_t query_depth) const;
504 
505  /** \brief Returns the voxel centers of all existing voxels at \c query_depth
506  \param[out] voxel_centers Vector of PointXYZ voxel centers for nodes that exist at that depth
507  \param[in] query_depth the depth of the tree at which to retrieve occupied/existing voxels
508  */
509  void
510  getOccupiedVoxelCenters(std::vector<Eigen::Vector3d, Eigen::aligned_allocator<Eigen::Vector3d> > &voxel_centers, size_t query_depth) const;
511 
512  /** \brief Gets the voxel centers of all occupied/existing leaves of the tree */
513  void
514  getOccupiedVoxelCenters(AlignedPointTVector &voxel_centers) const
515  {
516  getOccupiedVoxelCenters(voxel_centers, metadata_->getDepth ());
517  }
518 
519  /** \brief Returns the voxel centers of all occupied/existing leaves of the tree
520  * \param[out] voxel_centers std::vector of the centers of all occupied leaves of the octree
521  */
522  void
523  getOccupiedVoxelCenters(std::vector<Eigen::Vector3d, Eigen::aligned_allocator<Eigen::Vector3d> > &voxel_centers) const
524  {
525  getOccupiedVoxelCenters(voxel_centers, metadata_->getDepth ());
526  }
527 
528  // Serializers
529  // -----------------------------------------------------------------------
530 
531  /** \brief Save each .bin file as an XYZ file */
532  void
533  convertToXYZ ();
534 
535  /** \brief Write a python script using the vpython module containing all
536  * the bounding boxes */
537  void
538  writeVPythonVisual (const boost::filesystem::path filename);
539 
540  OutofcoreNodeType*
541  getBranchChildPtr (const BranchNode& branch_arg, unsigned char childIdx_arg) const;
542 
544  getLODFilter ();
545 
547  getLODFilter () const;
548 
549  /** \brief Sets the filter to use when building the levels of depth. Recommended filters are pcl::RandomSample<pcl::PCLPointCloud2> or pcl::VoxelGrid */
550  void
552 
553  /** \brief Returns the sample_percent_ used when constructing the LOD. */
554  double
556  {
557  return (sample_percent_);
558  }
559 
560  /** \brief Sets the sampling percent for constructing LODs. Each LOD gets sample_percent^d points.
561  * \param[in] sample_percent_arg Percentage between 0 and 1. */
562  inline void
563  setSamplePercent (const double sample_percent_arg)
564  {
565  this->sample_percent_ = std::fabs (sample_percent_arg) > 1.0 ? 1.0 : std::fabs (sample_percent_arg);
566  }
567 
568  protected:
569  void
570  init (const boost::uint64_t& depth, const Eigen::Vector3d& min, const Eigen::Vector3d& max, const boost::filesystem::path& root_name, const std::string& coord_sys);
571 
573 
575 
578 
580  operator= (const OutofcoreOctreeBase &rval);
581 
582  inline OutofcoreNodeType*
584  {
585  return (this->root_node_);
586  }
587 
588  /** \brief flush empty nodes only */
589  void
590  DeAllocEmptyNodeCache (OutofcoreNodeType* current);
591 
592  /** \brief Write octree definition ".octree" (defined by octree_extension_) to disk */
593  void
594  saveToFile ();
595 
596  /** \brief recursive portion of lod builder */
597  void
598  buildLODRecursive (const std::vector<BranchNode*>& current_branch);
599 
600  /** \brief Increment current depths (LOD for branch nodes) point count; called by addDataAtMaxDepth in OutofcoreOctreeBaseNode
601  */
602  inline void
603  incrementPointsInLOD (boost::uint64_t depth, boost::uint64_t inc);
604 
605  /** \brief Auxiliary function to validate path_name extension is .octree
606  *
607  * \return 0 if bad; 1 if extension is .oct_idx
608  */
609  bool
610  checkExtension (const boost::filesystem::path& path_name);
611 
612 
613  /** \brief DEPRECATED - Flush all nodes' cache
614  * \deprecated this was moved to the octree_node class
615  */
616  void
617  flushToDisk ();
618 
619  /** \brief DEPRECATED - Flush all non leaf nodes' cache
620  * \deprecated
621  */
622  void
623  flushToDiskLazy ();
624 
625  /** \brief DEPRECATED - Flush empty nodes only
626  * \deprecated
627  */
628  void
630 
631  /** \brief Pointer to the root node of the octree data structure */
632  OutofcoreNodeType* root_node_;
633 
634  /** \brief shared mutex for controlling read/write access to disk */
635  mutable boost::shared_mutex read_write_mutex_;
636 
637  boost::shared_ptr<OutofcoreOctreeBaseMetadata> metadata_;
638 
639  /** \brief defined as ".octree" to append to treepath files
640  * \note this might change
641  */
642  const static std::string TREE_EXTENSION_;
643  const static int OUTOFCORE_VERSION_;
644 
645  const static uint64_t LOAD_COUNT_ = static_cast<uint64_t>(2e9);
646 
647  private:
648 
649  /** \brief Auxiliary function to enlarge a bounding box to a cube. */
650  void
651  enlargeToCube (Eigen::Vector3d &bb_min, Eigen::Vector3d &bb_max);
652 
653  /** \brief Auxiliary function to compute the depth of the tree given the bounding box and the desired size of the leaf voxels */
654  boost::uint64_t
655  calculateDepth (const Eigen::Vector3d& min_bb, const Eigen::Vector3d& max_bb, const double leaf_resolution);
656 
657  double sample_percent_;
658 
660 
661  };
662  }
663 }
664 
665 
666 #endif // PCL_OUTOFCORE_OUTOFCOREOCTREEBASE_H_
boost::shared_ptr< const OutofcoreOctreeBase< ContainerT, PointT > > ConstPtr
Definition: octree_base.h:178
void DeAllocEmptyNodeCache()
DEPRECATED - Flush empty nodes only.
void queryFrustum(const double *planes, std::list< std::string > &file_names) const
void setLODFilter(const pcl::Filter< pcl::PCLPointCloud2 >::Ptr &filter_arg)
Sets the filter to use when building the levels of depth.
void getOccupiedVoxelCenters(std::vector< Eigen::Vector3d, Eigen::aligned_allocator< Eigen::Vector3d > > &voxel_centers) const
Returns the voxel centers of all occupied/existing leaves of the tree.
Definition: octree_base.h:523
void flushToDisk()
DEPRECATED - Flush all nodes' cache.
boost::uint64_t getTreeDepth() const
Definition: octree_base.h:439
double getVoxelSideLength() const
Gets the smallest (assumed) cubic voxel side lengths.
Definition: octree_base.h:460
OutofcoreOctreeBaseNode< ContainerT, PointT > BranchNode
Definition: octree_base.h:165
OutofcoreOctreeBaseNode< OutofcoreOctreeRamContainer< PointT >, PointT > octree_ram_node
Definition: octree_base.h:161
boost::uint64_t getNumPointsAtDepth(const boost::uint64_t &depth_index) const
Get number of points at specified LOD.
Definition: octree_base.h:404
boost::shared_ptr< PointCloud > PointCloudPtr
Definition: octree_base.h:185
boost::shared_ptr< OutofcoreOctreeBaseMetadata > metadata_
Definition: octree_base.h:637
OutofcoreBreadthFirstIterator< PointT, ContainerT > BreadthFirstIterator
Definition: octree_base.h:171
boost::uint64_t addDataToLeaf(const AlignedPointTVector &p)
Recursively add points to the tree.
virtual void queryBBIntersects(const Eigen::Vector3d &min_bb, const Eigen::Vector3d &max_bb, const boost::uint32_t query_depth, std::list< std::string > &file_names)
Recursive acquires PCD paths to any node with which the queried bounding box intersects (at query_dep...
void queryBBIncludes_subsample(const Eigen::Vector3d &min, const Eigen::Vector3d &max, uint64_t query_depth, const double percent, AlignedPointTVector &dst) const
Returns a random subsample of points within the given bounding box at query_depth.
OutofcoreOctreeBase(const boost::filesystem::path &root_node_name, const bool load_all)
Load an existing tree.
Definition: octree_base.hpp:77
boost::uint64_t getDepth() const
Get number of LODs, which is the height of the tree.
Definition: octree_base.h:433
void queryBBIncludes(const Eigen::Vector3d &min, const Eigen::Vector3d &max, const boost::uint64_t query_depth, AlignedPointTVector &dst) const
Get Points in BB, only points inside BB.
OutofcoreOctreeBaseNode Class internally representing nodes of an outofcore octree, with accessors to its data via the pcl::outofcore::OutofcoreOctreeDiskContainer class or pcl::outofcore::OutofcoreOctreeRamContainer class, whichever it is templated against.
static const uint64_t LOAD_COUNT_
Definition: octree_base.h:645
virtual void queryBoundingBox(const Eigen::Vector3d &min, const Eigen::Vector3d &max, const int query_depth, const pcl::PCLPointCloud2::Ptr &dst_blob, double percent=1.0)
Query all points falling within the input bounding box at query_depth and return a PCLPointCloud2 obj...
void writeVPythonVisual(const boost::filesystem::path filename)
Write a python script using the vpython module containing all the bounding boxes. ...
boost::shared_ptr< ::pcl::PCLPointCloud2 > Ptr
void setSamplePercent(const double sample_percent_arg)
Sets the sampling percent for constructing LODs.
Definition: octree_base.h:563
void convertToXYZ()
Save each .bin file as an XYZ file.
void printBoundingBox() const
Prints size of the bounding boxes to stdou.
Definition: octree_base.h:493
void incrementPointsInLOD(boost::uint64_t depth, boost::uint64_t inc)
Increment current depths (LOD for branch nodes) point count; called by addDataAtMaxDepth in Outofcore...
void flushToDiskLazy()
DEPRECATED - Flush all non leaf nodes' cache.
void saveToFile()
Write octree definition ".octree" (defined by octree_extension_) to disk.
boost::uint64_t addDataToLeaf_and_genLOD(AlignedPointTVector &p)
Recursively add points to the tree subsampling LODs on the way.
void init(const boost::uint64_t &depth, const Eigen::Vector3d &min, const Eigen::Vector3d &max, const boost::filesystem::path &root_name, const std::string &coord_sys)
OutofcoreOctreeBaseNode< ContainerT, PointT > LeafNode
Definition: octree_base.h:166
const OutofcoreDepthFirstIterator< PointT, ContainerT > ConstIterator
Definition: octree_base.h:169
Filter represents the base filter class.
Definition: filter.h:83
void buildLODRecursive(const std::vector< BranchNode * > &current_branch)
recursive portion of lod builder
void getOccupiedVoxelCenters(AlignedPointTVector &voxel_centers) const
Gets the voxel centers of all occupied/existing leaves of the tree.
Definition: octree_base.h:514
boost::shared_ptr< const std::vector< int > > IndicesConstPtr
Definition: octree_base.h:183
boost::shared_ptr< std::vector< int > > IndicesPtr
Definition: octree_base.h:182
boost::shared_ptr< OutofcoreOctreeBase< ContainerT, PointT > > Ptr
Definition: octree_base.h:177
std::vector< PointT, Eigen::aligned_allocator< PointT > > AlignedPointTVector
Definition: octree_base.h:188
void buildLOD()
Generate multi-resolution LODs for the tree, which are a uniform random sampling all child leafs belo...
OutofcoreOctreeBase< OutofcoreOctreeDiskContainer< PointT >, PointT > octree_disk
Definition: octree_base.h:157
const OutofcoreBreadthFirstIterator< PointT, ContainerT > BreadthFirstConstIterator
Definition: octree_base.h:172
bool getBinDimension(double &x, double &y) const
Computes the expected voxel dimensions at the leaves.
boost::uint64_t queryBoundingBoxNumPoints(const Eigen::Vector3d &min, const Eigen::Vector3d &max, const int query_depth, bool load_from_disk=true)
Queries the number of points in a bounding box.
static const std::string TREE_EXTENSION_
defined as ".octree" to append to treepath files
Definition: octree_base.h:642
boost::uint64_t addPointCloud_and_genLOD(pcl::PCLPointCloud2::Ptr &input_cloud)
Recursively add points to the tree.
PointCloud represents the base class in PCL for storing collections of 3D points. ...
void queryBBIntersects(const Eigen::Vector3d &min, const Eigen::Vector3d &max, const boost::uint32_t query_depth, std::list< std::string > &bin_name) const
Get a list of file paths at query_depth that intersect with your bounding box specified by min and ma...
bool getBoundingBox(Eigen::Vector3d &min, Eigen::Vector3d &max) const
Get the overall bounding box of the outofcore octree; this is the same as the bounding box of the roo...
pcl::PointCloud< PointT > PointCloud
Definition: octree_base.h:180
void getOccupiedVoxelCenters(AlignedPointTVector &voxel_centers, size_t query_depth) const
Returns the voxel centers of all existing voxels at query_depth.
OutofcoreNodeType * getBranchChildPtr(const BranchNode &branch_arg, unsigned char childIdx_arg) const
boost::shared_ptr< const PointCloud > PointCloudConstPtr
Definition: octree_base.h:186
pcl::Filter< pcl::PCLPointCloud2 >::Ptr getLODFilter()
const std::string & getCoordSystem() const
Get coordinate system tag from the JSON metadata file.
Definition: octree_base.h:468
Abstract octree iterator class.
OutofcoreNodeType * root_node_
Pointer to the root node of the octree data structure.
Definition: octree_base.h:632
const OutofcoreDepthFirstIterator< PointT, ContainerT > DepthFirstConstIterator
Definition: octree_base.h:175
const std::vector< boost::uint64_t > & getNumPointsVector() const
Get number of points at each LOD.
Definition: octree_base.h:425
OutofcoreDepthFirstIterator< PointT, ContainerT > DepthFirstIterator
Definition: octree_base.h:174
OutofcoreOctreeBase< OutofcoreOctreeRamContainer< PointT >, PointT > octree_ram
Definition: octree_base.h:160
A point structure representing Euclidean xyz coordinates, and the RGB color.
virtual void queryBoundingBox(const Eigen::Vector3d &min, const Eigen::Vector3d &max, const int query_depth, std::list< std::string > &filenames) const
Returns list of pcd files from nodes whose bounding boxes intersect with the input bounding box...
Definition: octree_base.h:381
OutofcoreOctreeBaseNode< OutofcoreOctreeDiskContainer< PointT >, PointT > octree_disk_node
Definition: octree_base.h:158
OutofcoreNodeType * getRootNode()
Definition: octree_base.h:583
This code defines the octree used for point storage at Urban Robotics.
Definition: octree_base.h:149
boost::uint64_t addPointCloud(PointCloudConstPtr point_cloud)
Copies the points from the point_cloud falling within the bounding box of the octree to the out-of-co...
RandomSample applies a random sampling with uniform probability.
Definition: random_sample.h:56
OutofcoreDepthFirstIterator< PointT, ContainerT > Iterator
Definition: octree_base.h:168
double getSamplePercent() const
Returns the sample_percent_ used when constructing the LOD.
Definition: octree_base.h:555
boost::shared_mutex read_write_mutex_
shared mutex for controlling read/write access to disk
Definition: octree_base.h:635
OutofcoreOctreeBaseNode< ContainerT, PointT > OutofcoreNodeType
Definition: octree_base.h:163
bool checkExtension(const boost::filesystem::path &path_name)
Auxiliary function to validate path_name extension is .octree.
OutofcoreOctreeBase & operator=(OutofcoreOctreeBase &rval)