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