39#ifndef PCL_OCTREE_2BUF_BASE_HPP
40#define PCL_OCTREE_2BUF_BASE_HPP
45template <
typename LeafContainerT,
typename BranchContainerT>
51template <
typename LeafContainerT,
typename BranchContainerT>
60template <
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))),
85template <
typename LeafContainerT,
typename BranchContainerT>
91 "[pcl::octree::Octree2BufBase::setTreeDepth] Tree depth (%lu) must be > 0!\n",
107template <
typename LeafContainerT,
typename BranchContainerT>
114 OctreeKey key(idx_x_arg, idx_y_arg, idx_z_arg);
121template <
typename LeafContainerT,
typename BranchContainerT>
128 OctreeKey key(idx_x_arg, idx_y_arg, idx_z_arg);
135template <
typename LeafContainerT,
typename BranchContainerT>
142 OctreeKey key(idx_x_arg, idx_y_arg, idx_z_arg);
149template <
typename LeafContainerT,
typename BranchContainerT>
156 OctreeKey key(idx_x_arg, idx_y_arg, idx_z_arg);
163template <
typename LeafContainerT,
typename BranchContainerT>
180template <
typename LeafContainerT,
typename BranchContainerT>
198 for (
unsigned char child_idx = 0; child_idx < 8; child_idx++) {
204template <
typename LeafContainerT,
typename BranchContainerT>
207 std::vector<char>& binary_tree_out_arg,
bool do_XOR_encoding_arg)
212 binary_tree_out_arg.clear();
216 root_node_, new_key, &binary_tree_out_arg,
nullptr, do_XOR_encoding_arg,
false);
223template <
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();
241 &binary_tree_out_arg,
242 &leaf_container_vector_arg,
251template <
typename LeafContainerT,
typename BranchContainerT>
254 std::vector<LeafContainerT*>& leaf_container_vector_arg)
259 leaf_container_vector_arg.clear();
264 root_node_, new_key,
nullptr, &leaf_container_vector_arg,
false,
false);
271template <
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();
289 binary_tree_in_it_end,
293 do_XOR_decoding_arg);
300template <
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();
326 binary_tree_in_it_end,
327 &leaf_container_vector_it,
328 &leaf_container_vector_it_end,
330 do_XOR_decoding_arg);
337template <
typename LeafContainerT,
typename BranchContainerT>
340 std::vector<LeafContainerT*>& leaf_container_vector_arg)
345 leaf_container_vector_arg.clear();
349 root_node_, new_key,
nullptr, &leaf_container_vector_arg,
false,
true);
356template <
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++) {
377 if (depth_mask_arg > 1) {
379 BranchNode* child_branch;
385 if (!branch_arg->
hasChild(buffer_selector_, child_idx)) {
392 child_branch =
static_cast<BranchNode*
>(child_node);
413 child_branch =
static_cast<BranchNode*
>(
426 LeafNode* child_leaf;
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);
436 child_leaf->getContainer() = LeafContainer();
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;
467template <
typename LeafContainerT,
typename BranchContainerT>
473 LeafContainerT*& result_arg)
const
476 unsigned char child_idx;
481 if (depth_mask_arg > 1) {
497 result_arg = leaf_node->getContainerPtr();
503template <
typename LeafContainerT,
typename BranchContainerT>
509 unsigned char child_idx;
516 if (depth_mask_arg > 1) {
526 bool bBranchOccupied =
529 if (!bBranchOccupied) {
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);
555template <
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 =
569 if (do_XOR_encoding_arg) {
571 const char branch_bit_pattern_prev_buffer =
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++) {
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) {
609 if (leaf_container_vector_arg)
610 leaf_container_vector_arg->push_back(child_leaf->getContainerPtr());
617 if (leaf_container_vector_arg)
618 leaf_container_vector_arg->push_back(child_leaf->getContainerPtr());
640template <
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++) {
662 if (binaryTreeIT_arg != binaryTreeIT_End_arg) {
664 char nodeBits = *binaryTreeIT_arg++;
667 char recoveredNodeBits;
668 if (do_XOR_decoding_arg) {
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;
698 child_branch =
static_cast<BranchNode*
>(child_node);
728 binaryTreeIT_End_arg,
729 dataVectorIterator_arg,
730 dataVectorEndIterator_arg,
732 do_XOR_decoding_arg);
744 child_leaf =
static_cast<LeafNode*
>(child_node);
760 if (dataVectorIterator_arg &&
761 (*dataVectorIterator_arg != *dataVectorEndIterator_arg)) {
762 LeafContainerT& container = **child_leaf;
763 container = ***dataVectorIterator_arg;
764 ++*dataVectorIterator_arg;
788template <
typename LeafContainerT,
typename BranchContainerT>
794 char occupied_children_bit_pattern_prev_buffer =
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++) {
824 if (unused_branches_bit_pattern & (1 << child_idx)) {
833#define PCL_INSTANTIATE_Octree2BufBase(T) \
834 template class PCL_EXPORTS pcl::octree::Octree2BufBase<T>;
OctreeNode * getChildPtr(unsigned char buffer_arg, unsigned char index_arg) const
Get child pointer in current branch node.
void setChildPtr(unsigned char buffer_arg, unsigned char index_arg, OctreeNode *newNode_arg)
Set 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 deleteBranch(BranchNode &branch_arg)
Delete branch and all its subchilds from octree (both buffers)
void serializeLeafs(std::vector< LeafContainerT * > &leaf_container_vector_arg)
Outputs a vector of all DataT elements that are stored within the octree leaf nodes.
BranchNode * createBranchChild(BranchNode &branch_arg, unsigned char child_idx_arg)
char getBranchBitPattern(const BranchNode &branch_arg) const
Generate bit pattern reflecting the existence of child node pointers for current buffer.
OctreeKey max_key_
key range
void switchBuffers()
Switch buffers and reset current octree structure.
OctreeLeafNode< OctreeContainerPointIndices > LeafNode
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.
std::size_t leaf_count_
Amount of leaf nodes.
uindex_t octree_depth_
Octree depth.
LeafNode * createLeafChild(BranchNode &branch_arg, unsigned char child_idx_arg)
Fetch and add a new leaf child to a branch class.
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.
unsigned char buffer_selector_
Currently active octree buffer.
char getBranchXORBitPattern(const BranchNode &branch_arg) const
Generate XOR bit pattern reflecting differences between the two octree buffers.
virtual void deserializeTreeCallback(LeafContainerT &, const OctreeKey &)
Callback executed for every leaf node data during deserialization.
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 deleteBranchChild(BranchNode &branch_arg, unsigned char buffer_selector_arg, unsigned char child_idx_arg)
BranchNode * root_node_
Pointer to root branch node of octree.
void setTreeDepth(uindex_t depth_arg)
Set the maximum depth of the octree.
bool tree_dirty_flag_
flags indicating if unused branches and leafs might exist in previous buffer
std::size_t branch_count_
Amount of branch nodes.
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).
uindex_t depth_mask_
Depth mask based on octree depth.
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...
virtual void serializeTreeCallback(LeafContainerT &, const OctreeKey &)
Callback executed for every leaf node data during serialization.
BufferedBranchNode< BranchContainerT > BranchNode
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 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.