40 #ifndef OPENVDB_TOOLS_INTERPOLATION_HAS_BEEN_INCLUDED 41 #define OPENVDB_TOOLS_INTERPOLATION_HAS_BEEN_INCLUDED 43 #include <openvdb/version.h> 51 #include <type_traits> 63 template <
size_t Order,
bool Staggered = false>
66 static_assert(Order < 3,
"Samplers of order higher than 2 are not supported");
67 static const char* name();
70 static bool consistent();
71 static bool staggered();
72 static size_t order();
79 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
80 typename TreeT::ValueType& result);
86 static typename TreeT::ValueType sample(
const TreeT& inTree,
const Vec3R& inCoord);
99 static const char*
name() {
return "point"; }
109 template<
class TreeT>
110 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
111 typename TreeT::ValueType& result);
115 template<
class TreeT>
116 static typename TreeT::ValueType sample(
const TreeT& inTree,
const Vec3R& inCoord);
122 static const char*
name() {
return "box"; }
132 template<
class TreeT>
133 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
134 typename TreeT::ValueType& result);
138 template<
class TreeT>
139 static typename TreeT::ValueType sample(
const TreeT& inTree,
const Vec3R& inCoord);
143 template<
class ValueT,
class TreeT,
size_t N>
144 static inline void getValues(ValueT (&data)[N][N][N],
const TreeT& inTree, Coord ijk);
149 template<
class ValueT,
class TreeT,
size_t N>
150 static inline bool probeValues(ValueT (&data)[N][N][N],
const TreeT& inTree, Coord ijk);
154 template<
class ValueT,
size_t N>
155 static inline void extrema(ValueT (&data)[N][N][N], ValueT& vMin, ValueT& vMax);
158 template<
class ValueT,
size_t N>
159 static inline ValueT trilinearInterpolation(ValueT (&data)[N][N][N],
const Vec3R& uvw);
165 static const char*
name() {
return "quadratic"; }
175 template<
class TreeT>
176 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
177 typename TreeT::ValueType& result);
181 template<
class TreeT>
182 static typename TreeT::ValueType sample(
const TreeT& inTree,
const Vec3R& inCoord);
184 template<
class ValueT,
size_t N>
185 static inline ValueT triquadraticInterpolation(ValueT (&data)[N][N][N],
const Vec3R& uvw);
199 static const char*
name() {
return "point"; }
209 template<
class TreeT>
210 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
211 typename TreeT::ValueType& result);
215 template<
class TreeT>
216 static typename TreeT::ValueType sample(
const TreeT& inTree,
const Vec3R& inCoord);
222 static const char*
name() {
return "box"; }
232 template<
class TreeT>
233 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
234 typename TreeT::ValueType& result);
238 template<
class TreeT>
239 static typename TreeT::ValueType sample(
const TreeT& inTree,
const Vec3R& inCoord);
245 static const char*
name() {
return "quadratic"; }
255 template<
class TreeT>
256 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
257 typename TreeT::ValueType& result);
261 template<
class TreeT>
262 static typename TreeT::ValueType sample(
const TreeT& inTree,
const Vec3R& inCoord);
283 template<
typename Gr
idOrTreeType,
typename SamplerType>
295 : mTree(&(grid.tree())), mTransform(&(grid.transform())) {}
300 : mTree(&tree), mTransform(&transform) {}
308 template<
typename RealType>
311 return this->isSample(Vec3d(x,y,z));
319 typename Coord::ValueType j,
320 typename Coord::ValueType k)
const 322 return this->isSample(Coord(i,j,k));
334 SamplerType::sample(*mTree, ispoint, result);
343 SamplerType::sample(*mTree, mTransform->worldToIndex(wspoint), result);
365 template<
typename TreeT,
typename SamplerType>
379 : mAccessor(&acc), mTransform(&transform) {}
387 template<
typename RealType>
390 return this->isSample(Vec3d(x,y,z));
398 typename Coord::ValueType j,
399 typename Coord::ValueType k)
const 401 return this->isSample(Coord(i,j,k));
413 SamplerType::sample(*mAccessor, ispoint, result);
422 SamplerType::sample(*mAccessor, mTransform->worldToIndex(wspoint), result);
444 template<
typename GridOrTreeT,
459 : mSourceTree(&(sourceGrid.tree()))
460 , mSourceXform(&(sourceGrid.transform()))
461 , mTargetXform(&targetXform)
462 , mAligned(targetXform == *mSourceXform)
472 : mSourceTree(&sourceTree)
473 , mSourceXform(&sourceXform)
474 , mTargetXform(&targetXform)
475 , mAligned(targetXform == sourceXform)
482 if (mAligned)
return mSourceTree->getValue(ijk);
483 const Vec3R world = mTargetXform->indexToWorld(ijk);
484 return SamplerT::sample(*mSourceTree, mSourceXform->worldToIndex(world));
489 const TreeType* mSourceTree;
496 template<
typename TreeT,
513 : mSourceAcc(&sourceAccessor)
514 , mSourceXform(&sourceXform)
515 , mTargetXform(&targetXform)
516 , mAligned(targetXform == sourceXform)
523 if (mAligned)
return mSourceAcc->getValue(ijk);
524 const Vec3R world = mTargetXform->indexToWorld(ijk);
525 return SamplerT::sample(*mSourceAcc, mSourceXform->worldToIndex(world));
540 template <
typename GridT,
543 typename FloatT =
float>
547 static_assert(std::is_floating_point<FloatT>::value,
548 "AlphaMask requires a floating-point value type");
556 , mSampler(mAcc, mask.transform() , grid.transform())
558 , mInvNorm(1/(max-min))
564 inline bool operator()(
const Coord& xyz, FloatT& a, FloatT& b)
const 568 if (mInvert) std::swap(a,b);
573 using AccT =
typename MaskType::ConstAccessor;
582 namespace local_util {
587 return Vec3i(
int(std::floor(v(0))),
int(std::floor(v(1))),
int(std::floor(v(2))));
594 return Vec3i(
int(std::ceil(v(0))),
int(std::ceil(v(1))),
int(std::ceil(v(2))));
601 return Vec3i(
int(::round(v(0))),
int(::round(v(1))),
int(::round(v(2))));
610 template<
class TreeT>
612 PointSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
613 typename TreeT::ValueType& result)
618 template<
class TreeT>
619 inline typename TreeT::ValueType
620 PointSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord)
628 template<
class ValueT,
class TreeT,
size_t N>
630 BoxSampler::getValues(ValueT (&data)[N][N][N],
const TreeT& inTree, Coord ijk)
632 data[0][0][0] = inTree.getValue(ijk);
635 data[0][0][1] = inTree.getValue(ijk);
638 data[0][1][1] = inTree.getValue(ijk);
641 data[0][1][0] = inTree.getValue(ijk);
645 data[1][0][0] = inTree.getValue(ijk);
648 data[1][0][1] = inTree.getValue(ijk);
651 data[1][1][1] = inTree.getValue(ijk);
654 data[1][1][0] = inTree.getValue(ijk);
657 template<
class ValueT,
class TreeT,
size_t N>
659 BoxSampler::probeValues(ValueT (&data)[N][N][N],
const TreeT& inTree, Coord ijk)
661 bool hasActiveValues =
false;
662 hasActiveValues |= inTree.probeValue(ijk, data[0][0][0]);
665 hasActiveValues |= inTree.probeValue(ijk, data[0][0][1]);
668 hasActiveValues |= inTree.probeValue(ijk, data[0][1][1]);
671 hasActiveValues |= inTree.probeValue(ijk, data[0][1][0]);
675 hasActiveValues |= inTree.probeValue(ijk, data[1][0][0]);
678 hasActiveValues |= inTree.probeValue(ijk, data[1][0][1]);
681 hasActiveValues |= inTree.probeValue(ijk, data[1][1][1]);
684 hasActiveValues |= inTree.probeValue(ijk, data[1][1][0]);
686 return hasActiveValues;
689 template<
class ValueT,
size_t N>
693 vMin = vMax = data[0][0][0];
711 template<
class ValueT,
size_t N>
713 BoxSampler::trilinearInterpolation(ValueT (&data)[N][N][N],
const Vec3R& uvw)
715 auto _interpolate = [](
const ValueT& a,
const ValueT& b,
double weight)
718 const auto temp = (b - a) * weight;
720 return static_cast<ValueT
>(a + ValueT(temp));
731 _interpolate(data[0][0][0], data[0][0][1], uvw[2]),
732 _interpolate(data[0][1][0], data[0][1][1], uvw[2]),
735 _interpolate(data[1][0][0], data[1][0][1], uvw[2]),
736 _interpolate(data[1][1][0], data[1][1][1], uvw[2]),
742 template<
class TreeT>
744 BoxSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
745 typename TreeT::ValueType& result)
747 using ValueT =
typename TreeT::ValueType;
750 const Vec3R uvw = inCoord - inIdx;
754 ValueT data[2][2][2];
756 const bool hasActiveValues = BoxSampler::probeValues(data, inTree, Coord(inIdx));
758 result = BoxSampler::trilinearInterpolation(data, uvw);
760 return hasActiveValues;
764 template<
class TreeT>
765 inline typename TreeT::ValueType
766 BoxSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord)
768 using ValueT =
typename TreeT::ValueType;
771 const Vec3R uvw = inCoord - inIdx;
775 ValueT data[2][2][2];
777 BoxSampler::getValues(data, inTree, Coord(inIdx));
779 return BoxSampler::trilinearInterpolation(data, uvw);
785 template<
class ValueT,
size_t N>
787 QuadraticSampler::triquadraticInterpolation(ValueT (&data)[N][N][N],
const Vec3R& uvw)
789 auto _interpolate = [](
const ValueT* value,
double weight)
793 a =
static_cast<ValueT
>(0.5 * (value[0] + value[2]) - value[1]),
794 b =
static_cast<ValueT
>(0.5 * (value[2] - value[0])),
795 c =
static_cast<ValueT
>(value[1]);
796 const auto temp = weight * (weight * a + b) + c;
798 return static_cast<ValueT
>(temp);
803 for (
int dx = 0; dx < 3; ++dx) {
805 for (
int dy = 0; dy < 3; ++dy) {
816 const ValueT* vz = &data[dx][dy][0];
817 vy[dy] = _interpolate(vz, uvw.
z());
822 vx[dx] = _interpolate(vy, uvw.
y());
826 return _interpolate(vx, uvw.
x());
829 template<
class TreeT>
831 QuadraticSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
832 typename TreeT::ValueType& result)
834 using ValueT =
typename TreeT::ValueType;
837 const Vec3R uvw = inCoord - inIdx;
842 ValueT data[3][3][3];
843 for (
int dx = 0, ix = inLoIdx.x(); dx < 3; ++dx, ++ix) {
844 for (
int dy = 0, iy = inLoIdx.y(); dy < 3; ++dy, ++iy) {
845 for (
int dz = 0, iz = inLoIdx.z(); dz < 3; ++dz, ++iz) {
846 if (inTree.probeValue(Coord(ix, iy, iz), data[dx][dy][dz])) active =
true;
851 result = QuadraticSampler::triquadraticInterpolation(data, uvw);
856 template<
class TreeT>
857 inline typename TreeT::ValueType
858 QuadraticSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord)
860 using ValueT =
typename TreeT::ValueType;
863 const Vec3R uvw = inCoord - inIdx;
867 ValueT data[3][3][3];
868 for (
int dx = 0, ix = inLoIdx.x(); dx < 3; ++dx, ++ix) {
869 for (
int dy = 0, iy = inLoIdx.y(); dy < 3; ++dy, ++iy) {
870 for (
int dz = 0, iz = inLoIdx.z(); dz < 3; ++dz, ++iz) {
871 data[dx][dy][dz] = inTree.getValue(Coord(ix, iy, iz));
876 return QuadraticSampler::triquadraticInterpolation(data, uvw);
883 template<
class TreeT>
885 StaggeredPointSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
886 typename TreeT::ValueType& result)
888 using ValueType =
typename TreeT::ValueType;
890 ValueType tempX, tempY, tempZ;
893 active = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0, 0), tempX) || active;
894 active = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0.5, 0), tempY) || active;
895 active = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0, 0.5), tempZ) || active;
897 result.x() = tempX.x();
898 result.y() = tempY.y();
899 result.z() = tempZ.z();
904 template<
class TreeT>
905 inline typename TreeT::ValueType
906 StaggeredPointSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord)
908 using ValueT =
typename TreeT::ValueType;
910 const ValueT tempX = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0.0, 0.0));
911 const ValueT tempY = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.0, 0.5, 0.0));
912 const ValueT tempZ = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.0, 0.0, 0.5));
914 return ValueT(tempX.x(), tempY.y(), tempZ.z());
921 template<
class TreeT>
923 StaggeredBoxSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
924 typename TreeT::ValueType& result)
926 using ValueType =
typename TreeT::ValueType;
928 ValueType tempX, tempY, tempZ;
929 tempX = tempY = tempZ = zeroVal<ValueType>();
932 active = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0, 0), tempX) || active;
933 active = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0.5, 0), tempY) || active;
934 active = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0, 0.5), tempZ) || active;
936 result.x() = tempX.x();
937 result.y() = tempY.y();
938 result.z() = tempZ.z();
943 template<
class TreeT>
944 inline typename TreeT::ValueType
945 StaggeredBoxSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord)
947 using ValueT =
typename TreeT::ValueType;
949 const ValueT tempX = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0.0, 0.0));
950 const ValueT tempY = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.0, 0.5, 0.0));
951 const ValueT tempZ = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.0, 0.0, 0.5));
953 return ValueT(tempX.x(), tempY.y(), tempZ.z());
960 template<
class TreeT>
962 StaggeredQuadraticSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
963 typename TreeT::ValueType& result)
965 using ValueType =
typename TreeT::ValueType;
967 ValueType tempX, tempY, tempZ;
970 active = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0, 0), tempX) || active;
971 active = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0.5, 0), tempY) || active;
972 active = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0, 0.5), tempZ) || active;
974 result.x() = tempX.x();
975 result.y() = tempY.y();
976 result.z() = tempZ.z();
981 template<
class TreeT>
982 inline typename TreeT::ValueType
983 StaggeredQuadraticSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord)
985 using ValueT =
typename TreeT::ValueType;
987 const ValueT tempX = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0.0, 0.0));
988 const ValueT tempY = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.0, 0.5, 0.0));
989 const ValueT tempZ = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.0, 0.0, 0.5));
991 return ValueT(tempX.x(), tempY.y(), tempZ.z());
1018 #endif // OPENVDB_TOOLS_INTERPOLATION_HAS_BEEN_INCLUDED
T & y()
Definition: Vec3.h:87
The Value Accessor Implementation and API methods. The majoirty of the API matches the API of a compa...
Definition: ValueAccessor.h:68
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
T & z()
Definition: Vec3.h:88
const Type & Max(const Type &a, const Type &b)
Return the maximum of two values.
Definition: Math.h:595
const Type & Min(const Type &a, const Type &b)
Return the minimum of two values.
Definition: Math.h:656
_TreeType TreeType
Definition: Grid.h:1061
T & x()
Reference to the component, e.g. v.x() = 4.5f;.
Definition: Vec3.h:86
Type SmoothUnitStep(Type x)
Return 0 if x < 0, 1 if x > 1 or else (3 − 2 x) x².
Definition: Math.h:287
std::shared_ptr< T > SharedPtr
Definition: Types.h:114
#define OPENVDB_ASSERT(X)
Definition: Assert.h:41
Definition: Exceptions.h:13
ValueAccessors are designed to help accelerate accesses into the OpenVDB Tree structures by storing c...
ValueAccessorImpl< TreeType, IsSafe, MutexType, openvdb::make_index_sequence< CacheLevels >> ValueAccessor
Default alias for a ValueAccessor. This is simply a helper alias for the generic definition but takes...
Definition: ValueAccessor.h:88
typename tree::ValueAccessor< TreeType > AccessorType
Definition: Grid.h:1072
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:121
Vec3< int32_t > Vec3i
Definition: Vec3.h:662
Container class that associates a tree with a transform and metadata.
Definition: Grid.h:28
math::Vec3< Real > Vec3R
Definition: Types.h:72
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:218