40#ifndef OPENVDB_TOOLS_INTERPOLATION_HAS_BEEN_INCLUDED
41#define OPENVDB_TOOLS_INTERPOLATION_HAS_BEEN_INCLUDED
43#include <openvdb/version.h>
62template <
size_t Order,
bool Staggered = false>
65 static_assert(Order < 3,
"Samplers of order higher than 2 are not supported");
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);
282template<
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));
321 return this->isSample(
Coord(i,j,k));
333 SamplerType::sample(*mTree, ispoint, result);
342 SamplerType::sample(*mTree, mTransform->worldToIndex(wspoint), result);
347 const TreeType* mTree;
364template<
typename TreeT,
typename SamplerType>
378 : mAccessor(&acc), mTransform(&transform) {}
386 template<
typename RealType>
389 return this->isSample(Vec3d(x,y,z));
400 return this->isSample(
Coord(i,j,k));
412 SamplerType::sample(*mAccessor, ispoint, result);
421 SamplerType::sample(*mAccessor, mTransform->worldToIndex(wspoint), result);
426 const AccessorType* mAccessor;
443template<
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;
495template<
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));
529 const AccessorType* mSourceAcc;
539template <
typename GridT,
542 typename FloatT =
float>
547 "AlphaMask requires a floating-point value type");
555 , mSampler(mAcc, mask.transform() , grid.transform())
567 if (mInvert) std::swap(a,b);
572 using AccT =
typename MaskType::ConstAccessor;
581namespace 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))));
611PointSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
612 typename TreeT::ValueType& result)
618inline typename TreeT::ValueType
619PointSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord)
627template<
class ValueT,
class TreeT,
size_t N>
629BoxSampler::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);
656template<
class ValueT,
class TreeT,
size_t N>
658BoxSampler::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;
688template<
class ValueT,
size_t N>
692 vMin = vMax = data[0][0][0];
710template<
class ValueT,
size_t N>
712BoxSampler::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]),
743BoxSampler::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;
764inline typename TreeT::ValueType
765BoxSampler::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);
784template<
class ValueT,
size_t N>
786QuadraticSampler::triquadraticInterpolation(ValueT (&data)[N][N][N],
const Vec3R& uvw)
788 auto _interpolate = [](
const ValueT*
value,
double weight)
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());
830QuadraticSampler::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);
856inline typename TreeT::ValueType
857QuadraticSampler::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);
884StaggeredPointSampler::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();
904inline typename TreeT::ValueType
905StaggeredPointSampler::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());
922StaggeredBoxSampler::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();
943inline typename TreeT::ValueType
944StaggeredBoxSampler::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());
961StaggeredQuadraticSampler::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();
981inline typename TreeT::ValueType
982StaggeredQuadraticSampler::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());
ValueT value
Definition: GridBuilder.h:1287
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
Container class that associates a tree with a transform and metadata.
Definition: Grid.h:577
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:25
Int32 ValueType
Definition: Coord.h:32
T & x()
Reference to the component, e.g. v.x() = 4.5f;.
Definition: Vec3.h:89
T & y()
Definition: Vec3.h:90
T & z()
Definition: Vec3.h:91
Type Min(Type a, Type b)
Definition: NanoVDB.h:651
Vec3< double > Vec3R
Definition: NanoVDB.h:1173
Vec3< int > Vec3i
Definition: NanoVDB.h:1176
Type Max(Type a, Type b)
Definition: NanoVDB.h:672
Type SmoothUnitStep(Type x)
Return 0 if x < 0, 1 if x > 1 or else (3 − 2 x) x².
Definition: Math.h:286
std::shared_ptr< T > SharedPtr
Definition: Types.h:114
Definition: Exceptions.h:13
_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