From 1ba2520a7255c86c3f32523460d3ea084deb94b8 Mon Sep 17 00:00:00 2001 From: Nick Avramoussis <4256455+Idclip@users.noreply.github.com> Date: Sun, 29 Jan 2023 18:13:27 +0000 Subject: [PATCH 1/2] Added a unittest for LeafManager construction from different tree configurations Signed-off-by: Nick Avramoussis <4256455+Idclip@users.noreply.github.com> --- openvdb/openvdb/unittest/TestLeafManager.cc | 34 +++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/openvdb/openvdb/unittest/TestLeafManager.cc b/openvdb/openvdb/unittest/TestLeafManager.cc index 8bce6d32d8..8d7f7d46de 100644 --- a/openvdb/openvdb/unittest/TestLeafManager.cc +++ b/openvdb/openvdb/unittest/TestLeafManager.cc @@ -2,6 +2,7 @@ // SPDX-License-Identifier: MPL-2.0 #include +#include #include #include #include "util.h" // for unittest_util::makeSphere() @@ -304,3 +305,36 @@ TEST_F(TestLeafManager, testReduce) } EXPECT_EQ(FloatTree::LeafNodeType::numValues(), n); } + +TEST_F(TestLeafManager, testTreeConfigurations) +{ + using Tree2Type = openvdb::tree::Tree< + openvdb::tree::RootNode< + openvdb::tree::LeafNode > >; + using Tree3Type = openvdb::tree::Tree3::Type; + using Tree4Type = openvdb::tree::Tree4::Type; + using Tree5Type = openvdb::tree::Tree5::Type; + + using TestConfigurations = openvdb::TypeList< + Tree2Type, Tree3Type, Tree4Type, Tree5Type + >; + + TestConfigurations::foreach([](auto tree) { + using TreeType = typename std::decay::type; + using LeafNodeType = typename TreeType::LeafNodeType; + using LeafManagerT = openvdb::tree::LeafManager; + + // Add 20 leaf nodes and make sure they are parsed correctly + constexpr int64_t Count = 20; + std::array ptrs; + + const int64_t start = -(Count/2)*LeafNodeType::DIM; + const int64_t end = (Count/2)*LeafNodeType::DIM; + for (int64_t idx = start; idx < end; idx+=LeafNodeType::DIM) { + ptrs[idx] = tree.touchLeaf(openvdb::math::Coord(idx)); + } + EXPECT_EQ(tree.leafCount(), Count); + LeafManagerT manager(tree); + EXPECT_EQ(manager.leafCount(), Count); + }); +} From cd4498bf17b47d0ffd11d719120a2d19fa28e796 Mon Sep 17 00:00:00 2001 From: Nick Avramoussis <4256455+Idclip@users.noreply.github.com> Date: Sun, 29 Jan 2023 18:14:05 +0000 Subject: [PATCH 2/2] Fixed a bug with LeafManager construction from a single level RootNode Signed-off-by: Nick Avramoussis <4256455+Idclip@users.noreply.github.com> --- openvdb/openvdb/tree/LeafManager.h | 7 +++++- openvdb/openvdb/tree/Tree.h | 28 +++++++++++++++++++-- openvdb/openvdb/unittest/TestLeafManager.cc | 17 +++++++------ pendingchanges/leafmanager_root_fix.txt | 7 ++++++ 4 files changed, 49 insertions(+), 10 deletions(-) create mode 100644 pendingchanges/leafmanager_root_fix.txt diff --git a/openvdb/openvdb/tree/LeafManager.h b/openvdb/openvdb/tree/LeafManager.h index 9e37c5e96e..bacb0557d9 100644 --- a/openvdb/openvdb/tree/LeafManager.h +++ b/openvdb/openvdb/tree/LeafManager.h @@ -586,7 +586,12 @@ class LeafManager using LeafParentT = typename CopyConstness::Type; std::deque leafParents; - mTree->getNodes(leafParents); + if constexpr(std::is_same::value) { + leafParents.emplace_back(&mTree->root()); + } + else { + mTree->getNodes(leafParents); + } // Compute the leaf counts for each node diff --git a/openvdb/openvdb/tree/Tree.h b/openvdb/openvdb/tree/Tree.h index 609be1e41b..7ae12744ab 100644 --- a/openvdb/openvdb/tree/Tree.h +++ b/openvdb/openvdb/tree/Tree.h @@ -576,8 +576,8 @@ class Tree: public TreeBase /// array.reserve(tree.leafCount());//this is a fast preallocation. /// tree.getNodes(array); /// @endcode - template void getNodes(ArrayT& array) { mRoot.getNodes(array); } - template void getNodes(ArrayT& array) const { mRoot.getNodes(array); } + template void getNodes(ArrayT& array); + template void getNodes(ArrayT& array) const; //@} /// @brief Steals all nodes of a certain type from the tree and @@ -1273,6 +1273,30 @@ Tree::writeBuffers(std::ostream &os, bool saveFloatAsHalf) const } +template +template +inline void +Tree::getNodes(ArrayT& array) +{ + using NodeT = typename std::remove_pointer::type; + static_assert(!std::is_same::value, + "getNodes() does not work for the RootNode. Use Tree::root()"); + mRoot.getNodes(array); +} + + +template +template +inline void +Tree::getNodes(ArrayT& array) const +{ + using NodeT = typename std::remove_pointer::type; + static_assert(!std::is_same::value, + "getNodes() does not work for the RootNode. Use Tree::root()"); + mRoot.getNodes(array); +} + + template inline void Tree::clear() diff --git a/openvdb/openvdb/unittest/TestLeafManager.cc b/openvdb/openvdb/unittest/TestLeafManager.cc index 8d7f7d46de..84770c7686 100644 --- a/openvdb/openvdb/unittest/TestLeafManager.cc +++ b/openvdb/openvdb/unittest/TestLeafManager.cc @@ -323,18 +323,21 @@ TEST_F(TestLeafManager, testTreeConfigurations) using TreeType = typename std::decay::type; using LeafNodeType = typename TreeType::LeafNodeType; using LeafManagerT = openvdb::tree::LeafManager; + using ConstLeafManagerT = openvdb::tree::LeafManager; - // Add 20 leaf nodes and make sure they are parsed correctly - constexpr int64_t Count = 20; - std::array ptrs; + // Add 20 leaf nodes and make sure they are constructed correctly + constexpr openvdb::Int32 Count = 20; - const int64_t start = -(Count/2)*LeafNodeType::DIM; - const int64_t end = (Count/2)*LeafNodeType::DIM; - for (int64_t idx = start; idx < end; idx+=LeafNodeType::DIM) { - ptrs[idx] = tree.touchLeaf(openvdb::math::Coord(idx)); + const openvdb::Int32 start = -(Count/2)*openvdb::Int32(LeafNodeType::DIM); + const openvdb::Int32 end = (Count/2)*openvdb::Int32(LeafNodeType::DIM); + for (openvdb::Int32 idx = start; idx < end; idx+=openvdb::Int32(LeafNodeType::DIM)) { + tree.touchLeaf(openvdb::math::Coord(idx)); } + EXPECT_EQ(tree.leafCount(), Count); LeafManagerT manager(tree); EXPECT_EQ(manager.leafCount(), Count); + ConstLeafManagerT cmanager(tree); + EXPECT_EQ(cmanager.leafCount(), Count); }); } diff --git a/pendingchanges/leafmanager_root_fix.txt b/pendingchanges/leafmanager_root_fix.txt new file mode 100644 index 0000000000..c51ab6eefe --- /dev/null +++ b/pendingchanges/leafmanager_root_fix.txt @@ -0,0 +1,7 @@ +OpenVDB: + - Bug Fixes: + - Fixed a bug with LeafManager which wouldn't correctly + initialize its LeafNode array for single level Tree configurations + i.e. RootNode (bug introduced in 7.2.0) + [Reported by @lanwatch] +