40 #ifndef OPENVDB_TOOLS_INTERPOLATION_HAS_BEEN_INCLUDED 41 #define OPENVDB_TOOLS_INTERPOLATION_HAS_BEEN_INCLUDED 43 #include <openvdb/version.h> 50 #include <type_traits> 62 template <
size_t Order,
bool Staggered = false>
65 static_assert(Order < 3,
"Samplers of order higher than 2 are not supported");
66 static const char* name();
69 static bool consistent();
70 static bool staggered();
71 static size_t order();
78 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
79 typename TreeT::ValueType& result);
85 static typename TreeT::ValueType sample(
const TreeT& inTree,
const Vec3R& inCoord);
98 static const char*
name() {
return "point"; }
108 template<
class TreeT>
109 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
110 typename TreeT::ValueType& result);
114 template<
class TreeT>
115 static typename TreeT::ValueType sample(
const TreeT& inTree,
const Vec3R& inCoord);
121 static const char*
name() {
return "box"; }
131 template<
class TreeT>
132 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
133 typename TreeT::ValueType& result);
137 template<
class TreeT>
138 static typename TreeT::ValueType sample(
const TreeT& inTree,
const Vec3R& inCoord);
142 template<
class ValueT,
class TreeT,
size_t N>
143 static inline void getValues(ValueT (&data)[N][N][N],
const TreeT& inTree, Coord ijk);
148 template<
class ValueT,
class TreeT,
size_t N>
149 static inline bool probeValues(ValueT (&data)[N][N][N],
const TreeT& inTree, Coord ijk);
153 template<
class ValueT,
size_t N>
154 static inline void extrema(ValueT (&data)[N][N][N], ValueT& vMin, ValueT& vMax);
157 template<
class ValueT,
size_t N>
158 static inline ValueT trilinearInterpolation(ValueT (&data)[N][N][N],
const Vec3R& uvw);
164 static const char*
name() {
return "quadratic"; }
174 template<
class TreeT>
175 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
176 typename TreeT::ValueType& result);
180 template<
class TreeT>
181 static typename TreeT::ValueType sample(
const TreeT& inTree,
const Vec3R& inCoord);
183 template<
class ValueT,
size_t N>
184 static inline ValueT triquadraticInterpolation(ValueT (&data)[N][N][N],
const Vec3R& uvw);
198 static const char*
name() {
return "point"; }
208 template<
class TreeT>
209 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
210 typename TreeT::ValueType& result);
214 template<
class TreeT>
215 static typename TreeT::ValueType sample(
const TreeT& inTree,
const Vec3R& inCoord);
221 static const char*
name() {
return "box"; }
231 template<
class TreeT>
232 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
233 typename TreeT::ValueType& result);
237 template<
class TreeT>
238 static typename TreeT::ValueType sample(
const TreeT& inTree,
const Vec3R& inCoord);
244 static const char*
name() {
return "quadratic"; }
254 template<
class TreeT>
255 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
256 typename TreeT::ValueType& result);
260 template<
class TreeT>
261 static typename TreeT::ValueType sample(
const TreeT& inTree,
const Vec3R& inCoord);
282 template<
typename Gr
idOrTreeType,
typename SamplerType>
294 : mTree(&(grid.tree())), mTransform(&(grid.transform())) {}
299 : mTree(&tree), mTransform(&transform) {}
307 template<
typename RealType>
310 return this->isSample(Vec3d(x,y,z));
318 typename Coord::ValueType j,
319 typename Coord::ValueType k)
const 321 return this->isSample(Coord(i,j,k));
333 SamplerType::sample(*mTree, ispoint, result);
342 SamplerType::sample(*mTree, mTransform->worldToIndex(wspoint), result);
364 template<
typename TreeT,
typename SamplerType>
378 : mAccessor(&acc), mTransform(&transform) {}
386 template<
typename RealType>
389 return this->isSample(Vec3d(x,y,z));
397 typename Coord::ValueType j,
398 typename Coord::ValueType k)
const 400 return this->isSample(Coord(i,j,k));
412 SamplerType::sample(*mAccessor, ispoint, result);
421 SamplerType::sample(*mAccessor, mTransform->worldToIndex(wspoint), result);
443 template<
typename GridOrTreeT,
458 : mSourceTree(&(sourceGrid.tree()))
459 , mSourceXform(&(sourceGrid.transform()))
460 , mTargetXform(&targetXform)
461 , mAligned(targetXform == *mSourceXform)
471 : mSourceTree(&sourceTree)
472 , mSourceXform(&sourceXform)
473 , mTargetXform(&targetXform)
474 , mAligned(targetXform == sourceXform)
481 if (mAligned)
return mSourceTree->getValue(ijk);
482 const Vec3R world = mTargetXform->indexToWorld(ijk);
483 return SamplerT::sample(*mSourceTree, mSourceXform->worldToIndex(world));
488 const TreeType* mSourceTree;
495 template<
typename TreeT,
512 : mSourceAcc(&sourceAccessor)
513 , mSourceXform(&sourceXform)
514 , mTargetXform(&targetXform)
515 , mAligned(targetXform == sourceXform)
522 if (mAligned)
return mSourceAcc->getValue(ijk);
523 const Vec3R world = mTargetXform->indexToWorld(ijk);
524 return SamplerT::sample(*mSourceAcc, mSourceXform->worldToIndex(world));
539 template <
typename GridT,
542 typename FloatT =
float>
547 "AlphaMask requires a floating-point value type");
555 , mSampler(mAcc, mask.transform() , grid.transform())
557 , mInvNorm(1/(max-min))
563 inline bool operator()(
const Coord& xyz, FloatT& a, FloatT& b)
const 567 if (mInvert) std::swap(a,b);
572 using AccT =
typename MaskType::ConstAccessor;
581 namespace local_util {
586 return Vec3i(
int(std::floor(v(0))),
int(std::floor(v(1))),
int(std::floor(v(2))));
593 return Vec3i(
int(std::ceil(v(0))),
int(std::ceil(v(1))),
int(std::ceil(v(2))));
600 return Vec3i(
int(::round(v(0))),
int(::round(v(1))),
int(::round(v(2))));
609 template<
class TreeT>
611 PointSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
612 typename TreeT::ValueType& result)
617 template<
class TreeT>
618 inline typename TreeT::ValueType
619 PointSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord)
627 template<
class ValueT,
class TreeT,
size_t N>
629 BoxSampler::getValues(ValueT (&data)[N][N][N],
const TreeT& inTree, Coord ijk)
631 data[0][0][0] = inTree.getValue(ijk);
634 data[0][0][1] = inTree.getValue(ijk);
637 data[0][1][1] = inTree.getValue(ijk);
640 data[0][1][0] = inTree.getValue(ijk);
644 data[1][0][0] = inTree.getValue(ijk);
647 data[1][0][1] = inTree.getValue(ijk);
650 data[1][1][1] = inTree.getValue(ijk);
653 data[1][1][0] = inTree.getValue(ijk);
656 template<
class ValueT,
class TreeT,
size_t N>
658 BoxSampler::probeValues(ValueT (&data)[N][N][N],
const TreeT& inTree, Coord ijk)
660 bool hasActiveValues =
false;
661 hasActiveValues |= inTree.probeValue(ijk, data[0][0][0]);
664 hasActiveValues |= inTree.probeValue(ijk, data[0][0][1]);
667 hasActiveValues |= inTree.probeValue(ijk, data[0][1][1]);
670 hasActiveValues |= inTree.probeValue(ijk, data[0][1][0]);
674 hasActiveValues |= inTree.probeValue(ijk, data[1][0][0]);
677 hasActiveValues |= inTree.probeValue(ijk, data[1][0][1]);
680 hasActiveValues |= inTree.probeValue(ijk, data[1][1][1]);
683 hasActiveValues |= inTree.probeValue(ijk, data[1][1][0]);
685 return hasActiveValues;
688 template<
class ValueT,
size_t N>
692 vMin = vMax = data[0][0][0];
710 template<
class ValueT,
size_t N>
712 BoxSampler::trilinearInterpolation(ValueT (&data)[N][N][N],
const Vec3R& uvw)
714 auto _interpolate = [](
const ValueT& a,
const ValueT& b,
double weight)
717 const auto temp = (b - a) * weight;
719 return static_cast<ValueT
>(a + ValueT(temp));
730 _interpolate(data[0][0][0], data[0][0][1], uvw[2]),
731 _interpolate(data[0][1][0], data[0][1][1], uvw[2]),
734 _interpolate(data[1][0][0], data[1][0][1], uvw[2]),
735 _interpolate(data[1][1][0], data[1][1][1], uvw[2]),
741 template<
class TreeT>
743 BoxSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
744 typename TreeT::ValueType& result)
746 using ValueT =
typename TreeT::ValueType;
749 const Vec3R uvw = inCoord - inIdx;
753 ValueT data[2][2][2];
755 const bool hasActiveValues = BoxSampler::probeValues(data, inTree, Coord(inIdx));
757 result = BoxSampler::trilinearInterpolation(data, uvw);
759 return hasActiveValues;
763 template<
class TreeT>
764 inline typename TreeT::ValueType
765 BoxSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord)
767 using ValueT =
typename TreeT::ValueType;
770 const Vec3R uvw = inCoord - inIdx;
774 ValueT data[2][2][2];
776 BoxSampler::getValues(data, inTree, Coord(inIdx));
778 return BoxSampler::trilinearInterpolation(data, uvw);
784 template<
class ValueT,
size_t N>
786 QuadraticSampler::triquadraticInterpolation(ValueT (&data)[N][N][N],
const Vec3R& uvw)
788 auto _interpolate = [](
const ValueT*
value,
double weight)
792 a =
static_cast<ValueT
>(0.5 * (value[0] + value[2]) - value[1]),
793 b =
static_cast<ValueT
>(0.5 * (value[2] - value[0])),
794 c =
static_cast<ValueT
>(value[1]);
795 const auto temp = weight * (weight * a + b) + c;
797 return static_cast<ValueT
>(temp);
802 for (
int dx = 0; dx < 3; ++dx) {
804 for (
int dy = 0; dy < 3; ++dy) {
815 const ValueT* vz = &data[dx][dy][0];
816 vy[dy] = _interpolate(vz, uvw.
z());
821 vx[dx] = _interpolate(vy, uvw.
y());
825 return _interpolate(vx, uvw.
x());
828 template<
class TreeT>
830 QuadraticSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
831 typename TreeT::ValueType& result)
833 using ValueT =
typename TreeT::ValueType;
836 const Vec3R uvw = inCoord - inIdx;
841 ValueT data[3][3][3];
842 for (
int dx = 0, ix = inLoIdx.x(); dx < 3; ++dx, ++ix) {
843 for (
int dy = 0, iy = inLoIdx.y(); dy < 3; ++dy, ++iy) {
844 for (
int dz = 0, iz = inLoIdx.z(); dz < 3; ++dz, ++iz) {
845 if (inTree.probeValue(Coord(ix, iy, iz), data[dx][dy][dz])) active =
true;
850 result = QuadraticSampler::triquadraticInterpolation(data, uvw);
855 template<
class TreeT>
856 inline typename TreeT::ValueType
857 QuadraticSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord)
859 using ValueT =
typename TreeT::ValueType;
862 const Vec3R uvw = inCoord - inIdx;
866 ValueT data[3][3][3];
867 for (
int dx = 0, ix = inLoIdx.x(); dx < 3; ++dx, ++ix) {
868 for (
int dy = 0, iy = inLoIdx.y(); dy < 3; ++dy, ++iy) {
869 for (
int dz = 0, iz = inLoIdx.z(); dz < 3; ++dz, ++iz) {
870 data[dx][dy][dz] = inTree.getValue(Coord(ix, iy, iz));
875 return QuadraticSampler::triquadraticInterpolation(data, uvw);
882 template<
class TreeT>
884 StaggeredPointSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
885 typename TreeT::ValueType& result)
887 using ValueType =
typename TreeT::ValueType;
889 ValueType tempX, tempY, tempZ;
892 active = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0, 0), tempX) || active;
893 active = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0.5, 0), tempY) || active;
894 active = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0, 0.5), tempZ) || active;
896 result.x() = tempX.x();
897 result.y() = tempY.y();
898 result.z() = tempZ.z();
903 template<
class TreeT>
904 inline typename TreeT::ValueType
905 StaggeredPointSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord)
907 using ValueT =
typename TreeT::ValueType;
909 const ValueT tempX = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0.0, 0.0));
910 const ValueT tempY = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.0, 0.5, 0.0));
911 const ValueT tempZ = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.0, 0.0, 0.5));
913 return ValueT(tempX.x(), tempY.y(), tempZ.z());
920 template<
class TreeT>
922 StaggeredBoxSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
923 typename TreeT::ValueType& result)
925 using ValueType =
typename TreeT::ValueType;
927 ValueType tempX, tempY, tempZ;
928 tempX = tempY = tempZ = zeroVal<ValueType>();
931 active = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0, 0), tempX) || active;
932 active = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0.5, 0), tempY) || active;
933 active = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0, 0.5), tempZ) || active;
935 result.x() = tempX.x();
936 result.y() = tempY.y();
937 result.z() = tempZ.z();
942 template<
class TreeT>
943 inline typename TreeT::ValueType
944 StaggeredBoxSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord)
946 using ValueT =
typename TreeT::ValueType;
948 const ValueT tempX = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0.0, 0.0));
949 const ValueT tempY = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.0, 0.5, 0.0));
950 const ValueT tempZ = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.0, 0.0, 0.5));
952 return ValueT(tempX.x(), tempY.y(), tempZ.z());
959 template<
class TreeT>
961 StaggeredQuadraticSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
962 typename TreeT::ValueType& result)
964 using ValueType =
typename TreeT::ValueType;
966 ValueType tempX, tempY, tempZ;
969 active = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0, 0), tempX) || active;
970 active = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0.5, 0), tempY) || active;
971 active = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0, 0.5), tempZ) || active;
973 result.x() = tempX.x();
974 result.y() = tempY.y();
975 result.z() = tempZ.z();
980 template<
class TreeT>
981 inline typename TreeT::ValueType
982 StaggeredQuadraticSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord)
984 using ValueT =
typename TreeT::ValueType;
986 const ValueT tempX = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0.0, 0.0));
987 const ValueT tempY = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.0, 0.5, 0.0));
988 const ValueT tempZ = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.0, 0.0, 0.5));
990 return ValueT(tempX.x(), tempY.y(), tempZ.z());
1017 #endif // OPENVDB_TOOLS_INTERPOLATION_HAS_BEEN_INCLUDED
Type SmoothUnitStep(Type x)
Return 0 if x < 0, 1 if x > 1 or else (3 − 2 x) x².
Definition: Math.h:286
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
Vec3< int32_t > Vec3i
Definition: Vec3.h:665
T & z()
Definition: Vec3.h:91
T & y()
Definition: Vec3.h:90
std::shared_ptr< T > SharedPtr
Definition: Types.h:114
math::Vec3< Real > Vec3R
Definition: Types.h:72
Definition: Exceptions.h:13
ValueT value
Definition: GridBuilder.h:1287
const Type & Max(const Type &a, const Type &b)
Return the maximum of two values.
Definition: Math.h:598
const Type & Min(const Type &a, const Type &b)
Return the minimum of two values.
Definition: Math.h:659
Container class that associates a tree with a transform and metadata.
Definition: Grid.h:28
T & x()
Reference to the component, e.g. v.x() = 4.5f;.
Definition: Vec3.h:89
_TreeType TreeType
Definition: Grid.h:1072
typename tree::ValueAccessor< TreeType > AccessorType
Definition: Grid.h:1083
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:116
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:202