67 #ifndef OPENVDB_TOOLS_INTERPOLATION_HAS_BEEN_INCLUDED
68 #define OPENVDB_TOOLS_INTERPOLATION_HAS_BEEN_INCLUDED
71 #include <boost/shared_ptr.hpp>
72 #include <openvdb/version.h>
73 #include <openvdb/Platform.h>
74 #include <openvdb/math/Math.h>
75 #include <openvdb/math/Transform.h>
76 #include <openvdb/Grid.h>
77 #include <openvdb/tree/ValueAccessor.h>
92 static const char*
name() {
return "point"; }
94 static bool mipmap() {
return false; }
100 template<
class TreeT>
101 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
102 typename TreeT::ValueType& result);
108 static const char*
name() {
return "box"; }
116 template<
class TreeT>
117 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
118 typename TreeT::ValueType& result);
122 template<
class TreeT>
123 static typename TreeT::ValueType sample(
const TreeT& inTree,
const Vec3R& inCoord);
126 template<
class ValueT,
size_t N>
127 static inline ValueT trilinearInterpolation(ValueT (& data)[N][N][N],
const Vec3R& uvw);
133 static const char*
name() {
return "quadratic"; }
141 template<
class TreeT>
142 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
143 typename TreeT::ValueType& result);
157 static const char*
name() {
return "point"; }
165 template<
class TreeT>
166 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
167 typename TreeT::ValueType& result);
173 static const char*
name() {
return "box"; }
181 template<
class TreeT>
182 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
183 typename TreeT::ValueType& result);
189 static const char*
name() {
return "quadratic"; }
197 template<
class TreeT>
198 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
199 typename TreeT::ValueType& result);
220 template<
typename Gr
idOrTreeType,
typename SamplerType>
224 typedef boost::shared_ptr<GridSampler>
Ptr;
232 : mTree(&(grid.tree())), mTransform(&(grid.transform())) {}
237 : mTree(&tree), mTransform(&transform) {}
245 template<
typename RealType>
246 ValueType
sampleVoxel(
const RealType& x,
const RealType& y,
const RealType& z)
const
248 return this->isSample(
Vec3d(x,y,z));
256 typename Coord::ValueType j,
257 typename Coord::ValueType k)
const
259 return this->isSample(Coord(i,j,k));
264 ValueType
isSample(
const Coord& ijk)
const {
return mTree->getValue(ijk); }
270 ValueType result = zeroVal<ValueType>();
271 SamplerType::sample(*mTree, ispoint, result);
279 ValueType result = zeroVal<ValueType>();
280 SamplerType::sample(*mTree, mTransform->worldToIndex(wspoint), result);
285 const TreeType* mTree;
302 template<
typename TreeT,
typename SamplerType>
306 typedef boost::shared_ptr<GridSampler>
Ptr;
316 : mAccessor(&acc), mTransform(&transform) {}
324 template<
typename RealType>
325 ValueType
sampleVoxel(
const RealType& x,
const RealType& y,
const RealType& z)
const
327 return this->isSample(
Vec3d(x,y,z));
335 typename Coord::ValueType j,
336 typename Coord::ValueType k)
const
338 return this->isSample(Coord(i,j,k));
343 ValueType
isSample(
const Coord& ijk)
const {
return mAccessor->getValue(ijk); }
349 ValueType result = zeroVal<ValueType>();
350 SamplerType::sample(*mAccessor, ispoint, result);
358 ValueType result = zeroVal<ValueType>();
359 SamplerType::sample(*mAccessor, mTransform->worldToIndex(wspoint), result);
364 const AccessorType* mAccessor;
381 template<
typename GridOrTreeT,
396 : mSourceTree(&(sourceGrid.tree()))
397 , mSourceXform(&(sourceGrid.transform()))
398 , mTargetXform(&targetXform)
399 , mAligned(targetXform == *mSourceXform)
409 : mSourceTree(&sourceTree)
410 , mSourceXform(&sourceXform)
411 , mTargetXform(&targetXform)
412 , mAligned(targetXform == sourceXform)
419 if (mAligned)
return mSourceTree->getValue(ijk);
420 const Vec3R world = mTargetXform->indexToWorld(ijk);
421 return SamplerT::sample(*mSourceTree, mSourceXform->worldToIndex(world));
426 const TreeType* mSourceTree;
433 template<
typename TreeT,
450 : mSourceAcc(&sourceAccessor)
451 , mSourceXform(&sourceXform)
452 , mTargetXform(&targetXform)
453 , mAligned(targetXform == sourceXform)
460 if (mAligned)
return mSourceAcc->getValue(ijk);
461 const Vec3R world = mTargetXform->indexToWorld(ijk);
462 return SamplerT::sample(*mSourceAcc, mSourceXform->worldToIndex(world));
467 const AccessorType* mSourceAcc;
477 template <
typename GridT,
480 typename FloatT =
float>
484 BOOST_STATIC_ASSERT(boost::is_floating_point<FloatT>::value);
492 , mSampler(mAcc, mask.transform() , grid.transform())
494 , mInvNorm(1/(max-min))
500 inline bool operator()(
const Coord& xyz, FloatT& a, FloatT& b)
const
504 if (mInvert) std::swap(a,b);
509 typedef typename MaskType::ConstAccessor
AccT;
518 namespace local_util {
523 return Vec3i(
int(std::floor(v(0))),
int(std::floor(v(1))),
int(std::floor(v(2))));
530 return Vec3i(
int(std::ceil(v(0))),
int(std::ceil(v(1))),
int(std::ceil(v(2))));
537 return Vec3i(
int(::round(v(0))),
int(::round(v(1))),
int(::round(v(2))));
546 template<
class TreeT>
548 PointSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
549 typename TreeT::ValueType& result)
552 return inTree.probeValue(Coord(inIdx), result);
559 template<
class ValueT,
size_t N>
561 BoxSampler::trilinearInterpolation(ValueT (& data)[N][N][N],
const Vec3R& uvw)
569 ValueT resultA, resultB;
571 resultA = data[0][0][0] + ValueT((data[0][0][1] - data[0][0][0]) * uvw[2]);
572 resultB = data[0][1][0] + ValueT((data[0][1][1] - data[0][1][0]) * uvw[2]);
573 ValueT result1 = resultA + ValueT((resultB-resultA) * uvw[1]);
575 resultA = data[1][0][0] + ValueT((data[1][0][1] - data[1][0][0]) * uvw[2]);
576 resultB = data[1][1][0] + ValueT((data[1][1][1] - data[1][1][0]) * uvw[2]);
577 ValueT result2 = resultA + ValueT((resultB - resultA) * uvw[1]);
579 return result1 + ValueT(uvw[0] * (result2 - result1));
583 template<
class TreeT>
585 BoxSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
586 typename TreeT::ValueType& result)
588 typedef typename TreeT::ValueType ValueT;
591 Vec3R uvw = inCoord - inIdx;
595 ValueT data[2][2][2];
597 bool hasActiveValues =
false;
599 hasActiveValues |= inTree.probeValue(ijk, data[0][0][0]);
601 hasActiveValues |= inTree.probeValue(ijk, data[0][0][1]);
603 hasActiveValues |= inTree.probeValue(ijk, data[0][1][1]);
605 hasActiveValues |= inTree.probeValue(ijk, data[0][1][0]);
608 hasActiveValues |= inTree.probeValue(ijk, data[1][0][0]);
610 hasActiveValues |= inTree.probeValue(ijk, data[1][0][1]);
612 hasActiveValues |= inTree.probeValue(ijk, data[1][1][1]);
614 hasActiveValues |= inTree.probeValue(ijk, data[1][1][0]);
616 result = trilinearInterpolation(data, uvw);
617 return hasActiveValues;
621 template<
class TreeT>
622 inline typename TreeT::ValueType
623 BoxSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord)
625 typedef typename TreeT::ValueType ValueT;
628 Vec3R uvw = inCoord - inIdx;
632 ValueT data[2][2][2];
635 data[0][0][0] = inTree.getValue(ijk);
637 data[0][0][1] = inTree.getValue(ijk);
639 data[0][1][1] = inTree.getValue(ijk);
641 data[0][1][0] = inTree.getValue(ijk);
644 data[1][0][0] = inTree.getValue(ijk);
646 data[1][0][1] = inTree.getValue(ijk);
648 data[1][1][1] = inTree.getValue(ijk);
650 data[1][1][0] = inTree.getValue(ijk);
652 return trilinearInterpolation(data, uvw);
659 template<
class TreeT>
661 QuadraticSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
662 typename TreeT::ValueType& result)
664 typedef typename TreeT::ValueType ValueT;
668 inLoIdx = inIdx -
Vec3i(1, 1, 1);
669 Vec3R frac = inCoord - inIdx;
675 for (
int dx = 0, ix = inLoIdx.x(); dx < 3; ++dx, ++ix) {
676 for (
int dy = 0, iy = inLoIdx.y(); dy < 3; ++dy, ++iy) {
677 for (
int dz = 0, iz = inLoIdx.z(); dz < 3; ++dz, ++iz) {
678 if (inTree.probeValue(Coord(ix, iy, iz), v[dx][dy][dz])) {
687 for (
int dx = 0; dx < 3; ++dx) {
689 for (
int dy = 0; dy < 3; ++dy) {
700 const ValueT* vz = &v[dx][dy][0];
702 az =
static_cast<ValueT
>(0.5 * (vz[0] + vz[2]) - vz[1]),
703 bz =
static_cast<ValueT
>(0.5 * (vz[2] - vz[0])),
704 cz =
static_cast<ValueT
>(vz[1]);
705 vy[dy] =
static_cast<ValueT
>(frac.
z() * (frac.
z() * az + bz) + cz);
711 ay =
static_cast<ValueT
>(0.5 * (vy[0] + vy[2]) - vy[1]),
712 by =
static_cast<ValueT
>(0.5 * (vy[2] - vy[0])),
713 cy =
static_cast<ValueT
>(vy[1]);
714 vx[dx] =
static_cast<ValueT
>(frac.
y() * (frac.
y() * ay + by) + cy);
719 ax =
static_cast<ValueT
>(0.5 * (vx[0] + vx[2]) - vx[1]),
720 bx =
static_cast<ValueT
>(0.5 * (vx[2] - vx[0])),
721 cx =
static_cast<ValueT
>(vx[1]);
722 result =
static_cast<ValueT
>(frac.
x() * (frac.
x() * ax + bx) + cx);
731 template<
class TreeT>
733 StaggeredPointSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
734 typename TreeT::ValueType& result)
736 typedef typename TreeT::ValueType ValueType;
738 ValueType tempX, tempY, tempZ;
741 active = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0, 0), tempX) || active;
742 active = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0.5, 0), tempY) || active;
743 active = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0, 0.5), tempZ) || active;
745 result.
x() = tempX.x();
746 result.y() = tempY.y();
747 result.z() = tempZ.z();
756 template<
class TreeT>
758 StaggeredBoxSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
759 typename TreeT::ValueType& result)
761 typedef typename TreeT::ValueType ValueType;
763 ValueType tempX, tempY, tempZ;
764 tempX = tempY = tempZ = zeroVal<ValueType>();
767 active = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0, 0), tempX) || active;
768 active = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0.5, 0), tempY) || active;
769 active = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0, 0.5), tempZ) || active;
771 result.x() = tempX.x();
772 result.y() = tempY.y();
773 result.z() = tempZ.z();
782 template<
class TreeT>
784 StaggeredQuadraticSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
785 typename TreeT::ValueType& result)
787 typedef typename TreeT::ValueType ValueType;
789 ValueType tempX, tempY, tempZ;
792 active = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0, 0), tempX) || active;
793 active = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0.5, 0), tempY) || active;
794 active = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0, 0.5), tempZ) || active;
796 result.x() = tempX.x();
797 result.y() = tempY.y();
798 result.z() = tempZ.z();
807 #endif // OPENVDB_TOOLS_INTERPOLATION_HAS_BEEN_INCLUDED
T & z()
Definition: Vec3.h:99
_TreeType TreeType
Definition: Grid.h:860
Vec3< int32_t > Vec3i
Definition: Vec3.h:626
#define OPENVDB_VERSION_NAME
Definition: version.h:43
math::Vec3< Real > Vec3R
Definition: Types.h:77
Type SmoothUnitStep(Type x)
Return 0 if x < 0, 1 if x > 1 or else .
Definition: Math.h:263
Definition: Exceptions.h:39
OPENVDB_API Hermite min(const Hermite &, const Hermite &)
min and max operations done directly on the compressed data.
T & x()
Reference to the component, e.g. v.x() = 4.5f;.
Definition: Vec3.h:97
Vec3< double > Vec3d
Definition: Vec3.h:629
T & y()
Definition: Vec3.h:98
OPENVDB_API Hermite max(const Hermite &, const Hermite &)
min and max operations done directly on the compressed data.
Container class that associates a tree with a transform and metadata.
Definition: Grid.h:54
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71