Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGermano Cavalcante <germano.costa@ig.com.br>2016-02-09 14:12:05 +0300
committerCampbell Barton <ideasman42@gmail.com>2016-02-09 14:47:14 +0300
commit9961d47a4f64358bcd19e9686c374a873163d874 (patch)
tree24c63f18ae8356f6759ec6dc6e6529c20cf65a70 /source/blender/blenlib/intern/BLI_kdopbvh.c
parentcaa16c1443dbac1a9b2ee7549c72717e1010787a (diff)
Add BLI_bvhtree_walk_dfs utility function
This generic function allows callers to walk the tree using callbacks to define behavior.
Diffstat (limited to 'source/blender/blenlib/intern/BLI_kdopbvh.c')
-rw-r--r--source/blender/blenlib/intern/BLI_kdopbvh.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c
index e8ff84e8f5f..baef5ab06d2 100644
--- a/source/blender/blenlib/intern/BLI_kdopbvh.c
+++ b/source/blender/blenlib/intern/BLI_kdopbvh.c
@@ -1998,3 +1998,79 @@ int BLI_bvhtree_range_query(BVHTree *tree, const float co[3], float radius, BVHT
return data.hits;
}
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name BLI_bvhtree_walk_dfs
+ * \{ */
+
+/**
+ * Runs first among nodes children of the first node before going to the next node in the same layer.
+ *
+ * \return false to break out of the search early.
+ */
+static bool bvhtree_walk_dfs_recursive(
+ BVHTree_WalkParentCallback walk_parent_cb,
+ BVHTree_WalkLeafCallback walk_leaf_cb,
+ BVHTree_WalkOrderCallback walk_order_cb,
+ const BVHNode *node, void *userdata)
+{
+ if (node->totnode == 0) {
+ return walk_leaf_cb((const BVHTreeAxisRange *)node->bv, node->index, userdata);
+ }
+ else {
+ /* First pick the closest node to recurse into */
+ if (walk_order_cb((const BVHTreeAxisRange *)node->bv, node->main_axis, userdata)) {
+ for (int i = 0; i != node->totnode; i++) {
+ if (walk_parent_cb((const BVHTreeAxisRange *)node->bv, userdata)) {
+ if (!bvhtree_walk_dfs_recursive(
+ walk_parent_cb, walk_leaf_cb, walk_order_cb,
+ node->children[i], userdata))
+ {
+ return false;
+ }
+ }
+ }
+ }
+ else {
+ for (int i = node->totnode - 1; i >= 0; i--) {
+ if (walk_parent_cb((const BVHTreeAxisRange *)node->bv, userdata)) {
+ if (!bvhtree_walk_dfs_recursive(
+ walk_parent_cb, walk_leaf_cb, walk_order_cb,
+ node->children[i], userdata))
+ {
+ return false;
+ }
+ }
+ }
+ }
+ }
+ return true;
+}
+
+/**
+ * This is a generic function to perform a depth first search on the BVHTree
+ * where the search order and nodes traversed depend on callbacks passed in.
+ *
+ * \param tree: Tree to walk.
+ * \param walk_parent_cb: Callback on a parents bound-box to test if it should be traversed.
+ * \param walk_leaf_cb: Callback to test leaf nodes, callback must store its own result,
+ * returning false exits early.
+ * \param walk_order_cb: Callback that indicates which direction to search,
+ * either from the node with the lower or higher k-dop axis value.
+ * \param userdata: Argument passed to all callbacks.
+ */
+void BLI_bvhtree_walk_dfs(
+ BVHTree *tree,
+ BVHTree_WalkParentCallback walk_parent_cb,
+ BVHTree_WalkLeafCallback walk_leaf_cb,
+ BVHTree_WalkOrderCallback walk_order_cb, void *userdata)
+{
+ const BVHNode *root = tree->nodes[tree->totleaf];
+ if (root != NULL) {
+ bvhtree_walk_dfs_recursive(walk_parent_cb, walk_leaf_cb, walk_order_cb, root, userdata);
+ }
+}
+
+/** \} */