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/Platform.h>
88 static const char*
name() {
return "point"; }
90 static bool mipmap() {
return false; }
97 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
98 typename TreeT::ValueType& result);
104 static const char*
name() {
return "box"; }
112 template<
class TreeT>
113 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
114 typename TreeT::ValueType& result);
118 template<
class TreeT>
119 static typename TreeT::ValueType sample(
const TreeT& inTree,
const Vec3R& inCoord);
122 template<
class ValueT,
size_t N>
123 static inline ValueT trilinearInterpolation(ValueT (& data)[N][N][N],
const Vec3R& uvw);
129 static const char*
name() {
return "quadratic"; }
137 template<
class TreeT>
138 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
139 typename TreeT::ValueType& result);
153 static const char*
name() {
return "point"; }
161 template<
class TreeT>
162 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
163 typename TreeT::ValueType& result);
169 static const char*
name() {
return "box"; }
177 template<
class TreeT>
178 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
179 typename TreeT::ValueType& result);
185 static const char*
name() {
return "quadratic"; }
193 template<
class TreeT>
194 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
195 typename TreeT::ValueType& result);
206 template<
typename TreeOrAccessorType,
typename SamplerType>
210 typedef boost::shared_ptr<GridSampler>
Ptr;
211 typedef typename TreeOrAccessorType::ValueType
ValueType;
218 mTree(&tree), mTransform(transform) {}
226 template<
typename RealType>
227 ValueType sampleVoxel(
const RealType& x,
const RealType& y,
const RealType& z)
const
229 return isSample(
Vec3d(x,y,z));
237 SamplerType::sample(*mTree, ispoint, result);
246 SamplerType::sample(*mTree, mTransform.worldToIndex(wspoint), result);
251 const TreeOrAccessorType* mTree;
264 template<
typename TreeType>
268 typedef boost::shared_ptr<GridSampling>
Ptr;
278 const TreeType&
tree()
const {
return *mTree; }
288 virtual ValueType sampleVoxel(
Real x,
Real y,
Real z)
const = 0;
292 const TreeType* mTree;
300 template<
typename TreeType>
305 typedef boost::shared_ptr<LinearInterp>
Ptr;
320 BoxSampler::sample(this->tree(),
Vec3R(x, y, z), result);
329 template<
typename TreeType>
334 typedef boost::shared_ptr<QuadraticInterp>
Ptr;
346 QuadraticSampler::sample(this->tree(),
Vec3R(x, y, z), result);
355 namespace local_util {
360 return Vec3i(
int(std::floor(v(0))),
int(std::floor(v(1))),
int(std::floor(v(2))));
367 return Vec3i(
int(std::ceil(v(0))),
int(std::ceil(v(1))),
int(std::ceil(v(2))));
374 return Vec3i(
int(::round(v(0))),
int(::round(v(1))),
int(::round(v(2))));
383 template<
class TreeT>
385 PointSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
386 typename TreeT::ValueType& result)
389 return inTree.probeValue(
Coord(inIdx), result);
396 template<
class ValueT,
size_t N>
398 BoxSampler::trilinearInterpolation(ValueT (& data)[N][N][N],
const Vec3R& uvw)
406 ValueT resultA, resultB;
408 resultA = data[0][0][0] + ValueT((data[0][0][1] - data[0][0][0]) * uvw[2]);
409 resultB = data[0][1][0] + ValueT((data[0][1][1] - data[0][1][0]) * uvw[2]);
410 ValueT result1 = resultA + ValueT((resultB-resultA) * uvw[1]);
412 resultA = data[1][0][0] + ValueT((data[1][0][1] - data[1][0][0]) * uvw[2]);
413 resultB = data[1][1][0] + ValueT((data[1][1][1] - data[1][1][0]) * uvw[2]);
414 ValueT result2 = resultA + ValueT((resultB - resultA) * uvw[1]);
416 return result1 + ValueT(uvw[0] * (result2 - result1));
420 template<
class TreeT>
422 BoxSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
423 typename TreeT::ValueType& result)
425 typedef typename TreeT::ValueType ValueT;
428 Vec3R uvw = inCoord - inIdx;
432 ValueT data[2][2][2];
434 bool hasActiveValues =
false;
436 hasActiveValues |= inTree.probeValue(ijk, data[0][0][0]);
438 hasActiveValues |= inTree.probeValue(ijk, data[0][0][1]);
440 hasActiveValues |= inTree.probeValue(ijk, data[0][1][1]);
442 hasActiveValues |= inTree.probeValue(ijk, data[0][1][0]);
445 hasActiveValues |= inTree.probeValue(ijk, data[1][0][0]);
447 hasActiveValues |= inTree.probeValue(ijk, data[1][0][1]);
449 hasActiveValues |= inTree.probeValue(ijk, data[1][1][1]);
451 hasActiveValues |= inTree.probeValue(ijk, data[1][1][0]);
453 result = trilinearInterpolation(data, uvw);
454 return hasActiveValues;
458 template<
class TreeT>
459 inline typename TreeT::ValueType
460 BoxSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord)
462 typedef typename TreeT::ValueType ValueT;
465 Vec3R uvw = inCoord - inIdx;
469 ValueT data[2][2][2];
472 data[0][0][0] = inTree.getValue(ijk);
474 data[0][0][1] = inTree.getValue(ijk);
476 data[0][1][1] = inTree.getValue(ijk);
478 data[0][1][0] = inTree.getValue(ijk);
481 data[1][0][0] = inTree.getValue(ijk);
483 data[1][0][1] = inTree.getValue(ijk);
485 data[1][1][1] = inTree.getValue(ijk);
487 data[1][1][0] = inTree.getValue(ijk);
489 return trilinearInterpolation(data, uvw);
496 template<
class TreeT>
498 QuadraticSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
499 typename TreeT::ValueType& result)
501 typedef typename TreeT::ValueType ValueT;
505 inLoIdx = inIdx -
Vec3i(1, 1, 1);
506 Vec3R frac = inCoord - inIdx;
512 for (
int dx = 0, ix = inLoIdx.x(); dx < 3; ++dx, ++ix) {
513 for (
int dy = 0, iy = inLoIdx.y(); dy < 3; ++dy, ++iy) {
514 for (
int dz = 0, iz = inLoIdx.z(); dz < 3; ++dz, ++iz) {
515 if (inTree.probeValue(
Coord(ix, iy, iz), v[dx][dy][dz])) {
524 for (
int dx = 0; dx < 3; ++dx) {
526 for (
int dy = 0; dy < 3; ++dy) {
537 const ValueT* vz = &v[dx][dy][0];
539 az =
static_cast<ValueT
>(0.5 * (vz[0] + vz[2]) - vz[1]),
540 bz =
static_cast<ValueT
>(0.5 * (vz[2] - vz[0])),
541 cz =
static_cast<ValueT
>(vz[1]);
542 vy[dy] =
static_cast<ValueT
>(frac.
z() * (frac.
z() * az + bz) + cz);
548 ay =
static_cast<ValueT
>(0.5 * (vy[0] + vy[2]) - vy[1]),
549 by =
static_cast<ValueT
>(0.5 * (vy[2] - vy[0])),
550 cy =
static_cast<ValueT
>(vy[1]);
551 vx[dx] =
static_cast<ValueT
>(frac.
y() * (frac.
y() * ay + by) + cy);
556 ax =
static_cast<ValueT
>(0.5 * (vx[0] + vx[2]) - vx[1]),
557 bx =
static_cast<ValueT
>(0.5 * (vx[2] - vx[0])),
558 cx =
static_cast<ValueT
>(vx[1]);
559 result =
static_cast<ValueT
>(frac.
x() * (frac.
x() * ax + bx) + cx);
568 template<
class TreeT>
570 StaggeredPointSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
571 typename TreeT::ValueType& result)
573 typedef typename TreeT::ValueType ValueType;
575 ValueType tempX, tempY, tempZ;
578 active = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0, 0), tempX) || active;
579 active = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0.5, 0), tempY) || active;
580 active = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0, 0.5), tempZ) || active;
582 result.
x() = tempX.x();
583 result.y() = tempY.y();
584 result.z() = tempZ.z();
593 template<
class TreeT>
595 StaggeredBoxSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
596 typename TreeT::ValueType& result)
598 typedef typename TreeT::ValueType ValueType;
600 ValueType tempX, tempY, tempZ;
601 tempX = tempY = tempZ = zeroVal<ValueType>();
604 active = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0, 0), tempX) || active;
605 active = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0.5, 0), tempY) || active;
606 active = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0, 0.5), tempZ) || active;
608 result.x() = tempX.x();
609 result.y() = tempY.y();
610 result.z() = tempZ.z();
619 template<
class TreeT>
621 StaggeredQuadraticSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
622 typename TreeT::ValueType& result)
624 typedef typename TreeT::ValueType ValueType;
626 ValueType tempX, tempY, tempZ;
629 active = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0, 0), tempX) || active;
630 active = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0.5, 0), tempY) || active;
631 active = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0, 0.5), tempZ) || active;
633 result.x() = tempX.x();
634 result.y() = tempY.y();
635 result.z() = tempZ.z();
644 #endif // OPENVDB_TOOLS_INTERPOLATION_HAS_BEEN_INCLUDED