38 #ifndef FCL_HIERARCHY_TREE_ARRAY_INL_H 39 #define FCL_HIERARCHY_TREE_ARRAY_INL_H 41 #include "fcl/broadphase/detail/hierarchy_tree_array.h" 49 namespace implementation_array
56 root_node = NULL_NODE;
60 for(
size_t i = 0; i < n_nodes_alloc - 1; ++i)
61 nodes[i].next = i + 1;
62 nodes[n_nodes_alloc - 1].next = NULL_NODE;
66 max_lookahead_level = -1;
67 bu_threshold = bu_threshold_;
68 topdown_level = topdown_level_;
85 init_0(leaves, n_leaves_);
88 init_1(leaves, n_leaves_);
91 init_2(leaves, n_leaves_);
94 init_3(leaves, n_leaves_);
97 init_0(leaves, n_leaves_);
102 template<
typename BV>
107 n_leaves = n_leaves_;
108 root_node = NULL_NODE;
110 memcpy(nodes, leaves,
sizeof(
NodeType) * n_leaves);
113 n_nodes_alloc = 2 * n_leaves;
114 for(
size_t i = n_leaves; i < n_nodes_alloc; ++i)
115 nodes[i].next = i + 1;
116 nodes[n_nodes_alloc - 1].next = NULL_NODE;
118 size_t* ids =
new size_t[n_leaves];
119 for(
size_t i = 0; i < n_leaves; ++i)
122 root_node = topdown(ids, ids + n_leaves);
126 max_lookahead_level = -1;
130 template<
typename BV>
135 n_leaves = n_leaves_;
136 root_node = NULL_NODE;
138 memcpy(nodes, leaves,
sizeof(
NodeType) * n_leaves);
141 n_nodes_alloc = 2 * n_leaves;
142 for(
size_t i = n_leaves; i < n_nodes_alloc; ++i)
143 nodes[i].next = i + 1;
144 nodes[n_nodes_alloc - 1].next = NULL_NODE;
149 bound_bv = nodes[0].bv;
150 for(
size_t i = 1; i < n_leaves; ++i)
151 bound_bv += nodes[i].bv;
153 morton_functor<typename BV::S, uint32> coder(bound_bv);
154 for(
size_t i = 0; i < n_leaves; ++i)
155 nodes[i].code = coder(nodes[i].bv.center());
158 size_t* ids =
new size_t[n_leaves];
159 for(
size_t i = 0; i < n_leaves; ++i)
162 FCL_SUPPRESS_MAYBE_UNINITIALIZED_BEGIN
164 FCL_SUPPRESS_MAYBE_UNINITIALIZED_END
166 std::sort(ids, ids + n_leaves, comp);
167 root_node = mortonRecurse_0(ids, ids + n_leaves, (1 << (coder.bits()-1)), coder.bits()-1);
173 max_lookahead_level = -1;
177 template<
typename BV>
182 n_leaves = n_leaves_;
183 root_node = NULL_NODE;
185 memcpy(nodes, leaves,
sizeof(
NodeType) * n_leaves);
188 n_nodes_alloc = 2 * n_leaves;
189 for(
size_t i = n_leaves; i < n_nodes_alloc; ++i)
190 nodes[i].next = i + 1;
191 nodes[n_nodes_alloc - 1].next = NULL_NODE;
196 bound_bv = nodes[0].bv;
197 for(
size_t i = 1; i < n_leaves; ++i)
198 bound_bv += nodes[i].bv;
200 morton_functor<typename BV::S, uint32> coder(bound_bv);
201 for(
size_t i = 0; i < n_leaves; ++i)
202 nodes[i].code = coder(nodes[i].bv.center());
205 size_t* ids =
new size_t[n_leaves];
206 for(
size_t i = 0; i < n_leaves; ++i)
209 FCL_SUPPRESS_MAYBE_UNINITIALIZED_BEGIN
211 FCL_SUPPRESS_MAYBE_UNINITIALIZED_END
213 std::sort(ids, ids + n_leaves, comp);
214 root_node = mortonRecurse_1(ids, ids + n_leaves, (1 << (coder.bits()-1)), coder.bits()-1);
220 max_lookahead_level = -1;
224 template<
typename BV>
229 n_leaves = n_leaves_;
230 root_node = NULL_NODE;
232 memcpy(nodes, leaves,
sizeof(
NodeType) * n_leaves);
235 n_nodes_alloc = 2 * n_leaves;
236 for(
size_t i = n_leaves; i < n_nodes_alloc; ++i)
237 nodes[i].next = i + 1;
238 nodes[n_nodes_alloc - 1].next = NULL_NODE;
243 bound_bv = nodes[0].bv;
244 for(
size_t i = 1; i < n_leaves; ++i)
245 bound_bv += nodes[i].bv;
247 morton_functor<typename BV::S, uint32> coder(bound_bv);
248 for(
size_t i = 0; i < n_leaves; ++i)
249 nodes[i].code = coder(nodes[i].bv.center());
252 size_t* ids =
new size_t[n_leaves];
253 for(
size_t i = 0; i < n_leaves; ++i)
256 FCL_SUPPRESS_MAYBE_UNINITIALIZED_BEGIN
258 FCL_SUPPRESS_MAYBE_UNINITIALIZED_END
260 std::sort(ids, ids + n_leaves, comp);
261 root_node = mortonRecurse_2(ids, ids + n_leaves);
267 max_lookahead_level = -1;
271 template<
typename BV>
274 size_t node = createNode(NULL_NODE, bv, data);
275 insertLeaf(root_node, node);
281 template<
typename BV>
290 template<
typename BV>
294 root_node = NULL_NODE;
297 nodes =
new NodeType[n_nodes_alloc];
298 for(
size_t i = 0; i < n_nodes_alloc; ++i)
299 nodes[i].next = i + 1;
300 nodes[n_nodes_alloc - 1].next = NULL_NODE;
304 max_lookahead_level = -1;
308 template<
typename BV>
311 return (n_nodes == 0);
315 template<
typename BV>
318 size_t root = removeLeaf(leaf);
319 if(root != NULL_NODE)
321 if(lookahead_level > 0)
323 for(
int i = 0; (i < lookahead_level) && (nodes[root].parent != NULL_NODE); ++i)
324 root = nodes[root].parent;
329 insertLeaf(root, leaf);
333 template<
typename BV>
336 if(nodes[leaf].bv.contain(bv))
return false;
342 template<
typename BV>
345 if(nodes[leaf].bv.contain(bv))
return false;
351 template<
typename BV>
354 if(nodes[leaf].bv.contain(bv))
return false;
360 template<
typename BV>
363 if(root_node == NULL_NODE)
return 0;
365 return getMaxHeight(root_node);
369 template<
typename BV>
372 if(root_node == NULL_NODE)
return 0;
375 getMaxDepth(root_node, 0, max_depth);
380 template<
typename BV>
383 if(root_node != NULL_NODE)
387 extractLeaves(root_node, leaves_);
388 root_node = NULL_NODE;
389 memcpy(nodes, leaves,
sizeof(
NodeType) * n_leaves);
392 for(
size_t i = n_leaves; i < n_nodes_alloc; ++i)
393 nodes[i].next = i + 1;
394 nodes[n_nodes_alloc - 1].next = NULL_NODE;
397 size_t* ids =
new size_t[n_leaves];
398 for(
size_t i = 0; i < n_leaves; ++i)
401 bottomup(ids, ids + n_leaves);
409 template<
typename BV>
412 if(root_node != NULL_NODE)
416 extractLeaves(root_node, leaves_);
417 root_node = NULL_NODE;
418 memcpy(nodes, leaves,
sizeof(
NodeType) * n_leaves);
421 for(
size_t i = n_leaves; i < n_nodes_alloc; ++i)
422 nodes[i].next = i + 1;
423 nodes[n_nodes_alloc - 1].next = NULL_NODE;
425 size_t* ids =
new size_t[n_leaves];
426 for(
size_t i = 0; i < n_leaves; ++i)
429 root_node = topdown(ids, ids + n_leaves);
435 template<
typename BV>
438 if(iterations < 0) iterations = n_leaves;
439 if((root_node != NULL_NODE) && (iterations > 0))
441 for(
int i = 0; i < iterations; ++i)
443 size_t node = root_node;
444 unsigned int bit = 0;
445 while(!nodes[node].isLeaf())
447 node = nodes[node].children[(opath>>bit)&1];
448 bit = (bit+1)&(
sizeof(
unsigned int) * 8-1);
457 template<
typename BV>
460 if(root_node != NULL_NODE)
461 recurseRefit(root_node);
465 template<
typename BV>
468 if(!nodes[root].isLeaf())
470 extractLeaves(nodes[root].children[0], leaves);
471 extractLeaves(nodes[root].children[1], leaves);
475 *leaves = nodes[root];
481 template<
typename BV>
488 template<
typename BV>
495 template<
typename BV>
502 template<
typename BV>
505 for(
int i = 0; i < depth; ++i)
508 std::cout <<
" (" << n->bv.min_[0] <<
", " << n->bv.min_[1] <<
", " << n->bv.min_[2] <<
"; " << n->bv.max_[0] <<
", " << n->bv.max_[1] <<
", " << n->bv.max_[2] <<
")" << std::endl;
514 print(n->children[0], depth+1);
515 print(n->children[1], depth+1);
520 template<
typename BV>
523 if(!nodes[node].isLeaf())
525 size_t height1 = getMaxHeight(nodes[node].children[0]);
526 size_t height2 = getMaxHeight(nodes[node].children[1]);
527 return std::max(height1, height2) + 1;
534 template<
typename BV>
537 if(!nodes[node].isLeaf())
539 getMaxDepth(nodes[node].children[0], depth+1, max_depth);
540 getmaxDepth(nodes[node].children[1], depth+1, max_depth);
543 max_depth = std::max(max_depth, depth);
547 template<
typename BV>
550 size_t* lcur_end = lend;
551 while(lbeg < lcur_end - 1)
553 size_t* min_it1 =
nullptr, *min_it2 =
nullptr;
554 S min_size = std::numeric_limits<S>::max();
555 for(
size_t* it1 = lbeg; it1 < lcur_end; ++it1)
557 for(
size_t* it2 = it1 + 1; it2 < lcur_end; ++it2)
559 S cur_size = (nodes[*it1].bv + nodes[*it2].bv).size();
560 if(cur_size < min_size)
569 size_t p = createNode(NULL_NODE, nodes[*min_it1].bv, nodes[*min_it2].bv,
nullptr);
570 nodes[p].children[0] = *min_it1;
571 nodes[p].children[1] = *min_it2;
572 nodes[*min_it1].parent = p;
573 nodes[*min_it2].parent = p;
575 size_t tmp = *min_it2;
577 *min_it2 = *lcur_end;
583 template<
typename BV>
586 switch(topdown_level)
589 return topdown_0(lbeg, lend);
592 return topdown_1(lbeg, lend);
595 return topdown_0(lbeg, lend);
600 template<
typename BV>
603 int num_leaves = lend - lbeg;
606 if(num_leaves > bu_threshold)
608 BV vol = nodes[*lbeg].bv;
609 for(
size_t* i = lbeg + 1; i < lend; ++i)
613 S extent[3] = {vol.width(), vol.height(), vol.depth()};
614 if(extent[1] > extent[0]) best_axis = 1;
615 if(extent[2] > extent[best_axis]) best_axis = 2;
618 size_t* lcenter = lbeg + num_leaves / 2;
619 std::nth_element(lbeg, lcenter, lend, comp);
621 size_t node = createNode(NULL_NODE, vol,
nullptr);
622 nodes[node].children[0] = topdown_0(lbeg, lcenter);
623 nodes[node].children[1] = topdown_0(lcenter, lend);
624 nodes[nodes[node].children[0]].parent = node;
625 nodes[nodes[node].children[1]].parent = node;
630 bottomup(lbeg, lend);
638 template<
typename BV>
641 int num_leaves = lend - lbeg;
644 if(num_leaves > bu_threshold)
646 Vector3<S> split_p = nodes[*lbeg].bv.center();
647 BV vol = nodes[*lbeg].bv;
648 for(
size_t* i = lbeg + 1; i < lend; ++i)
650 split_p += nodes[*i].bv.center();
653 split_p /= (S)(num_leaves);
655 int bestmidp = num_leaves;
656 int splitcount[3][2] = {{0,0}, {0,0}, {0,0}};
657 for(
size_t* i = lbeg; i < lend; ++i)
659 Vector3<S> x = nodes[*i].bv.center() - split_p;
660 for(
size_t j = 0; j < 3; ++j)
661 ++splitcount[j][x[j] > 0 ? 1 : 0];
664 for(
size_t i = 0; i < 3; ++i)
666 if((splitcount[i][0] > 0) && (splitcount[i][1] > 0))
668 int midp = std::abs(splitcount[i][0] - splitcount[i][1]);
677 if(best_axis < 0) best_axis = 0;
679 S split_value = split_p[best_axis];
680 size_t* lcenter = lbeg;
681 for(
size_t* i = lbeg; i < lend; ++i)
683 if(nodes[*i].bv.center()[best_axis] < split_value)
692 size_t node = createNode(NULL_NODE, vol,
nullptr);
693 nodes[node].children[0] = topdown_1(lbeg, lcenter);
694 nodes[node].children[1] = topdown_1(lcenter, lend);
695 nodes[nodes[node].children[0]].parent = node;
696 nodes[nodes[node].children[1]].parent = node;
701 bottomup(lbeg, lend);
709 template<
typename BV>
712 int num_leaves = lend - lbeg;
720 size_t* lcenter = std::lower_bound(lbeg, lend, NULL_NODE, comp);
724 uint32 split2 = split | (1 << (bits - 1));
725 return mortonRecurse_0(lbeg, lend, split2, bits - 1);
727 else if(lcenter == lend)
729 uint32 split1 = (split & (~(1 << bits))) | (1 << (bits - 1));
730 return mortonRecurse_0(lbeg, lend, split1, bits - 1);
734 uint32 split1 = (split & (~(1 << bits))) | (1 << (bits - 1));
735 uint32 split2 = split | (1 << (bits - 1));
737 size_t child1 = mortonRecurse_0(lbeg, lcenter, split1, bits - 1);
738 size_t child2 = mortonRecurse_0(lcenter, lend, split2, bits - 1);
739 size_t node = createNode(NULL_NODE,
nullptr);
740 nodes[node].children[0] = child1;
741 nodes[node].children[1] = child2;
742 nodes[child1].parent = node;
743 nodes[child2].parent = node;
749 size_t node = topdown(lbeg, lend);
758 template<
typename BV>
761 int num_leaves = lend - lbeg;
769 size_t* lcenter = std::lower_bound(lbeg, lend, NULL_NODE, comp);
773 uint32 split2 = split | (1 << (bits - 1));
774 return mortonRecurse_1(lbeg, lend, split2, bits - 1);
776 else if(lcenter == lend)
778 uint32 split1 = (split & (~(1 << bits))) | (1 << (bits - 1));
779 return mortonRecurse_1(lbeg, lend, split1, bits - 1);
783 uint32 split1 = (split & (~(1 << bits))) | (1 << (bits - 1));
784 uint32 split2 = split | (1 << (bits - 1));
786 size_t child1 = mortonRecurse_1(lbeg, lcenter, split1, bits - 1);
787 size_t child2 = mortonRecurse_1(lcenter, lend, split2, bits - 1);
788 size_t node = createNode(NULL_NODE,
nullptr);
789 nodes[node].children[0] = child1;
790 nodes[node].children[1] = child2;
791 nodes[child1].parent = node;
792 nodes[child2].parent = node;
798 size_t child1 = mortonRecurse_1(lbeg, lbeg + num_leaves / 2, 0, bits - 1);
799 size_t child2 = mortonRecurse_1(lbeg + num_leaves / 2, lend, 0, bits - 1);
800 size_t node = createNode(NULL_NODE,
nullptr);
801 nodes[node].children[0] = child1;
802 nodes[node].children[1] = child2;
803 nodes[child1].parent = node;
804 nodes[child2].parent = node;
813 template<
typename BV>
816 int num_leaves = lend - lbeg;
819 size_t child1 = mortonRecurse_2(lbeg, lbeg + num_leaves / 2);
820 size_t child2 = mortonRecurse_2(lbeg + num_leaves / 2, lend);
821 size_t node = createNode(NULL_NODE,
nullptr);
822 nodes[node].children[0] = child1;
823 nodes[node].children[1] = child2;
824 nodes[child1].parent = node;
825 nodes[child2].parent = node;
833 template<
typename BV>
836 if(root_node == NULL_NODE)
839 nodes[leaf].parent = NULL_NODE;
843 if(!nodes[root].isLeaf())
847 root = nodes[root].children[select(leaf, nodes[root].children[0], nodes[root].children[1], nodes)];
849 while(!nodes[root].isLeaf());
852 size_t prev = nodes[root].parent;
853 size_t node = createNode(prev, nodes[leaf].bv, nodes[root].bv,
nullptr);
854 if(prev != NULL_NODE)
856 nodes[prev].children[indexOf(root)] = node;
857 nodes[node].children[0] = root; nodes[root].parent = node;
858 nodes[node].children[1] = leaf; nodes[leaf].parent = node;
861 if(!nodes[prev].bv.contain(nodes[node].bv))
862 nodes[prev].bv = nodes[nodes[prev].children[0]].bv + nodes[nodes[prev].children[1]].bv;
866 }
while (NULL_NODE != (prev = nodes[node].parent));
870 nodes[node].children[0] = root; nodes[root].parent = node;
871 nodes[node].children[1] = leaf; nodes[leaf].parent = node;
878 template<
typename BV>
881 if(leaf == root_node)
883 root_node = NULL_NODE;
888 size_t parent = nodes[leaf].parent;
889 size_t prev = nodes[parent].parent;
890 size_t sibling = nodes[parent].children[1-indexOf(leaf)];
892 if(prev != NULL_NODE)
894 nodes[prev].children[indexOf(parent)] = sibling;
895 nodes[sibling].parent = prev;
897 while(prev != NULL_NODE)
899 BV new_bv = nodes[nodes[prev].children[0]].bv + nodes[nodes[prev].children[1]].bv;
900 if(!new_bv.equal(nodes[prev].bv))
902 nodes[prev].bv = new_bv;
903 prev = nodes[prev].parent;
908 return (prev != NULL_NODE) ? prev : root_node;
913 nodes[sibling].parent = NULL_NODE;
921 template<
typename BV>
924 size_t root = removeLeaf(leaf);
925 if(root != NULL_NODE)
927 if(max_lookahead_level >= 0)
929 for(
int i = 0; (i < max_lookahead_level) && (nodes[root].parent != NULL_NODE); ++i)
930 root = nodes[root].parent;
934 insertLeaf(root, leaf);
939 template<
typename BV>
942 return (nodes[nodes[node].parent].children[1] == node);
946 template<
typename BV>
949 if(freelist == NULL_NODE)
953 nodes =
new NodeType[n_nodes_alloc];
954 memcpy(nodes, old_nodes, n_nodes *
sizeof(
NodeType));
957 for(
size_t i = n_nodes; i < n_nodes_alloc - 1; ++i)
958 nodes[i].next = i + 1;
959 nodes[n_nodes_alloc - 1].next = NULL_NODE;
963 size_t node_id = freelist;
964 freelist = nodes[node_id].next;
965 nodes[node_id].parent = NULL_NODE;
966 nodes[node_id].children[0] = NULL_NODE;
967 nodes[node_id].children[1] = NULL_NODE;
973 template<
typename BV>
979 size_t node = allocateNode();
980 nodes[node].parent = parent;
981 nodes[node].data = data;
982 nodes[node].bv = bv1 + bv2;
987 template<
typename BV>
992 size_t node = allocateNode();
993 nodes[node].parent = parent;
994 nodes[node].data = data;
1000 template<
typename BV>
1004 size_t node = allocateNode();
1005 nodes[node].parent = parent;
1006 nodes[node].data = data;
1011 template<
typename BV>
1014 nodes[node].next = freelist;
1020 template<
typename BV>
1023 if(!nodes[node].isLeaf())
1025 recurseRefit(nodes[node].children[0]);
1026 recurseRefit(nodes[node].children[1]);
1027 nodes[node].bv = nodes[nodes[node].children[0]].bv + nodes[nodes[node].children[1]].bv;
1034 template<
typename BV>
1037 if((!nodes[root].isLeaf()) && depth)
1039 fetchLeaves(nodes[root].children[0], leaves, depth-1);
1040 fetchLeaves(nodes[root].children[1], leaves, depth-1);
1045 *leaves = nodes[root];
1051 template<
typename BV>
1053 : nodes(nodes_), d(d_)
1059 template<
typename BV>
1062 if(nodes[i].bv.center()[d] < nodes[j].bv.center()[d])
1069 template <
typename S,
typename BV>
1072 static bool run(
size_t query,
size_t node1,
size_t node2,
NodeBase<BV>* nodes)
1077 static bool run(
const BV& query,
size_t node1,
size_t node2,
NodeBase<BV>* nodes)
1084 template<
typename BV>
1085 size_t select(
size_t query,
size_t node1,
size_t node2,
NodeBase<BV>* nodes)
1091 template<
typename BV>
1092 size_t select(
const BV& query,
size_t node1,
size_t node2,
NodeBase<BV>* nodes)
1098 template <
typename S>
1101 static bool run(
size_t query,
size_t node1,
size_t node2,
NodeBase<
AABB<S>>* nodes)
1103 const AABB<S>& bv = nodes[query].bv;
1104 const AABB<S>& bv1 = nodes[node1].bv;
1105 const AABB<S>& bv2 = nodes[node2].bv;
1107 Vector3<S> v1 = v - (bv1.
min_ + bv1.
max_);
1108 Vector3<S> v2 = v - (bv2.
min_ + bv2.
max_);
1109 S d1 = fabs(v1[0]) + fabs(v1[1]) + fabs(v1[2]);
1110 S d2 = fabs(v2[0]) + fabs(v2[1]) + fabs(v2[2]);
1111 return (d1 < d2) ? 0 : 1;
1117 const AABB<S>& bv1 = nodes[node1].bv;
1118 const AABB<S>& bv2 = nodes[node2].bv;
1120 Vector3<S> v1 = v - (bv1.
min_ + bv1.
max_);
1121 Vector3<S> v2 = v - (bv2.
min_ + bv2.
max_);
1122 S d1 = fabs(v1[0]) + fabs(v1[1]) + fabs(v1[2]);
1123 S d2 = fabs(v2[0]) + fabs(v2[1]) + fabs(v2[2]);
1124 return (d1 < d2) ? 0 : 1;
Class for hierarchy tree structure.
Definition: hierarchy_tree_array.h:61
bool empty() const
Whether the tree is empty.
Definition: hierarchy_tree_array-inl.h:309
Main namespace.
Definition: broadphase_bruteforce-inl.h:45
void clear()
Clear the tree.
Definition: hierarchy_tree_array-inl.h:291
A class describing the AABB collision structure, which is a box in 3D space determined by two diagona...
Definition: AABB.h:49
void print(size_t root, int depth)
print the tree in a recursive way
Definition: hierarchy_tree_array-inl.h:503
Vector3< S > max_
The max point in the AABB.
Definition: AABB.h:59
HierarchyTree(int bu_threshold_=16, int topdown_level_=0)
Create hierarchy tree with suitable setting. bu_threshold decides the height of tree node to start bo...
Definition: hierarchy_tree_array-inl.h:54
void refit()
refit the tree, i.e., when the leaf nodes' bounding volumes change, update the entire tree in a botto...
Definition: hierarchy_tree_array-inl.h:458
size_t getMaxDepth() const
get the max depth of the tree
Definition: hierarchy_tree_array-inl.h:370
size_t getRoot() const
get the root of the tree
Definition: hierarchy_tree_array-inl.h:489
void remove(size_t leaf)
Remove a leaf node.
Definition: hierarchy_tree_array-inl.h:282
size_t insert(const BV &bv, void *data)
Initialize the tree by a set of leaves using algorithm with a given level.
Definition: hierarchy_tree_array-inl.h:272
Definition: hierarchy_tree_array-inl.h:1070
void balanceBottomup()
balance the tree from bottom
Definition: hierarchy_tree_array-inl.h:381
Vector3< S > min_
The min point in the AABB.
Definition: AABB.h:56
NodeType * getNodes() const
get the pointer to the nodes array
Definition: hierarchy_tree_array-inl.h:496
Definition: node_base_array.h:53
void balanceTopdown()
balance the tree from top
Definition: hierarchy_tree_array-inl.h:410
void init(NodeType *leaves, int n_leaves_, int level=0)
Initialize the tree by a set of leaves using algorithm with a given level.
Definition: hierarchy_tree_array-inl.h:80
size_t getMaxHeight() const
get the max height of the tree
Definition: hierarchy_tree_array-inl.h:361
void update(size_t leaf, int lookahead_level=-1)
update one leaf node
Definition: hierarchy_tree_array-inl.h:316
Functor comparing two nodes.
Definition: hierarchy_tree_array.h:261
void balanceIncremental(int iterations)
balance the tree in an incremental way
Definition: hierarchy_tree_array-inl.h:436
size_t size() const
number of leaves in the tree
Definition: hierarchy_tree_array-inl.h:482
void extractLeaves(size_t root, NodeType *&leaves) const
extract all the leaves of the tree
Definition: hierarchy_tree_array-inl.h:466