OpenVDB  8.1.1
PointSample.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3 
9 
10 #ifndef OPENVDB_POINTS_POINT_SAMPLE_HAS_BEEN_INCLUDED
11 #define OPENVDB_POINTS_POINT_SAMPLE_HAS_BEEN_INCLUDED
12 
15 
16 #include "PointDataGrid.h"
17 #include "PointAttribute.h"
18 
19 #include <sstream>
20 #include <type_traits>
21 
22 
23 namespace openvdb {
25 namespace OPENVDB_VERSION_NAME {
26 namespace points {
27 
28 
38 template<typename PointDataGridT, typename SourceGridT,
39  typename FilterT = NullFilter, typename InterrupterT = util::NullInterrupter>
40 inline void pointSample(PointDataGridT& points,
41  const SourceGridT& sourceGrid,
42  const Name& targetAttribute = "",
43  const FilterT& filter = NullFilter(),
44  InterrupterT* const interrupter = nullptr);
45 
46 
56 template<typename PointDataGridT, typename SourceGridT,
57  typename FilterT = NullFilter, typename InterrupterT = util::NullInterrupter>
58 inline void boxSample( PointDataGridT& points,
59  const SourceGridT& sourceGrid,
60  const Name& targetAttribute = "",
61  const FilterT& filter = NullFilter(),
62  InterrupterT* const interrupter = nullptr);
63 
64 
74 template<typename PointDataGridT, typename SourceGridT,
75  typename FilterT = NullFilter, typename InterrupterT = util::NullInterrupter>
76 inline void quadraticSample(PointDataGridT& points,
77  const SourceGridT& sourceGrid,
78  const Name& targetAttribute = "",
79  const FilterT& filter = NullFilter(),
80  InterrupterT* const interrupter = nullptr);
81 
82 
83 // This struct samples the source grid accessor using the world-space position supplied,
84 // with SamplerT providing the sampling scheme. In the case where ValueT does not match
85 // the value type of the source grid, the sample() method will also convert the sampled
86 // value into a ValueT value, using round-to-nearest for float-to-integer conversion.
88 {
89  template<typename ValueT, typename SamplerT, typename AccessorT>
90  inline ValueT sample(const AccessorT& accessor, const Vec3d& position) const;
91 };
92 
93 
94 // A dummy struct that is used to mean that the sampled attribute should either match the type
95 // of the existing attribute or the type of the source grid (if the attribute doesn't exist yet)
96 struct DummySampleType { };
97 
98 
112 template<typename PointDataGridT, typename SourceGridT, typename TargetValueT = DummySampleType,
113  typename SamplerT = SampleWithRounding, typename FilterT = NullFilter,
114  typename InterrupterT = util::NullInterrupter>
115 inline void sampleGrid( size_t order,
116  PointDataGridT& points,
117  const SourceGridT& sourceGrid,
118  const Name& targetAttribute,
119  const FilterT& filter = NullFilter(),
120  const SamplerT& sampler = SampleWithRounding(),
121  InterrupterT* const interrupter = nullptr,
122  const bool threaded = true);
123 
124 
126 
127 
128 namespace point_sample_internal {
129 
130 
131 template<typename FromType, typename ToType>
132 struct CompatibleTypes { enum { value = std::is_constructible<ToType, FromType>::value }; };
133 
134 // Specializations for types that can be converted from source grid to target attribute
135 template<typename T> struct CompatibleTypes<
136  T, T> { enum { value = true }; };
137 template<typename T> struct CompatibleTypes<
138  T, math::Vec2<T>> { enum { value = true }; };
139 template<typename T> struct CompatibleTypes<
140  T, math::Vec3<T>> { enum { value = true }; };
141 template<typename T> struct CompatibleTypes<
142  T, math::Vec4<T>> { enum { value = true }; };
143 template<typename T> struct CompatibleTypes<
144  math::Vec2<T>, math::Vec2<T>> { enum { value = true }; };
145 template<typename T> struct CompatibleTypes<
146  math::Vec3<T>, math::Vec3<T>> { enum { value = true }; };
147 template<typename T> struct CompatibleTypes<
148  math::Vec4<T>, math::Vec4<T>> { enum { value = true }; };
149 template<typename T0, typename T1> struct CompatibleTypes<
150  math::Vec2<T0>, math::Vec2<T1>> { enum { value = CompatibleTypes<T0, T1>::value }; };
151 template<typename T0, typename T1> struct CompatibleTypes<
152  math::Vec3<T0>, math::Vec3<T1>> { enum { value = CompatibleTypes<T0, T1>::value }; };
153 template<typename T0, typename T1> struct CompatibleTypes<
154  math::Vec4<T0>, math::Vec4<T1>> { enum { value = CompatibleTypes<T0, T1>::value }; };
155 template<typename T> struct CompatibleTypes<
156  ValueMask, T> { enum { value = CompatibleTypes<bool, T>::value }; };
157 
158 
159 // Ability to access the Order and Staggered template parameter from tools::Sampler<Order, Staggered>
160 template <typename T> struct SamplerTraits {
161  static const size_t Order = 0;
162  static const bool Staggered = false;
163 };
164 template <size_t T0, bool T1> struct SamplerTraits<tools::Sampler<T0, T1>> {
165  static const size_t Order = T0;
166  static const bool Staggered = T1;
167 };
168 
169 
170 // default sampling is incompatible, so throw an error
171 template <typename ValueT, typename SamplerT, typename AccessorT, bool Round, bool Compatible = false>
173 {
174  static inline void sample(ValueT&, const AccessorT&, const Vec3d&)
175  {
176  std::ostringstream ostr;
177  ostr << "Cannot sample a " << typeNameAsString<typename AccessorT::ValueType>()
178  << " grid on to a " << typeNameAsString<ValueT>() << " attribute";
179  OPENVDB_THROW(TypeError, ostr.str());
180  }
181 };
182 // partial specialization to handle sampling and rounding of compatible conversion
183 template <typename ValueT, typename SamplerT, typename AccessorT>
184 struct SampleWithRoundingOp<ValueT, SamplerT, AccessorT, /*Round=*/true, /*Compatible=*/true>
185 {
186  static inline void sample(ValueT& value, const AccessorT& accessor, const Vec3d& position)
187  {
188  value = ValueT(math::Round(SamplerT::sample(accessor, position)));
189  }
190 };
191 // partial specialization to handle sampling and simple casting of compatible conversion
192 template <typename ValueT, typename SamplerT, typename AccessorT>
193 struct SampleWithRoundingOp<ValueT, SamplerT, AccessorT, /*Round=*/false, /*Compatible=*/true>
194 {
195  static inline void sample(ValueT& value, const AccessorT& accessor, const Vec3d& position)
196  {
197  value = ValueT(SamplerT::sample(accessor, position));
198  }
199 };
200 
201 
202 template <typename PointDataGridT, typename SamplerT, typename FilterT, typename InterrupterT>
204 {
205 public:
206  PointDataSampler(size_t order,
207  PointDataGridT& points,
208  const SamplerT& sampler,
209  const FilterT& filter,
210  InterrupterT* const interrupter,
211  const bool threaded)
212  : mOrder(order)
213  , mPoints(points)
214  , mSampler(sampler)
215  , mFilter(filter)
216  , mInterrupter(interrupter)
217  , mThreaded(threaded) { }
218 
219 private:
220  // No-op transformation
221  struct AlignedTransform
222  {
223  inline Vec3d transform(const Vec3d& position) const { return position; }
224  }; // struct AlignedTransform
225 
226  // Re-sample world-space position from source to target transforms
227  struct NonAlignedTransform
228  {
229  NonAlignedTransform(const math::Transform& source, const math::Transform& target)
230  : mSource(source)
231  , mTarget(target) { }
232 
233  inline Vec3d transform(const Vec3d& position) const
234  {
235  return mSource.worldToIndex(mTarget.indexToWorld(position));
236  }
237 
238  private:
239  const math::Transform& mSource;
240  const math::Transform& mTarget;
241  }; // struct NonAlignedTransform
242 
243  // A simple convenience wrapper that contains the source grid accessor and the sampler
244  template <typename ValueT, typename SourceGridT, typename GridSamplerT>
245  struct SamplerWrapper
246  {
247  using ValueType = ValueT;
248  using SourceValueType = typename SourceGridT::ValueType;
249  using SourceAccessorT = typename SourceGridT::ConstAccessor;
250 
251  // can only sample from a bool or mask grid using a PointSampler
252  static const bool SourceIsBool = std::is_same<SourceValueType, bool>::value ||
253  std::is_same<SourceValueType, ValueMask>::value;
254  static const bool OrderIsZero = SamplerTraits<GridSamplerT>::Order == 0;
255  static const bool IsValid = !SourceIsBool || OrderIsZero;
256 
257  SamplerWrapper(const SourceGridT& sourceGrid, const SamplerT& sampler)
258  : mAccessor(sourceGrid.getConstAccessor())
259  , mSampler(sampler) { }
260 
261  // note that creating a new accessor from the underlying tree is faster than
262  // copying an existing accessor
263  SamplerWrapper(const SamplerWrapper& other)
264  : mAccessor(other.mAccessor.tree())
265  , mSampler(other.mSampler) { }
266 
267  template <bool IsValidT = IsValid>
268  inline typename std::enable_if<IsValidT, ValueT>::type
269  sample(const Vec3d& position) const {
270  return mSampler.template sample<ValueT, GridSamplerT, SourceAccessorT>(
271  mAccessor, position);
272  }
273 
274  template <bool IsValidT = IsValid>
275  inline typename std::enable_if<!IsValidT, ValueT>::type
276  sample(const Vec3d& /*position*/) const {
277  OPENVDB_THROW(RuntimeError, "Cannot sample bool grid with BoxSampler or QuadraticSampler.");
278  }
279 
280  private:
281  SourceAccessorT mAccessor;
282  const SamplerT& mSampler;
283  }; // struct SamplerWrapper
284 
285  template <typename SamplerWrapperT, typename TransformerT>
286  inline void doSample(const SamplerWrapperT& sampleWrapper, const Index targetIndex,
287  const TransformerT& transformer)
288  {
289  using PointDataTreeT = typename PointDataGridT::TreeType;
290  using LeafT = typename PointDataTreeT::LeafNodeType;
291  using LeafManagerT = typename tree::LeafManager<PointDataTreeT>;
292 
293  const auto& filter(mFilter);
294  const auto& interrupter(mInterrupter);
295 
296  auto sampleLambda = [targetIndex, &sampleWrapper, &transformer, &filter, &interrupter](
297  LeafT& leaf, size_t /*idx*/)
298  {
300 
301  if (util::wasInterrupted(interrupter)) {
302  tbb::task::self().cancel_group_execution();
303  return;
304  }
305 
306  SamplerWrapperT newSampleWrapper(sampleWrapper);
307  auto positionHandle = AttributeHandle<Vec3f>::create(leaf.constAttributeArray("P"));
308  auto targetHandle = TargetHandleT::create(leaf.attributeArray(targetIndex));
309  for (auto iter = leaf.beginIndexOn(filter); iter; ++iter) {
310  const Vec3d position = transformer.transform(
311  positionHandle->get(*iter) + iter.getCoord().asVec3d());
312  targetHandle->set(*iter, newSampleWrapper.sample(position));
313  }
314  };
315 
316  LeafManagerT leafManager(mPoints.tree());
317 
318  if (mInterrupter) mInterrupter->start();
319 
320  leafManager.foreach(sampleLambda, mThreaded);
321 
322  if (mInterrupter) mInterrupter->end();
323  }
324 
325  template <typename SourceGridT, typename SamplerWrapperT>
326  inline void resolveTransform(const SourceGridT& sourceGrid, const SamplerWrapperT& sampleWrapper,
327  const Index targetIndex)
328  {
329  const auto& sourceTransform = sourceGrid.constTransform();
330  const auto& pointsTransform = mPoints.constTransform();
331 
332  if (sourceTransform == pointsTransform) {
333  AlignedTransform transformer;
334  doSample(sampleWrapper, targetIndex, transformer);
335  } else {
336  NonAlignedTransform transformer(sourceTransform, pointsTransform);
337  doSample(sampleWrapper, targetIndex, transformer);
338  }
339  }
340 
341  template <typename SourceGridT, typename TargetValueT, size_t Order>
342  inline void resolveStaggered(const SourceGridT& sourceGrid, const Index targetIndex)
343  {
344  using SamplerWrapperT = SamplerWrapper<TargetValueT, SourceGridT, tools::Sampler<Order, false>>;
345  using StaggeredSamplerWrapperT = SamplerWrapper<TargetValueT, SourceGridT, tools::Sampler<Order, true>>;
346 
347  using SourceValueType = typename SourceGridT::ValueType;
348  if (VecTraits<SourceValueType>::Size == 3 && sourceGrid.getGridClass() == GRID_STAGGERED) {
349  StaggeredSamplerWrapperT sampleWrapper(sourceGrid, mSampler);
350  resolveTransform(sourceGrid, sampleWrapper, targetIndex);
351  } else {
352  SamplerWrapperT sampleWrapper(sourceGrid, mSampler);
353  resolveTransform(sourceGrid, sampleWrapper, targetIndex);
354  }
355  }
356 
357 public:
358  template <typename SourceGridT, typename TargetValueT = typename SourceGridT::ValueType>
359  inline void sample(const SourceGridT& sourceGrid, Index targetIndex)
360  {
361  using SourceValueType = typename SourceGridT::ValueType;
362  static const bool SourceIsMask = std::is_same<SourceValueType, bool>::value ||
363  std::is_same<SourceValueType, ValueMask>::value;
364 
365  if (SourceIsMask || mOrder == 0) {
366  resolveStaggered<SourceGridT, TargetValueT, 0>(sourceGrid, targetIndex);
367  } else if (mOrder == 1) {
368  resolveStaggered<SourceGridT, TargetValueT, 1>(sourceGrid, targetIndex);
369  } else if (mOrder == 2) {
370  resolveStaggered<SourceGridT, TargetValueT, 2>(sourceGrid, targetIndex);
371  }
372  }
373 
374 private:
375  size_t mOrder;
376  PointDataGridT& mPoints;
377  const SamplerT& mSampler;
378  const FilterT& mFilter;
379  InterrupterT* const mInterrupter;
380  const bool mThreaded;
381 }; // class PointDataSampler
382 
383 
384 template <typename PointDataGridT, typename ValueT>
386 {
387  static void append(PointDataGridT& points, const Name& attribute)
388  {
389  appendAttribute<ValueT>(points.tree(), attribute);
390  }
391 };
392 // partial specialization to disable attempts to append attribute type of DummySampleType
393 template <typename PointDataGridT>
394 struct AppendAttributeOp<PointDataGridT, DummySampleType>
395 {
396  static void append(PointDataGridT&, const Name&) { }
397 };
398 
399 } // namespace point_sample_internal
400 
401 
403 
404 
405 template<typename ValueT, typename SamplerT, typename AccessorT>
406 ValueT SampleWithRounding::sample(const AccessorT& accessor, const Vec3d& position) const
407 {
408  using namespace point_sample_internal;
409  using SourceValueT = typename AccessorT::ValueType;
410  static const bool staggered = SamplerTraits<SamplerT>::Staggered;
411  static const bool compatible = CompatibleTypes</*from=*/SourceValueT, /*to=*/ValueT>::value &&
412  (!staggered || (staggered && VecTraits<SourceValueT>::Size == 3));
413  static const bool round = std::is_floating_point<SourceValueT>::value &&
414  std::is_integral<ValueT>::value;
415  ValueT value;
416  SampleWithRoundingOp<ValueT, SamplerT, AccessorT, round, compatible>::sample(
417  value, accessor, position);
418  return value;
419 }
420 
421 
423 
424 
425 template<typename PointDataGridT, typename SourceGridT, typename TargetValueT,
426  typename SamplerT, typename FilterT, typename InterrupterT>
427 inline void sampleGrid( size_t order,
428  PointDataGridT& points,
429  const SourceGridT& sourceGrid,
430  const Name& targetAttribute,
431  const FilterT& filter,
432  const SamplerT& sampler,
433  InterrupterT* const interrupter,
434  const bool threaded)
435 {
438 
439  // use the name of the grid if no target attribute name supplied
440  Name attribute(targetAttribute);
441  if (targetAttribute.empty()) {
442  attribute = sourceGrid.getName();
443  }
444 
445  // we do not allow sampling onto the "P" attribute
446  if (attribute == "P") {
447  OPENVDB_THROW(RuntimeError, "Cannot sample onto the \"P\" attribute");
448  }
449 
450  auto leaf = points.tree().cbeginLeaf();
451  if (!leaf) return;
452 
453  PointDataSampler<PointDataGridT, SamplerT, FilterT, InterrupterT> pointDataSampler(
454  order, points, sampler, filter, interrupter, threaded);
455 
456  const auto& descriptor = leaf->attributeSet().descriptor();
457  size_t targetIndex = descriptor.find(attribute);
458  const bool attributeExists = targetIndex != AttributeSet::INVALID_POS;
459 
460  if (std::is_same<TargetValueT, DummySampleType>::value) {
461  if (!attributeExists) {
462  // append attribute of source grid value type
463  appendAttribute<typename SourceGridT::ValueType>(points.tree(), attribute);
464  targetIndex = leaf->attributeSet().descriptor().find(attribute);
465  assert(targetIndex != AttributeSet::INVALID_POS);
466 
467  // sample using same type as source grid
468  pointDataSampler.template sample<SourceGridT>(sourceGrid, Index(targetIndex));
469  } else {
470  auto targetIdx = static_cast<Index>(targetIndex);
471  // attempt to explicitly sample using type of existing attribute
472  const Name& targetType = descriptor.valueType(targetIndex);
473  if (targetType == typeNameAsString<Vec3f>()) {
474  pointDataSampler.template sample<SourceGridT, Vec3f>(sourceGrid, targetIdx);
475  } else if (targetType == typeNameAsString<Vec3d>()) {
476  pointDataSampler.template sample<SourceGridT, Vec3d>(sourceGrid, targetIdx);
477  } else if (targetType == typeNameAsString<Vec3i>()) {
478  pointDataSampler.template sample<SourceGridT, Vec3i>(sourceGrid, targetIdx);
479  } else if (targetType == typeNameAsString<int8_t>()) {
480  pointDataSampler.template sample<SourceGridT, int8_t>(sourceGrid, targetIdx);
481  } else if (targetType == typeNameAsString<int16_t>()) {
482  pointDataSampler.template sample<SourceGridT, int16_t>(sourceGrid, targetIdx);
483  } else if (targetType == typeNameAsString<int32_t>()) {
484  pointDataSampler.template sample<SourceGridT, int32_t>(sourceGrid, targetIdx);
485  } else if (targetType == typeNameAsString<int64_t>()) {
486  pointDataSampler.template sample<SourceGridT, int64_t>(sourceGrid, targetIdx);
487  } else if (targetType == typeNameAsString<float>()) {
488  pointDataSampler.template sample<SourceGridT, float>(sourceGrid, targetIdx);
489  } else if (targetType == typeNameAsString<double>()) {
490  pointDataSampler.template sample<SourceGridT, double>(sourceGrid, targetIdx);
491  } else if (targetType == typeNameAsString<bool>()) {
492  pointDataSampler.template sample<SourceGridT, bool>(sourceGrid, targetIdx);
493  } else {
494  std::ostringstream ostr;
495  ostr << "Cannot sample attribute of type - " << targetType;
496  OPENVDB_THROW(TypeError, ostr.str());
497  }
498  }
499  } else {
500  if (!attributeExists) {
501  // append attribute of target value type
502  // (point_sample_internal wrapper disables the ability to use DummySampleType)
503  AppendAttributeOp<PointDataGridT, TargetValueT>::append(points, attribute);
504  targetIndex = leaf->attributeSet().descriptor().find(attribute);
505  assert(targetIndex != AttributeSet::INVALID_POS);
506  }
507  else {
508  const Name targetType = typeNameAsString<TargetValueT>();
509  const Name attributeType = descriptor.valueType(targetIndex);
510  if (targetType != attributeType) {
511  std::ostringstream ostr;
512  ostr << "Requested attribute type " << targetType << " for sampling "
513  << " does not match existing attribute type " << attributeType;
514  OPENVDB_THROW(TypeError, ostr.str());
515  }
516  }
517 
518  // sample using target value type
519  pointDataSampler.template sample<SourceGridT, TargetValueT>(
520  sourceGrid, static_cast<Index>(targetIndex));
521  }
522 }
523 
524 template<typename PointDataGridT, typename SourceGridT, typename FilterT, typename InterrupterT>
525 inline void pointSample(PointDataGridT& points,
526  const SourceGridT& sourceGrid,
527  const Name& targetAttribute,
528  const FilterT& filter,
529  InterrupterT* const interrupter)
530 {
531  SampleWithRounding sampler;
532  sampleGrid(/*order=*/0, points, sourceGrid, targetAttribute, filter, sampler, interrupter);
533 }
534 
535 template<typename PointDataGridT, typename SourceGridT, typename FilterT, typename InterrupterT>
536 inline void boxSample( PointDataGridT& points,
537  const SourceGridT& sourceGrid,
538  const Name& targetAttribute,
539  const FilterT& filter,
540  InterrupterT* const interrupter)
541 {
542  SampleWithRounding sampler;
543  sampleGrid(/*order=*/1, points, sourceGrid, targetAttribute, filter, sampler, interrupter);
544 }
545 
546 template<typename PointDataGridT, typename SourceGridT, typename FilterT, typename InterrupterT>
547 inline void quadraticSample(PointDataGridT& points,
548  const SourceGridT& sourceGrid,
549  const Name& targetAttribute,
550  const FilterT& filter,
551  InterrupterT* const interrupter)
552 {
553  SampleWithRounding sampler;
554  sampleGrid(/*order=*/2, points, sourceGrid, targetAttribute, filter, sampler, interrupter);
555 }
556 
557 
559 
560 
561 } // namespace points
562 } // namespace OPENVDB_VERSION_NAME
563 } // namespace openvdb
564 
565 #endif // OPENVDB_POINTS_POINT_SAMPLE_HAS_BEEN_INCLUDED
Write-able version of AttributeHandle.
Definition: AttributeArray.h:871
Definition: Vec2.h:23
void sample(const SourceGridT &sourceGrid, Index targetIndex)
Definition: PointSample.h:359
#define OPENVDB_THROW(exception, message)
Definition: openvdb/Exceptions.h:74
Definition: AttributeArray.h:800
const char * typeNameAsString< float >()
Definition: openvdb/Types.h:398
std::string Name
Definition: Name.h:17
const char * typeNameAsString< int16_t >()
Definition: openvdb/Types.h:402
PointDataSampler(size_t order, PointDataGridT &points, const SamplerT &sampler, const FilterT &filter, InterrupterT *const interrupter, const bool threaded)
Definition: PointSample.h:206
Definition: Mat4.h:24
A no-op filter that can be used when iterating over all indices.
Definition: IndexIterator.h:50
Definition: openvdb/Types.h:200
Point attribute manipulation in a VDB Point Grid.
This class manages a linear array of pointers to a given tree&#39;s leaf nodes, as well as optional auxil...
Definition: LeafManager.h:84
Definition: openvdb/Types.h:107
Index32 Index
Definition: openvdb/Types.h:50
Definition: PointSample.h:87
void boxSample(PointDataGridT &points, const SourceGridT &sourceGrid, const Name &targetAttribute="", const FilterT &filter=NullFilter(), InterrupterT *const interrupter=nullptr)
Performs tri-linear sampling from a VDB grid onto a VDB Points attribute.
Definition: PointSample.h:536
Vec3< double > Vec3d
Definition: Vec3.h:668
Dummy NOOP interrupter class defining interface.
Definition: NullInterrupter.h:25
bool wasInterrupted(T *i, int percent=-1)
Definition: NullInterrupter.h:49
static void sample(ValueT &, const AccessorT &, const Vec3d &)
Definition: PointSample.h:174
static void append(PointDataGridT &, const Name &)
Definition: PointSample.h:396
Definition: Mat.h:187
Definition: openvdb/Exceptions.h:63
Definition: openvdb/Exceptions.h:13
void quadraticSample(PointDataGridT &points, const SourceGridT &sourceGrid, const Name &targetAttribute="", const FilterT &filter=NullFilter(), InterrupterT *const interrupter=nullptr)
Performs tri-quadratic sampling from a VDB grid onto a VDB Points attribute.
Definition: PointSample.h:547
Definition: openvdb/Exceptions.h:64
static void sample(ValueT &value, const AccessorT &accessor, const Vec3d &position)
Definition: PointSample.h:195
Definition: openvdb/Types.h:335
const char * typeNameAsString< double >()
Definition: openvdb/Types.h:399
const char * typeNameAsString< Vec3i >()
Definition: openvdb/Types.h:412
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
const char * typeNameAsString< Vec3d >()
Definition: openvdb/Types.h:414
float Round(float x)
Return x rounded to the nearest integer.
Definition: Math.h:822
const char * typeNameAsString< bool >()
Definition: openvdb/Types.h:395
const char * typeNameAsString< int64_t >()
Definition: openvdb/Types.h:406
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:116
Definition: PointSample.h:96
void sampleGrid(size_t order, PointDataGridT &points, const SourceGridT &sourceGrid, const Name &targetAttribute, const FilterT &filter=NullFilter(), const SamplerT &sampler=SampleWithRounding(), InterrupterT *const interrupter=nullptr, const bool threaded=true)
Performs sampling and conversion from a VDB grid onto a VDB Points attribute.
Definition: PointSample.h:427
static void append(PointDataGridT &points, const Name &attribute)
Definition: PointSample.h:387
const char * typeNameAsString< int8_t >()
Definition: openvdb/Types.h:400
void pointSample(PointDataGridT &points, const SourceGridT &sourceGrid, const Name &targetAttribute="", const FilterT &filter=NullFilter(), InterrupterT *const interrupter=nullptr)
Performs closest point sampling from a VDB grid onto a VDB Points attribute.
Definition: PointSample.h:525
static void sample(ValueT &value, const AccessorT &accessor, const Vec3d &position)
Definition: PointSample.h:186
const char * typeNameAsString< Vec3f >()
Definition: openvdb/Types.h:413
const char * typeNameAsString< int32_t >()
Definition: openvdb/Types.h:404
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:178
Definition: Transform.h:39