39 #ifndef PCL_OCTREE_2BUF_BASE_HPP
40 #define PCL_OCTREE_2BUF_BASE_HPP
45 template <
typename LeafContainerT,
typename BranchContainerT>
51 template <
typename LeafContainerT,
typename BranchContainerT>
60 template <
typename LeafContainerT,
typename BranchContainerT>
67 if (max_voxel_index_arg <= 0) {
68 PCL_ERROR(
"[pcl::octree::Octree2BufBase::setMaxVoxelIndex] Max voxel index (%lu) "
77 std::ceil(std::log2(max_voxel_index_arg))),
81 depth_mask_ = (1 << (treeDepth - 1));
85 template <
typename LeafContainerT,
typename BranchContainerT>
91 "[pcl::octree::Octree2BufBase::setTreeDepth] Tree depth (%lu) must be > 0!\n",
97 octree_depth_ = depth_arg;
100 depth_mask_ = (1 << (depth_arg - 1));
103 max_key_.x = max_key_.y = max_key_.z = (1 << depth_arg) - 1;
107 template <
typename LeafContainerT,
typename BranchContainerT>
114 OctreeKey key(idx_x_arg, idx_y_arg, idx_z_arg);
117 return (findLeaf(key));
121 template <
typename LeafContainerT,
typename BranchContainerT>
128 OctreeKey key(idx_x_arg, idx_y_arg, idx_z_arg);
131 return (createLeaf(key));
135 template <
typename LeafContainerT,
typename BranchContainerT>
142 OctreeKey key(idx_x_arg, idx_y_arg, idx_z_arg);
145 return existLeaf(key);
149 template <
typename LeafContainerT,
typename BranchContainerT>
156 OctreeKey key(idx_x_arg, idx_y_arg, idx_z_arg);
159 return (this->removeLeaf(key));
163 template <
typename LeafContainerT,
typename BranchContainerT>
169 deleteBranch(*root_node_);
173 tree_dirty_flag_ =
false;
180 template <
typename LeafContainerT,
typename BranchContainerT>
184 if (tree_dirty_flag_) {
186 treeCleanUpRecursive(root_node_);
190 buffer_selector_ = !buffer_selector_;
193 tree_dirty_flag_ =
true;
198 for (
unsigned char child_idx = 0; child_idx < 8; child_idx++) {
199 root_node_->setChildPtr(buffer_selector_, child_idx,
nullptr);
204 template <
typename LeafContainerT,
typename BranchContainerT>
207 std::vector<char>& binary_tree_out_arg,
bool do_XOR_encoding_arg)
212 binary_tree_out_arg.clear();
213 binary_tree_out_arg.reserve(this->branch_count_);
215 serializeTreeRecursive(
216 root_node_, new_key, &binary_tree_out_arg,
nullptr, do_XOR_encoding_arg,
false);
219 tree_dirty_flag_ =
false;
223 template <
typename LeafContainerT,
typename BranchContainerT>
226 std::vector<char>& binary_tree_out_arg,
227 std::vector<LeafContainerT*>& leaf_container_vector_arg,
228 bool do_XOR_encoding_arg)
233 binary_tree_out_arg.clear();
234 leaf_container_vector_arg.clear();
236 leaf_container_vector_arg.reserve(leaf_count_);
237 binary_tree_out_arg.reserve(this->branch_count_);
239 serializeTreeRecursive(root_node_,
241 &binary_tree_out_arg,
242 &leaf_container_vector_arg,
247 tree_dirty_flag_ =
false;
251 template <
typename LeafContainerT,
typename BranchContainerT>
254 std::vector<LeafContainerT*>& leaf_container_vector_arg)
259 leaf_container_vector_arg.clear();
261 leaf_container_vector_arg.reserve(leaf_count_);
263 serializeTreeRecursive(
264 root_node_, new_key,
nullptr, &leaf_container_vector_arg,
false,
false);
267 tree_dirty_flag_ =
false;
271 template <
typename LeafContainerT,
typename BranchContainerT>
274 std::vector<char>& binary_tree_in_arg,
bool do_XOR_decoding_arg)
282 auto binary_tree_in_it = binary_tree_in_arg.cbegin();
283 auto binary_tree_in_it_end = binary_tree_in_arg.cend();
285 deserializeTreeRecursive(root_node_,
289 binary_tree_in_it_end,
293 do_XOR_decoding_arg);
296 tree_dirty_flag_ =
false;
300 template <
typename LeafContainerT,
typename BranchContainerT>
303 std::vector<char>& binary_tree_in_arg,
304 std::vector<LeafContainerT*>& leaf_container_vector_arg,
305 bool do_XOR_decoding_arg)
310 auto leaf_container_vector_it = leaf_container_vector_arg.cbegin();
313 auto leaf_container_vector_it_end = leaf_container_vector_arg.cend();
319 auto binary_tree_in_it = binary_tree_in_arg.cbegin();
320 auto binary_tree_in_it_end = binary_tree_in_arg.cend();
322 deserializeTreeRecursive(root_node_,
326 binary_tree_in_it_end,
327 &leaf_container_vector_it,
328 &leaf_container_vector_it_end,
330 do_XOR_decoding_arg);
333 tree_dirty_flag_ =
false;
337 template <
typename LeafContainerT,
typename BranchContainerT>
340 std::vector<LeafContainerT*>& leaf_container_vector_arg)
345 leaf_container_vector_arg.clear();
346 leaf_container_vector_arg.reserve(leaf_count_);
348 serializeTreeRecursive(
349 root_node_, new_key,
nullptr, &leaf_container_vector_arg,
false,
true);
352 tree_dirty_flag_ =
false;
356 template <
typename LeafContainerT,
typename BranchContainerT>
364 bool branch_reset_arg)
367 if (branch_reset_arg) {
369 for (
unsigned char child_idx = 0; child_idx < 8; child_idx++) {
370 branch_arg->
setChildPtr(buffer_selector_, child_idx,
nullptr);
377 if (depth_mask_arg > 1) {
385 if (!branch_arg->
hasChild(buffer_selector_, child_idx)) {
388 if (branch_arg->
hasChild(!buffer_selector_, child_idx)) {
392 child_branch =
static_cast<BranchNode*
>(child_node);
393 branch_arg->
setChildPtr(buffer_selector_, child_idx, child_node);
397 deleteBranchChild(*branch_arg, !buffer_selector_, child_idx);
398 child_branch = createBranchChild(*branch_arg, child_idx);
406 child_branch = createBranchChild(*branch_arg, child_idx);
414 branch_arg->
getChildPtr(buffer_selector_, child_idx));
417 return createLeafRecursive(key_arg,
427 if (!branch_arg->
hasChild(buffer_selector_, child_idx)) {
431 if (branch_arg->
hasChild(!buffer_selector_, child_idx)) {
435 child_leaf =
static_cast<LeafNode*
>(child_node);
437 branch_arg->
setChildPtr(buffer_selector_, child_idx, child_node);
441 deleteBranchChild(*branch_arg, !buffer_selector_, child_idx);
442 child_leaf = createLeafChild(*branch_arg, child_idx);
448 child_leaf = createLeafChild(*branch_arg, child_idx);
453 return_leaf_arg = child_leaf;
454 parent_of_leaf_arg = branch_arg;
460 parent_of_leaf_arg = branch_arg;
463 return depth_mask_arg;
467 template <
typename LeafContainerT,
typename BranchContainerT>
473 LeafContainerT*& result_arg)
const
476 unsigned char child_idx;
481 if (depth_mask_arg > 1) {
489 findLeafRecursive(key_arg, depth_mask_arg >> 1, child_branch, result_arg);
493 if (branch_arg->
hasChild(buffer_selector_, child_idx)) {
503 template <
typename LeafContainerT,
typename BranchContainerT>
509 unsigned char child_idx;
516 if (depth_mask_arg > 1) {
526 bool bBranchOccupied =
527 deleteLeafRecursive(key_arg, depth_mask_arg >> 1, child_branch);
529 if (!bBranchOccupied) {
531 deleteBranchChild(*branch_arg, buffer_selector_, child_idx);
538 deleteBranchChild(*branch_arg, buffer_selector_, child_idx);
544 for (child_idx = 0; child_idx < 8; child_idx++) {
545 bNoChilds = branch_arg->
hasChild(buffer_selector_, child_idx);
555 template <
typename LeafContainerT,
typename BranchContainerT>
560 std::vector<char>* binary_tree_out_arg,
561 typename std::vector<LeafContainerT*>* leaf_container_vector_arg,
562 bool do_XOR_encoding_arg,
563 bool new_leafs_filter_arg)
565 if (binary_tree_out_arg) {
567 const char branch_bit_pattern_curr_buffer =
568 getBranchBitPattern(*branch_arg, buffer_selector_);
569 if (do_XOR_encoding_arg) {
571 const char branch_bit_pattern_prev_buffer =
572 getBranchBitPattern(*branch_arg, !buffer_selector_);
574 const char node_XOR_bit_pattern =
575 branch_bit_pattern_curr_buffer ^ branch_bit_pattern_prev_buffer;
577 binary_tree_out_arg->push_back(node_XOR_bit_pattern);
581 binary_tree_out_arg->push_back(branch_bit_pattern_curr_buffer);
586 for (
unsigned char child_idx = 0; child_idx < 8; child_idx++) {
587 if (branch_arg->
hasChild(buffer_selector_, child_idx)) {
596 serializeTreeRecursive(
static_cast<BranchNode*
>(child_node),
599 leaf_container_vector_arg,
601 new_leafs_filter_arg);
605 auto* child_leaf =
static_cast<LeafNode*
>(child_node);
607 if (new_leafs_filter_arg) {
608 if (!branch_arg->
hasChild(!buffer_selector_, child_idx)) {
609 if (leaf_container_vector_arg)
610 leaf_container_vector_arg->push_back(child_leaf->getContainerPtr());
612 serializeTreeCallback(**child_leaf, key_arg);
617 if (leaf_container_vector_arg)
618 leaf_container_vector_arg->push_back(child_leaf->getContainerPtr());
620 serializeTreeCallback(**child_leaf, key_arg);
632 else if (branch_arg->
hasChild(!buffer_selector_, child_idx)) {
634 deleteBranchChild(*branch_arg, !buffer_selector_, child_idx);
640 template <
typename LeafContainerT,
typename BranchContainerT>
646 typename std::vector<char>::const_iterator& binaryTreeIT_arg,
647 typename std::vector<char>::const_iterator& binaryTreeIT_End_arg,
648 typename std::vector<LeafContainerT*>::const_iterator* dataVectorIterator_arg,
649 typename std::vector<LeafContainerT*>::const_iterator* dataVectorEndIterator_arg,
650 bool branch_reset_arg,
651 bool do_XOR_decoding_arg)
655 if (branch_reset_arg) {
657 for (
unsigned char child_idx = 0; child_idx < 8; child_idx++) {
658 branch_arg->
setChildPtr(buffer_selector_, child_idx,
nullptr);
662 if (binaryTreeIT_arg != binaryTreeIT_End_arg) {
664 char nodeBits = *binaryTreeIT_arg++;
667 char recoveredNodeBits;
668 if (do_XOR_decoding_arg) {
670 getBranchBitPattern(*branch_arg, !buffer_selector_) ^ nodeBits;
673 recoveredNodeBits = nodeBits;
677 for (
unsigned char child_idx = 0; child_idx < 8; child_idx++) {
679 if (recoveredNodeBits & (1 << child_idx)) {
683 if (depth_mask_arg > 1) {
686 bool doNodeReset =
false;
691 if (!branch_arg->
hasChild(buffer_selector_, child_idx)) {
693 if (branch_arg->
hasChild(!buffer_selector_, child_idx)) {
695 branch_arg->
getChildPtr(!buffer_selector_, child_idx);
698 child_branch =
static_cast<BranchNode*
>(child_node);
699 branch_arg->
setChildPtr(buffer_selector_, child_idx, child_node);
703 deleteBranchChild(*branch_arg, !buffer_selector_, child_idx);
704 child_branch = createBranchChild(*branch_arg, child_idx);
712 child_branch = createBranchChild(*branch_arg, child_idx);
720 branch_arg->
getChildPtr(buffer_selector_, child_idx));
724 deserializeTreeRecursive(child_branch,
728 binaryTreeIT_End_arg,
729 dataVectorIterator_arg,
730 dataVectorEndIterator_arg,
732 do_XOR_decoding_arg);
739 if (branch_arg->
hasChild(!buffer_selector_, child_idx)) {
742 branch_arg->
getChildPtr(!buffer_selector_, child_idx);
744 child_leaf =
static_cast<LeafNode*
>(child_node);
745 branch_arg->
setChildPtr(buffer_selector_, child_idx, child_node);
749 deleteBranchChild(*branch_arg, !buffer_selector_, child_idx);
750 child_leaf = createLeafChild(*branch_arg, child_idx);
755 child_leaf = createLeafChild(*branch_arg, child_idx);
760 if (dataVectorIterator_arg &&
761 (*dataVectorIterator_arg != *dataVectorEndIterator_arg)) {
762 LeafContainerT& container = **child_leaf;
763 container = ***dataVectorIterator_arg;
764 ++*dataVectorIterator_arg;
770 deserializeTreeCallback(**child_leaf, key_arg);
776 else if (branch_arg->
hasChild(!buffer_selector_, child_idx)) {
778 branch_arg->
setChildPtr(buffer_selector_, child_idx,
nullptr);
781 deleteBranchChild(*branch_arg, !buffer_selector_, child_idx);
788 template <
typename LeafContainerT,
typename BranchContainerT>
794 char occupied_children_bit_pattern_prev_buffer =
795 getBranchBitPattern(*branch_arg, !buffer_selector_);
798 char node_XOR_bit_pattern = getBranchXORBitPattern(*branch_arg);
801 char unused_branches_bit_pattern =
802 node_XOR_bit_pattern & occupied_children_bit_pattern_prev_buffer;
805 for (
unsigned char child_idx = 0; child_idx < 8; child_idx++) {
806 if (branch_arg->
hasChild(buffer_selector_, child_idx)) {
812 treeCleanUpRecursive(
static_cast<BranchNode*
>(child_node));
824 if (unused_branches_bit_pattern & (1 << child_idx)) {
826 deleteBranchChild(*branch_arg, !buffer_selector_, child_idx);
833 #define PCL_INSTANTIATE_Octree2BufBase(T) \
834 template class PCL_EXPORTS pcl::octree::Octree2BufBase<T>;
void setChildPtr(unsigned char buffer_arg, unsigned char index_arg, OctreeNode *newNode_arg)
Set child pointer in current branch node.
OctreeNode * getChildPtr(unsigned char buffer_arg, unsigned char index_arg) const
Get child pointer in current branch node.
bool hasChild(unsigned char buffer_arg, unsigned char index_arg) const
Check if branch is pointing to a particular child node.
void serializeLeafs(std::vector< LeafContainerT * > &leaf_container_vector_arg)
Outputs a vector of all DataT elements that are stored within the octree leaf nodes.
void switchBuffers()
Switch buffers and reset current octree structure.
uindex_t createLeafRecursive(const OctreeKey &key_arg, uindex_t depth_mask_arg, BranchNode *branch_arg, LeafNode *&return_leaf_arg, BranchNode *&parent_of_leaf_arg, bool branch_reset_arg=false)
Create a leaf node at octree key.
void serializeTree(std::vector< char > &binary_tree_out_arg, bool do_XOR_encoding_arg=false)
Serialize octree into a binary output vector describing its branch node structure.
void treeCleanUpRecursive(BranchNode *branch_arg)
Recursively explore the octree and remove unused branch and leaf nodes.
void deleteTree()
Delete the octree structure and its leaf nodes.
void serializeTreeRecursive(BranchNode *branch_arg, OctreeKey &key_arg, std::vector< char > *binary_tree_out_arg, typename std::vector< LeafContainerT * > *leaf_container_vector_arg, bool do_XOR_encoding_arg=false, bool new_leafs_filter_arg=false)
Recursively explore the octree and output binary octree description together with a vector of leaf no...
bool existLeaf(uindex_t idx_x_arg, uindex_t idx_y_arg, uindex_t idx_z_arg) const
Check for the existence of leaf node at (idx_x_arg, idx_y_arg, idx_z_arg).
void deserializeTree(std::vector< char > &binary_tree_in_arg, bool do_XOR_decoding_arg=false)
Deserialize a binary octree description vector and create a corresponding octree structure.
LeafContainerT * createLeaf(uindex_t idx_x_arg, uindex_t idx_y_arg, uindex_t idx_z_arg)
Create new leaf node at (idx_x_arg, idx_y_arg, idx_z_arg).
void setTreeDepth(uindex_t depth_arg)
Set the maximum depth of the octree.
void setMaxVoxelIndex(uindex_t max_voxel_index_arg)
Set the maximum amount of voxels per dimension.
void removeLeaf(uindex_t idx_x_arg, uindex_t idx_y_arg, uindex_t idx_z_arg)
Remove leaf node at (idx_x_arg, idx_y_arg, idx_z_arg).
bool deleteLeafRecursive(const OctreeKey &key_arg, uindex_t depth_mask_arg, BranchNode *branch_arg)
Recursively search and delete leaf node.
LeafContainerT * findLeaf(uindex_t idx_x_arg, uindex_t idx_y_arg, uindex_t idx_z_arg)
Find leaf node at (idx_x_arg, idx_y_arg, idx_z_arg).
void serializeNewLeafs(std::vector< LeafContainerT * > &leaf_container_vector_arg)
Outputs a vector of all DataT elements from leaf nodes, that do not exist in the previous octree buff...
LeafContainerT LeafContainer
Octree2BufBase()
Empty constructor.
void findLeafRecursive(const OctreeKey &key_arg, uindex_t depth_mask_arg, BranchNode *branch_arg, LeafContainerT *&result_arg) const
Recursively search for a given leaf node and return a pointer.
virtual ~Octree2BufBase()
Empty deconstructor.
void deserializeTreeRecursive(BranchNode *branch_arg, uindex_t depth_mask_arg, OctreeKey &key_arg, typename std::vector< char >::const_iterator &binary_tree_in_it_arg, typename std::vector< char >::const_iterator &binary_tree_in_it_end_arg, typename std::vector< LeafContainerT * >::const_iterator *leaf_container_vector_it_arg, typename std::vector< LeafContainerT * >::const_iterator *leaf_container_vector_it_end_arg, bool branch_reset_arg=false, bool do_XOR_decoding_arg=false)
Rebuild an octree based on binary XOR octree description and DataT objects for leaf node initializati...
void popBranch()
pop child node from octree key
void pushBranch(unsigned char childIndex)
push a child node to the octree key
unsigned char getChildIdxWithDepthMask(uindex_t depthMask) const
get child node index using depthMask
static unsigned char getMaxDepth()
Abstract octree leaf class
const ContainerT & getContainer() const
Get const reference to container.
const ContainerT * getContainerPtr() const
Get const pointer to container.
Abstract octree node class
virtual node_type_t getNodeType() const =0
Pure virtual method for retrieving the type of octree node (branch or leaf)
detail::int_type_t< detail::index_type_size, false > uindex_t
Type used for an unsigned index in PCL.