00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #ifndef OCTREE_2BUF_BASE_HPP
00040 #define OCTREE_2BUF_BASE_HPP
00041
00042 namespace pcl
00043 {
00044 namespace octree
00045 {
00047 template<typename DataT, typename LeafT, typename BranchT>
00048 Octree2BufBase<DataT, LeafT, BranchT>::Octree2BufBase () :
00049 leafCount_ (0),
00050 branchCount_ (1),
00051 objectCount_ (0),
00052 rootNode_ (new BranchNode ()),
00053 depthMask_ (0),
00054 maxKey_ (),
00055 branchNodePool_ (),
00056 leafNodePool_ (),
00057 bufferSelector_ (0),
00058 treeDirtyFlag_ (false),
00059 octreeDepth_ (0)
00060 {
00061 }
00062
00064 template<typename DataT, typename LeafT, typename BranchT>
00065 Octree2BufBase<DataT, LeafT, BranchT>::~Octree2BufBase ()
00066 {
00067
00068 deleteTree ();
00069 delete (rootNode_);
00070 poolCleanUp ();
00071 }
00072
00074 template<typename DataT, typename LeafT, typename BranchT> void
00075 Octree2BufBase<DataT, LeafT, BranchT>::setMaxVoxelIndex (unsigned int maxVoxelIndex_arg)
00076 {
00077 unsigned int treeDepth;
00078
00079 assert (maxVoxelIndex_arg > 0);
00080
00081
00082 treeDepth = std::max ((std::min (static_cast<unsigned int> (OCT_MAXTREEDEPTH),
00083 static_cast<unsigned int> (std::ceil (Log2 (maxVoxelIndex_arg))))),
00084 static_cast<unsigned int> (0));
00085
00086
00087 depthMask_ = (1 << (treeDepth - 1));
00088 }
00089
00091 template<typename DataT, typename LeafT, typename BranchT> void
00092 Octree2BufBase<DataT, LeafT, BranchT>::setTreeDepth (unsigned int depth_arg)
00093 {
00094 assert (depth_arg > 0);
00095
00096
00097 octreeDepth_ = depth_arg;
00098
00099
00100 depthMask_ = (1 << (depth_arg - 1));
00101
00102
00103 maxKey_.x = maxKey_.y = maxKey_.z = (1 << depth_arg) - 1;
00104 }
00105
00107 template<typename DataT, typename LeafT, typename BranchT> void
00108 Octree2BufBase<DataT, LeafT, BranchT>::addData (unsigned int idxX_arg, unsigned int idxY_arg,
00109 unsigned int idxZ_arg, const DataT& data_arg)
00110 {
00111
00112 OctreeKey key (idxX_arg, idxY_arg, idxZ_arg);
00113
00114
00115 addData (key, data_arg);
00116 }
00117
00119 template<typename DataT, typename LeafT, typename BranchT> bool
00120 Octree2BufBase<DataT, LeafT, BranchT>::getData (unsigned int idxX_arg, unsigned int idxY_arg,
00121 unsigned int idxZ_arg, DataT& data_arg) const
00122 {
00123
00124 OctreeKey key (idxX_arg, idxY_arg, idxZ_arg);
00125
00126
00127 LeafT* leaf = findLeaf (key);
00128 if (leaf)
00129 {
00130
00131 leaf->getData (data_arg);
00132 }
00133
00134 return (leaf != 0);
00135 }
00136
00138 template<typename DataT, typename LeafT, typename BranchT> bool
00139 Octree2BufBase<DataT, LeafT, BranchT>::existLeaf (unsigned int idxX_arg, unsigned int idxY_arg,
00140 unsigned int idxZ_arg) const
00141 {
00142
00143 OctreeKey key (idxX_arg, idxY_arg, idxZ_arg);
00144
00145
00146 return existLeaf (key);
00147 }
00148
00150 template<typename DataT, typename LeafT, typename BranchT> void
00151 Octree2BufBase<DataT, LeafT, BranchT>::removeLeaf (unsigned int idxX_arg, unsigned int idxY_arg,
00152 unsigned int idxZ_arg)
00153 {
00154
00155 OctreeKey key (idxX_arg, idxY_arg, idxZ_arg);
00156
00157
00158 return (this->removeLeaf (key));
00159 }
00160
00162 template<typename DataT, typename LeafT, typename BranchT> void
00163 Octree2BufBase<DataT, LeafT, BranchT>::deleteTree ( bool freeMemory_arg )
00164 {
00165 if (rootNode_)
00166 {
00167
00168 deleteBranch (*rootNode_);
00169 leafCount_ = 0;
00170 branchCount_ = 1;
00171 objectCount_ = 0;
00172
00173 treeDirtyFlag_ = false;
00174 depthMask_ = 0;
00175 octreeDepth_ = 0;
00176 }
00177
00178
00179 if (freeMemory_arg)
00180 poolCleanUp ();
00181 }
00182
00184 template<typename DataT, typename LeafT, typename BranchT> void
00185 Octree2BufBase<DataT, LeafT, BranchT>::switchBuffers ()
00186 {
00187 if (treeDirtyFlag_)
00188 {
00189
00190 treeCleanUpRecursive (rootNode_);
00191 }
00192
00193
00194 bufferSelector_ = !bufferSelector_;
00195
00196
00197 treeDirtyFlag_ = true;
00198 leafCount_ = 0;
00199 objectCount_ = 0;
00200 branchCount_ = 1;
00201
00202 unsigned char childIdx;
00203
00204 for (childIdx = 0; childIdx < 8; childIdx++)
00205 {
00206 rootNode_->setChildPtr(bufferSelector_, childIdx, 0);
00207 }
00208 }
00209
00211 template<typename DataT, typename LeafT, typename BranchT> void
00212 Octree2BufBase<DataT, LeafT, BranchT>::serializeTree (std::vector<char>& binaryTreeOut_arg, bool doXOREncoding_arg)
00213 {
00214 OctreeKey newKey;
00215
00216
00217 binaryTreeOut_arg.clear ();
00218 binaryTreeOut_arg.reserve (this->branchCount_);
00219
00220 serializeTreeRecursive (rootNode_, newKey, &binaryTreeOut_arg, 0,
00221 doXOREncoding_arg, false, 0);
00222
00223
00224 treeDirtyFlag_ = false;
00225 }
00226
00228 template<typename DataT, typename LeafT, typename BranchT> void
00229 Octree2BufBase<DataT, LeafT, BranchT>::serializeTree (std::vector<char>& binaryTreeOut_arg,
00230 std::vector<DataT>& dataVector_arg, bool doXOREncoding_arg)
00231 {
00232 OctreeKey newKey;
00233
00234
00235 binaryTreeOut_arg.clear ();
00236 dataVector_arg.clear ();
00237
00238 dataVector_arg.reserve (objectCount_);
00239 binaryTreeOut_arg.reserve (this->branchCount_);
00240
00241 serializeTreeRecursive (rootNode_, newKey, &binaryTreeOut_arg, &dataVector_arg, doXOREncoding_arg, false, 0);
00242
00243
00244 treeDirtyFlag_ = false;
00245 }
00246
00248 template<typename DataT, typename LeafT, typename BranchT> void
00249 Octree2BufBase<DataT, LeafT, BranchT>::serializeLeafs (std::vector<DataT>& dataVector_arg)
00250 {
00251 OctreeKey newKey;
00252
00253
00254 dataVector_arg.clear ();
00255
00256 dataVector_arg.reserve (objectCount_);
00257
00258 serializeTreeRecursive (rootNode_, newKey, 0, &dataVector_arg, false, false, 0);
00259
00260
00261 treeDirtyFlag_ = false;
00262 }
00263
00265 template<typename DataT, typename LeafT, typename BranchT> void
00266 Octree2BufBase<DataT, LeafT, BranchT>::deserializeTree (std::vector<char>& binaryTreeIn_arg, bool doXORDecoding_arg)
00267 {
00268 OctreeKey newKey;
00269
00270
00271 leafCount_ = 0;
00272
00273
00274 std::vector<char>::const_iterator binaryTreeVectorIterator =
00275 binaryTreeIn_arg.begin ();
00276 std::vector<char>::const_iterator binaryTreeVectorIteratorEnd =
00277 binaryTreeIn_arg.end ();
00278
00279 deserializeTreeRecursive (rootNode_, depthMask_, newKey,
00280 binaryTreeVectorIterator, binaryTreeVectorIteratorEnd, 0, 0, false,
00281 doXORDecoding_arg);
00282
00283
00284 treeDirtyFlag_ = false;
00285 }
00286
00288 template<typename DataT, typename LeafT, typename BranchT> void
00289 Octree2BufBase<DataT, LeafT, BranchT>::deserializeTree (std::vector<char>& binaryTreeIn_arg,
00290 std::vector<DataT>& dataVector_arg, bool doXORDecoding_arg)
00291 {
00292 OctreeKey newKey;
00293
00294
00295 typename std::vector<DataT>::const_iterator dataVectorIterator = dataVector_arg.begin ();
00296
00297
00298 typename std::vector<DataT>::const_iterator dataVectorEndIterator = dataVector_arg.end ();
00299
00300
00301 leafCount_ = 0;
00302
00303
00304 std::vector<char>::const_iterator binaryTreeVectorIterator = binaryTreeIn_arg.begin ();
00305 std::vector<char>::const_iterator binaryTreeVectorIteratorEnd = binaryTreeIn_arg.end ();
00306
00307 deserializeTreeRecursive (rootNode_, depthMask_, newKey, binaryTreeVectorIterator, binaryTreeVectorIteratorEnd, &dataVectorIterator,
00308 &dataVectorEndIterator, false, doXORDecoding_arg);
00309
00310
00311
00312 treeDirtyFlag_ = false;
00313 }
00314
00315
00317 template<typename DataT, typename LeafT, typename BranchT> void
00318 Octree2BufBase<DataT, LeafT, BranchT>::serializeNewLeafs (std::vector<DataT>& dataVector_arg,
00319 const int minPointsPerLeaf_arg)
00320 {
00321 OctreeKey newKey;
00322
00323
00324 dataVector_arg.clear ();
00325
00326 dataVector_arg.reserve (leafCount_);
00327
00328 serializeTreeRecursive (rootNode_, newKey, 0, &dataVector_arg, false, true, minPointsPerLeaf_arg);
00329
00330
00331 treeDirtyFlag_ = false;
00332 }
00333
00335 template<typename DataT, typename LeafT, typename BranchT> LeafT*
00336 Octree2BufBase<DataT, LeafT, BranchT>::createLeafRecursive (const OctreeKey& key_arg, unsigned int depthMask_arg,
00337 BranchNode* branch_arg, bool branchReset_arg)
00338 {
00339
00340 unsigned char childIdx;
00341 LeafT* result = 0;
00342
00343
00344 if (branchReset_arg)
00345 {
00346
00347 for (childIdx = 0; childIdx < 8; childIdx++)
00348 {
00349 branch_arg->setChildPtr(bufferSelector_, childIdx, 0);
00350 }
00351 }
00352
00353
00354 childIdx = key_arg.getChildIdxWithDepthMask (depthMask_arg);
00355
00356 if (depthMask_arg > 1)
00357 {
00358
00359 BranchNode* childBranch;
00360 bool doNodeReset;
00361
00362 doNodeReset = false;
00363
00364
00365 if (!branch_arg->hasChild(bufferSelector_, childIdx))
00366 {
00367
00368
00369 if (branch_arg->hasChild(!bufferSelector_, childIdx))
00370 {
00371 OctreeNode* childNode = branch_arg->getChildPtr(!bufferSelector_,childIdx);
00372
00373 if (childNode->getNodeType()==BRANCH_NODE) {
00374 childBranch = static_cast<BranchNode*> (childNode);
00375 branch_arg->setChildPtr(bufferSelector_, childIdx, childNode);
00376 } else {
00377
00378 deleteBranchChild (*branch_arg, !bufferSelector_, childIdx);
00379 createBranchChild (*branch_arg, childIdx, childBranch);
00380 }
00381
00382
00383 doNodeReset = true;
00384
00385 }
00386 else
00387 {
00388
00389 createBranchChild (*branch_arg, childIdx, childBranch);
00390 }
00391
00392 branchCount_++;
00393 }
00394
00395 else
00396 childBranch = static_cast<BranchNode*> (branch_arg->getChildPtr(bufferSelector_,childIdx));
00397
00398
00399 result = createLeafRecursive (key_arg, depthMask_arg / 2, childBranch, doNodeReset);
00400 }
00401 else
00402 {
00403
00404 LeafNode* childLeaf;
00405 if (!branch_arg->hasChild(bufferSelector_, childIdx))
00406 {
00407
00408
00409
00410 if (branch_arg->hasChild(!bufferSelector_, childIdx))
00411 {
00412
00413 OctreeNode * childNode = branch_arg->getChildPtr(!bufferSelector_,childIdx);
00414 if (childNode->getNodeType () == LEAF_NODE)
00415 {
00416 childLeaf = static_cast<LeafNode*> (childNode);
00417 branch_arg->setChildPtr(bufferSelector_, childIdx, childNode);
00418 childLeaf->reset ();
00419 } else {
00420
00421 deleteBranchChild (*branch_arg, !bufferSelector_, childIdx);
00422 createLeafChild (*branch_arg, childIdx, childLeaf);
00423 }
00424 leafCount_++;
00425 }
00426 else
00427 {
00428
00429 createLeafChild (*branch_arg, childIdx, childLeaf);
00430 leafCount_++;
00431 }
00432
00433
00434 result = childLeaf;
00435 }
00436 else
00437 {
00438
00439 childLeaf = static_cast<LeafNode*> (branch_arg->getChildPtr(bufferSelector_,childIdx));
00440
00441
00442 result = childLeaf;
00443 }
00444 }
00445
00446 return (result);
00447 }
00448
00450 template<typename DataT, typename LeafT, typename BranchT> LeafT*
00451 Octree2BufBase<DataT, LeafT, BranchT>::findLeafRecursive (const OctreeKey& key_arg, unsigned int depthMask_arg,
00452 BranchNode* branch_arg) const
00453 {
00454
00455 unsigned char childIdx;
00456 LeafT* result = 0;
00457
00458
00459 childIdx = key_arg.getChildIdxWithDepthMask (depthMask_arg);
00460
00461 if (depthMask_arg > 1)
00462 {
00463
00464 BranchNode* childBranch;
00465 childBranch = static_cast<BranchNode*> (branch_arg->getChildPtr(bufferSelector_,childIdx));
00466
00467 if (childBranch)
00468
00469 result = findLeafRecursive (key_arg, depthMask_arg / 2, childBranch);
00470 }
00471 else
00472 {
00473
00474 if (branch_arg->hasChild(bufferSelector_, childIdx))
00475 {
00476
00477 LeafNode* childLeaf = static_cast<LeafNode*> (branch_arg->getChildPtr(bufferSelector_,childIdx));
00478 result = childLeaf;
00479 }
00480 }
00481 return (result);
00482 }
00483
00485 template<typename DataT, typename LeafT, typename BranchT> bool
00486 Octree2BufBase<DataT, LeafT, BranchT>::deleteLeafRecursive (const OctreeKey& key_arg, unsigned int depthMask_arg,
00487 BranchNode* branch_arg)
00488 {
00489
00490 unsigned char childIdx;
00491
00492 bool bNoChilds;
00493
00494
00495 childIdx = key_arg.getChildIdxWithDepthMask (depthMask_arg);
00496
00497 if (depthMask_arg > 1)
00498 {
00499
00500 BranchNode* childBranch;
00501 bool bBranchOccupied;
00502
00503
00504 childBranch = static_cast<BranchNode*> (branch_arg->getChildPtr(bufferSelector_,childIdx));
00505
00506 if (childBranch)
00507 {
00508
00509 bBranchOccupied = deleteLeafRecursive (key_arg, depthMask_arg / 2, childBranch);
00510
00511 if (!bBranchOccupied)
00512 {
00513
00514 deleteBranchChild (*branch_arg, bufferSelector_, childIdx);
00515 branchCount_--;
00516 }
00517 }
00518 }
00519 else
00520 {
00521
00522 deleteBranchChild (*branch_arg, bufferSelector_, childIdx);
00523 leafCount_--;
00524 }
00525
00526
00527 bNoChilds = false;
00528 for (childIdx = 0; childIdx < 8; childIdx++)
00529 {
00530 bNoChilds = branch_arg->hasChild(bufferSelector_, childIdx);
00531 if (bNoChilds)
00532 break;
00533 }
00534
00535
00536 return (bNoChilds);
00537 }
00538
00540 template<typename DataT, typename LeafT, typename BranchT> void Octree2BufBase<
00541 DataT, LeafT, BranchT>::serializeTreeRecursive (BranchNode* branch_arg,
00542 OctreeKey& key_arg, std::vector<char>* binaryTreeOut_arg,
00543 typename std::vector<DataT>* dataVector_arg, bool doXOREncoding_arg,
00544 bool newLeafsFilter_arg, std::size_t minPointsPerLeaf_arg)
00545 {
00546
00547 unsigned char childIdx;
00548
00549
00550 char branchBitPatternCurrBuffer;
00551 char branchBitPatternPrevBuffer;
00552 char nodeXORBitPattern;
00553
00554
00555 branchBitPatternCurrBuffer = getBranchBitPattern (*branch_arg, bufferSelector_);
00556 branchBitPatternPrevBuffer = getBranchBitPattern (*branch_arg, !bufferSelector_);
00557
00558
00559 nodeXORBitPattern = branchBitPatternCurrBuffer ^ branchBitPatternPrevBuffer;
00560
00561 if (binaryTreeOut_arg)
00562 {
00563 if (doXOREncoding_arg)
00564 {
00565
00566 binaryTreeOut_arg->push_back (nodeXORBitPattern);
00567 }
00568 else
00569 {
00570
00571 binaryTreeOut_arg->push_back (branchBitPatternCurrBuffer);
00572 }
00573 }
00574
00575
00576 for (childIdx = 0; childIdx < 8; childIdx++)
00577 {
00578 if (branch_arg->hasChild(bufferSelector_, childIdx))
00579 {
00580
00581 key_arg.pushBranch(childIdx);
00582
00583 OctreeNode *childNode = branch_arg->getChildPtr(bufferSelector_,childIdx);
00584
00585 switch (childNode->getNodeType ())
00586 {
00587 case BRANCH_NODE:
00588 {
00589
00590 serializeTreeRecursive (static_cast<BranchNode*> (childNode),
00591 key_arg, binaryTreeOut_arg, dataVector_arg, doXOREncoding_arg,
00592 newLeafsFilter_arg, minPointsPerLeaf_arg);
00593 break;
00594 }
00595 case LEAF_NODE:
00596 {
00597 LeafNode* childLeaf = static_cast<LeafNode*> (childNode);
00598
00599
00600 if (childLeaf->getSize () >= minPointsPerLeaf_arg)
00601 {
00602 if (!newLeafsFilter_arg)
00603 {
00604 if (dataVector_arg)
00605 childLeaf->getData (*dataVector_arg);
00606
00607
00608 serializeTreeCallback (*childLeaf, key_arg);
00609 }
00610 else if (!branch_arg->hasChild (!bufferSelector_, childIdx))
00611 {
00612 if (dataVector_arg)
00613 childLeaf->getData (*dataVector_arg);
00614
00615 serializeTreeCallback (*childLeaf, key_arg);
00616 }
00617 }
00618
00619
00620 break;
00621 }
00622 default:
00623 break;
00624 }
00625
00626
00627 key_arg.popBranch();
00628 }
00629 else if (branch_arg->hasChild (!bufferSelector_, childIdx))
00630 {
00631
00632
00633 deleteBranchChild (*branch_arg, !bufferSelector_, childIdx);
00634
00635 }
00636
00637 }
00638 }
00639
00640
00642 template<typename DataT, typename LeafT, typename BranchT> void
00643 Octree2BufBase<DataT, LeafT, BranchT>::deserializeTreeRecursive (BranchNode* branch_arg,
00644 unsigned int depthMask_arg, OctreeKey& key_arg,
00645 typename std::vector<char>::const_iterator& binaryTreeIT_arg,
00646 typename std::vector<char>::const_iterator& binaryTreeIT_End_arg,
00647 typename std::vector<DataT>::const_iterator* dataVectorIterator_arg,
00648 typename std::vector<DataT>::const_iterator* dataVectorEndIterator_arg,
00649 bool branchReset_arg, bool doXORDecoding_arg)
00650 {
00651
00652 unsigned char childIdx;
00653
00654
00655 char nodeBits;
00656 char recoveredNodeBits;
00657
00658
00659 if (branchReset_arg)
00660 {
00661
00662 for (childIdx = 0; childIdx < 8; childIdx++)
00663 {
00664 branch_arg->setChildPtr(bufferSelector_, childIdx, 0);
00665 }
00666 }
00667
00668 if (binaryTreeIT_arg!=binaryTreeIT_End_arg) {
00669
00670 nodeBits = *binaryTreeIT_arg++;
00671
00672
00673
00674 if (doXORDecoding_arg)
00675 {
00676 recoveredNodeBits = getBranchBitPattern (*branch_arg, !bufferSelector_) ^ nodeBits;
00677 }
00678 else
00679 {
00680 recoveredNodeBits = nodeBits;
00681 }
00682
00683
00684 for (childIdx = 0; childIdx < 8; childIdx++)
00685 {
00686
00687 if (recoveredNodeBits & (1 << childIdx))
00688 {
00689
00690 key_arg.pushBranch(childIdx);
00691
00692 bool doNodeReset;
00693
00694 doNodeReset = false;
00695
00696 if (depthMask_arg > 1)
00697 {
00698
00699
00700 BranchNode* childBranch;
00701
00702
00703 if (!branch_arg->hasChild(bufferSelector_, childIdx))
00704 {
00705
00706 if (branch_arg->hasChild(!bufferSelector_, childIdx))
00707 {
00708 OctreeNode* childNode = branch_arg->getChildPtr(!bufferSelector_,childIdx);
00709
00710 if (childNode->getNodeType()==BRANCH_NODE) {
00711 childBranch = static_cast<BranchNode*> (childNode);
00712 branch_arg->setChildPtr(bufferSelector_, childIdx, childNode);
00713 } else {
00714
00715 deleteBranchChild (*branch_arg, !bufferSelector_, childIdx);
00716 createBranchChild (*branch_arg, childIdx, childBranch);
00717 }
00718
00719
00720 doNodeReset = true;
00721 }
00722 else
00723 {
00724
00725 createBranchChild (*branch_arg, childIdx, childBranch);
00726 }
00727
00728 branchCount_++;
00729
00730 }
00731 else
00732 {
00733
00734 childBranch = static_cast<BranchNode*> (branch_arg->getChildPtr(bufferSelector_,childIdx));
00735 }
00736
00737
00738 deserializeTreeRecursive (childBranch, depthMask_arg / 2, key_arg,
00739 binaryTreeIT_arg, binaryTreeIT_End_arg,
00740 dataVectorIterator_arg, dataVectorEndIterator_arg,
00741 doNodeReset, doXORDecoding_arg);
00742
00743 }
00744 else
00745 {
00746
00747 LeafNode* childLeaf;
00748
00749
00750 if (branch_arg->hasChild(!bufferSelector_, childIdx))
00751 {
00752
00753 OctreeNode* childNode = branch_arg->getChildPtr(!bufferSelector_,childIdx);
00754 if (childNode->getNodeType()==LEAF_NODE) {
00755 childLeaf = static_cast<LeafNode*> (childNode);
00756 branch_arg->setChildPtr(bufferSelector_, childIdx, childNode);
00757 childLeaf->reset ();
00758 } else {
00759
00760 deleteBranchChild (*branch_arg, !bufferSelector_, childIdx);
00761 createLeafChild (*branch_arg, childIdx, childLeaf);
00762 }
00763 }
00764 else
00765 {
00766
00767 createLeafChild (*branch_arg, childIdx, childLeaf);
00768 }
00769
00770 leafCount_++;
00771
00772 OctreeKey dataKey;
00773 bool bKeyBasedEncoding = false;
00774
00775 if (dataVectorIterator_arg && dataVectorEndIterator_arg)
00776 {
00777
00778 while ( (*dataVectorIterator_arg != *dataVectorEndIterator_arg)
00779 && (this->genOctreeKeyForDataT (**dataVectorIterator_arg,
00780 dataKey) && (dataKey == key_arg)))
00781 {
00782 childLeaf->setData (**dataVectorIterator_arg);
00783 (*dataVectorIterator_arg)++;
00784 bKeyBasedEncoding = true;
00785 objectCount_++;
00786 }
00787
00788
00789 if (!bKeyBasedEncoding)
00790 {
00791 childLeaf->setData (**dataVectorIterator_arg);
00792 (*dataVectorIterator_arg)++;
00793 objectCount_++;
00794 }
00795 }
00796
00797
00798 this->deserializeTreeCallback (*childLeaf, key_arg);
00799 }
00800
00801
00802 key_arg.popBranch();
00803 }
00804 else if (branch_arg->hasChild (!bufferSelector_, childIdx))
00805 {
00806
00807 branch_arg->setChildPtr(bufferSelector_, childIdx, 0);
00808
00809
00810 deleteBranchChild (*branch_arg, !bufferSelector_, childIdx);
00811 }
00812 }
00813 }
00814
00815 }
00816
00818 template<typename DataT, typename LeafT, typename BranchT> void
00819 Octree2BufBase<DataT, LeafT, BranchT>::treeCleanUpRecursive (BranchNode* branch_arg)
00820 {
00821
00822 unsigned char childIdx;
00823
00824
00825 char nodeBitPatternLastBuffer;
00826 char nodeXORBitPattern;
00827 char unusedBranchesBits;
00828
00829
00830 nodeBitPatternLastBuffer = getBranchBitPattern (*branch_arg, !bufferSelector_);
00831
00832
00833 nodeXORBitPattern = getBranchXORBitPattern (*branch_arg);
00834
00835
00836 unusedBranchesBits = nodeXORBitPattern & nodeBitPatternLastBuffer;
00837
00838
00839 for (childIdx = 0; childIdx < 8; childIdx++)
00840 {
00841 if (branch_arg->hasChild(bufferSelector_, childIdx))
00842 {
00843 OctreeNode *childNode = branch_arg->getChildPtr(bufferSelector_,childIdx);
00844
00845 switch (childNode->getNodeType ())
00846 {
00847 case BRANCH_NODE:
00848 {
00849
00850 treeCleanUpRecursive (static_cast<BranchNode*> (childNode));
00851 break;
00852 }
00853 case LEAF_NODE:
00854
00855 break;
00856 default:
00857 break;
00858 }
00859 }
00860
00861
00862 if (unusedBranchesBits & (1 << childIdx))
00863 {
00864
00865 deleteBranchChild (*branch_arg, !bufferSelector_, childIdx);
00866 }
00867 }
00868 }
00869 }
00870 }
00871
00872 #define PCL_INSTANTIATE_Octree2BufBase(T) template class PCL_EXPORTS pcl::octree::Octree2BufBase<T>;
00873
00874 #endif
00875