37 #ifndef OPENVDB_POINTS_POINT_SAMPLE_HAS_BEEN_INCLUDED 38 #define OPENVDB_POINTS_POINT_SAMPLE_HAS_BEEN_INCLUDED 47 #include <type_traits> 65 template<
typename PointDataGridT,
typename SourceGridT,
66 typename FilterT = NullFilter,
typename InterrupterT = util::NullInterrupter>
68 const SourceGridT& sourceGrid,
69 const Name& targetAttribute =
"",
70 const FilterT& filter = NullFilter(),
71 InterrupterT*
const interrupter =
nullptr);
83 template<
typename PointDataGridT,
typename SourceGridT,
84 typename FilterT = NullFilter,
typename InterrupterT = util::NullInterrupter>
85 inline void boxSample( PointDataGridT& points,
86 const SourceGridT& sourceGrid,
87 const Name& targetAttribute =
"",
88 const FilterT& filter = NullFilter(),
89 InterrupterT*
const interrupter =
nullptr);
101 template<
typename PointDataGridT,
typename SourceGridT,
102 typename FilterT = NullFilter,
typename InterrupterT = util::NullInterrupter>
104 const SourceGridT& sourceGrid,
105 const Name& targetAttribute =
"",
106 const FilterT& filter = NullFilter(),
107 InterrupterT*
const interrupter =
nullptr);
116 template<
typename ValueT,
typename SamplerT,
typename AccessorT>
117 inline ValueT sample(
const AccessorT& accessor,
const Vec3d& position)
const;
139 template<
typename PointDataGridT,
typename SourceGridT,
typename TargetValueT =
DummySampleType,
143 PointDataGridT& points,
144 const SourceGridT& sourceGrid,
145 const Name& targetAttribute,
148 InterrupterT*
const interrupter =
nullptr,
149 const bool threaded =
true);
155 namespace point_sample_internal {
158 template<
typename FromType,
typename ToType>
159 struct CompatibleTypes {
enum { value = std::is_constructible<ToType, FromType>::value }; };
163 T, T> {
enum { value =
true }; };
165 T, math::
Vec2<T>> {
enum { value =
true }; };
167 T, math::
Vec3<T>> {
enum { value =
true }; };
169 T, math::
Vec4<T>> {
enum { value =
true }; };
188 static const bool Staggered =
false;
190 template <
size_t T0,
bool T1>
struct SamplerTraits<tools::Sampler<T0, T1>> {
191 static const bool Staggered = T1;
196 template <
typename ValueT,
typename SamplerT,
typename AccessorT,
bool Round,
bool Compatible = false>
199 static inline void sample(ValueT&,
const AccessorT&,
const Vec3d&)
201 std::ostringstream ostr;
202 ostr <<
"Cannot sample a " << typeNameAsString<typename AccessorT::ValueType>()
203 <<
" grid on to a " << typeNameAsString<ValueT>() <<
" attribute";
208 template <
typename ValueT,
typename SamplerT,
typename AccessorT>
211 static inline void sample(ValueT& value,
const AccessorT& accessor,
const Vec3d& position)
213 value = ValueT(
math::Round(SamplerT::sample(accessor, position)));
217 template <
typename ValueT,
typename SamplerT,
typename AccessorT>
220 static inline void sample(ValueT& value,
const AccessorT& accessor,
const Vec3d& position)
222 value = ValueT(SamplerT::sample(accessor, position));
227 template <
typename Po
intDataGr
idT,
typename SamplerT,
typename FilterT,
typename InterrupterT>
232 PointDataGridT& points,
233 const SamplerT& sampler,
234 const FilterT& filter,
235 InterrupterT*
const interrupter,
241 , mInterrupter(interrupter)
242 , mThreaded(threaded) { }
246 struct AlignedTransform
248 inline Vec3d transform(
const Vec3d& position)
const {
return position; }
252 struct NonAlignedTransform
256 , mTarget(target) { }
258 inline Vec3d transform(
const Vec3d& position)
const 260 return mSource.worldToIndex(mTarget.indexToWorld(position));
264 const math::Transform& mSource;
265 const math::Transform& mTarget;
269 template <
typename ValueT,
typename SourceGr
idT,
typename Gr
idSamplerT>
270 struct SamplerWrapper
272 using ValueType = ValueT;
273 using SourceAccessorT =
typename SourceGridT::ConstAccessor;
275 SamplerWrapper(
const SourceGridT& sourceGrid,
const SamplerT& sampler)
276 : mAccessor(sourceGrid.getConstAccessor())
277 , mSampler(sampler) { }
281 SamplerWrapper(
const SamplerWrapper& other)
282 : mAccessor(other.mAccessor.tree())
283 , mSampler(other.mSampler) { }
285 inline ValueT sample(
const Vec3d& position)
const {
286 return mSampler.template sample<ValueT, GridSamplerT, SourceAccessorT>(
287 mAccessor, position);
291 SourceAccessorT mAccessor;
292 const SamplerT& mSampler;
295 template <
typename SamplerWrapperT,
typename TransformerT>
296 inline void doSample(
const SamplerWrapperT& sampleWrapper,
const Index targetIndex,
297 const TransformerT& transformer)
299 using PointDataTreeT =
typename PointDataGridT::TreeType;
300 using LeafT =
typename PointDataTreeT::LeafNodeType;
301 using LeafManagerT =
typename tree::LeafManager<PointDataTreeT>;
303 const auto& filter(mFilter);
304 const auto& interrupter(mInterrupter);
306 auto sampleLambda = [targetIndex, &sampleWrapper, &transformer, &filter, &interrupter](
307 LeafT& leaf,
size_t )
309 using TargetHandleT = AttributeWriteHandle<typename SamplerWrapperT::ValueType>;
312 tbb::task::self().cancel_group_execution();
316 SamplerWrapperT newSampleWrapper(sampleWrapper);
317 auto positionHandle = AttributeHandle<Vec3f>::create(leaf.constAttributeArray(
"P"));
318 auto targetHandle = TargetHandleT::create(leaf.attributeArray(targetIndex));
319 for (
auto iter = leaf.beginIndexOn(filter); iter; ++iter) {
320 const Vec3d position = transformer.transform(
321 positionHandle->get(*iter) + iter.getCoord().asVec3d());
322 targetHandle->set(*iter, newSampleWrapper.sample(position));
326 LeafManagerT leafManager(mPoints.tree());
328 if (mInterrupter) mInterrupter->start();
330 leafManager.foreach(sampleLambda, mThreaded);
332 if (mInterrupter) mInterrupter->end();
335 template <
typename SourceGr
idT,
typename SamplerWrapperT>
336 inline void resolveTransform(
const SourceGridT& sourceGrid,
const SamplerWrapperT& sampleWrapper,
337 const Index targetIndex)
339 const auto& sourceTransform = sourceGrid.constTransform();
340 const auto& pointsTransform = mPoints.constTransform();
342 if (sourceTransform == pointsTransform) {
343 AlignedTransform transformer;
344 doSample(sampleWrapper, targetIndex, transformer);
346 NonAlignedTransform transformer(sourceTransform, pointsTransform);
347 doSample(sampleWrapper, targetIndex, transformer);
351 template <
typename SourceGr
idT,
typename TargetValueT,
size_t Order>
352 inline void resolveStaggered(
const SourceGridT& sourceGrid,
const Index targetIndex)
354 using SamplerWrapperT = SamplerWrapper<TargetValueT, SourceGridT, tools::Sampler<Order, false>>;
355 using StaggeredSamplerWrapperT = SamplerWrapper<TargetValueT, SourceGridT, tools::Sampler<Order, true>>;
357 using SourceValueType =
typename SourceGridT::ValueType;
359 StaggeredSamplerWrapperT sampleWrapper(sourceGrid, mSampler);
360 resolveTransform(sourceGrid, sampleWrapper, targetIndex);
362 SamplerWrapperT sampleWrapper(sourceGrid, mSampler);
363 resolveTransform(sourceGrid, sampleWrapper, targetIndex);
368 template <
typename SourceGr
idT,
typename TargetValueT =
typename SourceGr
idT::ValueType>
369 inline void sample(
const SourceGridT& sourceGrid,
Index targetIndex)
372 resolveStaggered<SourceGridT, TargetValueT, 0>(sourceGrid, targetIndex);
373 }
else if (mOrder == 1) {
374 resolveStaggered<SourceGridT, TargetValueT, 1>(sourceGrid, targetIndex);
375 }
else if (mOrder == 2) {
376 resolveStaggered<SourceGridT, TargetValueT, 2>(sourceGrid, targetIndex);
382 PointDataGridT& mPoints;
383 const SamplerT& mSampler;
384 const FilterT& mFilter;
385 InterrupterT*
const mInterrupter;
386 const bool mThreaded;
390 template <
typename Po
intDataGr
idT,
typename ValueT>
393 static void append(PointDataGridT& points,
const Name& attribute)
395 appendAttribute<ValueT>(points.tree(), attribute);
399 template <
typename Po
intDataGr
idT>
411 template<
typename ValueT,
typename SamplerT,
typename AccessorT>
412 ValueT SampleWithRounding::sample(
const AccessorT& accessor,
const Vec3d& position)
const 414 using namespace point_sample_internal;
415 using SourceValueT =
typename AccessorT::ValueType;
416 static const bool staggered = SamplerTraits<SamplerT>::Staggered;
417 static const bool compatible = CompatibleTypes<SourceValueT, ValueT>::value &&
419 static const bool round = std::is_floating_point<SourceValueT>::value &&
420 std::is_integral<ValueT>::value;
422 SampleWithRoundingOp<ValueT, SamplerT, AccessorT, round, compatible>::sample(
423 value, accessor, position);
431 template<
typename PointDataGridT,
typename SourceGridT,
typename TargetValueT,
432 typename SamplerT,
typename FilterT,
typename InterrupterT>
434 PointDataGridT& points,
435 const SourceGridT& sourceGrid,
436 const Name& targetAttribute,
437 const FilterT& filter,
438 const SamplerT& sampler,
439 InterrupterT*
const interrupter,
446 Name attribute(targetAttribute);
447 if (targetAttribute.empty()) {
448 attribute = sourceGrid.getName();
452 if (attribute ==
"P") {
456 auto leaf = points.tree().cbeginLeaf();
459 PointDataSampler<PointDataGridT, SamplerT, FilterT, InterrupterT> pointDataSampler(
460 order, points, sampler, filter, interrupter, threaded);
462 const auto& descriptor = leaf->attributeSet().descriptor();
463 size_t targetIndex = descriptor.find(attribute);
464 const bool attributeExists = targetIndex != AttributeSet::INVALID_POS;
466 if (std::is_same<TargetValueT, DummySampleType>::value) {
467 if (!attributeExists) {
469 appendAttribute<typename SourceGridT::ValueType>(points.tree(), attribute);
470 targetIndex = leaf->attributeSet().descriptor().find(attribute);
471 assert(targetIndex != AttributeSet::INVALID_POS);
474 pointDataSampler.template sample<SourceGridT>(sourceGrid,
Index(targetIndex));
476 auto targetIdx = static_cast<Index>(targetIndex);
478 const Name& targetType = descriptor.valueType(targetIndex);
480 pointDataSampler.template sample<SourceGridT, Vec3f>(sourceGrid, targetIdx);
482 pointDataSampler.template sample<SourceGridT, Vec3d>(sourceGrid, targetIdx);
484 pointDataSampler.template sample<SourceGridT, Vec3i>(sourceGrid, targetIdx);
486 pointDataSampler.template sample<SourceGridT, int16_t>(sourceGrid, targetIdx);
488 pointDataSampler.template sample<SourceGridT, int32_t>(sourceGrid, targetIdx);
490 pointDataSampler.template sample<SourceGridT, int64_t>(sourceGrid, targetIdx);
492 pointDataSampler.template sample<SourceGridT, float>(sourceGrid, targetIdx);
494 pointDataSampler.template sample<SourceGridT, double>(sourceGrid, targetIdx);
496 pointDataSampler.template sample<SourceGridT, bool>(sourceGrid, targetIdx);
498 std::ostringstream ostr;
499 ostr <<
"Cannot sample attribute of type - " << targetType;
504 if (!attributeExists) {
507 AppendAttributeOp<PointDataGridT, TargetValueT>::append(points, attribute);
508 targetIndex = leaf->attributeSet().descriptor().find(attribute);
509 assert(targetIndex != AttributeSet::INVALID_POS);
512 const Name targetType = typeNameAsString<TargetValueT>();
513 const Name attributeType = descriptor.valueType(targetIndex);
514 if (targetType != attributeType) {
515 std::ostringstream ostr;
516 ostr <<
"Requested attribute type " << targetType <<
" for sampling " 517 <<
" does not match existing attribute type " << attributeType;
523 pointDataSampler.template sample<SourceGridT, TargetValueT>(
524 sourceGrid, static_cast<Index>(targetIndex));
528 template<
typename Po
intDataGr
idT,
typename SourceGr
idT,
typename FilterT,
typename InterrupterT>
530 const SourceGridT& sourceGrid,
531 const Name& targetAttribute,
532 const FilterT& filter,
533 InterrupterT*
const interrupter)
536 sampleGrid(0, points, sourceGrid, targetAttribute, filter, sampler, interrupter);
539 template<
typename Po
intDataGr
idT,
typename SourceGr
idT,
typename FilterT,
typename InterrupterT>
541 const SourceGridT& sourceGrid,
542 const Name& targetAttribute,
543 const FilterT& filter,
544 InterrupterT*
const interrupter)
547 sampleGrid(1, points, sourceGrid, targetAttribute, filter, sampler, interrupter);
550 template<
typename Po
intDataGr
idT,
typename SourceGr
idT,
typename FilterT,
typename InterrupterT>
552 const SourceGridT& sourceGrid,
553 const Name& targetAttribute,
554 const FilterT& filter,
555 InterrupterT*
const interrupter)
558 sampleGrid(2, points, sourceGrid, targetAttribute, filter, sampler, interrupter);
569 #endif // OPENVDB_POINTS_POINT_SAMPLE_HAS_BEEN_INCLUDED const char * typeNameAsString< int64_t >()
Definition: Types.h:349
static void sample(ValueT &value, const AccessorT &accessor, const Vec3d &position)
Definition: PointSample.h:211
static void append(PointDataGridT &points, const Name &attribute)
Definition: PointSample.h:393
const char * typeNameAsString< Vec3i >()
Definition: Types.h:355
Definition: Exceptions.h:90
float Round(float x)
Return x rounded to the nearest integer.
Definition: Math.h:773
A no-op filter that can be used when iterating over all indices.
Definition: IndexIterator.h:77
static const int Size
Definition: Types.h:217
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:529
Index32 Index
Definition: Types.h:61
const char * typeNameAsString< double >()
Definition: Types.h:343
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:109
Vec3< double > Vec3d
Definition: Vec3.h:679
Definition: PointSample.h:391
bool wasInterrupted(T *i, int percent=-1)
Definition: NullInterrupter.h:76
static void append(PointDataGridT &, const Name &)
Definition: PointSample.h:402
void sample(const SourceGridT &sourceGrid, Index targetIndex)
Definition: PointSample.h:369
static void sample(ValueT &value, const AccessorT &accessor, const Vec3d &position)
Definition: PointSample.h:220
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:540
const char * typeNameAsString< int32_t >()
Definition: Types.h:347
Point attribute manipulation in a VDB Point Grid.
Definition: Exceptions.h:91
PointDataSampler(size_t order, PointDataGridT &points, const SamplerT &sampler, const FilterT &filter, InterrupterT *const interrupter, const bool threaded)
Definition: PointSample.h:231
Definition: PointSample.h:123
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:136
const char * typeNameAsString< bool >()
Definition: Types.h:339
Definition: Exceptions.h:40
Definition: PointSample.h:187
Dummy NOOP interrupter class defining interface.
Definition: NullInterrupter.h:52
const char * typeNameAsString< Vec3d >()
Definition: Types.h:357
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:551
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
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:433
const char * typeNameAsString< float >()
Definition: Types.h:342
Definition: PointSample.h:159
Definition: PointSample.h:114
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:188
Definition: PointSample.h:228
static void sample(ValueT &, const AccessorT &, const Vec3d &)
Definition: PointSample.h:199
const char * typeNameAsString< int16_t >()
Definition: Types.h:345
std::string Name
Definition: Name.h:44
const char * typeNameAsString< Vec3f >()
Definition: Types.h:356
Definition: PointSample.h:197