67 #ifndef OPENVDB_TOOLS_INTERPOLATION_HAS_BEEN_INCLUDED 68 #define OPENVDB_TOOLS_INTERPOLATION_HAS_BEEN_INCLUDED 70 #include <openvdb/version.h> 71 #include <openvdb/Platform.h> 72 #include <openvdb/math/Math.h> 73 #include <openvdb/math/Transform.h> 74 #include <openvdb/Grid.h> 75 #include <openvdb/tree/ValueAccessor.h> 77 #include <type_traits> 89 template <
size_t Order,
bool Staggered = false>
92 static_assert(Order < 3,
"Samplers of order higher than 2 are not supported");
93 static const char* name();
96 static bool consistent();
97 static bool staggered();
98 static size_t order();
104 template<
class TreeT>
105 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
106 typename TreeT::ValueType& result);
111 template<
class TreeT>
112 static typename TreeT::ValueType sample(
const TreeT& inTree,
const Vec3R& inCoord);
125 static const char*
name() {
return "point"; }
135 template<
class TreeT>
136 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
137 typename TreeT::ValueType& result);
141 template<
class TreeT>
142 static typename TreeT::ValueType sample(
const TreeT& inTree,
const Vec3R& inCoord);
148 static const char*
name() {
return "box"; }
158 template<
class TreeT>
159 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
160 typename TreeT::ValueType& result);
164 template<
class TreeT>
165 static typename TreeT::ValueType sample(
const TreeT& inTree,
const Vec3R& inCoord);
169 template<
class ValueT,
class TreeT,
size_t N>
170 static inline void getValues(ValueT (&data)[N][N][N],
const TreeT& inTree,
Coord ijk);
175 template<
class ValueT,
class TreeT,
size_t N>
176 static inline bool probeValues(ValueT (&data)[N][N][N],
const TreeT& inTree,
Coord ijk);
180 template<
class ValueT,
size_t N>
181 static inline void extrema(ValueT (&data)[N][N][N], ValueT& vMin, ValueT& vMax);
184 template<
class ValueT,
size_t N>
185 static inline ValueT trilinearInterpolation(ValueT (&data)[N][N][N],
const Vec3R& uvw);
191 static const char*
name() {
return "quadratic"; }
201 template<
class TreeT>
202 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
203 typename TreeT::ValueType& result);
207 template<
class TreeT>
208 static typename TreeT::ValueType sample(
const TreeT& inTree,
const Vec3R& inCoord);
210 template<
class ValueT,
size_t N>
211 static inline ValueT triquadraticInterpolation(ValueT (&data)[N][N][N],
const Vec3R& uvw);
225 static const char*
name() {
return "point"; }
235 template<
class TreeT>
236 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
237 typename TreeT::ValueType& result);
241 template<
class TreeT>
242 static typename TreeT::ValueType sample(
const TreeT& inTree,
const Vec3R& inCoord);
248 static const char*
name() {
return "box"; }
258 template<
class TreeT>
259 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
260 typename TreeT::ValueType& result);
264 template<
class TreeT>
265 static typename TreeT::ValueType sample(
const TreeT& inTree,
const Vec3R& inCoord);
271 static const char*
name() {
return "quadratic"; }
281 template<
class TreeT>
282 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
283 typename TreeT::ValueType& result);
287 template<
class TreeT>
288 static typename TreeT::ValueType sample(
const TreeT& inTree,
const Vec3R& inCoord);
309 template<
typename Gr
idOrTreeType,
typename SamplerType>
321 : mTree(&(grid.tree())), mTransform(&(grid.transform())) {}
326 : mTree(&tree), mTransform(&transform) {}
334 template<
typename RealType>
337 return this->isSample(
Vec3d(x,y,z));
348 return this->isSample(
Coord(i,j,k));
360 SamplerType::sample(*mTree, ispoint, result);
369 SamplerType::sample(*mTree, mTransform->worldToIndex(wspoint), result);
391 template<
typename TreeT,
typename SamplerType>
405 : mAccessor(&acc), mTransform(&transform) {}
413 template<
typename RealType>
416 return this->isSample(
Vec3d(x,y,z));
427 return this->isSample(
Coord(i,j,k));
439 SamplerType::sample(*mAccessor, ispoint, result);
448 SamplerType::sample(*mAccessor, mTransform->worldToIndex(wspoint), result);
470 template<
typename GridOrTreeT,
485 : mSourceTree(&(sourceGrid.tree()))
486 , mSourceXform(&(sourceGrid.transform()))
487 , mTargetXform(&targetXform)
488 , mAligned(targetXform == *mSourceXform)
498 : mSourceTree(&sourceTree)
499 , mSourceXform(&sourceXform)
500 , mTargetXform(&targetXform)
501 , mAligned(targetXform == sourceXform)
508 if (mAligned)
return mSourceTree->getValue(ijk);
509 const Vec3R world = mTargetXform->indexToWorld(ijk);
510 return SamplerT::sample(*mSourceTree, mSourceXform->worldToIndex(world));
515 const TreeType* mSourceTree;
522 template<
typename TreeT,
539 : mSourceAcc(&sourceAccessor)
540 , mSourceXform(&sourceXform)
541 , mTargetXform(&targetXform)
542 , mAligned(targetXform == sourceXform)
549 if (mAligned)
return mSourceAcc->getValue(ijk);
550 const Vec3R world = mTargetXform->indexToWorld(ijk);
551 return SamplerT::sample(*mSourceAcc, mSourceXform->worldToIndex(world));
566 template <
typename GridT,
569 typename FloatT =
float>
573 static_assert(std::is_floating_point<FloatT>::value,
574 "AlphaMask requires a floating-point value type");
582 , mSampler(mAcc, mask.transform() , grid.transform())
584 , mInvNorm(1/(max-min))
594 if (mInvert) std::swap(a,b);
599 using AccT =
typename MaskType::ConstAccessor;
608 namespace local_util {
613 return Vec3i(
int(std::floor(v(0))),
int(std::floor(v(1))),
int(std::floor(v(2))));
620 return Vec3i(
int(std::ceil(v(0))),
int(std::ceil(v(1))),
int(std::ceil(v(2))));
627 return Vec3i(
int(::round(v(0))),
int(::round(v(1))),
int(::round(v(2))));
636 template<
class TreeT>
638 PointSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
639 typename TreeT::ValueType& result)
644 template<
class TreeT>
645 inline typename TreeT::ValueType
646 PointSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord)
654 template<
class ValueT,
class TreeT,
size_t N>
656 BoxSampler::getValues(ValueT (&data)[N][N][N],
const TreeT& inTree,
Coord ijk)
658 data[0][0][0] = inTree.getValue(ijk);
661 data[0][0][1] = inTree.getValue(ijk);
664 data[0][1][1] = inTree.getValue(ijk);
667 data[0][1][0] = inTree.getValue(ijk);
671 data[1][0][0] = inTree.getValue(ijk);
674 data[1][0][1] = inTree.getValue(ijk);
677 data[1][1][1] = inTree.getValue(ijk);
680 data[1][1][0] = inTree.getValue(ijk);
683 template<
class ValueT,
class TreeT,
size_t N>
685 BoxSampler::probeValues(ValueT (&data)[N][N][N],
const TreeT& inTree,
Coord ijk)
687 bool hasActiveValues =
false;
688 hasActiveValues |= inTree.probeValue(ijk, data[0][0][0]);
691 hasActiveValues |= inTree.probeValue(ijk, data[0][0][1]);
694 hasActiveValues |= inTree.probeValue(ijk, data[0][1][1]);
697 hasActiveValues |= inTree.probeValue(ijk, data[0][1][0]);
701 hasActiveValues |= inTree.probeValue(ijk, data[1][0][0]);
704 hasActiveValues |= inTree.probeValue(ijk, data[1][0][1]);
707 hasActiveValues |= inTree.probeValue(ijk, data[1][1][1]);
710 hasActiveValues |= inTree.probeValue(ijk, data[1][1][0]);
712 return hasActiveValues;
715 template<
class ValueT,
size_t N>
719 vMin = vMax = data[0][0][0];
737 template<
class ValueT,
size_t N>
739 BoxSampler::trilinearInterpolation(ValueT (&data)[N][N][N],
const Vec3R& uvw)
747 ValueT resultA, resultB;
749 resultA = data[0][0][0] + ValueT((data[0][0][1] - data[0][0][0]) * uvw[2]);
750 resultB = data[0][1][0] + ValueT((data[0][1][1] - data[0][1][0]) * uvw[2]);
751 ValueT result1 = resultA + ValueT((resultB-resultA) * uvw[1]);
753 resultA = data[1][0][0] + ValueT((data[1][0][1] - data[1][0][0]) * uvw[2]);
754 resultB = data[1][1][0] + ValueT((data[1][1][1] - data[1][1][0]) * uvw[2]);
755 ValueT result2 = resultA + ValueT((resultB - resultA) * uvw[1]);
757 return result1 + ValueT(uvw[0] * (result2 - result1));
761 template<
class TreeT>
763 BoxSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
764 typename TreeT::ValueType& result)
766 using ValueT =
typename TreeT::ValueType;
769 const Vec3R uvw = inCoord - inIdx;
773 ValueT data[2][2][2];
775 const bool hasActiveValues = BoxSampler::probeValues(data, inTree,
Coord(inIdx));
777 result = BoxSampler::trilinearInterpolation(data, uvw);
779 return hasActiveValues;
783 template<
class TreeT>
784 inline typename TreeT::ValueType
785 BoxSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord)
787 using ValueT =
typename TreeT::ValueType;
790 const Vec3R uvw = inCoord - inIdx;
794 ValueT data[2][2][2];
796 BoxSampler::getValues(data, inTree,
Coord(inIdx));
798 return BoxSampler::trilinearInterpolation(data, uvw);
804 template<
class ValueT,
size_t N>
806 QuadraticSampler::triquadraticInterpolation(ValueT (&data)[N][N][N],
const Vec3R& uvw)
810 for (
int dx = 0; dx < 3; ++dx) {
812 for (
int dy = 0; dy < 3; ++dy) {
823 const ValueT* vz = &data[dx][dy][0];
825 az =
static_cast<ValueT
>(0.5 * (vz[0] + vz[2]) - vz[1]),
826 bz =
static_cast<ValueT
>(0.5 * (vz[2] - vz[0])),
827 cz =
static_cast<ValueT
>(vz[1]);
828 vy[dy] =
static_cast<ValueT
>(uvw.
z() * (uvw.
z() * az + bz) + cz);
834 ay =
static_cast<ValueT
>(0.5 * (vy[0] + vy[2]) - vy[1]),
835 by =
static_cast<ValueT
>(0.5 * (vy[2] - vy[0])),
836 cy =
static_cast<ValueT
>(vy[1]);
837 vx[dx] =
static_cast<ValueT
>(uvw.
y() * (uvw.
y() * ay + by) + cy);
842 ax =
static_cast<ValueT
>(0.5 * (vx[0] + vx[2]) - vx[1]),
843 bx =
static_cast<ValueT
>(0.5 * (vx[2] - vx[0])),
844 cx =
static_cast<ValueT
>(vx[1]);
845 return static_cast<ValueT
>(uvw.
x() * (uvw.
x() * ax + bx) + cx);
848 template<
class TreeT>
850 QuadraticSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
851 typename TreeT::ValueType& result)
853 using ValueT =
typename TreeT::ValueType;
856 const Vec3R uvw = inCoord - inIdx;
861 ValueT data[3][3][3];
862 for (
int dx = 0, ix = inLoIdx.x(); dx < 3; ++dx, ++ix) {
863 for (
int dy = 0, iy = inLoIdx.y(); dy < 3; ++dy, ++iy) {
864 for (
int dz = 0, iz = inLoIdx.z(); dz < 3; ++dz, ++iz) {
865 if (inTree.probeValue(
Coord(ix, iy, iz), data[dx][dy][dz])) active =
true;
870 result = QuadraticSampler::triquadraticInterpolation(data, uvw);
875 template<
class TreeT>
876 inline typename TreeT::ValueType
877 QuadraticSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord)
879 using ValueT =
typename TreeT::ValueType;
882 const Vec3R uvw = inCoord - inIdx;
886 ValueT data[3][3][3];
887 for (
int dx = 0, ix = inLoIdx.x(); dx < 3; ++dx, ++ix) {
888 for (
int dy = 0, iy = inLoIdx.y(); dy < 3; ++dy, ++iy) {
889 for (
int dz = 0, iz = inLoIdx.z(); dz < 3; ++dz, ++iz) {
890 data[dx][dy][dz] = inTree.getValue(
Coord(ix, iy, iz));
895 return QuadraticSampler::triquadraticInterpolation(data, uvw);
902 template<
class TreeT>
904 StaggeredPointSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
905 typename TreeT::ValueType& result)
907 using ValueType =
typename TreeT::ValueType;
909 ValueType tempX, tempY, tempZ;
912 active = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0, 0), tempX) || active;
913 active = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0.5, 0), tempY) || active;
914 active = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0, 0.5), tempZ) || active;
916 result.x() = tempX.x();
917 result.y() = tempY.y();
918 result.z() = tempZ.z();
923 template<
class TreeT>
924 inline typename TreeT::ValueType
925 StaggeredPointSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord)
927 using ValueT =
typename TreeT::ValueType;
929 const ValueT tempX = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0.0, 0.0));
930 const ValueT tempY = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.0, 0.5, 0.0));
931 const ValueT tempZ = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.0, 0.0, 0.5));
933 return ValueT(tempX.x(), tempY.y(), tempZ.z());
940 template<
class TreeT>
942 StaggeredBoxSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
943 typename TreeT::ValueType& result)
945 using ValueType =
typename TreeT::ValueType;
947 ValueType tempX, tempY, tempZ;
948 tempX = tempY = tempZ = zeroVal<ValueType>();
951 active = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0, 0), tempX) || active;
952 active = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0.5, 0), tempY) || active;
953 active = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0, 0.5), tempZ) || active;
955 result.x() = tempX.x();
956 result.y() = tempY.y();
957 result.z() = tempZ.z();
962 template<
class TreeT>
963 inline typename TreeT::ValueType
964 StaggeredBoxSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord)
966 using ValueT =
typename TreeT::ValueType;
968 const ValueT tempX = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0.0, 0.0));
969 const ValueT tempY = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.0, 0.5, 0.0));
970 const ValueT tempZ = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.0, 0.0, 0.5));
972 return ValueT(tempX.x(), tempY.y(), tempZ.z());
979 template<
class TreeT>
981 StaggeredQuadraticSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
982 typename TreeT::ValueType& result)
984 using ValueType =
typename TreeT::ValueType;
986 ValueType tempX, tempY, tempZ;
989 active = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0, 0), tempX) || active;
990 active = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0.5, 0), tempY) || active;
991 active = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0, 0.5), tempZ) || active;
993 result.x() = tempX.x();
994 result.y() = tempY.y();
995 result.z() = tempZ.z();
1000 template<
class TreeT>
1001 inline typename TreeT::ValueType
1002 StaggeredQuadraticSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord)
1004 using ValueT =
typename TreeT::ValueType;
1006 const ValueT tempX = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0.0, 0.0));
1007 const ValueT tempY = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.0, 0.5, 0.0));
1008 const ValueT tempZ = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.0, 0.0, 0.5));
1010 return ValueT(tempX.x(), tempY.y(), tempZ.z());
1037 #endif // OPENVDB_TOOLS_INTERPOLATION_HAS_BEEN_INCLUDED T & y()
Definition: Vec3.h:111
const Type & Min(const Type &a, const Type &b)
Return the minimum of two values.
Definition: Math.h:610
const Type & Max(const Type &a, const Type &b)
Return the maximum of two values.
Definition: Math.h:549
typename tree::ValueAccessor< TreeType > AccessorType
Definition: Grid.h:957
Int32 ValueType
Definition: Coord.h:59
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:51
std::shared_ptr< T > SharedPtr
Definition: Types.h:139
Type SmoothUnitStep(Type x)
Return 0 if x < 0, 1 if x > 1 or else (3 − 2 x) x².
Definition: Math.h:256
Vec3< int32_t > Vec3i
Definition: Vec3.h:676
Vec3< double > Vec3d
Definition: Vec3.h:679
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:136
math::Vec3< Real > Vec3R
Definition: Types.h:79
T & x()
Reference to the component, e.g. v.x() = 4.5f;.
Definition: Vec3.h:110
Definition: Exceptions.h:40
_TreeType TreeType
Definition: Grid.h:946
Container class that associates a tree with a transform and metadata.
Definition: Grid.h:55
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:188
T & z()
Definition: Vec3.h:112