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.
907916template <typename SdfGridT, typename ExtValueT>
908917struct 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