Skip to content

Commit 6cca30f

Browse files
authored
Merge pull request #1482 from apradhana/fastsweeping_pruneminmaxfloat
Prune SDF value if there is a float max or float min.
2 parents 2d4f31c + 108d879 commit 6cca30f

File tree

1 file changed

+67
-4
lines changed

1 file changed

+67
-4
lines changed

openvdb/openvdb/tools/FastSweeping.h

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include <openvdb/math/Math.h> // for Abs() and isExactlyEqual()
3535
#include <openvdb/math/Stencils.h> // for GradStencil
3636
#include <openvdb/tree/LeafManager.h>
37+
#include <openvdb/tree/NodeManager.h> // for PruneMinMaxFltKernel
3738

3839
#include "LevelSetUtil.h"
3940
#include "Morphology.h"
@@ -688,6 +689,7 @@ class FastSweeping
688689
struct InitSdf;
689690
struct DilateKernel;// initialization to dilate a SDF
690691
struct MinMaxKernel;
692+
struct PruneMinMaxFltKernel;// prune sdf if it has min float or max float
691693
struct SweepingKernel;// performs the actual concurrent sparse fast sweeping
692694

693695
// Define the topology (i.e. stencil) of the neighboring grid points
@@ -889,6 +891,11 @@ void FastSweeping<SdfGridT, ExtValueT>::sweep(int nIter, bool finalize)
889891
MinMaxKernel kernel;
890892
auto e = kernel.run(*mSdfGrid);//multi-threaded
891893
//auto e = extrema(mGrid->beginValueOn());// 100x slower!!!!
894+
if (kernel.mFltMinExists || kernel.mFltMaxExists) {
895+
tree::NodeManager<SdfTreeT> nodeManager(mSdfGrid->tree());
896+
PruneMinMaxFltKernel op(e.min(), e.max());
897+
nodeManager.foreachTopDown(op, true /* = threaded*/, 1 /* = grainSize*/);
898+
}
892899
#ifdef BENCHMARK_FAST_SWEEPING
893900
std::cerr << "Min = " << e.min() << " Max = " << e.max() << std::endl;
894901
timer.restart("Changing asymmetric background value");
@@ -904,13 +911,15 @@ void FastSweeping<SdfGridT, ExtValueT>::sweep(int nIter, bool finalize)
904911
/// Private class of FastSweeping to quickly compute the extrema
905912
/// values of the active voxels in the leaf nodes. Several orders
906913
/// of magnitude faster than tools::extrema!
914+
/// Also determines whether there is float max or float min stored
915+
/// in a voxel.
907916
template <typename SdfGridT, typename ExtValueT>
908917
struct FastSweeping<SdfGridT, ExtValueT>::MinMaxKernel
909918
{
910919
using LeafMgr = tree::LeafManager<const SdfTreeT>;
911920
using LeafRange = typename LeafMgr::LeafRange;
912-
MinMaxKernel() : mMin(std::numeric_limits<SdfValueT>::max()), mMax(-mMin) {}
913-
MinMaxKernel(MinMaxKernel& other, tbb::split) : mMin(other.mMin), mMax(other.mMax) {}
921+
MinMaxKernel() : mMin(std::numeric_limits<SdfValueT>::max()), mMax(-mMin), mFltMinExists(false), mFltMaxExists(true) {}
922+
MinMaxKernel(MinMaxKernel& other, tbb::split) : mMin(other.mMin), mMax(other.mMax), mFltMinExists(other.mFltMinExists), mFltMaxExists(other.mFltMaxExists) {}
914923

915924
math::MinMax<SdfValueT> run(const SdfGridT &grid)
916925
{
@@ -924,8 +933,12 @@ struct FastSweeping<SdfGridT, ExtValueT>::MinMaxKernel
924933
for (auto leafIter = r.begin(); leafIter; ++leafIter) {
925934
for (auto voxelIter = leafIter->beginValueOn(); voxelIter; ++voxelIter) {
926935
const SdfValueT v = *voxelIter;
927-
if (v < mMin) mMin = v;
928-
if (v > mMax) mMax = v;
936+
const bool vEqFltMin = v == -std::numeric_limits<SdfValueT>::max();
937+
const bool vEqFltMax = v == std::numeric_limits<SdfValueT>::max();
938+
if (v < mMin && !vEqFltMin) mMin = v;
939+
if (v > mMax && !vEqFltMax) mMax = v;
940+
if (vEqFltMin) mFltMinExists = true;
941+
if (vEqFltMax) mFltMaxExists = true;
929942
}
930943
}
931944
}
@@ -934,11 +947,61 @@ struct FastSweeping<SdfGridT, ExtValueT>::MinMaxKernel
934947
{
935948
if (other.mMin < mMin) mMin = other.mMin;
936949
if (other.mMax > mMax) mMax = other.mMax;
950+
mFltMinExists = other.mFltMinExists || mFltMinExists;
951+
mFltMaxExists = other.mFltMaxExists || mFltMaxExists;
937952
}
938953

939954
SdfValueT mMin, mMax;
955+
bool mFltMinExists, mFltMaxExists;
940956
};// FastSweeping::MinMaxKernel
941957

958+
/// Private class of FastSweeping to prune sdf value that is equal to float max or
959+
/// float min.
960+
template <typename SdfGridT, typename ExtValueT>
961+
struct FastSweeping<SdfGridT, ExtValueT>::PruneMinMaxFltKernel {
962+
PruneMinMaxFltKernel(SdfValueT min, SdfValueT max) : mMin(min), mMax(max) {}
963+
964+
// Root node
965+
void operator()(typename SdfTreeT::RootNodeType& node, size_t = 1) const {
966+
for (auto iter = node.beginValueAll(); iter; ++iter) {
967+
if (*iter == -std::numeric_limits<SdfValueT>::max()) {
968+
iter.setValue(mMin);
969+
}
970+
if (*iter == std::numeric_limits<SdfValueT>::max()) {
971+
iter.setValue(mMax);
972+
}
973+
}
974+
}
975+
976+
// Internal nodes
977+
template<typename NodeT>
978+
void operator()(NodeT& node, size_t = 1) const
979+
{
980+
for (auto iter = node.beginValueAll(); iter; ++iter) {
981+
if (*iter == -std::numeric_limits<SdfValueT>::max()) {
982+
iter.setValue(mMin);
983+
}
984+
if (*iter == std::numeric_limits<SdfValueT>::max()) {
985+
iter.setValue(mMax);
986+
}
987+
}
988+
}
989+
990+
// Leaf nodes
991+
void operator()(typename SdfTreeT::LeafNodeType& leaf, size_t = 1) const
992+
{
993+
for (auto iter = leaf.beginValueOn(); iter; ++iter) {
994+
if (*iter == -std::numeric_limits<SdfValueT>::max()) {
995+
iter.setValue(mMin);
996+
}
997+
if (*iter == std::numeric_limits<SdfValueT>::max()) {
998+
iter.setValue(mMax);
999+
}
1000+
}
1001+
}
1002+
SdfValueT mMin, mMax;
1003+
};// FastSweeping::PruneMinMaxFltKernel
1004+
9421005
////////////////////////////////////////////////////////////////////////////////
9431006

9441007
/// Private class of FastSweeping to perform multi-threaded initialization

0 commit comments

Comments
 (0)