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");
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));
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;
364 template<
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;
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));
529 const AccessorType* mSourceAcc;
539 template <
typename GridT,
542 typename FloatT =
float>
546 static_assert(std::is_floating_point<FloatT>::value,
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;
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());
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
ValueAccessors are designed to help accelerate accesses into the OpenVDB Tree structures by storing c...
Container class that associates a tree with a transform and metadata.
Definition: Grid.h:571
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:25
Int32 ValueType
Definition: Coord.h:32
T & y()
Definition: Vec3.h:86
T & z()
Definition: Vec3.h:87
T & x()
Reference to the component, e.g. v.x() = 4.5f;.
Definition: Vec3.h:85
The Value Accessor Implementation and API methods. The majoirty of the API matches the API of a compa...
Definition: ValueAccessor.h:367
Type SmoothUnitStep(Type x)
Return 0 if x < 0, 1 if x > 1 or else (3 − 2 x) x².
Definition: Math.h:287
const Type & Min(const Type &a, const Type &b)
Return the minimum of two values.
Definition: Math.h:656
const Type & Max(const Type &a, const Type &b)
Return the maximum of two values.
Definition: Math.h:595
Vec3< int32_t > Vec3i
Definition: Vec3.h:661
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
math::Vec3< Real > Vec3R
Definition: Types.h:72
std::shared_ptr< T > SharedPtr
Definition: Types.h:114
Definition: Exceptions.h:13
_TreeType TreeType
Definition: Grid.h:1061
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
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:212