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;
314 : mAccessor(&acc), mTransform(&transform) {}
322 template<
typename RealType>
325 return this->isSample(
Vec3d(x,y,z));
333 typename Coord::ValueType j,
334 typename Coord::ValueType k)
const
336 return this->isSample(Coord(i,j,k));
348 SamplerType::sample(*mAccessor, ispoint, result);
357 SamplerType::sample(*mAccessor, mTransform->worldToIndex(wspoint), result);
362 const AccessorType* mAccessor;
382 template<
typename SourceGridT,
383 typename TargetGridT,
390 : mTarget(&target), mSource(&source), mAccessor(source.tree()),
391 mAligned(target.transform() == source.transform())
398 return mAligned ? mAccessor.getValue(ijk) : SamplerT::sample(mAccessor,
399 mSource->worldToIndex(mTarget->indexToWorld(ijk)));
402 const TargetGridT* mTarget;
403 const SourceGridT* mSource;
404 typename SourceGridT::ConstAccessor mAccessor;
412 namespace local_util {
417 return Vec3i(
int(std::floor(v(0))),
int(std::floor(v(1))),
int(std::floor(v(2))));
424 return Vec3i(
int(std::ceil(v(0))),
int(std::ceil(v(1))),
int(std::ceil(v(2))));
431 return Vec3i(
int(::round(v(0))),
int(::round(v(1))),
int(::round(v(2))));
440 template<
class TreeT>
442 PointSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
443 typename TreeT::ValueType& result)
446 return inTree.probeValue(Coord(inIdx), result);
453 template<
class ValueT,
size_t N>
455 BoxSampler::trilinearInterpolation(ValueT (& data)[N][N][N],
const Vec3R& uvw)
463 ValueT resultA, resultB;
465 resultA = data[0][0][0] + ValueT((data[0][0][1] - data[0][0][0]) * uvw[2]);
466 resultB = data[0][1][0] + ValueT((data[0][1][1] - data[0][1][0]) * uvw[2]);
467 ValueT result1 = resultA + ValueT((resultB-resultA) * uvw[1]);
469 resultA = data[1][0][0] + ValueT((data[1][0][1] - data[1][0][0]) * uvw[2]);
470 resultB = data[1][1][0] + ValueT((data[1][1][1] - data[1][1][0]) * uvw[2]);
471 ValueT result2 = resultA + ValueT((resultB - resultA) * uvw[1]);
473 return result1 + ValueT(uvw[0] * (result2 - result1));
477 template<
class TreeT>
479 BoxSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
480 typename TreeT::ValueType& result)
482 typedef typename TreeT::ValueType ValueT;
485 Vec3R uvw = inCoord - inIdx;
489 ValueT data[2][2][2];
491 bool hasActiveValues =
false;
493 hasActiveValues |= inTree.probeValue(ijk, data[0][0][0]);
495 hasActiveValues |= inTree.probeValue(ijk, data[0][0][1]);
497 hasActiveValues |= inTree.probeValue(ijk, data[0][1][1]);
499 hasActiveValues |= inTree.probeValue(ijk, data[0][1][0]);
502 hasActiveValues |= inTree.probeValue(ijk, data[1][0][0]);
504 hasActiveValues |= inTree.probeValue(ijk, data[1][0][1]);
506 hasActiveValues |= inTree.probeValue(ijk, data[1][1][1]);
508 hasActiveValues |= inTree.probeValue(ijk, data[1][1][0]);
510 result = trilinearInterpolation(data, uvw);
511 return hasActiveValues;
515 template<
class TreeT>
516 inline typename TreeT::ValueType
517 BoxSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord)
519 typedef typename TreeT::ValueType ValueT;
522 Vec3R uvw = inCoord - inIdx;
526 ValueT data[2][2][2];
529 data[0][0][0] = inTree.getValue(ijk);
531 data[0][0][1] = inTree.getValue(ijk);
533 data[0][1][1] = inTree.getValue(ijk);
535 data[0][1][0] = inTree.getValue(ijk);
538 data[1][0][0] = inTree.getValue(ijk);
540 data[1][0][1] = inTree.getValue(ijk);
542 data[1][1][1] = inTree.getValue(ijk);
544 data[1][1][0] = inTree.getValue(ijk);
546 return trilinearInterpolation(data, uvw);
553 template<
class TreeT>
555 QuadraticSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
556 typename TreeT::ValueType& result)
558 typedef typename TreeT::ValueType ValueT;
562 inLoIdx = inIdx -
Vec3i(1, 1, 1);
563 Vec3R frac = inCoord - inIdx;
569 for (
int dx = 0, ix = inLoIdx.x(); dx < 3; ++dx, ++ix) {
570 for (
int dy = 0, iy = inLoIdx.y(); dy < 3; ++dy, ++iy) {
571 for (
int dz = 0, iz = inLoIdx.z(); dz < 3; ++dz, ++iz) {
572 if (inTree.probeValue(Coord(ix, iy, iz), v[dx][dy][dz])) {
581 for (
int dx = 0; dx < 3; ++dx) {
583 for (
int dy = 0; dy < 3; ++dy) {
594 const ValueT* vz = &v[dx][dy][0];
596 az =
static_cast<ValueT
>(0.5 * (vz[0] + vz[2]) - vz[1]),
597 bz =
static_cast<ValueT
>(0.5 * (vz[2] - vz[0])),
598 cz =
static_cast<ValueT
>(vz[1]);
599 vy[dy] =
static_cast<ValueT
>(frac.
z() * (frac.
z() * az + bz) + cz);
605 ay =
static_cast<ValueT
>(0.5 * (vy[0] + vy[2]) - vy[1]),
606 by =
static_cast<ValueT
>(0.5 * (vy[2] - vy[0])),
607 cy =
static_cast<ValueT
>(vy[1]);
608 vx[dx] =
static_cast<ValueT
>(frac.
y() * (frac.
y() * ay + by) + cy);
613 ax =
static_cast<ValueT
>(0.5 * (vx[0] + vx[2]) - vx[1]),
614 bx =
static_cast<ValueT
>(0.5 * (vx[2] - vx[0])),
615 cx =
static_cast<ValueT
>(vx[1]);
616 result =
static_cast<ValueT
>(frac.
x() * (frac.
x() * ax + bx) + cx);
625 template<
class TreeT>
627 StaggeredPointSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
628 typename TreeT::ValueType& result)
630 typedef typename TreeT::ValueType ValueType;
632 ValueType tempX, tempY, tempZ;
635 active = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0, 0), tempX) || active;
636 active = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0.5, 0), tempY) || active;
637 active = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0, 0.5), tempZ) || active;
639 result.
x() = tempX.x();
640 result.y() = tempY.y();
641 result.z() = tempZ.z();
650 template<
class TreeT>
652 StaggeredBoxSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
653 typename TreeT::ValueType& result)
655 typedef typename TreeT::ValueType ValueType;
657 ValueType tempX, tempY, tempZ;
658 tempX = tempY = tempZ = zeroVal<ValueType>();
661 active = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0, 0), tempX) || active;
662 active = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0.5, 0), tempY) || active;
663 active = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0, 0.5), tempZ) || active;
665 result.x() = tempX.x();
666 result.y() = tempY.y();
667 result.z() = tempZ.z();
676 template<
class TreeT>
678 StaggeredQuadraticSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
679 typename TreeT::ValueType& result)
681 typedef typename TreeT::ValueType ValueType;
683 ValueType tempX, tempY, tempZ;
686 active = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0, 0), tempX) || active;
687 active = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0.5, 0), tempY) || active;
688 active = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0, 0.5), tempZ) || active;
690 result.x() = tempX.x();
691 result.y() = tempY.y();
692 result.z() = tempZ.z();
701 #endif // OPENVDB_TOOLS_INTERPOLATION_HAS_BEEN_INCLUDED
math::Vec3< Real > Vec3R
Definition: Types.h:74
T & y()
Definition: Vec3.h:95
Vec3< int32_t > Vec3i
Definition: Vec3.h:602
Container class that associates a tree with a transform and metadata.
Definition: Grid.h:54
#define OPENVDB_VERSION_NAME
Definition: version.h:45
T & z()
Definition: Vec3.h:96
Vec3< double > Vec3d
Definition: Vec3.h:605
_TreeType TreeType
Definition: Grid.h:825
#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