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