38 #ifndef HPP_FCL_HIERARCHY_TREE_INL_H 39 #define HPP_FCL_HIERARCHY_TREE_INL_H 49 template <
typename BV>
54 max_lookahead_level = -1;
56 bu_threshold = bu_threshold_;
57 topdown_level = topdown_level_;
61 template <
typename BV>
67 template <
typename BV>
88 template <
typename BV>
91 Node* leaf = createNode(
nullptr, bv, data);
92 insertLeaf(root_node, leaf);
98 template <
typename BV>
106 template <
typename BV>
108 if (root_node) recurseDeleteNode(root_node);
112 max_lookahead_level = -1;
117 template <
typename BV>
119 return (
nullptr == root_node);
123 template <
typename BV>
136 if (lookahead_level > 0) {
138 for (
int i = 0; (i < lookahead_level) && sub_root->
parent; ++i)
139 sub_root = sub_root->
parent;
143 sub_root = root_node;
147 insertLeaf(sub_root, leaf);
151 template <
typename BV>
153 if (leaf->
bv.contain(bv))
return false;
159 template <
typename S,
typename BV>
164 if (leaf->
bv.contain(bv))
return false;
172 if (leaf->
bv.contain(bv))
return false;
179 template <
typename BV>
186 template <
typename BV>
192 template <
typename BV>
194 if (!root_node)
return 0;
195 return getMaxHeight(root_node);
199 template <
typename BV>
201 if (!root_node)
return 0;
204 getMaxDepth(root_node, 0, max_depth);
209 template <
typename BV>
212 std::vector<Node*> leaves;
213 leaves.reserve(n_leaves);
214 fetchLeaves(root_node, leaves);
215 bottomup(leaves.begin(), leaves.end());
216 root_node = leaves[0];
221 template <
typename BV>
224 std::vector<Node*> leaves;
225 leaves.reserve(n_leaves);
226 fetchLeaves(root_node, leaves);
227 root_node = topdown(leaves.begin(), leaves.end());
232 template <
typename BV>
234 if (iterations < 0) iterations = (int)n_leaves;
235 if (root_node && (iterations > 0)) {
236 for (
int i = 0; i < iterations; ++i) {
237 Node* node = root_node;
238 unsigned int bit = 0;
240 node = sort(node, root_node)->
children[(opath >> bit) & 1];
241 bit = (bit + 1) & (
sizeof(
unsigned int) * 8 - 1);
250 template <
typename BV>
252 if (root_node) recurseRefit(root_node);
256 template <
typename BV>
258 std::vector<Node*>& leaves)
const {
260 extractLeaves(root->
children[0], leaves);
261 extractLeaves(root->
children[1], leaves);
263 leaves.push_back(root);
267 template <
typename BV>
273 template <
typename BV>
279 template <
typename BV>
285 template <
typename BV>
287 for (
int i = 0; i < depth; ++i) std::cout <<
" ";
288 std::cout <<
" (" << root->
bv.min_[0] <<
", " << root->
bv.min_[1] <<
", " 289 << root->
bv.min_[2] <<
"; " << root->
bv.max_[0] <<
", " 290 << root->
bv.max_[1] <<
", " << root->
bv.max_[2] <<
")" << std::endl;
299 template <
typename BV>
303 while (lbeg < lcur_end - 1) {
305 FCL_REAL min_size = (std::numeric_limits<FCL_REAL>::max)();
308 FCL_REAL cur_size = ((*it1)->bv + (*it2)->bv).size();
309 if (cur_size < min_size) {
317 Node* n[2] = {*min_it1, *min_it2};
318 Node* p = createNode(
nullptr, n[0]->bv, n[1]->bv,
nullptr);
324 Node* tmp = *min_it2;
326 *min_it2 = *lcur_end;
332 template <
typename BV>
335 switch (topdown_level) {
337 return topdown_0(lbeg, lend);
340 return topdown_1(lbeg, lend);
343 return topdown_0(lbeg, lend);
348 template <
typename BV>
351 size_t height1 = getMaxHeight(node->
children[0]);
352 size_t height2 = getMaxHeight(node->
children[1]);
353 return std::max(height1, height2) + 1;
359 template <
typename BV>
361 size_t& max_depth)
const {
363 getMaxDepth(node->
children[0], depth + 1, max_depth);
364 getMaxDepth(node->
children[1], depth + 1, max_depth);
366 max_depth = std::max(max_depth, depth);
370 template <
typename BV>
373 long num_leaves = lend - lbeg;
374 if (num_leaves > 1) {
375 if (num_leaves > bu_threshold) {
376 BV vol = (*lbeg)->
bv;
380 FCL_REAL extent[3] = {vol.width(), vol.height(), vol.depth()};
381 if (extent[1] > extent[0]) best_axis = 1;
382 if (extent[2] > extent[best_axis]) best_axis = 2;
386 std::nth_element(lbeg, lcenter, lend,
387 std::bind(&nodeBaseLess<BV>, std::placeholders::_1,
388 std::placeholders::_2, std::ref(best_axis)));
390 Node* node = createNode(
nullptr, vol,
nullptr);
391 node->
children[0] = topdown_0(lbeg, lcenter);
392 node->
children[1] = topdown_0(lcenter, lend);
397 bottomup(lbeg, lend);
405 template <
typename BV>
408 long num_leaves = lend - lbeg;
409 if (num_leaves > 1) {
410 if (num_leaves > bu_threshold) {
411 Vec3f split_p = (*lbeg)->
bv.center();
412 BV vol = (*lbeg)->bv;
414 for (it = lbeg + 1; it < lend; ++it) {
415 split_p += (*it)->bv.center();
418 split_p /=
static_cast<FCL_REAL>(num_leaves);
420 long bestmidp = num_leaves;
421 int splitcount[3][2] = {{0, 0}, {0, 0}, {0, 0}};
422 for (it = lbeg; it < lend; ++it) {
423 Vec3f x = (*it)->bv.center() - split_p;
424 for (
int j = 0; j < 3; ++j) ++splitcount[j][x[j] > 0 ? 1 : 0];
427 for (
int i = 0; i < 3; ++i) {
428 if ((splitcount[i][0] > 0) && (splitcount[i][1] > 0)) {
429 long midp = std::abs(splitcount[i][0] - splitcount[i][1]);
430 if (midp < bestmidp) {
437 if (best_axis < 0) best_axis = 0;
439 FCL_REAL split_value = split_p[best_axis];
441 for (it = lbeg; it < lend; ++it) {
442 if ((*it)->bv.center()[best_axis] < split_value) {
450 Node* node = createNode(
nullptr, vol,
nullptr);
451 node->
children[0] = topdown_1(lbeg, lcenter);
452 node->
children[1] = topdown_1(lcenter, lend);
457 bottomup(lbeg, lend);
465 template <
typename BV>
468 root_node = topdown(leaves.begin(), leaves.end());
469 n_leaves = leaves.size();
470 max_lookahead_level = -1;
475 template <
typename BV>
480 if (leaves.size() > 0) bound_bv = leaves[0]->bv;
481 for (
size_t i = 1; i < leaves.size(); ++i) bound_bv += leaves[i]->bv;
483 morton_functor<FCL_REAL, uint32_t> coder(bound_bv);
484 for (
size_t i = 0; i < leaves.size(); ++i)
485 leaves[i]->code = coder(leaves[i]->bv.center());
487 std::sort(leaves.begin(), leaves.end(), SortByMorton());
489 root_node = mortonRecurse_0(leaves.begin(), leaves.end(),
490 (1 << (coder.bits() - 1)), coder.bits() - 1);
493 n_leaves = leaves.size();
494 max_lookahead_level = -1;
499 template <
typename BV>
504 if (leaves.size() > 0) bound_bv = leaves[0]->bv;
505 for (
size_t i = 1; i < leaves.size(); ++i) bound_bv += leaves[i]->bv;
507 morton_functor<FCL_REAL, uint32_t> coder(bound_bv);
508 for (
size_t i = 0; i < leaves.size(); ++i)
509 leaves[i]->code = coder(leaves[i]->bv.center());
511 std::sort(leaves.begin(), leaves.end(), SortByMorton());
513 root_node = mortonRecurse_1(leaves.begin(), leaves.end(),
514 (1 << (coder.bits() - 1)), coder.bits() - 1);
517 n_leaves = leaves.size();
518 max_lookahead_level = -1;
523 template <
typename BV>
528 if (leaves.size() > 0) bound_bv = leaves[0]->bv;
529 for (
size_t i = 1; i < leaves.size(); ++i) bound_bv += leaves[i]->bv;
531 morton_functor<FCL_REAL, uint32_t> coder(bound_bv);
532 for (
size_t i = 0; i < leaves.size(); ++i)
533 leaves[i]->code = coder(leaves[i]->bv.center());
535 std::sort(leaves.begin(), leaves.end(), SortByMorton());
537 root_node = mortonRecurse_2(leaves.begin(), leaves.end());
540 n_leaves = leaves.size();
541 max_lookahead_level = -1;
546 template <
typename BV>
549 const uint32_t& split,
int bits) {
550 long num_leaves = lend - lbeg;
551 if (num_leaves > 1) {
556 std::lower_bound(lbeg, lend, &dummy, SortByMorton());
558 if (lcenter == lbeg) {
559 uint32_t split2 = split | (1 << (bits - 1));
560 return mortonRecurse_0(lbeg, lend, split2, bits - 1);
561 }
else if (lcenter == lend) {
562 uint32_t split1 = (split & (~(1 << bits))) | (1 << (bits - 1));
563 return mortonRecurse_0(lbeg, lend, split1, bits - 1);
565 uint32_t split1 = (split & (~(1 << bits))) | (1 << (bits - 1));
566 uint32_t split2 = split | (1 << (bits - 1));
568 Node* child1 = mortonRecurse_0(lbeg, lcenter, split1, bits - 1);
569 Node* child2 = mortonRecurse_0(lcenter, lend, split2, bits - 1);
570 Node* node = createNode(
nullptr,
nullptr);
578 Node* node = topdown(lbeg, lend);
586 template <
typename BV>
589 const uint32_t& split,
int bits) {
590 long num_leaves = lend - lbeg;
591 if (num_leaves > 1) {
596 std::lower_bound(lbeg, lend, &dummy, SortByMorton());
598 if (lcenter == lbeg) {
599 uint32_t split2 = split | (1 << (bits - 1));
600 return mortonRecurse_1(lbeg, lend, split2, bits - 1);
601 }
else if (lcenter == lend) {
602 uint32_t split1 = (split & (~(1 << bits))) | (1 << (bits - 1));
603 return mortonRecurse_1(lbeg, lend, split1, bits - 1);
605 uint32_t split1 = (split & (~(1 << bits))) | (1 << (bits - 1));
606 uint32_t split2 = split | (1 << (bits - 1));
608 Node* child1 = mortonRecurse_1(lbeg, lcenter, split1, bits - 1);
609 Node* child2 = mortonRecurse_1(lcenter, lend, split2, bits - 1);
610 Node* node = createNode(
nullptr,
nullptr);
618 Node* child1 = mortonRecurse_1(lbeg, lbeg + num_leaves / 2, 0, bits - 1);
619 Node* child2 = mortonRecurse_1(lbeg + num_leaves / 2, lend, 0, bits - 1);
620 Node* node = createNode(
nullptr,
nullptr);
632 template <
typename BV>
635 long num_leaves = lend - lbeg;
636 if (num_leaves > 1) {
637 Node* child1 = mortonRecurse_2(lbeg, lbeg + num_leaves / 2);
638 Node* child2 = mortonRecurse_2(lbeg + num_leaves / 2, lend);
639 Node* node = createNode(
nullptr,
nullptr);
650 template <
typename BV>
652 Node* root = removeLeaf(leaf);
654 if (max_lookahead_level >= 0) {
655 for (
int i = 0; (i < max_lookahead_level) && root->
parent; ++i)
662 insertLeaf(root, leaf);
666 template <
typename BV>
670 size_t i = indexOf(n);
687 std::swap(p->
bv, n->
bv);
694 template <
typename BV>
714 Node* sibling = sub_root;
715 while (!sibling->
isLeaf()) {
722 Node* node = createNode(prev, leaf->
bv, sibling->
bv,
nullptr);
736 prev->
children[indexOf(sibling)] = node;
746 if (!prev->
bv.contain(node->
bv))
751 }
while (
nullptr != (prev = node->
parent));
775 template <
typename BV>
782 if (leaf == root_node) {
807 prev->
children[indexOf(parent)] = sibling;
813 if (!(new_bv == prev->
bv)) {
820 return prev ? prev : root_node;
833 sibling->
parent =
nullptr;
840 template <
typename BV>
843 if ((!root->
isLeaf()) && depth) {
844 fetchLeaves(root->
children[0], leaves, depth - 1);
845 fetchLeaves(root->
children[1], leaves, depth - 1);
848 leaves.push_back(root);
853 template <
typename BV>
856 return (node->
parent->children[1] == node);
860 template <
typename BV>
864 Node* node = createNode(parent, data);
870 template <
typename BV>
875 Node* node = createNode(parent, data);
876 node->
bv = bv1 + bv2;
881 template <
typename BV>
884 Node* node =
nullptr;
897 template <
typename BV>
899 if (free_node != node) {
906 template <
typename BV>
909 recurseDeleteNode(node->
children[0]);
910 recurseDeleteNode(node->
children[1]);
913 if (node == root_node) root_node =
nullptr;
918 template <
typename BV>
929 template <
typename BV>
931 if (a->
bv.center()[d] < b->
bv.center()[d])
return true;
936 template <
typename S,
typename BV>
951 template <
typename BV>
958 template <
typename BV>
965 template <
typename S>
971 const AABB& bv1 = node1.
bv;
972 const AABB& bv2 = node2.
bv;
976 FCL_REAL d1 = fabs(v1[0]) + fabs(v1[1]) + fabs(v1[2]);
977 FCL_REAL d2 = fabs(v2[0]) + fabs(v2[1]) + fabs(v2[2]);
978 return (d1 < d2) ? 0 : 1;
983 const AABB& bv = query;
984 const AABB& bv1 = node1.
bv;
985 const AABB& bv2 = node2.
bv;
989 FCL_REAL d1 = fabs(v1[0]) + fabs(v1[1]) + fabs(v1[2]);
990 FCL_REAL d2 = fabs(v2[0]) + fabs(v2[1]) + fabs(v2[2]);
991 return (d1 < d2) ? 0 : 1;
Node * createNode(Node *parent, const BV &bv, void *data)
create one node (leaf or internal)
void init_2(std::vector< Node *> &leaves)
init tree from leaves using morton code. It uses morton_0, i.e., for nodes which is of depth more tha...
Vec3f min_
The min point in the AABB.
static std::size_t run(const AABB &query, const NodeBase< AABB > &node1, const NodeBase< AABB > &node2)
std::vector< NodeBase< hpp::fcl::AABB > *>::iterator NodeVecIterator
bool isLeaf() const
whether is a leaf
uint32_t code
morton code for current BV
void balanceTopdown()
balance the tree from top
static bool run(const HierarchyTree< BV > &tree, typename HierarchyTree< BV >::Node *leaf, const BV &bv, const Vec3f &, FCL_REAL)
Node * mortonRecurse_2(const NodeVecIterator lbeg, const NodeVecIterator lend)
Node * topdown_1(const NodeVecIterator lbeg, const NodeVecIterator lend)
construct a tree from a list of nodes stored in [lbeg, lend) in a topdown manner. During construction...
NodeBase< BV > * parent
pointer to parent node
static size_t indexOf(Node *node)
Node * getRoot() const
get the root of the tree
void fetchLeaves(Node *root, std::vector< Node *> &leaves, int depth=-1)
Delete all internal nodes and return all leaves nodes with given depth from root. ...
Node * mortonRecurse_1(const NodeVecIterator lbeg, const NodeVecIterator lend, const uint32_t &split, int bits)
void balanceIncremental(int iterations)
balance the tree in an incremental way
void refit()
refit the tree, i.e., when the leaf nodes' bounding volumes change, update the entire tree in a botto...
void recurseDeleteNode(Node *node)
size_t size() const
number of leaves in the tree
NodeBase< BV > * children[2]
for leaf node, children nodes
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...
Class for hierarchy tree structure.
size_t getMaxHeight() const
get the max height of the tree
void update(Node *leaf, int lookahead_level=-1)
Updates a leaf node. A use case is when the bounding volume of an object changes. Ensure every parent...
void clear()
Clear the tree.
Node * topdown_0(const NodeVecIterator lbeg, const NodeVecIterator lend)
construct a tree from a list of nodes stored in [lbeg, lend) in a topdown manner. During construction...
void balanceBottomup()
balance the tree from bottom
Node * mortonRecurse_0(const NodeVecIterator lbeg, const NodeVecIterator lend, const uint32_t &split, int bits)
A class describing the AABB collision structure, which is a box in 3D space determined by two diagona...
Vec3f max_
The max point in the AABB.
void extractLeaves(const Node *root, std::vector< Node *> &leaves) const
extract all the leaves of the tree
void remove(Node *leaf)
Remove a leaf node.
void deleteNode(Node *node)
static std::size_t run(const BV &, const NodeBase< BV > &, const NodeBase< BV > &)
Node * sort(Node *n, Node *&r)
sort node n and its parent according to their memory position
void insertLeaf(Node *const sub_root, Node *const leaf)
Insert a leaf node and also update its ancestors. Maintain the tree as a full binary tree (every inte...
void recurseRefit(Node *node)
size_t getMaxDepth() const
get the max depth of the tree
size_t select(const NodeBase< BV > &query, const NodeBase< BV > &node1, const NodeBase< BV > &node2)
select from node1 and node2 which is close to a given query. 0 for node1 and 1 for node2 ...
Node * topdown(const NodeVecIterator lbeg, const NodeVecIterator lend)
construct a tree for a set of leaves from top
void print(Node *root, int depth)
print the tree in a recursive way
void bottomup(const NodeVecIterator lbeg, const NodeVecIterator lend)
construct a tree for a set of leaves from bottom – very heavy way
void init_3(std::vector< Node *> &leaves)
init tree from leaves using morton code. It uses morton_2, i.e., for all nodes, we simply divide the ...
Node * insert(const BV &bv, void *data)
Insest a node.
static bool run(const HierarchyTree< BV > &tree, typename HierarchyTree< BV >::Node *leaf, const BV &bv, const Vec3f &)
void init(std::vector< Node *> &leaves, int level=0)
Initialize the tree by a set of leaves using algorithm with a given level.
Node * removeLeaf(Node *const leaf)
Remove a leaf. Maintain the tree as a full binary tree (every interior node has exactly two children)...
void init_1(std::vector< Node *> &leaves)
init tree from leaves using morton code. It uses morton_0, i.e., for nodes which is of depth more tha...
BV bv
the bounding volume for the node
Eigen::Matrix< FCL_REAL, 3, 1 > Vec3f
void update_(Node *leaf, const BV &bv)
update one leaf node's bounding volume
bool empty() const
Whether the tree is empty.
void print(const Tensor &tensor)
static std::size_t run(const NodeBase< AABB > &node, const NodeBase< AABB > &node1, const NodeBase< AABB > &node2)
static std::size_t run(const NodeBase< BV > &, const NodeBase< BV > &, const NodeBase< BV > &)
bool nodeBaseLess(NodeBase< BV > *a, NodeBase< BV > *b, int d)
Compare two nodes accoording to the d-th dimension of node center.
void init_0(std::vector< Node *> &leaves)
init tree from leaves in the topdown manner (topdown_0 or topdown_1)