10 #ifndef OPENVDB_POINTS_POINT_SAMPLE_HAS_BEEN_INCLUDED 11 #define OPENVDB_POINTS_POINT_SAMPLE_HAS_BEEN_INCLUDED 20 #include <type_traits> 38 template<
typename PointDataGridT,
typename SourceGridT,
39 typename FilterT = NullFilter,
typename InterrupterT = util::NullInterrupter>
41 const SourceGridT& sourceGrid,
42 const Name& targetAttribute =
"",
43 const FilterT& filter = NullFilter(),
44 InterrupterT*
const interrupter =
nullptr);
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);
74 template<
typename PointDataGridT,
typename SourceGridT,
75 typename FilterT = NullFilter,
typename InterrupterT = util::NullInterrupter>
77 const SourceGridT& sourceGrid,
78 const Name& targetAttribute =
"",
79 const FilterT& filter = NullFilter(),
80 InterrupterT*
const interrupter =
nullptr);
89 template<
typename ValueT,
typename SamplerT,
typename AccessorT>
90 inline ValueT sample(
const AccessorT& accessor,
const Vec3d& position)
const;
112 template<
typename PointDataGridT,
typename SourceGridT,
typename TargetValueT =
DummySampleType,
116 PointDataGridT& points,
117 const SourceGridT& sourceGrid,
118 const Name& targetAttribute,
121 InterrupterT*
const interrupter =
nullptr,
122 const bool threaded =
true);
128 namespace point_sample_internal {
131 template<
typename FromType,
typename ToType>
132 struct CompatibleTypes {
enum { value = std::is_constructible<ToType, FromType>::value }; };
136 T, T> {
enum { value =
true }; };
138 T, math::
Vec2<T>> {
enum { value =
true }; };
140 T, math::
Vec3<T>> {
enum { value =
true }; };
142 T, math::
Vec4<T>> {
enum { value =
true }; };
161 static const bool Staggered =
false;
163 template <
size_t T0,
bool T1>
struct SamplerTraits<tools::Sampler<T0, T1>> {
164 static const bool Staggered = T1;
169 template <
typename ValueT,
typename SamplerT,
typename AccessorT,
bool Round,
bool Compatible = false>
172 static inline void sample(ValueT&,
const AccessorT&,
const Vec3d&)
174 std::ostringstream ostr;
175 ostr <<
"Cannot sample a " << typeNameAsString<typename AccessorT::ValueType>()
176 <<
" grid on to a " << typeNameAsString<ValueT>() <<
" attribute";
181 template <
typename ValueT,
typename SamplerT,
typename AccessorT>
184 static inline void sample(ValueT& value,
const AccessorT& accessor,
const Vec3d& position)
186 value = ValueT(
math::Round(SamplerT::sample(accessor, position)));
190 template <
typename ValueT,
typename SamplerT,
typename AccessorT>
193 static inline void sample(ValueT& value,
const AccessorT& accessor,
const Vec3d& position)
195 value = ValueT(SamplerT::sample(accessor, position));
200 template <
typename Po
intDataGr
idT,
typename SamplerT,
typename FilterT,
typename InterrupterT>
205 PointDataGridT& points,
206 const SamplerT& sampler,
207 const FilterT& filter,
208 InterrupterT*
const interrupter,
214 , mInterrupter(interrupter)
215 , mThreaded(threaded) { }
219 struct AlignedTransform
221 inline Vec3d transform(
const Vec3d& position)
const {
return position; }
225 struct NonAlignedTransform
229 , mTarget(target) { }
231 inline Vec3d transform(
const Vec3d& position)
const 233 return mSource.worldToIndex(mTarget.indexToWorld(position));
237 const math::Transform& mSource;
238 const math::Transform& mTarget;
242 template <
typename ValueT,
typename SourceGr
idT,
typename Gr
idSamplerT>
243 struct SamplerWrapper
245 using ValueType = ValueT;
246 using SourceAccessorT =
typename SourceGridT::ConstAccessor;
248 SamplerWrapper(
const SourceGridT& sourceGrid,
const SamplerT& sampler)
249 : mAccessor(sourceGrid.getConstAccessor())
250 , mSampler(sampler) { }
254 SamplerWrapper(
const SamplerWrapper& other)
255 : mAccessor(other.mAccessor.tree())
256 , mSampler(other.mSampler) { }
258 inline ValueT sample(
const Vec3d& position)
const {
259 return mSampler.template sample<ValueT, GridSamplerT, SourceAccessorT>(
260 mAccessor, position);
264 SourceAccessorT mAccessor;
265 const SamplerT& mSampler;
268 template <
typename SamplerWrapperT,
typename TransformerT>
269 inline void doSample(
const SamplerWrapperT& sampleWrapper,
const Index targetIndex,
270 const TransformerT& transformer)
272 using PointDataTreeT =
typename PointDataGridT::TreeType;
273 using LeafT =
typename PointDataTreeT::LeafNodeType;
274 using LeafManagerT =
typename tree::LeafManager<PointDataTreeT>;
276 const auto& filter(mFilter);
277 const auto& interrupter(mInterrupter);
279 auto sampleLambda = [targetIndex, &sampleWrapper, &transformer, &filter, &interrupter](
280 LeafT& leaf,
size_t )
282 using TargetHandleT = AttributeWriteHandle<typename SamplerWrapperT::ValueType>;
285 tbb::task::self().cancel_group_execution();
289 SamplerWrapperT newSampleWrapper(sampleWrapper);
290 auto positionHandle = AttributeHandle<Vec3f>::create(leaf.constAttributeArray(
"P"));
291 auto targetHandle = TargetHandleT::create(leaf.attributeArray(targetIndex));
292 for (
auto iter = leaf.beginIndexOn(filter); iter; ++iter) {
293 const Vec3d position = transformer.transform(
294 positionHandle->get(*iter) + iter.getCoord().asVec3d());
295 targetHandle->set(*iter, newSampleWrapper.sample(position));
299 LeafManagerT leafManager(mPoints.tree());
301 if (mInterrupter) mInterrupter->start();
303 leafManager.foreach(sampleLambda, mThreaded);
305 if (mInterrupter) mInterrupter->end();
308 template <
typename SourceGr
idT,
typename SamplerWrapperT>
309 inline void resolveTransform(
const SourceGridT& sourceGrid,
const SamplerWrapperT& sampleWrapper,
310 const Index targetIndex)
312 const auto& sourceTransform = sourceGrid.constTransform();
313 const auto& pointsTransform = mPoints.constTransform();
315 if (sourceTransform == pointsTransform) {
316 AlignedTransform transformer;
317 doSample(sampleWrapper, targetIndex, transformer);
319 NonAlignedTransform transformer(sourceTransform, pointsTransform);
320 doSample(sampleWrapper, targetIndex, transformer);
324 template <
typename SourceGr
idT,
typename TargetValueT,
size_t Order>
325 inline void resolveStaggered(
const SourceGridT& sourceGrid,
const Index targetIndex)
327 using SamplerWrapperT = SamplerWrapper<TargetValueT, SourceGridT, tools::Sampler<Order, false>>;
328 using StaggeredSamplerWrapperT = SamplerWrapper<TargetValueT, SourceGridT, tools::Sampler<Order, true>>;
330 using SourceValueType =
typename SourceGridT::ValueType;
332 StaggeredSamplerWrapperT sampleWrapper(sourceGrid, mSampler);
333 resolveTransform(sourceGrid, sampleWrapper, targetIndex);
335 SamplerWrapperT sampleWrapper(sourceGrid, mSampler);
336 resolveTransform(sourceGrid, sampleWrapper, targetIndex);
341 template <
typename SourceGr
idT,
typename TargetValueT =
typename SourceGr
idT::ValueType>
342 inline void sample(
const SourceGridT& sourceGrid,
Index targetIndex)
345 resolveStaggered<SourceGridT, TargetValueT, 0>(sourceGrid, targetIndex);
346 }
else if (mOrder == 1) {
347 resolveStaggered<SourceGridT, TargetValueT, 1>(sourceGrid, targetIndex);
348 }
else if (mOrder == 2) {
349 resolveStaggered<SourceGridT, TargetValueT, 2>(sourceGrid, targetIndex);
355 PointDataGridT& mPoints;
356 const SamplerT& mSampler;
357 const FilterT& mFilter;
358 InterrupterT*
const mInterrupter;
359 const bool mThreaded;
363 template <
typename Po
intDataGr
idT,
typename ValueT>
366 static void append(PointDataGridT& points,
const Name& attribute)
368 appendAttribute<ValueT>(points.tree(), attribute);
372 template <
typename Po
intDataGr
idT>
384 template<
typename ValueT,
typename SamplerT,
typename AccessorT>
385 ValueT SampleWithRounding::sample(
const AccessorT& accessor,
const Vec3d& position)
const 387 using namespace point_sample_internal;
388 using SourceValueT =
typename AccessorT::ValueType;
389 static const bool staggered = SamplerTraits<SamplerT>::Staggered;
390 static const bool compatible = CompatibleTypes<SourceValueT, ValueT>::value &&
392 static const bool round = std::is_floating_point<SourceValueT>::value &&
393 std::is_integral<ValueT>::value;
395 SampleWithRoundingOp<ValueT, SamplerT, AccessorT, round, compatible>::sample(
396 value, accessor, position);
404 template<
typename PointDataGridT,
typename SourceGridT,
typename TargetValueT,
405 typename SamplerT,
typename FilterT,
typename InterrupterT>
407 PointDataGridT& points,
408 const SourceGridT& sourceGrid,
409 const Name& targetAttribute,
410 const FilterT& filter,
411 const SamplerT& sampler,
412 InterrupterT*
const interrupter,
419 Name attribute(targetAttribute);
420 if (targetAttribute.empty()) {
421 attribute = sourceGrid.getName();
425 if (attribute ==
"P") {
429 auto leaf = points.tree().cbeginLeaf();
432 PointDataSampler<PointDataGridT, SamplerT, FilterT, InterrupterT> pointDataSampler(
433 order, points, sampler, filter, interrupter, threaded);
435 const auto& descriptor = leaf->attributeSet().descriptor();
436 size_t targetIndex = descriptor.find(attribute);
437 const bool attributeExists = targetIndex != AttributeSet::INVALID_POS;
439 if (std::is_same<TargetValueT, DummySampleType>::value) {
440 if (!attributeExists) {
442 appendAttribute<typename SourceGridT::ValueType>(points.tree(), attribute);
443 targetIndex = leaf->attributeSet().descriptor().find(attribute);
444 assert(targetIndex != AttributeSet::INVALID_POS);
447 pointDataSampler.template sample<SourceGridT>(sourceGrid,
Index(targetIndex));
449 auto targetIdx =
static_cast<Index>(targetIndex);
451 const Name& targetType = descriptor.valueType(targetIndex);
453 pointDataSampler.template sample<SourceGridT, Vec3f>(sourceGrid, targetIdx);
455 pointDataSampler.template sample<SourceGridT, Vec3d>(sourceGrid, targetIdx);
457 pointDataSampler.template sample<SourceGridT, Vec3i>(sourceGrid, targetIdx);
459 pointDataSampler.template sample<SourceGridT, int8_t>(sourceGrid, targetIdx);
461 pointDataSampler.template sample<SourceGridT, int16_t>(sourceGrid, targetIdx);
463 pointDataSampler.template sample<SourceGridT, int32_t>(sourceGrid, targetIdx);
465 pointDataSampler.template sample<SourceGridT, int64_t>(sourceGrid, targetIdx);
467 pointDataSampler.template sample<SourceGridT, float>(sourceGrid, targetIdx);
469 pointDataSampler.template sample<SourceGridT, double>(sourceGrid, targetIdx);
471 pointDataSampler.template sample<SourceGridT, bool>(sourceGrid, targetIdx);
473 std::ostringstream ostr;
474 ostr <<
"Cannot sample attribute of type - " << targetType;
479 if (!attributeExists) {
482 AppendAttributeOp<PointDataGridT, TargetValueT>::append(points, attribute);
483 targetIndex = leaf->attributeSet().descriptor().find(attribute);
484 assert(targetIndex != AttributeSet::INVALID_POS);
487 const Name targetType = typeNameAsString<TargetValueT>();
488 const Name attributeType = descriptor.valueType(targetIndex);
489 if (targetType != attributeType) {
490 std::ostringstream ostr;
491 ostr <<
"Requested attribute type " << targetType <<
" for sampling " 492 <<
" does not match existing attribute type " << attributeType;
498 pointDataSampler.template sample<SourceGridT, TargetValueT>(
499 sourceGrid,
static_cast<Index>(targetIndex));
503 template<
typename Po
intDataGr
idT,
typename SourceGr
idT,
typename FilterT,
typename InterrupterT>
505 const SourceGridT& sourceGrid,
506 const Name& targetAttribute,
507 const FilterT& filter,
508 InterrupterT*
const interrupter)
511 sampleGrid(0, points, sourceGrid, targetAttribute, filter, sampler, interrupter);
514 template<
typename Po
intDataGr
idT,
typename SourceGr
idT,
typename FilterT,
typename InterrupterT>
516 const SourceGridT& sourceGrid,
517 const Name& targetAttribute,
518 const FilterT& filter,
519 InterrupterT*
const interrupter)
522 sampleGrid(1, points, sourceGrid, targetAttribute, filter, sampler, interrupter);
525 template<
typename Po
intDataGr
idT,
typename SourceGr
idT,
typename FilterT,
typename InterrupterT>
527 const SourceGridT& sourceGrid,
528 const Name& targetAttribute,
529 const FilterT& filter,
530 InterrupterT*
const interrupter)
533 sampleGrid(2, points, sourceGrid, targetAttribute, filter, sampler, interrupter);
544 #endif // OPENVDB_POINTS_POINT_SAMPLE_HAS_BEEN_INCLUDED A no-op filter that can be used when iterating over all indices.
Definition: IndexIterator.h:50
const char * typeNameAsString< float >()
Definition: Types.h:519
static const int Size
Definition: Types.h:184
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:526
Vec3< double > Vec3d
Definition: Vec3.h:662
Definition: PointSample.h:364
const char * typeNameAsString< Vec3d >()
Definition: Types.h:535
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:82
std::string Name
Definition: Name.h:17
static void append(PointDataGridT &, const Name &)
Definition: PointSample.h:375
Definition: PointSample.h:132
static void append(PointDataGridT &points, const Name &attribute)
Definition: PointSample.h:366
float Round(float x)
Return x rounded to the nearest integer.
Definition: Math.h:766
Definition: PointSample.h:170
Point attribute manipulation in a VDB Point Grid.
Definition: PointSample.h:96
const char * typeNameAsString< int8_t >()
Definition: Types.h:521
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:406
const char * typeNameAsString< Vec3i >()
Definition: Types.h:533
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:504
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:102
static void sample(ValueT &value, const AccessorT &accessor, const Vec3d &position)
Definition: PointSample.h:184
Definition: Exceptions.h:13
Dummy NOOP interrupter class defining interface.
Definition: NullInterrupter.h:25
bool wasInterrupted(T *i, int percent=-1)
Definition: NullInterrupter.h:49
const char * typeNameAsString< Vec3f >()
Definition: Types.h:534
const char * typeNameAsString< double >()
Definition: Types.h:520
Definition: PointSample.h:201
const char * typeNameAsString< int32_t >()
Definition: Types.h:525
Definition: Exceptions.h:63
Index32 Index
Definition: Types.h:31
PointDataSampler(size_t order, PointDataGridT &points, const SamplerT &sampler, const FilterT &filter, InterrupterT *const interrupter, const bool threaded)
Definition: PointSample.h:204
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
Definition: PointSample.h:160
const char * typeNameAsString< bool >()
Definition: Types.h:516
static void sample(ValueT &, const AccessorT &, const Vec3d &)
Definition: PointSample.h:172
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:154
void sample(const SourceGridT &sourceGrid, Index targetIndex)
Definition: PointSample.h:342
Definition: PointSample.h:87
static void sample(ValueT &value, const AccessorT &accessor, const Vec3d &position)
Definition: PointSample.h:193
const char * typeNameAsString< int16_t >()
Definition: Types.h:523
Definition: Exceptions.h:64
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:515
const char * typeNameAsString< int64_t >()
Definition: Types.h:527