From ed5046d029ca950ec5ebc0af30243741d7fe2274 Mon Sep 17 00:00:00 2001 From: Dan Bailey Date: Tue, 5 Mar 2024 18:43:56 -0800 Subject: [PATCH] Add an example to demonstrate sampling and point advection using an adaptive grid Signed-off-by: Dan Bailey --- openvdb/openvdb/tools/Interpolation.h | 106 +++++++++++++++-------- openvdb/openvdb/unittest/TestAdaptive.cc | 34 ++++++++ 2 files changed, 102 insertions(+), 38 deletions(-) diff --git a/openvdb/openvdb/tools/Interpolation.h b/openvdb/openvdb/tools/Interpolation.h index 5a3cbc2eca..19444d1b88 100644 --- a/openvdb/openvdb/tools/Interpolation.h +++ b/openvdb/openvdb/tools/Interpolation.h @@ -629,29 +629,35 @@ template inline void BoxSampler::getValues(ValueT (&data)[N][N][N], const TreeT& inTree, Coord ijk) { - data[0][0][0] = inTree.getValue(ijk); // i, j, k + // This algorithm is only defined for sparse grids - ijk[2] += 1; - data[0][0][1] = inTree.getValue(ijk); // i, j, k + 1 + if constexpr (TreeTraits::IsSparse) { + data[0][0][0] = inTree.getValue(ijk); // i, j, k - ijk[1] += 1; - data[0][1][1] = inTree.getValue(ijk); // i, j+1, k + 1 + ijk[2] += 1; + data[0][0][1] = inTree.getValue(ijk); // i, j, k + 1 - ijk[2] -= 1; - data[0][1][0] = inTree.getValue(ijk); // i, j+1, k + ijk[1] += 1; + data[0][1][1] = inTree.getValue(ijk); // i, j+1, k + 1 - ijk[0] += 1; - ijk[1] -= 1; - data[1][0][0] = inTree.getValue(ijk); // i+1, j, k + ijk[2] -= 1; + data[0][1][0] = inTree.getValue(ijk); // i, j+1, k - ijk[2] += 1; - data[1][0][1] = inTree.getValue(ijk); // i+1, j, k + 1 + ijk[0] += 1; + ijk[1] -= 1; + data[1][0][0] = inTree.getValue(ijk); // i+1, j, k - ijk[1] += 1; - data[1][1][1] = inTree.getValue(ijk); // i+1, j+1, k + 1 + ijk[2] += 1; + data[1][0][1] = inTree.getValue(ijk); // i+1, j, k + 1 - ijk[2] -= 1; - data[1][1][0] = inTree.getValue(ijk); // i+1, j+1, k + ijk[1] += 1; + data[1][1][1] = inTree.getValue(ijk); // i+1, j+1, k + 1 + + ijk[2] -= 1; + data[1][1][0] = inTree.getValue(ijk); // i+1, j+1, k + } else { + static_assert(AlwaysFalseValue, "Not Implemented"); + } } template @@ -744,20 +750,32 @@ inline bool BoxSampler::sample(const TreeT& inTree, const Vec3R& inCoord, typename TreeT::ValueType& result) { - using ValueT = typename TreeT::ValueType; - - const Vec3i inIdx = local_util::floorVec3(inCoord); - const Vec3R uvw = inCoord - inIdx; - - // Retrieve the values of the eight voxels surrounding the - // fractional source coordinates. - ValueT data[2][2][2]; - - const bool hasActiveValues = BoxSampler::probeValues(data, inTree, Coord(inIdx)); - - result = BoxSampler::trilinearInterpolation(data, uvw); - - return hasActiveValues; + if constexpr (TreeTraits::IsSparse) { + using ValueT = typename TreeT::ValueType; + + const Vec3i inIdx = local_util::floorVec3(inCoord); + const Vec3R uvw = inCoord - inIdx; + + // Retrieve the values of the eight voxels surrounding the + // fractional source coordinates. + ValueT data[2][2][2]; + + const bool hasActiveValues = BoxSampler::probeValues(data, inTree, Coord(inIdx)); + + result = BoxSampler::trilinearInterpolation(data, uvw); + + return hasActiveValues; + } else if constexpr (TreeTraits::IsAdaptive) { + // As an example, return the background value. + // This is where the logic that could sample against an adaptive tree would live. + // Extract the tree from the Tree or ValueAccessor + auto& tree = TreeAdapter::tree(inTree); + result = tree.background(); + return true; + } else { + static_assert(AlwaysFalseValue, "Not Implemented"); + } + std::abort(); // unreachable } @@ -765,18 +783,30 @@ template inline typename TreeT::ValueType BoxSampler::sample(const TreeT& inTree, const Vec3R& inCoord) { - using ValueT = typename TreeT::ValueType; + if constexpr (TreeTraits::IsSparse) { - const Vec3i inIdx = local_util::floorVec3(inCoord); - const Vec3R uvw = inCoord - inIdx; + using ValueT = typename TreeT::ValueType; - // Retrieve the values of the eight voxels surrounding the - // fractional source coordinates. - ValueT data[2][2][2]; + const Vec3i inIdx = local_util::floorVec3(inCoord); + const Vec3R uvw = inCoord - inIdx; + + // Retrieve the values of the eight voxels surrounding the + // fractional source coordinates. + ValueT data[2][2][2]; - BoxSampler::getValues(data, inTree, Coord(inIdx)); + BoxSampler::getValues(data, inTree, Coord(inIdx)); - return BoxSampler::trilinearInterpolation(data, uvw); + return BoxSampler::trilinearInterpolation(data, uvw); + } else if constexpr (TreeTraits::IsAdaptive) { + // As an example, return the background value. + // This is where the logic that could sample against an adaptive tree would live. + // Extract the tree from the Tree or ValueAccessor + auto& tree = TreeAdapter::tree(inTree); + return tree.background(); + } else { + static_assert(AlwaysFalseValue, "Not Implemented"); + } + std::abort(); // unreachable } diff --git a/openvdb/openvdb/unittest/TestAdaptive.cc b/openvdb/openvdb/unittest/TestAdaptive.cc index a71a7c1bd4..7e894e2714 100644 --- a/openvdb/openvdb/unittest/TestAdaptive.cc +++ b/openvdb/openvdb/unittest/TestAdaptive.cc @@ -2,6 +2,8 @@ // SPDX-License-Identifier: MPL-2.0 #include +#include +#include #include #include @@ -23,3 +25,35 @@ TEST_F(TestAdaptive, test) EXPECT_EQ(adaptiveGrid.background(), 5.0f); } + +TEST_F(TestAdaptive, testSample) +{ + const float background = 5.0f; + openvdb::adaptive::AdaptiveGrid adaptiveGrid(background); + + float result = openvdb::tools::BoxSampler::sample(adaptiveGrid.tree(), openvdb::Vec3R(1.3, 1.6, 1.8)); + + EXPECT_EQ(result, background); +} + +TEST_F(TestAdaptive, testAdvect) +{ + using AdaptiveGridT = openvdb::adaptive::AdaptiveGrid; + using PointAdvectT = openvdb::tools::PointAdvect; + using PointListT = PointAdvectT::PointListType; + + const openvdb::Vec3s background(0.0f, 1.0f, 0.0f); + AdaptiveGridT adaptiveGrid(background); + + openvdb::tools::PointAdvect pointAdvect(adaptiveGrid); + + PointListT points; + points.push_back(openvdb::Vec3s(0.0f, 0.0f, 0.0f)); + points.push_back(openvdb::Vec3s(1.0f, 2.0f, 3.0f)); + + float dt = 1/24.0f; + pointAdvect.advect(points, dt); + + EXPECT_EQ(points[0], openvdb::Vec3s(0.0f, dt, 0.0f)); + EXPECT_EQ(points[1], openvdb::Vec3s(1.0f, 2.0f + dt, 3.0f)); +}