Point Cloud Library (PCL)  1.6.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
octree_base.hpp
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (c) 2010-2011, Willow Garage, Inc.
6  *
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * * Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  * * Redistributions in binary form must reproduce the above
16  * copyright notice, this list of conditions and the following
17  * disclaimer in the documentation and/or other materials provided
18  * with the distribution.
19  * * Neither the name of Willow Garage, Inc. nor the names of its
20  * contributors may be used to endorse or promote products derived
21  * from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  *
36  * $Id: octree_base.hpp 6119 2012-07-03 18:50:04Z aichim $
37  */
38 
39 #ifndef OCTREE_BASE_HPP
40 #define OCTREE_BASE_HPP
41 
42 #include <vector>
43 
44 #include <pcl/impl/instantiate.hpp>
45 #include <pcl/point_types.h>
46 #include <pcl/octree/octree.h>
47 
48 // maximum depth of octree as we are using "unsigned int" octree keys / bit masks
49 #define OCT_MAXTREEDEPTH ( sizeof(size_t) * 8 )
50 
51 namespace pcl
52 {
53  namespace octree
54  {
56  template<typename DataT, typename LeafT, typename BranchT>
58  leafCount_ (0),
59  branchCount_ (1),
60  objectCount_ (0),
61  rootNode_ (new BranchNode ()),
62  maxObjsPerLeaf_(0),
63  depthMask_ (0),
64  octreeDepth_ (0),
65  maxKey_ (),
66  branchNodePool_ (),
67  leafNodePool_ ()
68  {
69  }
70 
72  template<typename DataT, typename LeafT, typename BranchT>
74  {
75  // deallocate tree structure
76  deleteTree ();
77  delete (rootNode_);
78  poolCleanUp ();
79  }
80 
82  template<typename DataT, typename LeafT, typename BranchT> void
83  OctreeBase<DataT, LeafT, BranchT>::setMaxVoxelIndex (unsigned int maxVoxelIndex_arg)
84  {
85  unsigned int treeDepth;
86 
87  assert (maxVoxelIndex_arg>0);
88 
89  // tree depth == amount of bits of maxVoxels
90  treeDepth = std::max ((std::min (static_cast<unsigned int> (OCT_MAXTREEDEPTH),
91  static_cast<unsigned int> (std::ceil (Log2 (maxVoxelIndex_arg))))),
92  static_cast<unsigned int> (0));
93 
94  // define depthMask_ by setting a single bit to 1 at bit position == tree depth
95  depthMask_ = (1 << (treeDepth - 1));
96  }
97 
99  template<typename DataT, typename LeafT, typename BranchT>
100  void
102  {
103  assert(depth_arg>0);
104 
105  // set octree depth
106  octreeDepth_ = depth_arg;
107 
108  // define depthMask_ by setting a single bit to 1 at bit position == tree depth
109  depthMask_ = (1 << (depth_arg - 1));
110 
111  // define max. keys
112  maxKey_.x = maxKey_.y = maxKey_.z = (1 << depth_arg) - 1;
113  }
114 
116  template<typename DataT, typename LeafT, typename BranchT> void
117  OctreeBase<DataT, LeafT, BranchT>::addData (unsigned int idxX_arg, unsigned int idxY_arg,
118  unsigned int idxZ_arg, const DataT& data_arg)
119  {
120  // generate key
121  OctreeKey key (idxX_arg, idxY_arg, idxZ_arg);
122 
123  // add data_arg to octree
124  addData (key, data_arg);
125  }
126 
128  template<typename DataT, typename LeafT, typename BranchT>bool
129  OctreeBase<DataT, LeafT, BranchT>::getData (unsigned int idxX_arg, unsigned int idxY_arg,
130  unsigned int idxZ_arg, DataT& data_arg) const
131  {
132  // generate key
133  OctreeKey key (idxX_arg, idxY_arg, idxZ_arg);
134 
135  // search for leaf at key
136  LeafNode* leaf = findLeaf (key);
137  if (leaf)
138  {
139  // if successful, decode data to data_arg
140  leaf->getData (data_arg);
141  }
142 
143  // returns true on success
144  return (leaf != 0);
145  }
146 
148  template<typename DataT, typename LeafT, typename BranchT> bool
149  OctreeBase<DataT, LeafT, BranchT>::existLeaf (unsigned int idxX_arg, unsigned int idxY_arg,
150  unsigned int idxZ_arg) const
151  {
152  // generate key
153  OctreeKey key (idxX_arg, idxY_arg, idxZ_arg);
154 
155  // check if key exist in octree
156  return ( existLeaf (key));
157  }
158 
160  template<typename DataT, typename LeafT, typename BranchT> void
161  OctreeBase<DataT, LeafT, BranchT>::removeLeaf (unsigned int idxX_arg, unsigned int idxY_arg,
162  unsigned int idxZ_arg)
163  {
164  // generate key
165  OctreeKey key (idxX_arg, idxY_arg, idxZ_arg);
166 
167  // check if key exist in octree
168  deleteLeafRecursive (key, depthMask_, rootNode_);
169  }
170 
172  template<typename DataT, typename LeafT, typename BranchT> void
174  {
175 
176  if (rootNode_)
177  {
178  // reset octree
179  deleteBranch (*rootNode_);
180  leafCount_ = 0;
181  branchCount_ = 1;
182  objectCount_ = 0;
183 
184  }
185 
186  // delete node pool
187  if (freeMemory_arg)
188  poolCleanUp ();
189 
190  }
191 
193  template<typename DataT, typename LeafT, typename BranchT> void
194  OctreeBase<DataT, LeafT, BranchT>::serializeTree (std::vector<char>& binaryTreeOut_arg)
195  {
196  // serialization requires fixed octree depth
197  // maxObjsPerLeaf_>0 indicates a dynamic octree structure
198  assert (!maxObjsPerLeaf_);
199 
200  OctreeKey newKey;
201 
202  // clear binary vector
203  binaryTreeOut_arg.clear ();
204  binaryTreeOut_arg.reserve (this->branchCount_);
205 
206  serializeTreeRecursive (rootNode_, newKey, &binaryTreeOut_arg, 0 );
207  }
208 
210  template<typename DataT, typename LeafT, typename BranchT> void
211  OctreeBase<DataT, LeafT, BranchT>::serializeTree (std::vector<char>& binaryTreeOut_arg, std::vector<DataT>& dataVector_arg)
212  {
213  // serialization requires fixed octree depth
214  // maxObjsPerLeaf_>0 indicates a dynamic octree structure
215  assert (!maxObjsPerLeaf_);
216 
217  OctreeKey newKey;
218 
219  // clear output vectors
220  binaryTreeOut_arg.clear ();
221  dataVector_arg.clear ();
222 
223  dataVector_arg.reserve (this->objectCount_);
224  binaryTreeOut_arg.reserve (this->branchCount_);
225 
226  serializeTreeRecursive (rootNode_, newKey, &binaryTreeOut_arg, &dataVector_arg );
227  }
228 
230  template<typename DataT, typename LeafT, typename BranchT> void
231  OctreeBase<DataT, LeafT, BranchT>::serializeLeafs (std::vector<DataT>& dataVector_arg)
232  {
233  // serialization requires fixed octree depth
234  // maxObjsPerLeaf_>0 indicates a dynamic octree structure
235  assert (!maxObjsPerLeaf_);
236 
237  OctreeKey newKey;
238 
239  // clear output vector
240  dataVector_arg.clear ();
241 
242  dataVector_arg.reserve(this->objectCount_);
243 
244  serializeTreeRecursive (rootNode_, newKey, 0, &dataVector_arg );
245  }
246 
248  template<typename DataT, typename LeafT, typename BranchT> void
249  OctreeBase<DataT, LeafT, BranchT>::deserializeTree (std::vector<char>& binaryTreeIn_arg)
250  {
251  // serialization requires fixed octree depth
252  // maxObjsPerLeaf_>0 indicates a dynamic octree structure
253  assert (!maxObjsPerLeaf_);
254 
255  OctreeKey newKey;
256 
257  // free existing tree before tree rebuild
258  deleteTree ();
259 
260  //iterator for binary tree structure vector
261  std::vector<char>::const_iterator binaryTreeVectorIterator = binaryTreeIn_arg.begin ();
262  std::vector<char>::const_iterator binaryTreeVectorIteratorEnd = binaryTreeIn_arg.end ();
263 
264  deserializeTreeRecursive (rootNode_, depthMask_, newKey,
265  binaryTreeVectorIterator, binaryTreeVectorIteratorEnd, 0, 0);
266 
267  }
268 
270  template<typename DataT, typename LeafT, typename BranchT> void
271  OctreeBase<DataT, LeafT, BranchT>::deserializeTree (std::vector<char>& binaryTreeIn_arg,
272  std::vector<DataT>& dataVector_arg)
273  {
274  // serialization requires fixed octree depth
275  // maxObjsPerLeaf_>0 indicates a dynamic octree structure
276  assert (!maxObjsPerLeaf_);
277 
278  OctreeKey newKey;
279 
280  // set data iterator to first element
281  typename std::vector<DataT>::const_iterator dataVectorIterator = dataVector_arg.begin ();
282 
283  // set data iterator to last element
284  typename std::vector<DataT>::const_iterator dataVectorEndIterator = dataVector_arg.end ();
285 
286  // free existing tree before tree rebuild
287  deleteTree ();
288 
289  //iterator for binary tree structure vector
290  std::vector<char>::const_iterator binaryTreeVectorIterator = binaryTreeIn_arg.begin ();
291  std::vector<char>::const_iterator binaryTreeVectorIteratorEnd = binaryTreeIn_arg.end ();
292 
293  deserializeTreeRecursive (rootNode_, depthMask_, newKey,
294  binaryTreeVectorIterator, binaryTreeVectorIteratorEnd, &dataVectorIterator, &dataVectorEndIterator);
295 
296  }
297 
299  template<typename DataT, typename LeafT, typename BranchT> void OctreeBase<
300  DataT, LeafT, BranchT>::addDataToLeafRecursive (
301  const OctreeKey& key_arg, unsigned int depthMask_arg,
302  const DataT& data_arg, BranchNode* branch_arg)
303  {
304  // index to branch child
305  unsigned char childIdx;
306 
307  // find branch child from key
308  childIdx = key_arg.getChildIdxWithDepthMask(depthMask_arg);
309 
310  // add data to branch node container
311  branch_arg->setData (data_arg);
312 
313  OctreeNode* childNode = (*branch_arg)[childIdx];
314 
315  if (!childNode)
316  {
317  if ((!maxObjsPerLeaf_) && (depthMask_arg > 1)) {
318  // if required branch does not exist -> create it
319  BranchNode* childBranch;
320  createBranchChild (*branch_arg, childIdx, childBranch);
321 
322  branchCount_++;
323 
324  // recursively proceed with indexed child branch
325  addDataToLeafRecursive (key_arg, depthMask_arg / 2, data_arg, childBranch);
326 
327  } else {
328  LeafNode* childLeaf;
329 
330  // if leaf node at childIdx does not exist
331  createLeafChild (*branch_arg, childIdx, childLeaf);
332  leafCount_++;
333 
334  // add data to leaf
335  childLeaf->setData (data_arg);
336  objectCount_++;
337  }
338  } else {
339 
340  // Node exists already
341  switch (childNode->getNodeType()) {
342  case BRANCH_NODE:
343  // recursively proceed with indexed child branch
344  addDataToLeafRecursive (key_arg, depthMask_arg / 2, data_arg, static_cast<BranchNode*> (childNode));
345  break;
346 
347  case LEAF_NODE:
348  LeafNode* childLeaf = static_cast<LeafNode*> (childNode);
349 
350  if ( (!maxObjsPerLeaf_) || (!depthMask_arg) )
351  {
352  // add data to leaf
353  childLeaf->setData (data_arg);
354  objectCount_++;
355  } else {
356  size_t leafObjCount = childLeaf->getSize();
357 
358  if (leafObjCount<maxObjsPerLeaf_) {
359  // add data to leaf
360  childLeaf->setData (data_arg);
361  objectCount_++;
362  } else {
363  // leaf node needs to be expanded
364 
365  // copy leaf data
366  std::vector<DataT> leafData;
367  leafData.reserve(leafObjCount);
368 
369  childLeaf->getData (leafData);
370 
371  // delete current leaf node
372  deleteBranchChild(*branch_arg,childIdx);
373  leafCount_ --;
374 
375  // create new branch node
376  BranchNode* childBranch;
377  createBranchChild (*branch_arg, childIdx, childBranch);
378  branchCount_ ++;
379 
380  typename std::vector<DataT>::const_iterator lData = leafData.begin();
381  typename std::vector<DataT>::const_iterator lDataEnd = leafData.end();
382 
383  // add data to new branch
384  OctreeKey dataKey;
385  while (lData!=lDataEnd) {
386  // get data object
387  const DataT& data = *lData++;
388 
389  // generate new key for data object
390  if (this->genOctreeKeyForDataT(data, dataKey)) {
391  addDataToLeafRecursive (dataKey, depthMask_arg / 2, data, childBranch);
392  }
393  }
394 
395  // and add new DataT object
396  addDataToLeafRecursive (key_arg, depthMask_arg / 2, data_arg, childBranch);
397 
398  // correct object counter
399  objectCount_ -= leafObjCount;
400  }
401  }
402  break;
403  }
404  }
405  }
406 
408  template<typename DataT, typename LeafT, typename BranchT> void
409  OctreeBase<DataT, LeafT, BranchT>::findLeafRecursive (
410  const OctreeKey& key_arg, unsigned int depthMask_arg, BranchNode* branch_arg, LeafNode*& result_arg) const
411  {
412  // index to branch child
413  unsigned char childIdx;
414 
415  // find branch child from key
416  childIdx = key_arg.getChildIdxWithDepthMask(depthMask_arg);
417 
418  OctreeNode* childNode = (*branch_arg)[childIdx];
419 
420  if (childNode) {
421  switch (childNode->getNodeType()) {
422  case BRANCH_NODE:
423  // we have not reached maximum tree depth
424  BranchNode* childBranch;
425  childBranch = static_cast<BranchNode*> (childNode);
426 
427  findLeafRecursive (key_arg, depthMask_arg / 2, childBranch, result_arg);
428  break;
429 
430  case LEAF_NODE:
431  // return existing leaf node
432  LeafNode* childLeaf;
433  childLeaf = static_cast<LeafNode*> (childNode);
434  result_arg = childLeaf;
435  break;
436  }
437  }
438  }
439 
441  template<typename DataT, typename LeafT, typename BranchT> bool
442  OctreeBase<DataT, LeafT, BranchT>::deleteLeafRecursive (const OctreeKey& key_arg, unsigned int depthMask_arg,
443  BranchNode* branch_arg)
444  {
445  // index to branch child
446  unsigned char childIdx;
447  // indicates if branch is empty and can be safely removed
448  bool bNoChilds;
449 
450  // find branch child from key
451  childIdx = key_arg.getChildIdxWithDepthMask(depthMask_arg);
452 
453  OctreeNode* childNode = (*branch_arg)[childIdx];
454 
455  if (childNode) {
456  switch (childNode->getNodeType()) {
457 
458  case BRANCH_NODE:
459  BranchNode* childBranch;
460  childBranch = static_cast<BranchNode*> (childNode);
461 
462  // recursively explore the indexed child branch
463  bNoChilds = deleteLeafRecursive (key_arg, depthMask_arg / 2, childBranch);
464 
465  if (!bNoChilds)
466  {
467  // child branch does not own any sub-child nodes anymore -> delete child branch
468  deleteBranchChild(*branch_arg, childIdx);
469  branchCount_--;
470  }
471  break;
472 
473  case LEAF_NODE:
474  // return existing leaf node
475 
476  // our child is a leaf node -> delete it
477  deleteBranchChild (*branch_arg, childIdx);
478  leafCount_--;
479  break;
480  }
481  }
482 
483  // check if current branch still owns childs
484  bNoChilds = false;
485  for (childIdx = 0; (!bNoChilds) && (childIdx < 8); childIdx++)
486  {
487  bNoChilds = branch_arg->hasChild(childIdx);
488  }
489  // return true if current branch can be deleted
490  return (bNoChilds);
491  }
492 
494  template<typename DataT, typename LeafT, typename BranchT> void OctreeBase<
495  DataT, LeafT, BranchT>::serializeTreeRecursive (const BranchNode* branch_arg, OctreeKey& key_arg,
496  std::vector<char>* binaryTreeOut_arg,
497  typename std::vector<DataT>* dataVector_arg) const
498  {
499 
500  // child iterator
501  unsigned char childIdx;
502  char nodeBitPattern;
503 
504  // branch occupancy bit pattern
505  nodeBitPattern = getBranchBitPattern (*branch_arg);
506 
507  // write bit pattern to output vector
508  if (binaryTreeOut_arg)
509  binaryTreeOut_arg->push_back (nodeBitPattern);
510 
511  // iterate over all children
512  for (childIdx = 0; childIdx < 8; childIdx++)
513  {
514 
515  // if child exist
516  if (branch_arg->hasChild(childIdx))
517  {
518  // add current branch voxel to key
519  key_arg.pushBranch(childIdx);
520 
521  const OctreeNode *childNode = branch_arg->getChildPtr(childIdx);
522 
523  switch (childNode->getNodeType ())
524  {
525  case BRANCH_NODE:
526  {
527  // recursively proceed with indexed child branch
528  serializeTreeRecursive (
529  static_cast<const BranchNode*> (childNode), key_arg,
530  binaryTreeOut_arg, dataVector_arg);
531  break;
532  }
533  case LEAF_NODE:
534  {
535  const LeafNode* childLeaf = static_cast<const LeafNode*> (childNode);
536 
537  if (dataVector_arg)
538  childLeaf->getData (*dataVector_arg);
539 
540  // we reached a leaf node -> execute serialization callback
541  serializeTreeCallback (*childLeaf, key_arg);
542  break;
543  }
544  default:
545  break;
546  }
547 
548  // pop current branch voxel from key
549  key_arg.popBranch();
550  }
551  }
552  }
553 
554 
555 
557  template<typename DataT, typename LeafT, typename BranchT> void
558  OctreeBase<DataT, LeafT, BranchT>::deserializeTreeRecursive (BranchNode* branch_arg,
559  unsigned int depthMask_arg, OctreeKey& key_arg,
560  typename std::vector<char>::const_iterator& binaryTreeIT_arg,
561  typename std::vector<char>::const_iterator& binaryTreeIT_End_arg,
562  typename std::vector<DataT>::const_iterator* dataVectorIterator_arg,
563  typename std::vector<DataT>::const_iterator* dataVectorEndIterator_arg)
564  {
565  // child iterator
566  unsigned char childIdx;
567  char nodeBits;
568 
569  if (binaryTreeIT_arg != binaryTreeIT_End_arg ) {
570  // read branch occupancy bit pattern from input vector
571  nodeBits = (*binaryTreeIT_arg);
572  binaryTreeIT_arg++;
573 
574  // iterate over all children
575  for (childIdx = 0; childIdx < 8; childIdx++)
576  {
577  // if occupancy bit for childIdx is set..
578  if (nodeBits & (1 << childIdx))
579  {
580  // add current branch voxel to key
581  key_arg.pushBranch(childIdx);
582 
583  if (depthMask_arg > 1)
584  {
585  // we have not reached maximum tree depth
586  BranchNode * newBranch;
587 
588  // create new child branch
589  createBranchChild (*branch_arg, childIdx, newBranch);
590 
591  branchCount_++;
592 
593  // recursively proceed with new child branch
594  deserializeTreeRecursive (newBranch, depthMask_arg / 2, key_arg, binaryTreeIT_arg,binaryTreeIT_End_arg, dataVectorIterator_arg,
595  dataVectorEndIterator_arg);
596  }
597  else
598  {
599  // we reached leaf node level
600 
601  LeafNode* childLeaf;
602 
603  // create leaf node
604  createLeafChild (*branch_arg, childIdx, childLeaf);
605 
606  OctreeKey dataKey;
607  bool bKeyBasedEncoding = false;
608 
609  if (dataVectorIterator_arg
610  && (*dataVectorIterator_arg != *dataVectorEndIterator_arg))
611  {
612 
613  // add DataT objects to octree leaf as long as their key fit to voxel
614  while ( ( (*dataVectorIterator_arg)
615  != (*dataVectorEndIterator_arg))
616  && (this->genOctreeKeyForDataT (**dataVectorIterator_arg,
617  dataKey) && (dataKey == key_arg)))
618  {
619  childLeaf->setData (**dataVectorIterator_arg);
620  (*dataVectorIterator_arg)++;
621  bKeyBasedEncoding = true;
622  objectCount_++;
623  }
624 
625  // add single DataT object to octree if key-based encoding is disabled
626  if (!bKeyBasedEncoding)
627  {
628  childLeaf->setData (**dataVectorIterator_arg);
629  (*dataVectorIterator_arg)++;
630  objectCount_++;
631  }
632  }
633 
634  leafCount_++;
635 
636  // execute deserialization callback
637  deserializeTreeCallback (*childLeaf, key_arg);
638  }
639 
640  // pop current branch voxel from key
641  key_arg.popBranch();
642  }
643  }
644  }
645  }
646 
647  }
648 }
649 
650 #define PCL_INSTANTIATE_OctreeBase(T) template class PCL_EXPORTS pcl::octree::OctreeBase<T>;
651 
652 #endif
653