OpenVDB 13.0.1
Loading...
Searching...
No Matches
Interpolation.h
Go to the documentation of this file.
1// Copyright Contributors to the OpenVDB Project
2// SPDX-License-Identifier: Apache-2.0
3
4/// @file Interpolation.h
5///
6/// Sampler classes such as PointSampler and BoxSampler that are intended for use
7/// with tools::GridTransformer should operate in voxel space and must adhere to
8/// the interface described in the example below:
9/// @code
10/// struct MySampler
11/// {
12/// // Return a short name that can be used to identify this sampler
13/// // in error messages and elsewhere.
14/// const char* name() { return "mysampler"; }
15///
16/// // Return the radius of the sampling kernel in voxels, not including
17/// // the center voxel. This is the number of voxels of padding that
18/// // are added to all sides of a volume as a result of resampling.
19/// int radius() { return 2; }
20///
21/// // Return true if scaling by a factor smaller than 0.5 (along any axis)
22/// // should be handled via a mipmapping-like scheme of successive halvings
23/// // of a grid's resolution, until the remaining scale factor is
24/// // greater than or equal to 1/2. Set this to false only when high-quality
25/// // scaling is not required.
26/// bool mipmap() { return true; }
27///
28/// // Specify if sampling at a location that is collocated with a grid point
29/// // is guaranteed to return the exact value at that grid point.
30/// // For most sampling kernels, this should be false.
31/// bool consistent() { return false; }
32///
33/// // Sample the tree at the given coordinates and return the result in val.
34/// // Return true if the sampled value is active.
35/// template<class TreeT>
36/// bool sample(const TreeT& tree, const Vec3R& coord, typename TreeT::ValueType& val);
37/// };
38/// @endcode
39
40#ifndef OPENVDB_TOOLS_INTERPOLATION_HAS_BEEN_INCLUDED
41#define OPENVDB_TOOLS_INTERPOLATION_HAS_BEEN_INCLUDED
42
43#include <openvdb/version.h> // for OPENVDB_VERSION_NAME
44#include <openvdb/Platform.h> // for round()
45#include <openvdb/math/Math.h>// for SmoothUnitStep
46#include <openvdb/math/Transform.h> // for Transform
47#include <openvdb/Grid.h>
49#include <openvdb/util/Assert.h>
50#include <cmath>
51#include <type_traits>
52
53namespace openvdb {
55namespace OPENVDB_VERSION_NAME {
56namespace tools {
57
58/// @brief Provises a unified interface for sampling, i.e. interpolation.
59/// @details Order = 0: closest point
60/// Order = 1: tri-linear
61/// Order = 2: tri-quadratic
62/// Staggered: Set to true for MAC grids
63template <size_t Order, bool Staggered = false>
64struct Sampler
65{
66 static_assert(Order < 3, "Samplers of order higher than 2 are not supported");
67 static const char* name();
68 static int radius();
69 static bool mipmap();
70 static bool consistent();
71 static bool staggered();
72 static size_t order();
73
74 /// @brief Sample @a inTree at the floating-point index coordinate @a inCoord
75 /// and store the result in @a result.
76 ///
77 /// @return @c true if the sampled value is active.
78 template<class TreeT>
79 static bool sample(const TreeT& inTree, const Vec3R& inCoord,
80 typename TreeT::ValueType& result);
81
82 /// @brief Sample @a inTree at the floating-point index coordinate @a inCoord.
83 ///
84 /// @return the reconstructed value
85 template<class TreeT>
86 static typename TreeT::ValueType sample(const TreeT& inTree, const Vec3R& inCoord);
87};
88
89//////////////////////////////////////// Non-Staggered Samplers
90
91// The following samplers operate in voxel space.
92// When the samplers are applied to grids holding vector or other non-scalar data,
93// the data is assumed to be collocated. For example, using the BoxSampler on a grid
94// with ValueType Vec3f assumes that all three elements in a vector can be assigned
95// the same physical location. Consider using the GridSampler below instead.
96
98{
99 static const char* name() { return "point"; }
100 static int radius() { return 0; }
101 static bool mipmap() { return false; }
102 static bool consistent() { return true; }
103 static bool staggered() { return false; }
104 static size_t order() { return 0; }
105
106 /// @brief Sample @a inTree at the nearest neighbor to @a inCoord
107 /// and store the result in @a result.
108 /// @return @c true if the sampled value is active.
109 template<class TreeT>
110 static bool sample(const TreeT& inTree, const Vec3R& inCoord,
111 typename TreeT::ValueType& result);
112
113 /// @brief Sample @a inTree at the nearest neighbor to @a inCoord
114 /// @return the reconstructed value
115 template<class TreeT>
116 static typename TreeT::ValueType sample(const TreeT& inTree, const Vec3R& inCoord);
117};
118
119
121{
122 static const char* name() { return "box"; }
123 static int radius() { return 1; }
124 static bool mipmap() { return true; }
125 static bool consistent() { return true; }
126 static bool staggered() { return false; }
127 static size_t order() { return 1; }
128
129 /// @brief Trilinearly reconstruct @a inTree at @a inCoord
130 /// and store the result in @a result.
131 /// @return @c true if any one of the sampled values is active.
132 template<class TreeT>
133 static bool sample(const TreeT& inTree, const Vec3R& inCoord,
134 typename TreeT::ValueType& result);
135
136 /// @brief Trilinearly reconstruct @a inTree at @a inCoord.
137 /// @return the reconstructed value
138 template<class TreeT>
139 static typename TreeT::ValueType sample(const TreeT& inTree, const Vec3R& inCoord);
140
141 /// @brief Import all eight values from @a inTree to support
142 /// tri-linear interpolation.
143 template<class ValueT, class TreeT, size_t N>
144 static inline void getValues(ValueT (&data)[N][N][N], const TreeT& inTree, Coord ijk);
145
146 /// @brief Import all eight values from @a inTree to support
147 /// tri-linear interpolation.
148 /// @return @c true if any of the eight values are active
149 template<class ValueT, class TreeT, size_t N>
150 static inline bool probeValues(ValueT (&data)[N][N][N], const TreeT& inTree, Coord ijk);
151
152 /// @brief Find the minimum and maximum values of the eight cell
153 /// values in @ data. The default *component wise* less than
154 /// comparison operator is used.
155 template<class ValueT, size_t N>
156 static inline void extrema(ValueT (&data)[N][N][N], ValueT& vMin, ValueT& vMax);
157
158 /// @return the tri-linear interpolation with the unit cell coordinates @a uvw
159 template<class ValueT, size_t N>
160 static inline ValueT trilinearInterpolation(ValueT (&data)[N][N][N], const Vec3R& uvw);
161};
162
163
165{
166 static const char* name() { return "quadratic"; }
167 static int radius() { return 1; }
168 static bool mipmap() { return true; }
169 static bool consistent() { return false; }
170 static bool staggered() { return false; }
171 static size_t order() { return 2; }
172
173 /// @brief Triquadratically reconstruct @a inTree at @a inCoord
174 /// and store the result in @a result.
175 /// @return @c true if any one of the sampled values is active.
176 template<class TreeT>
177 static bool sample(const TreeT& inTree, const Vec3R& inCoord,
178 typename TreeT::ValueType& result);
179
180 /// @brief Triquadratically reconstruct @a inTree at to @a inCoord.
181 /// @return the reconstructed value
182 template<class TreeT>
183 static typename TreeT::ValueType sample(const TreeT& inTree, const Vec3R& inCoord);
184
185 template<class ValueT, size_t N>
186 static inline ValueT triquadraticInterpolation(ValueT (&data)[N][N][N], const Vec3R& uvw);
187};
188
189
190//////////////////////////////////////// Staggered Samplers
191
192
193// The following samplers operate in voxel space and are designed for Vec3
194// staggered grid data (e.g., fluid simulations using the Marker-and-Cell approach
195// associate elements of the velocity vector with different physical locations:
196// the faces of a cube).
197
199{
200 static const char* name() { return "point"; }
201 static int radius() { return 0; }
202 static bool mipmap() { return false; }
203 static bool consistent() { return false; }
204 static bool staggered() { return true; }
205 static size_t order() { return 0; }
206
207 /// @brief Sample @a inTree at the nearest neighbor to @a inCoord
208 /// and store the result in @a result.
209 /// @return true if the sampled value is active.
210 template<class TreeT>
211 static bool sample(const TreeT& inTree, const Vec3R& inCoord,
212 typename TreeT::ValueType& result);
213
214 /// @brief Sample @a inTree at the nearest neighbor to @a inCoord
215 /// @return the reconstructed value
216 template<class TreeT>
217 static typename TreeT::ValueType sample(const TreeT& inTree, const Vec3R& inCoord);
218};
219
220
222{
223 static const char* name() { return "box"; }
224 static int radius() { return 1; }
225 static bool mipmap() { return true; }
226 static bool consistent() { return false; }
227 static bool staggered() { return true; }
228 static size_t order() { return 1; }
229
230 /// @brief Trilinearly reconstruct @a inTree at @a inCoord
231 /// and store the result in @a result.
232 /// @return true if any one of the sampled value is active.
233 template<class TreeT>
234 static bool sample(const TreeT& inTree, const Vec3R& inCoord,
235 typename TreeT::ValueType& result);
236
237 /// @brief Trilinearly reconstruct @a inTree at @a inCoord.
238 /// @return the reconstructed value
239 template<class TreeT>
240 static typename TreeT::ValueType sample(const TreeT& inTree, const Vec3R& inCoord);
241};
242
243
245{
246 static const char* name() { return "quadratic"; }
247 static int radius() { return 1; }
248 static bool mipmap() { return true; }
249 static bool consistent() { return false; }
250 static bool staggered() { return true; }
251 static size_t order() { return 2; }
252
253 /// @brief Triquadratically reconstruct @a inTree at @a inCoord
254 /// and store the result in @a result.
255 /// @return true if any one of the sampled values is active.
256 template<class TreeT>
257 static bool sample(const TreeT& inTree, const Vec3R& inCoord,
258 typename TreeT::ValueType& result);
259
260 /// @brief Triquadratically reconstruct @a inTree at to @a inCoord.
261 /// @return the reconstructed value
262 template<class TreeT>
263 static typename TreeT::ValueType sample(const TreeT& inTree, const Vec3R& inCoord);
264};
265
266
267//////////////////////////////////////// GridSampler
268
269
270/// @brief Class that provides the interface for continuous sampling
271/// of values in a tree.
272///
273/// @details Since trees support only discrete voxel sampling, TreeSampler
274/// must be used to sample arbitrary continuous points in (world or
275/// index) space.
276///
277/// @warning This implementation of the GridSampler stores a pointer
278/// to a Tree for value access. While this is thread-safe it is
279/// uncached and hence slow compared to using a
280/// ValueAccessor. Consequently it is normally advisable to use the
281/// template specialization below that employs a
282/// ValueAccessor. However, care must be taken when dealing with
283/// multi-threading (see warning below).
284template<typename GridOrTreeType, typename SamplerType>
286{
287public:
289 using ValueType = typename GridOrTreeType::ValueType;
293
294 /// @param grid a grid to be sampled
295 explicit GridSampler(const GridType& grid)
296 : mTree(&(grid.tree())), mTransform(&(grid.transform())) {}
297
298 /// @param tree a tree to be sampled, or a ValueAccessor for the tree
299 /// @param transform is used when sampling world space locations.
301 : mTree(&tree), mTransform(&transform) {}
302
303 const math::Transform& transform() const { return *mTransform; }
304
305 /// @brief Sample a point in index space in the grid.
306 /// @param x Fractional x-coordinate of point in index-coordinates of grid
307 /// @param y Fractional y-coordinate of point in index-coordinates of grid
308 /// @param z Fractional z-coordinate of point in index-coordinates of grid
309 template<typename RealType>
310 ValueType sampleVoxel(const RealType& x, const RealType& y, const RealType& z) const
311 {
312 return this->isSample(Vec3d(x,y,z));
313 }
314
315 /// @brief Sample value in integer index space
316 /// @param i Integer x-coordinate in index space
317 /// @param j Integer y-coordinate in index space
318 /// @param k Integer x-coordinate in index space
320 typename Coord::ValueType j,
321 typename Coord::ValueType k) const
322 {
323 return this->isSample(Coord(i,j,k));
324 }
325
326 /// @brief Sample value in integer index space
327 /// @param ijk the location in index space
328 ValueType isSample(const Coord& ijk) const { return mTree->getValue(ijk); }
329
330 /// @brief Sample in fractional index space
331 /// @param ispoint the location in index space
332 ValueType isSample(const Vec3d& ispoint) const
333 {
334 ValueType result = zeroVal<ValueType>();
335 SamplerType::sample(*mTree, ispoint, result);
336 return result;
337 }
338
339 /// @brief Sample in world space
340 /// @param wspoint the location in world space
341 ValueType wsSample(const Vec3d& wspoint) const
342 {
343 ValueType result = zeroVal<ValueType>();
344 SamplerType::sample(*mTree, mTransform->worldToIndex(wspoint), result);
345 return result;
346 }
347
348private:
349 const TreeType* mTree;
350 const math::Transform* mTransform;
351}; // class GridSampler
352
353
354/// @brief Specialization of GridSampler for construction from a ValueAccessor type
355///
356/// @note This version should normally be favored over the one above
357/// that takes a Grid or Tree. The reason is this version uses a
358/// ValueAccessor that performs fast (cached) access where the
359/// tree-based flavor performs slower (uncached) access.
360///
361/// @warning Since this version stores a pointer to an (externally
362/// allocated) value accessor it is not threadsafe. Hence each thread
363/// should have its own instance of a GridSampler constructed from a
364/// local ValueAccessor. Alternatively the Grid/Tree-based GridSampler
365/// is threadsafe, but also slower.
366template<typename TreeT, typename SamplerType>
367class GridSampler<tree::ValueAccessor<TreeT>, SamplerType>
368{
369public:
371 using ValueType = typename TreeT::ValueType;
372 using TreeType = TreeT;
375
376 /// @param acc a ValueAccessor to be sampled
377 /// @param transform is used when sampling world space locations.
380 : mAccessor(&acc), mTransform(&transform) {}
381
382 const math::Transform& transform() const { return *mTransform; }
383
384 /// @brief Sample a point in index space in the grid.
385 /// @param x Fractional x-coordinate of point in index-coordinates of grid
386 /// @param y Fractional y-coordinate of point in index-coordinates of grid
387 /// @param z Fractional z-coordinate of point in index-coordinates of grid
388 template<typename RealType>
389 ValueType sampleVoxel(const RealType& x, const RealType& y, const RealType& z) const
390 {
391 return this->isSample(Vec3d(x,y,z));
392 }
393
394 /// @brief Sample value in integer index space
395 /// @param i Integer x-coordinate in index space
396 /// @param j Integer y-coordinate in index space
397 /// @param k Integer x-coordinate in index space
399 typename Coord::ValueType j,
400 typename Coord::ValueType k) const
401 {
402 return this->isSample(Coord(i,j,k));
403 }
404
405 /// @brief Sample value in integer index space
406 /// @param ijk the location in index space
407 ValueType isSample(const Coord& ijk) const { return mAccessor->getValue(ijk); }
408
409 /// @brief Sample in fractional index space
410 /// @param ispoint the location in index space
411 ValueType isSample(const Vec3d& ispoint) const
412 {
413 ValueType result = zeroVal<ValueType>();
414 SamplerType::sample(*mAccessor, ispoint, result);
415 return result;
416 }
417
418 /// @brief Sample in world space
419 /// @param wspoint the location in world space
420 ValueType wsSample(const Vec3d& wspoint) const
421 {
422 ValueType result = zeroVal<ValueType>();
423 SamplerType::sample(*mAccessor, mTransform->worldToIndex(wspoint), result);
424 return result;
425 }
426
427private:
428 const AccessorType* mAccessor;//not thread-safe!
429 const math::Transform* mTransform;
430};//Specialization of GridSampler
431
432
433//////////////////////////////////////// DualGridSampler
434
435
436/// @brief This is a simple convenience class that allows for sampling
437/// from a source grid into the index space of a target grid. At
438/// construction the source and target grids are checked for alignment
439/// which potentially renders interpolation unnecessary. Else
440/// interpolation is performed according to the templated Sampler
441/// type.
442///
443/// @warning For performance reasons the check for alignment of the
444/// two grids is only performed at construction time!
445template<typename GridOrTreeT,
446 typename SamplerT>
448{
449public:
450 using ValueType = typename GridOrTreeT::ValueType;
454
455 /// @brief Grid and transform constructor.
456 /// @param sourceGrid Source grid.
457 /// @param targetXform Transform of the target grid.
458 DualGridSampler(const GridType& sourceGrid,
459 const math::Transform& targetXform)
460 : mSourceTree(&(sourceGrid.tree()))
461 , mSourceXform(&(sourceGrid.transform()))
462 , mTargetXform(&targetXform)
463 , mAligned(targetXform == *mSourceXform)
464 {
465 }
466 /// @brief Tree and transform constructor.
467 /// @param sourceTree Source tree.
468 /// @param sourceXform Transform of the source grid.
469 /// @param targetXform Transform of the target grid.
470 DualGridSampler(const TreeType& sourceTree,
471 const math::Transform& sourceXform,
472 const math::Transform& targetXform)
473 : mSourceTree(&sourceTree)
474 , mSourceXform(&sourceXform)
475 , mTargetXform(&targetXform)
476 , mAligned(targetXform == sourceXform)
477 {
478 }
479 /// @brief Return the value of the source grid at the index
480 /// coordinates, ijk, relative to the target grid (or its tranform).
481 inline ValueType operator()(const Coord& ijk) const
482 {
483 if (mAligned) return mSourceTree->getValue(ijk);
484 const Vec3R world = mTargetXform->indexToWorld(ijk);
485 return SamplerT::sample(*mSourceTree, mSourceXform->worldToIndex(world));
486 }
487 /// @brief Return true if the two grids are aligned.
488 inline bool isAligned() const { return mAligned; }
489private:
490 const TreeType* mSourceTree;
491 const math::Transform* mSourceXform;
492 const math::Transform* mTargetXform;
493 const bool mAligned;
494};// DualGridSampler
495
496/// @brief Specialization of DualGridSampler for construction from a ValueAccessor type.
497template<typename TreeT,
498 typename SamplerT>
499class DualGridSampler<tree::ValueAccessor<TreeT>, SamplerT>
500{
501 public:
502 using ValueType = typename TreeT::ValueType;
503 using TreeType = TreeT;
506
507 /// @brief ValueAccessor and transform constructor.
508 /// @param sourceAccessor ValueAccessor into the source grid.
509 /// @param sourceXform Transform for the source grid.
510 /// @param targetXform Transform for the target grid.
511 DualGridSampler(const AccessorType& sourceAccessor,
512 const math::Transform& sourceXform,
513 const math::Transform& targetXform)
514 : mSourceAcc(&sourceAccessor)
515 , mSourceXform(&sourceXform)
516 , mTargetXform(&targetXform)
517 , mAligned(targetXform == sourceXform)
518 {
519 }
520 /// @brief Return the value of the source grid at the index
521 /// coordinates, ijk, relative to the target grid.
522 inline ValueType operator()(const Coord& ijk) const
523 {
524 if (mAligned) return mSourceAcc->getValue(ijk);
525 const Vec3R world = mTargetXform->indexToWorld(ijk);
526 return SamplerT::sample(*mSourceAcc, mSourceXform->worldToIndex(world));
527 }
528 /// @brief Return true if the two grids are aligned.
529 inline bool isAligned() const { return mAligned; }
530private:
531 const AccessorType* mSourceAcc;
532 const math::Transform* mSourceXform;
533 const math::Transform* mTargetXform;
534 const bool mAligned;
535};//Specialization of DualGridSampler
536
537//////////////////////////////////////// AlphaMask
538
539
540// Class to derive the normalized alpha mask
541template <typename GridT,
542 typename MaskT,
543 typename SamplerT = tools::BoxSampler,
544 typename FloatT = float>
546{
547public:
548 static_assert(std::is_floating_point<FloatT>::value,
549 "AlphaMask requires a floating-point value type");
550 using GridType = GridT;
551 using MaskType = MaskT;
552 using SamlerType = SamplerT;
553 using FloatType = FloatT;
554
555 AlphaMask(const GridT& grid, const MaskT& mask, FloatT min, FloatT max, bool invert)
556 : mAcc(mask.tree())
557 , mSampler(mAcc, mask.transform() , grid.transform())
558 , mMin(min)
559 , mInvNorm(1/(max-min))
560 , mInvert(invert)
561 {
562 OPENVDB_ASSERT(min < max);
563 }
564
565 inline bool operator()(const Coord& xyz, FloatT& a, FloatT& b) const
566 {
567 a = math::SmoothUnitStep( (mSampler(xyz) - mMin) * mInvNorm );//smooth mapping to 0->1
568 b = 1 - a;
569 if (mInvert) std::swap(a,b);
570 return a>0;
571 }
572
573protected:
574 using AccT = typename MaskType::ConstAccessor;
577 const FloatT mMin, mInvNorm;
578 const bool mInvert;
579};// AlphaMask
580
581////////////////////////////////////////
582
583namespace local_util {
584
585inline Vec3i
587{
588 return Vec3i(int(std::floor(v(0))), int(std::floor(v(1))), int(std::floor(v(2))));
589}
590
591
592inline Vec3i
594{
595 return Vec3i(int(std::ceil(v(0))), int(std::ceil(v(1))), int(std::ceil(v(2))));
596}
597
598
599inline Vec3i
601{
602 return Vec3i(int(::round(v(0))), int(::round(v(1))), int(::round(v(2))));
603}
604
605} // namespace local_util
606
607
608//////////////////////////////////////// PointSampler
609
610
611template<class TreeT>
612inline bool
613PointSampler::sample(const TreeT& inTree, const Vec3R& inCoord,
614 typename TreeT::ValueType& result)
615{
616 return inTree.probeValue(Coord(local_util::roundVec3(inCoord)), result);
617}
618
619template<class TreeT>
620inline typename TreeT::ValueType
621PointSampler::sample(const TreeT& inTree, const Vec3R& inCoord)
622{
623 return inTree.getValue(Coord(local_util::roundVec3(inCoord)));
624}
625
626
627//////////////////////////////////////// BoxSampler
628
629template<class ValueT, class TreeT, size_t N>
630inline void
631BoxSampler::getValues(ValueT (&data)[N][N][N], const TreeT& inTree, Coord ijk)
632{
633 data[0][0][0] = inTree.getValue(ijk); // i, j, k
634
635 ijk[2] += 1;
636 data[0][0][1] = inTree.getValue(ijk); // i, j, k + 1
637
638 ijk[1] += 1;
639 data[0][1][1] = inTree.getValue(ijk); // i, j+1, k + 1
640
641 ijk[2] -= 1;
642 data[0][1][0] = inTree.getValue(ijk); // i, j+1, k
643
644 ijk[0] += 1;
645 ijk[1] -= 1;
646 data[1][0][0] = inTree.getValue(ijk); // i+1, j, k
647
648 ijk[2] += 1;
649 data[1][0][1] = inTree.getValue(ijk); // i+1, j, k + 1
650
651 ijk[1] += 1;
652 data[1][1][1] = inTree.getValue(ijk); // i+1, j+1, k + 1
653
654 ijk[2] -= 1;
655 data[1][1][0] = inTree.getValue(ijk); // i+1, j+1, k
656}
657
658template<class ValueT, class TreeT, size_t N>
659inline bool
660BoxSampler::probeValues(ValueT (&data)[N][N][N], const TreeT& inTree, Coord ijk)
661{
662 bool hasActiveValues = false;
663 hasActiveValues |= inTree.probeValue(ijk, data[0][0][0]); // i, j, k
664
665 ijk[2] += 1;
666 hasActiveValues |= inTree.probeValue(ijk, data[0][0][1]); // i, j, k + 1
667
668 ijk[1] += 1;
669 hasActiveValues |= inTree.probeValue(ijk, data[0][1][1]); // i, j+1, k + 1
670
671 ijk[2] -= 1;
672 hasActiveValues |= inTree.probeValue(ijk, data[0][1][0]); // i, j+1, k
673
674 ijk[0] += 1;
675 ijk[1] -= 1;
676 hasActiveValues |= inTree.probeValue(ijk, data[1][0][0]); // i+1, j, k
677
678 ijk[2] += 1;
679 hasActiveValues |= inTree.probeValue(ijk, data[1][0][1]); // i+1, j, k + 1
680
681 ijk[1] += 1;
682 hasActiveValues |= inTree.probeValue(ijk, data[1][1][1]); // i+1, j+1, k + 1
683
684 ijk[2] -= 1;
685 hasActiveValues |= inTree.probeValue(ijk, data[1][1][0]); // i+1, j+1, k
686
687 return hasActiveValues;
688}
689
690template<class ValueT, size_t N>
691inline void
692BoxSampler::extrema(ValueT (&data)[N][N][N], ValueT& vMin, ValueT &vMax)
693{
694 vMin = vMax = data[0][0][0];
695 vMin = math::cwiseLessThan(vMin, data[0][0][1]) ? vMin : data[0][0][1];
696 vMax = math::cwiseLessThan(vMax, data[0][0][1]) ? data[0][0][1] : vMax;
697 vMin = math::cwiseLessThan(vMin, data[0][1][0]) ? vMin : data[0][1][0];
698 vMax = math::cwiseLessThan(vMax, data[0][1][0]) ? data[0][1][0] : vMax;
699 vMin = math::cwiseLessThan(vMin, data[0][1][1]) ? vMin : data[0][1][1];
700 vMax = math::cwiseLessThan(vMax, data[0][1][1]) ? data[0][1][1] : vMax;
701 vMin = math::cwiseLessThan(vMin, data[1][0][0]) ? vMin : data[1][0][0];
702 vMax = math::cwiseLessThan(vMax, data[1][0][0]) ? data[1][0][0] : vMax;
703 vMin = math::cwiseLessThan(vMin, data[1][0][1]) ? vMin : data[1][0][1];
704 vMax = math::cwiseLessThan(vMax, data[1][0][1]) ? data[1][0][1] : vMax;
705 vMin = math::cwiseLessThan(vMin, data[1][1][0]) ? vMin : data[1][1][0];
706 vMax = math::cwiseLessThan(vMax, data[1][1][0]) ? data[1][1][0] : vMax;
707 vMin = math::cwiseLessThan(vMin, data[1][1][1]) ? vMin : data[1][1][1];
708 vMax = math::cwiseLessThan(vMax, data[1][1][1]) ? data[1][1][1] : vMax;
709}
710
711
712template<class ValueT, size_t N>
713inline ValueT
714BoxSampler::trilinearInterpolation(ValueT (&data)[N][N][N], const Vec3R& uvw)
715{
716 auto _interpolate = [](const ValueT& a, const ValueT& b, double weight)
717 {
719 const auto temp = (b - a) * weight;
721 return static_cast<ValueT>(a + ValueT(temp));
722 };
723
724 // Trilinear interpolation:
725 // The eight surrounding latice values are used to construct the result. \n
726 // result(x,y,z) =
727 // v000 (1-x)(1-y)(1-z) + v001 (1-x)(1-y)z + v010 (1-x)y(1-z) + v011 (1-x)yz
728 // + v100 x(1-y)(1-z) + v101 x(1-y)z + v110 xy(1-z) + v111 xyz
729
730 return _interpolate(
731 _interpolate(
732 _interpolate(data[0][0][0], data[0][0][1], uvw[2]),
733 _interpolate(data[0][1][0], data[0][1][1], uvw[2]),
734 uvw[1]),
735 _interpolate(
736 _interpolate(data[1][0][0], data[1][0][1], uvw[2]),
737 _interpolate(data[1][1][0], data[1][1][1], uvw[2]),
738 uvw[1]),
739 uvw[0]);
740}
741
742
743template<class TreeT>
744inline bool
745BoxSampler::sample(const TreeT& inTree, const Vec3R& inCoord,
746 typename TreeT::ValueType& result)
747{
748 using ValueT = typename TreeT::ValueType;
749
750 const Vec3i inIdx = local_util::floorVec3(inCoord);
751 const Vec3R uvw = inCoord - inIdx;
752
753 // Retrieve the values of the eight voxels surrounding the
754 // fractional source coordinates.
755 ValueT data[2][2][2];
756
757 const bool hasActiveValues = BoxSampler::probeValues(data, inTree, Coord(inIdx));
758
759 result = BoxSampler::trilinearInterpolation(data, uvw);
760
761 return hasActiveValues;
762}
763
764
765template<class TreeT>
766inline typename TreeT::ValueType
767BoxSampler::sample(const TreeT& inTree, const Vec3R& inCoord)
768{
769 using ValueT = typename TreeT::ValueType;
770
771 const Vec3i inIdx = local_util::floorVec3(inCoord);
772 const Vec3R uvw = inCoord - inIdx;
773
774 // Retrieve the values of the eight voxels surrounding the
775 // fractional source coordinates.
776 ValueT data[2][2][2];
777
778 BoxSampler::getValues(data, inTree, Coord(inIdx));
779
780 return BoxSampler::trilinearInterpolation(data, uvw);
781}
782
783
784//////////////////////////////////////// QuadraticSampler
785
786template<class ValueT, size_t N>
787inline ValueT
788QuadraticSampler::triquadraticInterpolation(ValueT (&data)[N][N][N], const Vec3R& uvw)
789{
790 auto _interpolate = [](const ValueT* value, double weight)
791 {
793 const ValueT
794 a = static_cast<ValueT>(0.5 * (value[0] + value[2]) - value[1]),
795 b = static_cast<ValueT>(0.5 * (value[2] - value[0])),
796 c = static_cast<ValueT>(value[1]);
797 const auto temp = weight * (weight * a + b) + c;
799 return static_cast<ValueT>(temp);
800 };
801
802 /// @todo For vector types, interpolate over each component independently.
803 ValueT vx[3];
804 for (int dx = 0; dx < 3; ++dx) {
805 ValueT vy[3];
806 for (int dy = 0; dy < 3; ++dy) {
807 // Fit a parabola to three contiguous samples in z
808 // (at z=-1, z=0 and z=1), then evaluate the parabola at z',
809 // where z' is the fractional part of inCoord.z, i.e.,
810 // inCoord.z - inIdx.z. The coefficients come from solving
811 //
812 // | (-1)^2 -1 1 || a | | v0 |
813 // | 0 0 1 || b | = | v1 |
814 // | 1^2 1 1 || c | | v2 |
815 //
816 // for a, b and c.
817 const ValueT* vz = &data[dx][dy][0];
818 vy[dy] = _interpolate(vz, uvw.z());
819 }//loop over y
820 // Fit a parabola to three interpolated samples in y, then
821 // evaluate the parabola at y', where y' is the fractional
822 // part of inCoord.y.
823 vx[dx] = _interpolate(vy, uvw.y());
824 }//loop over x
825 // Fit a parabola to three interpolated samples in x, then
826 // evaluate the parabola at the fractional part of inCoord.x.
827 return _interpolate(vx, uvw.x());
828}
829
830template<class TreeT>
831inline bool
832QuadraticSampler::sample(const TreeT& inTree, const Vec3R& inCoord,
833 typename TreeT::ValueType& result)
834{
835 using ValueT = typename TreeT::ValueType;
836
837 const Vec3i inIdx = local_util::floorVec3(inCoord), inLoIdx = inIdx - Vec3i(1, 1, 1);
838 const Vec3R uvw = inCoord - inIdx;
839
840 // Retrieve the values of the 27 voxels surrounding the
841 // fractional source coordinates.
842 bool active = false;
843 ValueT data[3][3][3];
844 for (int dx = 0, ix = inLoIdx.x(); dx < 3; ++dx, ++ix) {
845 for (int dy = 0, iy = inLoIdx.y(); dy < 3; ++dy, ++iy) {
846 for (int dz = 0, iz = inLoIdx.z(); dz < 3; ++dz, ++iz) {
847 if (inTree.probeValue(Coord(ix, iy, iz), data[dx][dy][dz])) active = true;
848 }
849 }
850 }
851
853
854 return active;
855}
856
857template<class TreeT>
858inline typename TreeT::ValueType
859QuadraticSampler::sample(const TreeT& inTree, const Vec3R& inCoord)
860{
861 using ValueT = typename TreeT::ValueType;
862
863 const Vec3i inIdx = local_util::floorVec3(inCoord), inLoIdx = inIdx - Vec3i(1, 1, 1);
864 const Vec3R uvw = inCoord - inIdx;
865
866 // Retrieve the values of the 27 voxels surrounding the
867 // fractional source coordinates.
868 ValueT data[3][3][3];
869 for (int dx = 0, ix = inLoIdx.x(); dx < 3; ++dx, ++ix) {
870 for (int dy = 0, iy = inLoIdx.y(); dy < 3; ++dy, ++iy) {
871 for (int dz = 0, iz = inLoIdx.z(); dz < 3; ++dz, ++iz) {
872 data[dx][dy][dz] = inTree.getValue(Coord(ix, iy, iz));
873 }
874 }
875 }
876
878}
879
880
881//////////////////////////////////////// StaggeredPointSampler
882
883
884template<class TreeT>
885inline bool
886StaggeredPointSampler::sample(const TreeT& inTree, const Vec3R& inCoord,
887 typename TreeT::ValueType& result)
888{
889 using ValueType = typename TreeT::ValueType;
890
891 ValueType tempX, tempY, tempZ;
892 bool active = false;
893
894 active = PointSampler::sample<TreeT>(inTree, inCoord + Vec3R(0.5, 0, 0), tempX) || active;
895 active = PointSampler::sample<TreeT>(inTree, inCoord + Vec3R(0, 0.5, 0), tempY) || active;
896 active = PointSampler::sample<TreeT>(inTree, inCoord + Vec3R(0, 0, 0.5), tempZ) || active;
897
898 result.x() = tempX.x();
899 result.y() = tempY.y();
900 result.z() = tempZ.z();
901
902 return active;
903}
904
905template<class TreeT>
906inline typename TreeT::ValueType
907StaggeredPointSampler::sample(const TreeT& inTree, const Vec3R& inCoord)
908{
909 using ValueT = typename TreeT::ValueType;
910
911 const ValueT tempX = PointSampler::sample<TreeT>(inTree, inCoord + Vec3R(0.5, 0.0, 0.0));
912 const ValueT tempY = PointSampler::sample<TreeT>(inTree, inCoord + Vec3R(0.0, 0.5, 0.0));
913 const ValueT tempZ = PointSampler::sample<TreeT>(inTree, inCoord + Vec3R(0.0, 0.0, 0.5));
914
915 return ValueT(tempX.x(), tempY.y(), tempZ.z());
916}
917
918
919//////////////////////////////////////// StaggeredBoxSampler
920
921
922template<class TreeT>
923inline bool
924StaggeredBoxSampler::sample(const TreeT& inTree, const Vec3R& inCoord,
925 typename TreeT::ValueType& result)
926{
927 using ValueType = typename TreeT::ValueType;
928
929 ValueType tempX, tempY, tempZ;
930 tempX = tempY = tempZ = zeroVal<ValueType>();
931 bool active = false;
932
933 active = BoxSampler::sample<TreeT>(inTree, inCoord + Vec3R(0.5, 0, 0), tempX) || active;
934 active = BoxSampler::sample<TreeT>(inTree, inCoord + Vec3R(0, 0.5, 0), tempY) || active;
935 active = BoxSampler::sample<TreeT>(inTree, inCoord + Vec3R(0, 0, 0.5), tempZ) || active;
936
937 result.x() = tempX.x();
938 result.y() = tempY.y();
939 result.z() = tempZ.z();
940
941 return active;
942}
943
944template<class TreeT>
945inline typename TreeT::ValueType
946StaggeredBoxSampler::sample(const TreeT& inTree, const Vec3R& inCoord)
947{
948 using ValueT = typename TreeT::ValueType;
949
950 const ValueT tempX = BoxSampler::sample<TreeT>(inTree, inCoord + Vec3R(0.5, 0.0, 0.0));
951 const ValueT tempY = BoxSampler::sample<TreeT>(inTree, inCoord + Vec3R(0.0, 0.5, 0.0));
952 const ValueT tempZ = BoxSampler::sample<TreeT>(inTree, inCoord + Vec3R(0.0, 0.0, 0.5));
953
954 return ValueT(tempX.x(), tempY.y(), tempZ.z());
955}
956
957
958//////////////////////////////////////// StaggeredQuadraticSampler
959
960
961template<class TreeT>
962inline bool
963StaggeredQuadraticSampler::sample(const TreeT& inTree, const Vec3R& inCoord,
964 typename TreeT::ValueType& result)
965{
966 using ValueType = typename TreeT::ValueType;
967
968 ValueType tempX, tempY, tempZ;
969 bool active = false;
970
971 active = QuadraticSampler::sample<TreeT>(inTree, inCoord + Vec3R(0.5, 0, 0), tempX) || active;
972 active = QuadraticSampler::sample<TreeT>(inTree, inCoord + Vec3R(0, 0.5, 0), tempY) || active;
973 active = QuadraticSampler::sample<TreeT>(inTree, inCoord + Vec3R(0, 0, 0.5), tempZ) || active;
974
975 result.x() = tempX.x();
976 result.y() = tempY.y();
977 result.z() = tempZ.z();
978
979 return active;
980}
981
982template<class TreeT>
983inline typename TreeT::ValueType
984StaggeredQuadraticSampler::sample(const TreeT& inTree, const Vec3R& inCoord)
985{
986 using ValueT = typename TreeT::ValueType;
987
988 const ValueT tempX = QuadraticSampler::sample<TreeT>(inTree, inCoord + Vec3R(0.5, 0.0, 0.0));
989 const ValueT tempY = QuadraticSampler::sample<TreeT>(inTree, inCoord + Vec3R(0.0, 0.5, 0.0));
990 const ValueT tempZ = QuadraticSampler::sample<TreeT>(inTree, inCoord + Vec3R(0.0, 0.0, 0.5));
991
992 return ValueT(tempX.x(), tempY.y(), tempZ.z());
993}
994
995//////////////////////////////////////// Sampler
996
997template <>
998struct Sampler<0, false> : public PointSampler {};
999
1000template <>
1001struct Sampler<1, false> : public BoxSampler {};
1002
1003template <>
1004struct Sampler<2, false> : public QuadraticSampler {};
1005
1006template <>
1007struct Sampler<0, true> : public StaggeredPointSampler {};
1008
1009template <>
1010struct Sampler<1, true> : public StaggeredBoxSampler {};
1011
1012template <>
1013struct Sampler<2, true> : public StaggeredQuadraticSampler {};
1014
1015} // namespace tools
1016} // namespace OPENVDB_VERSION_NAME
1017} // namespace openvdb
1018
1019#endif // OPENVDB_TOOLS_INTERPOLATION_HAS_BEEN_INCLUDED
#define OPENVDB_ASSERT(X)
Definition Assert.h:41
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
#define OPENVDB_NO_TYPE_CONVERSION_WARNING_BEGIN
Bracket code with OPENVDB_NO_TYPE_CONVERSION_WARNING_BEGIN/_END, to inhibit warnings about type conve...
Definition Platform.h:231
#define OPENVDB_NO_TYPE_CONVERSION_WARNING_END
Definition Platform.h:232
ValueAccessors are designed to help accelerate accesses into the OpenVDB Tree structures by storing c...
Int32 ValueType
Definition Coord.h:33
Container class that associates a tree with a transform and metadata.
Definition Grid.h:571
Signed (x, y, z) 32-bit integer coordinates.
Definition Coord.h:26
Definition Transform.h:40
T & x()
Reference to the component, e.g. v.x() = 4.5f;.
Definition Vec3.h:86
T & y()
Definition Vec3.h:87
T & z()
Definition Vec3.h:88
const FloatT mMin
Definition Interpolation.h:577
tools::DualGridSampler< AccT, SamplerT > mSampler
Definition Interpolation.h:576
SamplerT SamlerType
Definition Interpolation.h:552
AlphaMask(const GridT &grid, const MaskT &mask, FloatT min, FloatT max, bool invert)
Definition Interpolation.h:555
FloatT FloatType
Definition Interpolation.h:553
const FloatT mInvNorm
Definition Interpolation.h:577
typename MaskType::ConstAccessor AccT
Definition Interpolation.h:574
const bool mInvert
Definition Interpolation.h:578
MaskT MaskType
Definition Interpolation.h:551
AccT mAcc
Definition Interpolation.h:575
bool operator()(const Coord &xyz, FloatT &a, FloatT &b) const
Definition Interpolation.h:565
GridT GridType
Definition Interpolation.h:550
DualGridSampler(const AccessorType &sourceAccessor, const math::Transform &sourceXform, const math::Transform &targetXform)
ValueAccessor and transform constructor.
Definition Interpolation.h:511
typename TreeT::ValueType ValueType
Definition Interpolation.h:502
bool isAligned() const
Return true if the two grids are aligned.
Definition Interpolation.h:529
typename tree::ValueAccessor< TreeT > AccessorType
Definition Interpolation.h:505
ValueType operator()(const Coord &ijk) const
Return the value of the source grid at the index coordinates, ijk, relative to the target grid.
Definition Interpolation.h:522
This is a simple convenience class that allows for sampling from a source grid into the index space o...
Definition Interpolation.h:448
typename GridOrTreeT::ValueType ValueType
Definition Interpolation.h:450
typename TreeAdapter< GridOrTreeT >::GridType GridType
Definition Interpolation.h:451
bool isAligned() const
Return true if the two grids are aligned.
Definition Interpolation.h:488
DualGridSampler(const GridType &sourceGrid, const math::Transform &targetXform)
Grid and transform constructor.
Definition Interpolation.h:458
DualGridSampler(const TreeType &sourceTree, const math::Transform &sourceXform, const math::Transform &targetXform)
Tree and transform constructor.
Definition Interpolation.h:470
typename TreeAdapter< GridOrTreeT >::TreeType TreeType
Definition Interpolation.h:452
typename TreeAdapter< GridType >::AccessorType AccessorType
Definition Interpolation.h:453
ValueType operator()(const Coord &ijk) const
Return the value of the source grid at the index coordinates, ijk, relative to the target grid (or it...
Definition Interpolation.h:481
typename TreeT::ValueType ValueType
Definition Interpolation.h:371
ValueType isSample(const Coord &ijk) const
Sample value in integer index space.
Definition Interpolation.h:407
typename tree::ValueAccessor< TreeT > AccessorType
Definition Interpolation.h:374
ValueType sampleVoxel(const RealType &x, const RealType &y, const RealType &z) const
Sample a point in index space in the grid.
Definition Interpolation.h:389
ValueType wsSample(const Vec3d &wspoint) const
Sample in world space.
Definition Interpolation.h:420
GridSampler(const AccessorType &acc, const math::Transform &transform)
Definition Interpolation.h:378
SharedPtr< GridSampler > Ptr
Definition Interpolation.h:370
const math::Transform & transform() const
Definition Interpolation.h:382
ValueType sampleVoxel(typename Coord::ValueType i, typename Coord::ValueType j, typename Coord::ValueType k) const
Sample value in integer index space.
Definition Interpolation.h:398
ValueType isSample(const Vec3d &ispoint) const
Sample in fractional index space.
Definition Interpolation.h:411
typename TreeAdapter< GridOrTreeType >::TreeType TreeType
Definition Interpolation.h:291
GridSampler(const GridType &grid)
Definition Interpolation.h:295
typename GridOrTreeType::ValueType ValueType
Definition Interpolation.h:289
ValueType isSample(const Coord &ijk) const
Definition Interpolation.h:328
typename TreeAdapter< GridOrTreeType >::GridType GridType
Definition Interpolation.h:290
ValueType sampleVoxel(const RealType &x, const RealType &y, const RealType &z) const
Sample a point in index space in the grid.
Definition Interpolation.h:310
GridSampler(const TreeType &tree, const math::Transform &transform)
Definition Interpolation.h:300
ValueType wsSample(const Vec3d &wspoint) const
Sample in world space.
Definition Interpolation.h:341
typename TreeAdapter< GridOrTreeType >::AccessorType AccessorType
Definition Interpolation.h:292
SharedPtr< GridSampler > Ptr
Definition Interpolation.h:288
const math::Transform & transform() const
Definition Interpolation.h:303
ValueType sampleVoxel(typename Coord::ValueType i, typename Coord::ValueType j, typename Coord::ValueType k) const
Sample value in integer index space.
Definition Interpolation.h:319
ValueType isSample(const Vec3d &ispoint) const
Sample in fractional index space.
Definition Interpolation.h:332
Type SmoothUnitStep(Type x)
Return 0 if x < 0, 1 if x > 1 or else (3 − 2 x) x².
Definition Math.h:300
bool cwiseLessThan(const Mat< SIZE, T > &m0, const Mat< SIZE, T > &m1)
Definition Mat.h:1015
Vec3< double > Vec3d
Definition Vec3.h:708
Vec3< int32_t > Vec3i
Definition Vec3.h:705
Definition GridTransformer.h:272
Vec3i ceilVec3(const Vec3R &v)
Definition Interpolation.h:593
Vec3i roundVec3(const Vec3R &v)
Definition Interpolation.h:600
Vec3i floorVec3(const Vec3R &v)
Definition Interpolation.h:586
math::Extrema extrema(const IterT &iter, bool threaded=true)
Iterate over a scalar grid and compute extrema (min/max) of the values of the voxels that are visited...
Definition Statistics.h:354
Definition PointDataGrid.h:170
ValueAccessorImpl< TreeType, IsSafe, MutexType, openvdb::make_index_sequence< CacheLevels > > ValueAccessor
Default alias for a ValueAccessor. This is simply a helper alias for the generic definition but takes...
Definition ValueAccessor.h:86
constexpr T zeroVal()
Return the value of type T that corresponds to zero.
Definition Math.h:71
math::Vec3< Real > Vec3R
Definition Types.h:53
std::shared_ptr< T > SharedPtr
Definition Types.h:95
Definition Exceptions.h:13
_TreeType TreeType
Definition Grid.h:1059
Grid< NonConstTreeType > GridType
Definition Grid.h:1064
typename tree::ValueAccessor< TreeType > AccessorType
Definition Grid.h:1070
Definition Interpolation.h:121
static bool staggered()
Definition Interpolation.h:126
static void getValues(ValueT(&data)[N][N][N], const TreeT &inTree, Coord ijk)
Import all eight values from inTree to support tri-linear interpolation.
Definition Interpolation.h:631
static bool probeValues(ValueT(&data)[N][N][N], const TreeT &inTree, Coord ijk)
Import all eight values from inTree to support tri-linear interpolation.
Definition Interpolation.h:660
static size_t order()
Definition Interpolation.h:127
static int radius()
Definition Interpolation.h:123
static bool mipmap()
Definition Interpolation.h:124
static const char * name()
Definition Interpolation.h:122
static ValueT trilinearInterpolation(ValueT(&data)[N][N][N], const Vec3R &uvw)
Definition Interpolation.h:714
static bool sample(const TreeT &inTree, const Vec3R &inCoord, typename TreeT::ValueType &result)
Trilinearly reconstruct inTree at inCoord and store the result in result.
Definition Interpolation.h:745
static void extrema(ValueT(&data)[N][N][N], ValueT &vMin, ValueT &vMax)
Find the minimum and maximum values of the eight cell values in @ data. The default component wise le...
Definition Interpolation.h:692
static bool consistent()
Definition Interpolation.h:125
Definition Interpolation.h:98
static bool staggered()
Definition Interpolation.h:103
static size_t order()
Definition Interpolation.h:104
static int radius()
Definition Interpolation.h:100
static bool mipmap()
Definition Interpolation.h:101
static const char * name()
Definition Interpolation.h:99
static bool sample(const TreeT &inTree, const Vec3R &inCoord, typename TreeT::ValueType &result)
Sample inTree at the nearest neighbor to inCoord and store the result in result.
Definition Interpolation.h:613
static bool consistent()
Definition Interpolation.h:102
Definition Interpolation.h:165
static bool staggered()
Definition Interpolation.h:170
static ValueT triquadraticInterpolation(ValueT(&data)[N][N][N], const Vec3R &uvw)
Definition Interpolation.h:788
static size_t order()
Definition Interpolation.h:171
static int radius()
Definition Interpolation.h:167
static bool mipmap()
Definition Interpolation.h:168
static const char * name()
Definition Interpolation.h:166
static bool sample(const TreeT &inTree, const Vec3R &inCoord, typename TreeT::ValueType &result)
Triquadratically reconstruct inTree at inCoord and store the result in result.
Definition Interpolation.h:832
static bool consistent()
Definition Interpolation.h:169
Provises a unified interface for sampling, i.e. interpolation.
Definition Interpolation.h:65
static const char * name()
static bool sample(const TreeT &inTree, const Vec3R &inCoord, typename TreeT::ValueType &result)
Sample inTree at the floating-point index coordinate inCoord and store the result in result.
static TreeT::ValueType sample(const TreeT &inTree, const Vec3R &inCoord)
Sample inTree at the floating-point index coordinate inCoord.
Definition Interpolation.h:222
static bool staggered()
Definition Interpolation.h:227
static size_t order()
Definition Interpolation.h:228
static int radius()
Definition Interpolation.h:224
static bool mipmap()
Definition Interpolation.h:225
static const char * name()
Definition Interpolation.h:223
static bool sample(const TreeT &inTree, const Vec3R &inCoord, typename TreeT::ValueType &result)
Trilinearly reconstruct inTree at inCoord and store the result in result.
Definition Interpolation.h:924
static bool consistent()
Definition Interpolation.h:226
Definition Interpolation.h:199
static bool staggered()
Definition Interpolation.h:204
static size_t order()
Definition Interpolation.h:205
static int radius()
Definition Interpolation.h:201
static bool mipmap()
Definition Interpolation.h:202
static const char * name()
Definition Interpolation.h:200
static bool sample(const TreeT &inTree, const Vec3R &inCoord, typename TreeT::ValueType &result)
Sample inTree at the nearest neighbor to inCoord and store the result in result.
Definition Interpolation.h:886
static bool consistent()
Definition Interpolation.h:203
static bool staggered()
Definition Interpolation.h:250
static size_t order()
Definition Interpolation.h:251
static int radius()
Definition Interpolation.h:247
static bool mipmap()
Definition Interpolation.h:248
static const char * name()
Definition Interpolation.h:246
static bool sample(const TreeT &inTree, const Vec3R &inCoord, typename TreeT::ValueType &result)
Triquadratically reconstruct inTree at inCoord and store the result in result.
Definition Interpolation.h:963
static bool consistent()
Definition Interpolation.h:249
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:284