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/Transform.h>
75 #include <openvdb/Grid.h>
76 #include <openvdb/tree/ValueAccessor.h>
91 static const char*
name() {
return "point"; }
93 static bool mipmap() {
return false; }
100 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
101 typename TreeT::ValueType& result);
107 static const char*
name() {
return "box"; }
115 template<
class TreeT>
116 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
117 typename TreeT::ValueType& result);
121 template<
class TreeT>
122 static typename TreeT::ValueType sample(
const TreeT& inTree,
const Vec3R& inCoord);
125 template<
class ValueT,
size_t N>
126 static inline ValueT trilinearInterpolation(ValueT (& data)[N][N][N],
const Vec3R& uvw);
132 static const char*
name() {
return "quadratic"; }
140 template<
class TreeT>
141 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
142 typename TreeT::ValueType& result);
156 static const char*
name() {
return "point"; }
164 template<
class TreeT>
165 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
166 typename TreeT::ValueType& result);
172 static const char*
name() {
return "box"; }
180 template<
class TreeT>
181 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
182 typename TreeT::ValueType& result);
188 static const char*
name() {
return "quadratic"; }
196 template<
class TreeT>
197 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
198 typename TreeT::ValueType& result);
219 template<
typename Gr
idOrTreeType,
typename SamplerType>
223 typedef boost::shared_ptr<GridSampler>
Ptr;
231 : mTree(&(grid.tree())), mTransform(&(grid.transform())) {}
236 : mTree(&tree), mTransform(&transform) {}
244 template<
typename RealType>
247 return this->isSample(
Vec3d(x,y,z));
255 typename Coord::ValueType j,
256 typename Coord::ValueType k)
const
258 return this->isSample(Coord(i,j,k));
270 SamplerType::sample(*mTree, ispoint, result);
279 SamplerType::sample(*mTree, mTransform->worldToIndex(wspoint), result);
284 const TreeType* mTree;
301 template<
typename TreeT,
typename SamplerType>
305 typedef boost::shared_ptr<GridSampler>
Ptr;
315 : mAccessor(&acc), mTransform(&transform) {}
323 template<
typename RealType>
326 return this->isSample(
Vec3d(x,y,z));
334 typename Coord::ValueType j,
335 typename Coord::ValueType k)
const
337 return this->isSample(Coord(i,j,k));
349 SamplerType::sample(*mAccessor, ispoint, result);
358 SamplerType::sample(*mAccessor, mTransform->worldToIndex(wspoint), result);
363 const AccessorType* mAccessor;
380 template<
typename GridOrTreeT,
395 : mSourceTree(&(sourceGrid.tree()))
396 , mSourceXform(&(sourceGrid.transform()))
397 , mTargetXform(&targetXform)
398 , mAligned(targetXform == *mSourceXform)
408 : mSourceTree(&sourceTree)
409 , mSourceXform(&sourceXform)
410 , mTargetXform(&targetXform)
411 , mAligned(targetXform == sourceXform)
418 if (mAligned)
return mSourceTree->getValue(ijk);
419 const Vec3R world = mTargetXform->indexToWorld(ijk);
420 return SamplerT::sample(*mSourceTree, mSourceXform->worldToIndex(world));
425 const TreeType* mSourceTree;
432 template<
typename TreeT,
449 : mSourceAcc(&sourceAccessor)
450 , mSourceXform(&sourceXform)
451 , mTargetXform(&targetXform)
452 , mAligned(targetXform == sourceXform)
459 if (mAligned)
return mSourceAcc->getValue(ijk);
460 const Vec3R world = mTargetXform->indexToWorld(ijk);
461 return SamplerT::sample(*mSourceAcc, mSourceXform->worldToIndex(world));
466 const AccessorType* mSourceAcc;
475 namespace local_util {
480 return Vec3i(
int(std::floor(v(0))),
int(std::floor(v(1))),
int(std::floor(v(2))));
487 return Vec3i(
int(std::ceil(v(0))),
int(std::ceil(v(1))),
int(std::ceil(v(2))));
494 return Vec3i(
int(::round(v(0))),
int(::round(v(1))),
int(::round(v(2))));
503 template<
class TreeT>
505 PointSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
506 typename TreeT::ValueType& result)
509 return inTree.probeValue(Coord(inIdx), result);
516 template<
class ValueT,
size_t N>
518 BoxSampler::trilinearInterpolation(ValueT (& data)[N][N][N],
const Vec3R& uvw)
526 ValueT resultA, resultB;
528 resultA = data[0][0][0] + ValueT((data[0][0][1] - data[0][0][0]) * uvw[2]);
529 resultB = data[0][1][0] + ValueT((data[0][1][1] - data[0][1][0]) * uvw[2]);
530 ValueT result1 = resultA + ValueT((resultB-resultA) * uvw[1]);
532 resultA = data[1][0][0] + ValueT((data[1][0][1] - data[1][0][0]) * uvw[2]);
533 resultB = data[1][1][0] + ValueT((data[1][1][1] - data[1][1][0]) * uvw[2]);
534 ValueT result2 = resultA + ValueT((resultB - resultA) * uvw[1]);
536 return result1 + ValueT(uvw[0] * (result2 - result1));
540 template<
class TreeT>
542 BoxSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
543 typename TreeT::ValueType& result)
545 typedef typename TreeT::ValueType ValueT;
548 Vec3R uvw = inCoord - inIdx;
552 ValueT data[2][2][2];
554 bool hasActiveValues =
false;
556 hasActiveValues |= inTree.probeValue(ijk, data[0][0][0]);
558 hasActiveValues |= inTree.probeValue(ijk, data[0][0][1]);
560 hasActiveValues |= inTree.probeValue(ijk, data[0][1][1]);
562 hasActiveValues |= inTree.probeValue(ijk, data[0][1][0]);
565 hasActiveValues |= inTree.probeValue(ijk, data[1][0][0]);
567 hasActiveValues |= inTree.probeValue(ijk, data[1][0][1]);
569 hasActiveValues |= inTree.probeValue(ijk, data[1][1][1]);
571 hasActiveValues |= inTree.probeValue(ijk, data[1][1][0]);
573 result = trilinearInterpolation(data, uvw);
574 return hasActiveValues;
578 template<
class TreeT>
579 inline typename TreeT::ValueType
580 BoxSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord)
582 typedef typename TreeT::ValueType ValueT;
585 Vec3R uvw = inCoord - inIdx;
589 ValueT data[2][2][2];
592 data[0][0][0] = inTree.getValue(ijk);
594 data[0][0][1] = inTree.getValue(ijk);
596 data[0][1][1] = inTree.getValue(ijk);
598 data[0][1][0] = inTree.getValue(ijk);
601 data[1][0][0] = inTree.getValue(ijk);
603 data[1][0][1] = inTree.getValue(ijk);
605 data[1][1][1] = inTree.getValue(ijk);
607 data[1][1][0] = inTree.getValue(ijk);
609 return trilinearInterpolation(data, uvw);
616 template<
class TreeT>
618 QuadraticSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
619 typename TreeT::ValueType& result)
621 typedef typename TreeT::ValueType ValueT;
625 inLoIdx = inIdx -
Vec3i(1, 1, 1);
626 Vec3R frac = inCoord - inIdx;
632 for (
int dx = 0, ix = inLoIdx.x(); dx < 3; ++dx, ++ix) {
633 for (
int dy = 0, iy = inLoIdx.y(); dy < 3; ++dy, ++iy) {
634 for (
int dz = 0, iz = inLoIdx.z(); dz < 3; ++dz, ++iz) {
635 if (inTree.probeValue(Coord(ix, iy, iz), v[dx][dy][dz])) {
644 for (
int dx = 0; dx < 3; ++dx) {
646 for (
int dy = 0; dy < 3; ++dy) {
657 const ValueT* vz = &v[dx][dy][0];
659 az =
static_cast<ValueT
>(0.5 * (vz[0] + vz[2]) - vz[1]),
660 bz =
static_cast<ValueT
>(0.5 * (vz[2] - vz[0])),
661 cz =
static_cast<ValueT
>(vz[1]);
662 vy[dy] =
static_cast<ValueT
>(frac.
z() * (frac.
z() * az + bz) + cz);
668 ay =
static_cast<ValueT
>(0.5 * (vy[0] + vy[2]) - vy[1]),
669 by =
static_cast<ValueT
>(0.5 * (vy[2] - vy[0])),
670 cy =
static_cast<ValueT
>(vy[1]);
671 vx[dx] =
static_cast<ValueT
>(frac.
y() * (frac.
y() * ay + by) + cy);
676 ax =
static_cast<ValueT
>(0.5 * (vx[0] + vx[2]) - vx[1]),
677 bx =
static_cast<ValueT
>(0.5 * (vx[2] - vx[0])),
678 cx =
static_cast<ValueT
>(vx[1]);
679 result =
static_cast<ValueT
>(frac.
x() * (frac.
x() * ax + bx) + cx);
688 template<
class TreeT>
690 StaggeredPointSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
691 typename TreeT::ValueType& result)
693 typedef typename TreeT::ValueType ValueType;
695 ValueType tempX, tempY, tempZ;
698 active = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0, 0), tempX) || active;
699 active = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0.5, 0), tempY) || active;
700 active = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0, 0.5), tempZ) || active;
702 result.
x() = tempX.x();
703 result.y() = tempY.y();
704 result.z() = tempZ.z();
713 template<
class TreeT>
715 StaggeredBoxSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
716 typename TreeT::ValueType& result)
718 typedef typename TreeT::ValueType ValueType;
720 ValueType tempX, tempY, tempZ;
721 tempX = tempY = tempZ = zeroVal<ValueType>();
724 active = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0, 0), tempX) || active;
725 active = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0.5, 0), tempY) || active;
726 active = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0, 0.5), tempZ) || active;
728 result.x() = tempX.x();
729 result.y() = tempY.y();
730 result.z() = tempZ.z();
739 template<
class TreeT>
741 StaggeredQuadraticSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
742 typename TreeT::ValueType& result)
744 typedef typename TreeT::ValueType ValueType;
746 ValueType tempX, tempY, tempZ;
749 active = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0, 0), tempX) || active;
750 active = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0.5, 0), tempY) || active;
751 active = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0, 0.5), tempZ) || active;
753 result.x() = tempX.x();
754 result.y() = tempY.y();
755 result.z() = tempZ.z();
764 #endif // OPENVDB_TOOLS_INTERPOLATION_HAS_BEEN_INCLUDED
math::Vec3< Real > Vec3R
Definition: Types.h:75
T & z()
Definition: Vec3.h:96
T & y()
Definition: Vec3.h:95
Container class that associates a tree with a transform and metadata.
Definition: Grid.h:54
#define OPENVDB_VERSION_NAME
Definition: version.h:45
Vec3< int32_t > Vec3i
Definition: Vec3.h:622
Vec3< double > Vec3d
Definition: Vec3.h:625
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:67
T & x()
Reference to the component, e.g. v.x() = 4.5f;.
Definition: Vec3.h:94
_TreeType TreeType
Definition: Grid.h:839