Skip to content

Commit 7edd8cd

Browse files
authored
Merge pull request #1574 from Idclip/leafmanager_root_leaf_fix
LeafManager LeafArray bugfix from RootNode<LeafNode>
2 parents 0cd5ed7 + cd4498b commit 7edd8cd

File tree

4 files changed

+76
-3
lines changed

4 files changed

+76
-3
lines changed

openvdb/openvdb/tree/LeafManager.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,12 @@ class LeafManager
586586
using LeafParentT = typename CopyConstness<TreeType, NonConstLeafParentT>::Type;
587587

588588
std::deque<LeafParentT*> leafParents;
589-
mTree->getNodes(leafParents);
589+
if constexpr(std::is_same<NonConstLeafParentT, RootNodeType>::value) {
590+
leafParents.emplace_back(&mTree->root());
591+
}
592+
else {
593+
mTree->getNodes(leafParents);
594+
}
590595

591596
// Compute the leaf counts for each node
592597

openvdb/openvdb/tree/Tree.h

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -576,8 +576,8 @@ class Tree: public TreeBase
576576
/// array.reserve(tree.leafCount());//this is a fast preallocation.
577577
/// tree.getNodes(array);
578578
/// @endcode
579-
template<typename ArrayT> void getNodes(ArrayT& array) { mRoot.getNodes(array); }
580-
template<typename ArrayT> void getNodes(ArrayT& array) const { mRoot.getNodes(array); }
579+
template<typename ArrayT> void getNodes(ArrayT& array);
580+
template<typename ArrayT> void getNodes(ArrayT& array) const;
581581
//@}
582582

583583
/// @brief Steals all nodes of a certain type from the tree and
@@ -1273,6 +1273,30 @@ Tree<RootNodeType>::writeBuffers(std::ostream &os, bool saveFloatAsHalf) const
12731273
}
12741274

12751275

1276+
template<typename RootNodeType>
1277+
template<typename ArrayT>
1278+
inline void
1279+
Tree<RootNodeType>::getNodes(ArrayT& array)
1280+
{
1281+
using NodeT = typename std::remove_pointer<typename ArrayT::value_type>::type;
1282+
static_assert(!std::is_same<NodeT, RootNodeType>::value,
1283+
"getNodes() does not work for the RootNode. Use Tree::root()");
1284+
mRoot.getNodes(array);
1285+
}
1286+
1287+
1288+
template<typename RootNodeType>
1289+
template<typename ArrayT>
1290+
inline void
1291+
Tree<RootNodeType>::getNodes(ArrayT& array) const
1292+
{
1293+
using NodeT = typename std::remove_pointer<typename ArrayT::value_type>::type;
1294+
static_assert(!std::is_same<NodeT, const RootNodeType>::value,
1295+
"getNodes() does not work for the RootNode. Use Tree::root()");
1296+
mRoot.getNodes(array);
1297+
}
1298+
1299+
12761300
template<typename RootNodeType>
12771301
inline void
12781302
Tree<RootNodeType>::clear()

openvdb/openvdb/unittest/TestLeafManager.cc

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// SPDX-License-Identifier: MPL-2.0
33

44
#include <openvdb/Types.h>
5+
#include <openvdb/TypeList.h>
56
#include <openvdb/tree/LeafManager.h>
67
#include <openvdb/util/CpuTimer.h>
78
#include "util.h" // for unittest_util::makeSphere()
@@ -304,3 +305,39 @@ TEST_F(TestLeafManager, testReduce)
304305
}
305306
EXPECT_EQ(FloatTree::LeafNodeType::numValues(), n);
306307
}
308+
309+
TEST_F(TestLeafManager, testTreeConfigurations)
310+
{
311+
using Tree2Type = openvdb::tree::Tree<
312+
openvdb::tree::RootNode<
313+
openvdb::tree::LeafNode<float, 3> > >;
314+
using Tree3Type = openvdb::tree::Tree3<float, 4, 3>::Type;
315+
using Tree4Type = openvdb::tree::Tree4<float, 5, 4, 3>::Type;
316+
using Tree5Type = openvdb::tree::Tree5<float, 5, 5, 4, 3>::Type;
317+
318+
using TestConfigurations = openvdb::TypeList<
319+
Tree2Type, Tree3Type, Tree4Type, Tree5Type
320+
>;
321+
322+
TestConfigurations::foreach([](auto tree) {
323+
using TreeType = typename std::decay<decltype(tree)>::type;
324+
using LeafNodeType = typename TreeType::LeafNodeType;
325+
using LeafManagerT = openvdb::tree::LeafManager<TreeType>;
326+
using ConstLeafManagerT = openvdb::tree::LeafManager<const TreeType>;
327+
328+
// Add 20 leaf nodes and make sure they are constructed correctly
329+
constexpr openvdb::Int32 Count = 20;
330+
331+
const openvdb::Int32 start = -(Count/2)*openvdb::Int32(LeafNodeType::DIM);
332+
const openvdb::Int32 end = (Count/2)*openvdb::Int32(LeafNodeType::DIM);
333+
for (openvdb::Int32 idx = start; idx < end; idx+=openvdb::Int32(LeafNodeType::DIM)) {
334+
tree.touchLeaf(openvdb::math::Coord(idx));
335+
}
336+
337+
EXPECT_EQ(tree.leafCount(), Count);
338+
LeafManagerT manager(tree);
339+
EXPECT_EQ(manager.leafCount(), Count);
340+
ConstLeafManagerT cmanager(tree);
341+
EXPECT_EQ(cmanager.leafCount(), Count);
342+
});
343+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
OpenVDB:
2+
- Bug Fixes:
3+
- Fixed a bug with LeafManager which wouldn't correctly
4+
initialize its LeafNode array for single level Tree configurations
5+
i.e. RootNode<LeafNode> (bug introduced in 7.2.0)
6+
[Reported by @lanwatch]
7+

0 commit comments

Comments
 (0)