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>
90 static const char*
name() {
return "point"; }
92 static bool mipmap() {
return false; }
99 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
100 typename TreeT::ValueType& result);
106 static const char*
name() {
return "box"; }
114 template<
class TreeT>
115 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
116 typename TreeT::ValueType& result);
120 template<
class TreeT>
121 static typename TreeT::ValueType sample(
const TreeT& inTree,
const Vec3R& inCoord);
124 template<
class ValueT,
size_t N>
125 static inline ValueT trilinearInterpolation(ValueT (& data)[N][N][N],
const Vec3R& uvw);
131 static const char*
name() {
return "quadratic"; }
139 template<
class TreeT>
140 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
141 typename TreeT::ValueType& result);
155 static const char*
name() {
return "point"; }
163 template<
class TreeT>
164 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
165 typename TreeT::ValueType& result);
171 static const char*
name() {
return "box"; }
179 template<
class TreeT>
180 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
181 typename TreeT::ValueType& result);
187 static const char*
name() {
return "quadratic"; }
195 template<
class TreeT>
196 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
197 typename TreeT::ValueType& result);
208 template<
typename TreeOrAccessorType,
typename SamplerType>
212 typedef boost::shared_ptr<GridSampler>
Ptr;
213 typedef typename TreeOrAccessorType::ValueType
ValueType;
220 mTree(&tree), mTransform(transform) {}
228 template<
typename RealType>
229 ValueType sampleVoxel(
const RealType& x,
const RealType& y,
const RealType& z)
const
231 return isSample(
Vec3d(x,y,z));
239 SamplerType::sample(*mTree, ispoint, result);
248 SamplerType::sample(*mTree, mTransform.worldToIndex(wspoint), result);
253 const TreeOrAccessorType* mTree;
261 namespace local_util {
266 return Vec3i(
int(std::floor(v(0))),
int(std::floor(v(1))),
int(std::floor(v(2))));
273 return Vec3i(
int(std::ceil(v(0))),
int(std::ceil(v(1))),
int(std::ceil(v(2))));
280 return Vec3i(
int(::round(v(0))),
int(::round(v(1))),
int(::round(v(2))));
289 template<
class TreeT>
291 PointSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
292 typename TreeT::ValueType& result)
295 return inTree.probeValue(
Coord(inIdx), result);
302 template<
class ValueT,
size_t N>
304 BoxSampler::trilinearInterpolation(ValueT (& data)[N][N][N],
const Vec3R& uvw)
312 ValueT resultA, resultB;
314 resultA = data[0][0][0] + ValueT((data[0][0][1] - data[0][0][0]) * uvw[2]);
315 resultB = data[0][1][0] + ValueT((data[0][1][1] - data[0][1][0]) * uvw[2]);
316 ValueT result1 = resultA + ValueT((resultB-resultA) * uvw[1]);
318 resultA = data[1][0][0] + ValueT((data[1][0][1] - data[1][0][0]) * uvw[2]);
319 resultB = data[1][1][0] + ValueT((data[1][1][1] - data[1][1][0]) * uvw[2]);
320 ValueT result2 = resultA + ValueT((resultB - resultA) * uvw[1]);
322 return result1 + ValueT(uvw[0] * (result2 - result1));
326 template<
class TreeT>
328 BoxSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
329 typename TreeT::ValueType& result)
331 typedef typename TreeT::ValueType ValueT;
334 Vec3R uvw = inCoord - inIdx;
338 ValueT data[2][2][2];
340 bool hasActiveValues =
false;
342 hasActiveValues |= inTree.probeValue(ijk, data[0][0][0]);
344 hasActiveValues |= inTree.probeValue(ijk, data[0][0][1]);
346 hasActiveValues |= inTree.probeValue(ijk, data[0][1][1]);
348 hasActiveValues |= inTree.probeValue(ijk, data[0][1][0]);
351 hasActiveValues |= inTree.probeValue(ijk, data[1][0][0]);
353 hasActiveValues |= inTree.probeValue(ijk, data[1][0][1]);
355 hasActiveValues |= inTree.probeValue(ijk, data[1][1][1]);
357 hasActiveValues |= inTree.probeValue(ijk, data[1][1][0]);
359 result = trilinearInterpolation(data, uvw);
360 return hasActiveValues;
364 template<
class TreeT>
365 inline typename TreeT::ValueType
366 BoxSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord)
368 typedef typename TreeT::ValueType ValueT;
371 Vec3R uvw = inCoord - inIdx;
375 ValueT data[2][2][2];
378 data[0][0][0] = inTree.getValue(ijk);
380 data[0][0][1] = inTree.getValue(ijk);
382 data[0][1][1] = inTree.getValue(ijk);
384 data[0][1][0] = inTree.getValue(ijk);
387 data[1][0][0] = inTree.getValue(ijk);
389 data[1][0][1] = inTree.getValue(ijk);
391 data[1][1][1] = inTree.getValue(ijk);
393 data[1][1][0] = inTree.getValue(ijk);
395 return trilinearInterpolation(data, uvw);
402 template<
class TreeT>
404 QuadraticSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
405 typename TreeT::ValueType& result)
407 typedef typename TreeT::ValueType ValueT;
411 inLoIdx = inIdx -
Vec3i(1, 1, 1);
412 Vec3R frac = inCoord - inIdx;
418 for (
int dx = 0, ix = inLoIdx.x(); dx < 3; ++dx, ++ix) {
419 for (
int dy = 0, iy = inLoIdx.y(); dy < 3; ++dy, ++iy) {
420 for (
int dz = 0, iz = inLoIdx.z(); dz < 3; ++dz, ++iz) {
421 if (inTree.probeValue(
Coord(ix, iy, iz), v[dx][dy][dz])) {
430 for (
int dx = 0; dx < 3; ++dx) {
432 for (
int dy = 0; dy < 3; ++dy) {
443 const ValueT* vz = &v[dx][dy][0];
445 az =
static_cast<ValueT
>(0.5 * (vz[0] + vz[2]) - vz[1]),
446 bz =
static_cast<ValueT
>(0.5 * (vz[2] - vz[0])),
447 cz =
static_cast<ValueT
>(vz[1]);
448 vy[dy] =
static_cast<ValueT
>(frac.
z() * (frac.
z() * az + bz) + cz);
454 ay =
static_cast<ValueT
>(0.5 * (vy[0] + vy[2]) - vy[1]),
455 by =
static_cast<ValueT
>(0.5 * (vy[2] - vy[0])),
456 cy =
static_cast<ValueT
>(vy[1]);
457 vx[dx] =
static_cast<ValueT
>(frac.
y() * (frac.
y() * ay + by) + cy);
462 ax =
static_cast<ValueT
>(0.5 * (vx[0] + vx[2]) - vx[1]),
463 bx =
static_cast<ValueT
>(0.5 * (vx[2] - vx[0])),
464 cx =
static_cast<ValueT
>(vx[1]);
465 result =
static_cast<ValueT
>(frac.
x() * (frac.
x() * ax + bx) + cx);
474 template<
class TreeT>
476 StaggeredPointSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
477 typename TreeT::ValueType& result)
479 typedef typename TreeT::ValueType ValueType;
481 ValueType tempX, tempY, tempZ;
484 active = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0, 0), tempX) || active;
485 active = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0.5, 0), tempY) || active;
486 active = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0, 0.5), tempZ) || active;
488 result.
x() = tempX.x();
489 result.y() = tempY.y();
490 result.z() = tempZ.z();
499 template<
class TreeT>
501 StaggeredBoxSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
502 typename TreeT::ValueType& result)
504 typedef typename TreeT::ValueType ValueType;
506 ValueType tempX, tempY, tempZ;
507 tempX = tempY = tempZ = zeroVal<ValueType>();
510 active = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0, 0), tempX) || active;
511 active = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0.5, 0), tempY) || active;
512 active = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0, 0.5), tempZ) || active;
514 result.x() = tempX.x();
515 result.y() = tempY.y();
516 result.z() = tempZ.z();
525 template<
class TreeT>
527 StaggeredQuadraticSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
528 typename TreeT::ValueType& result)
530 typedef typename TreeT::ValueType ValueType;
532 ValueType tempX, tempY, tempZ;
535 active = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0, 0), tempX) || active;
536 active = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0.5, 0), tempY) || active;
537 active = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0, 0.5), tempZ) || active;
539 result.x() = tempX.x();
540 result.y() = tempY.y();
541 result.z() = tempZ.z();
550 #endif // OPENVDB_TOOLS_INTERPOLATION_HAS_BEEN_INCLUDED