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
static const unsigned char maxDepth
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
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.