67 #ifndef OPENVDB_TOOLS_INTERPOLATION_HAS_BEEN_INCLUDED 68 #define OPENVDB_TOOLS_INTERPOLATION_HAS_BEEN_INCLUDED 71 #include <boost/shared_ptr.hpp> 89 template <
size_t Order,
bool Staggered = false>
92 BOOST_STATIC_ASSERT(Order < 3);
93 static const char* name();
96 static bool consistent();
97 static bool staggered();
98 static size_t order();
104 template<
class TreeT>
105 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
106 typename TreeT::ValueType& result);
111 template<
class TreeT>
112 static typename TreeT::ValueType sample(
const TreeT& inTree,
const Vec3R& inCoord);
125 static const char*
name() {
return "point"; }
135 template<
class TreeT>
136 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
137 typename TreeT::ValueType& result);
141 template<
class TreeT>
142 static typename TreeT::ValueType sample(
const TreeT& inTree,
const Vec3R& inCoord);
148 static const char*
name() {
return "box"; }
158 template<
class TreeT>
159 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
160 typename TreeT::ValueType& result);
164 template<
class TreeT>
165 static typename TreeT::ValueType sample(
const TreeT& inTree,
const Vec3R& inCoord);
169 template<
class ValueT,
class TreeT,
size_t N>
170 static inline void getValues(ValueT (&data)[N][N][N],
const TreeT& inTree,
Coord ijk);
175 template<
class ValueT,
class TreeT,
size_t N>
176 static inline bool probeValues(ValueT (&data)[N][N][N],
const TreeT& inTree,
Coord ijk);
180 template<
class ValueT,
size_t N>
181 static inline void extrema(ValueT (&data)[N][N][N], ValueT& vMin, ValueT& vMax);
184 template<
class ValueT,
size_t N>
185 static inline ValueT trilinearInterpolation(ValueT (&data)[N][N][N],
const Vec3R& uvw);
191 static const char*
name() {
return "quadratic"; }
201 template<
class TreeT>
202 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
203 typename TreeT::ValueType& result);
207 template<
class TreeT>
208 static typename TreeT::ValueType sample(
const TreeT& inTree,
const Vec3R& inCoord);
210 template<
class ValueT,
size_t N>
211 static inline ValueT triquadraticInterpolation(ValueT (&data)[N][N][N],
const Vec3R& uvw);
225 static const char*
name() {
return "point"; }
235 template<
class TreeT>
236 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
237 typename TreeT::ValueType& result);
241 template<
class TreeT>
242 static typename TreeT::ValueType sample(
const TreeT& inTree,
const Vec3R& inCoord);
248 static const char*
name() {
return "box"; }
258 template<
class TreeT>
259 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
260 typename TreeT::ValueType& result);
264 template<
class TreeT>
265 static typename TreeT::ValueType sample(
const TreeT& inTree,
const Vec3R& inCoord);
271 static const char*
name() {
return "quadratic"; }
281 template<
class TreeT>
282 static bool sample(
const TreeT& inTree,
const Vec3R& inCoord,
283 typename TreeT::ValueType& result);
287 template<
class TreeT>
288 static typename TreeT::ValueType sample(
const TreeT& inTree,
const Vec3R& inCoord);
309 template<
typename Gr
idOrTreeType,
typename SamplerType>
313 typedef boost::shared_ptr<GridSampler>
Ptr;
321 : mTree(&(grid.tree())), mTransform(&(grid.transform())) {}
326 : mTree(&tree), mTransform(&transform) {}
334 template<
typename RealType>
335 ValueType
sampleVoxel(
const RealType& x,
const RealType& y,
const RealType& z)
const 337 return this->isSample(
Vec3d(x,y,z));
348 return this->isSample(
Coord(i,j,k));
359 ValueType result = zeroVal<ValueType>();
360 SamplerType::sample(*mTree, ispoint, result);
368 ValueType result = zeroVal<ValueType>();
369 SamplerType::sample(*mTree, mTransform->worldToIndex(wspoint), result);
374 const TreeType* mTree;
391 template<
typename TreeT,
typename SamplerType>
395 typedef boost::shared_ptr<GridSampler>
Ptr;
405 : mAccessor(&acc), mTransform(&transform) {}
413 template<
typename RealType>
414 ValueType
sampleVoxel(
const RealType& x,
const RealType& y,
const RealType& z)
const 416 return this->isSample(
Vec3d(x,y,z));
427 return this->isSample(
Coord(i,j,k));
432 ValueType
isSample(
const Coord& ijk)
const {
return mAccessor->getValue(ijk); }
438 ValueType result = zeroVal<ValueType>();
439 SamplerType::sample(*mAccessor, ispoint, result);
447 ValueType result = zeroVal<ValueType>();
448 SamplerType::sample(*mAccessor, mTransform->worldToIndex(wspoint), result);
453 const AccessorType* mAccessor;
470 template<
typename GridOrTreeT,
485 : mSourceTree(&(sourceGrid.tree()))
486 , mSourceXform(&(sourceGrid.transform()))
487 , mTargetXform(&targetXform)
488 , mAligned(targetXform == *mSourceXform)
498 : mSourceTree(&sourceTree)
499 , mSourceXform(&sourceXform)
500 , mTargetXform(&targetXform)
501 , mAligned(targetXform == sourceXform)
508 if (mAligned)
return mSourceTree->getValue(ijk);
509 const Vec3R world = mTargetXform->indexToWorld(ijk);
510 return SamplerT::sample(*mSourceTree, mSourceXform->worldToIndex(world));
515 const TreeType* mSourceTree;
522 template<
typename TreeT,
539 : mSourceAcc(&sourceAccessor)
540 , mSourceXform(&sourceXform)
541 , mTargetXform(&targetXform)
542 , mAligned(targetXform == sourceXform)
549 if (mAligned)
return mSourceAcc->getValue(ijk);
550 const Vec3R world = mTargetXform->indexToWorld(ijk);
551 return SamplerT::sample(*mSourceAcc, mSourceXform->worldToIndex(world));
556 const AccessorType* mSourceAcc;
566 template <
typename GridT,
569 typename FloatT =
float>
573 BOOST_STATIC_ASSERT(boost::is_floating_point<FloatT>::value);
581 , mSampler(mAcc, mask.transform() , grid.transform())
583 , mInvNorm(1/(max-min))
593 if (mInvert) std::swap(a,b);
598 typedef typename MaskType::ConstAccessor
AccT;
607 namespace local_util {
612 return Vec3i(
int(std::floor(v(0))),
int(std::floor(v(1))),
int(std::floor(v(2))));
619 return Vec3i(
int(std::ceil(v(0))),
int(std::ceil(v(1))),
int(std::ceil(v(2))));
626 return Vec3i(
int(::round(v(0))),
int(::round(v(1))),
int(::round(v(2))));
635 template<
class TreeT>
637 PointSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
638 typename TreeT::ValueType& result)
643 template<
class TreeT>
644 inline typename TreeT::ValueType
645 PointSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord)
653 template<
class ValueT,
class TreeT,
size_t N>
655 BoxSampler::getValues(ValueT (&data)[N][N][N],
const TreeT& inTree,
Coord ijk)
657 data[0][0][0] = inTree.getValue(ijk);
660 data[0][0][1] = inTree.getValue(ijk);
663 data[0][1][1] = inTree.getValue(ijk);
666 data[0][1][0] = inTree.getValue(ijk);
670 data[1][0][0] = inTree.getValue(ijk);
673 data[1][0][1] = inTree.getValue(ijk);
676 data[1][1][1] = inTree.getValue(ijk);
679 data[1][1][0] = inTree.getValue(ijk);
682 template<
class ValueT,
class TreeT,
size_t N>
684 BoxSampler::probeValues(ValueT (&data)[N][N][N],
const TreeT& inTree,
Coord ijk)
686 bool hasActiveValues =
false;
687 hasActiveValues |= inTree.probeValue(ijk, data[0][0][0]);
690 hasActiveValues |= inTree.probeValue(ijk, data[0][0][1]);
693 hasActiveValues |= inTree.probeValue(ijk, data[0][1][1]);
696 hasActiveValues |= inTree.probeValue(ijk, data[0][1][0]);
700 hasActiveValues |= inTree.probeValue(ijk, data[1][0][0]);
703 hasActiveValues |= inTree.probeValue(ijk, data[1][0][1]);
706 hasActiveValues |= inTree.probeValue(ijk, data[1][1][1]);
709 hasActiveValues |= inTree.probeValue(ijk, data[1][1][0]);
711 return hasActiveValues;
714 template<
class ValueT,
size_t N>
718 vMin = vMax = data[0][0][0];
736 template<
class ValueT,
size_t N>
738 BoxSampler::trilinearInterpolation(ValueT (&data)[N][N][N],
const Vec3R& uvw)
746 ValueT resultA, resultB;
748 resultA = data[0][0][0] + ValueT((data[0][0][1] - data[0][0][0]) * uvw[2]);
749 resultB = data[0][1][0] + ValueT((data[0][1][1] - data[0][1][0]) * uvw[2]);
750 ValueT result1 = resultA + ValueT((resultB-resultA) * uvw[1]);
752 resultA = data[1][0][0] + ValueT((data[1][0][1] - data[1][0][0]) * uvw[2]);
753 resultB = data[1][1][0] + ValueT((data[1][1][1] - data[1][1][0]) * uvw[2]);
754 ValueT result2 = resultA + ValueT((resultB - resultA) * uvw[1]);
756 return result1 + ValueT(uvw[0] * (result2 - result1));
760 template<
class TreeT>
762 BoxSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
763 typename TreeT::ValueType& result)
765 typedef typename TreeT::ValueType ValueT;
768 const Vec3R uvw = inCoord - inIdx;
772 ValueT data[2][2][2];
774 const bool hasActiveValues = BoxSampler::probeValues(data, inTree,
Coord(inIdx));
776 result = BoxSampler::trilinearInterpolation(data, uvw);
778 return hasActiveValues;
782 template<
class TreeT>
783 inline typename TreeT::ValueType
784 BoxSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord)
786 typedef typename TreeT::ValueType ValueT;
789 const Vec3R uvw = inCoord - inIdx;
793 ValueT data[2][2][2];
795 BoxSampler::getValues(data, inTree,
Coord(inIdx));
797 return BoxSampler::trilinearInterpolation(data, uvw);
803 template<
class ValueT,
size_t N>
805 QuadraticSampler::triquadraticInterpolation(ValueT (&data)[N][N][N],
const Vec3R& uvw)
809 for (
int dx = 0; dx < 3; ++dx) {
811 for (
int dy = 0; dy < 3; ++dy) {
822 const ValueT* vz = &data[dx][dy][0];
824 az =
static_cast<ValueT
>(0.5 * (vz[0] + vz[2]) - vz[1]),
825 bz =
static_cast<ValueT
>(0.5 * (vz[2] - vz[0])),
826 cz =
static_cast<ValueT
>(vz[1]);
827 vy[dy] =
static_cast<ValueT
>(uvw.
z() * (uvw.
z() * az + bz) + cz);
833 ay =
static_cast<ValueT
>(0.5 * (vy[0] + vy[2]) - vy[1]),
834 by =
static_cast<ValueT
>(0.5 * (vy[2] - vy[0])),
835 cy =
static_cast<ValueT
>(vy[1]);
836 vx[dx] =
static_cast<ValueT
>(uvw.
y() * (uvw.
y() * ay + by) + cy);
841 ax =
static_cast<ValueT
>(0.5 * (vx[0] + vx[2]) - vx[1]),
842 bx =
static_cast<ValueT
>(0.5 * (vx[2] - vx[0])),
843 cx =
static_cast<ValueT
>(vx[1]);
844 return static_cast<ValueT
>(uvw.
x() * (uvw.
x() * ax + bx) + cx);
847 template<
class TreeT>
849 QuadraticSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
850 typename TreeT::ValueType& result)
852 typedef typename TreeT::ValueType ValueT;
855 const Vec3R uvw = inCoord - inIdx;
860 ValueT data[3][3][3];
861 for (
int dx = 0, ix = inLoIdx.x(); dx < 3; ++dx, ++ix) {
862 for (
int dy = 0, iy = inLoIdx.y(); dy < 3; ++dy, ++iy) {
863 for (
int dz = 0, iz = inLoIdx.z(); dz < 3; ++dz, ++iz) {
864 if (inTree.probeValue(
Coord(ix, iy, iz), data[dx][dy][dz])) active =
true;
869 result = QuadraticSampler::triquadraticInterpolation(data, uvw);
874 template<
class TreeT>
875 inline typename TreeT::ValueType
876 QuadraticSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord)
878 typedef typename TreeT::ValueType ValueT;
881 const Vec3R uvw = inCoord - inIdx;
885 ValueT data[3][3][3];
886 for (
int dx = 0, ix = inLoIdx.x(); dx < 3; ++dx, ++ix) {
887 for (
int dy = 0, iy = inLoIdx.y(); dy < 3; ++dy, ++iy) {
888 for (
int dz = 0, iz = inLoIdx.z(); dz < 3; ++dz, ++iz) {
889 data[dx][dy][dz] = inTree.getValue(
Coord(ix, iy, iz));
894 return QuadraticSampler::triquadraticInterpolation(data, uvw);
901 template<
class TreeT>
903 StaggeredPointSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
904 typename TreeT::ValueType& result)
906 typedef typename TreeT::ValueType ValueType;
908 ValueType tempX, tempY, tempZ;
911 active = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0, 0), tempX) || active;
912 active = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0.5, 0), tempY) || active;
913 active = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0, 0.5), tempZ) || active;
915 result.x() = tempX.x();
916 result.y() = tempY.y();
917 result.z() = tempZ.z();
922 template<
class TreeT>
923 inline typename TreeT::ValueType
924 StaggeredPointSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord)
926 typedef typename TreeT::ValueType ValueT;
928 const ValueT tempX = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0.0, 0.0));
929 const ValueT tempY = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.0, 0.5, 0.0));
930 const ValueT tempZ = PointSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.0, 0.0, 0.5));
932 return ValueT(tempX.x(), tempY.y(), tempZ.z());
939 template<
class TreeT>
941 StaggeredBoxSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
942 typename TreeT::ValueType& result)
944 typedef typename TreeT::ValueType ValueType;
946 ValueType tempX, tempY, tempZ;
947 tempX = tempY = tempZ = zeroVal<ValueType>();
950 active = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0, 0), tempX) || active;
951 active = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0.5, 0), tempY) || active;
952 active = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0, 0.5), tempZ) || active;
954 result.x() = tempX.x();
955 result.y() = tempY.y();
956 result.z() = tempZ.z();
961 template<
class TreeT>
962 inline typename TreeT::ValueType
963 StaggeredBoxSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord)
965 typedef typename TreeT::ValueType ValueT;
967 const ValueT tempX = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0.0, 0.0));
968 const ValueT tempY = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.0, 0.5, 0.0));
969 const ValueT tempZ = BoxSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.0, 0.0, 0.5));
971 return ValueT(tempX.x(), tempY.y(), tempZ.z());
978 template<
class TreeT>
980 StaggeredQuadraticSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord,
981 typename TreeT::ValueType& result)
983 typedef typename TreeT::ValueType ValueType;
985 ValueType tempX, tempY, tempZ;
988 active = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0, 0), tempX) || active;
989 active = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0.5, 0), tempY) || active;
990 active = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0, 0, 0.5), tempZ) || active;
992 result.x() = tempX.x();
993 result.y() = tempY.y();
994 result.z() = tempZ.z();
999 template<
class TreeT>
1000 inline typename TreeT::ValueType
1001 StaggeredQuadraticSampler::sample(
const TreeT& inTree,
const Vec3R& inCoord)
1003 typedef typename TreeT::ValueType ValueT;
1005 const ValueT tempX = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.5, 0.0, 0.0));
1006 const ValueT tempY = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.0, 0.5, 0.0));
1007 const ValueT tempZ = QuadraticSampler::sample<TreeT>(inTree, inCoord +
Vec3R(0.0, 0.0, 0.5));
1009 return ValueT(tempX.x(), tempY.y(), tempZ.z());
1036 #endif // OPENVDB_TOOLS_INTERPOLATION_HAS_BEEN_INCLUDED
T & z()
Definition: Vec3.h:99
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
const Type & Min(const Type &a, const Type &b)
Return the minimum of two values.
Definition: Math.h:622
Int32 ValueType
Definition: Coord.h:55
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:47
Type SmoothUnitStep(Type x)
Return 0 if x < 0, 1 if x > 1 or else .
Definition: Math.h:272
Vec3< int32_t > Vec3i
Definition: Vec3.h:648
#define OPENVDB_VERSION_NAME
Definition: version.h:43
Vec3< double > Vec3d
Definition: Vec3.h:651
T & x()
Reference to the component, e.g. v.x() = 4.5f;.
Definition: Vec3.h:97
Definition: Exceptions.h:39
_TreeType TreeType
Definition: Grid.h:900
T & y()
Definition: Vec3.h:98
const Type & Max(const Type &a, const Type &b)
Return the maximum of two values.
Definition: Math.h:561
math::Vec3< Real > Vec3R
Definition: Types.h:76
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
Container class that associates a tree with a transform and metadata.
Definition: Grid.h:54