9#ifndef OPENVDB_POINTS_POINT_SAMPLE_IMPL_HAS_BEEN_INCLUDED 
   10#define OPENVDB_POINTS_POINT_SAMPLE_IMPL_HAS_BEEN_INCLUDED 
   19namespace point_sample_internal {
 
   22template<
typename FromType, 
typename ToType>
 
   23struct CompatibleTypes { 
enum { value = std::is_constructible<ToType, FromType>::value }; };
 
   26template<
typename T> 
struct CompatibleTypes<
 
   27    T, T> {                             
enum { value = 
true }; };
 
   28template<
typename T> 
struct CompatibleTypes<
 
   29    T, math::Vec2<T>> {                 
enum { value = 
true }; };
 
   30template<
typename T> 
struct CompatibleTypes<
 
   31    T, math::Vec3<T>> {                 
enum { value = 
true }; };
 
   32template<
typename T> 
struct CompatibleTypes<
 
   33    T, math::Vec4<T>> {                 
enum { value = 
true }; };
 
   34template<
typename T> 
struct CompatibleTypes<
 
   35    math::Vec2<T>, math::Vec2<T>> {     
enum { value = 
true }; };
 
   36template<
typename T> 
struct CompatibleTypes<
 
   37    math::Vec3<T>, math::Vec3<T>> {     
enum { value = 
true }; };
 
   38template<
typename T> 
struct CompatibleTypes<
 
   39    math::Vec4<T>, math::Vec4<T>> {     
enum { value = 
true }; };
 
   40template<
typename T0, 
typename T1> 
struct CompatibleTypes<
 
   41    math::Vec2<T0>, math::Vec2<T1>> {   
enum { value = CompatibleTypes<T0, T1>::value }; };
 
   42template<
typename T0, 
typename T1> 
struct CompatibleTypes<
 
   43    math::Vec3<T0>, math::Vec3<T1>> {   
enum { value = CompatibleTypes<T0, T1>::value }; };
 
   44template<
typename T0, 
typename T1> 
struct CompatibleTypes<
 
   45    math::Vec4<T0>, math::Vec4<T1>> {   
enum { value = CompatibleTypes<T0, T1>::value }; };
 
   46template<
typename T> 
struct CompatibleTypes<
 
   47    ValueMask, T> {                     
enum { value = CompatibleTypes<bool, T>::value }; };
 
   51template <
typename T> 
struct SamplerTraits {
 
   52    static const size_t Order = 0;
 
   55template <
size_t T0, 
bool T1> 
struct SamplerTraits<tools::Sampler<T0, T1>> {
 
   56    static const size_t Order = T0;
 
   62template <
typename ValueT, 
typename SamplerT, 
typename AccessorT, 
bool Round, 
bool Compatible = false>
 
   63struct SampleWithRoundingOp
 
   65    static inline void sample(ValueT&, 
const AccessorT&, 
const Vec3d&)
 
   67        std::ostringstream ostr;
 
   68        ostr << 
"Cannot sample a " << typeNameAsString<typename AccessorT::ValueType>()
 
   69            << 
" grid on to a " << typeNameAsString<ValueT>() << 
" attribute";
 
   74template <
typename ValueT, 
typename SamplerT, 
typename AccessorT>
 
   75struct SampleWithRoundingOp<ValueT, SamplerT, AccessorT, true, true>
 
   77    static inline void sample(ValueT& value, 
const AccessorT& accessor, 
const Vec3d& position)
 
   79        value = ValueT(math::Round(SamplerT::sample(accessor, position)));
 
   83template <
typename ValueT, 
typename SamplerT, 
typename AccessorT>
 
   84struct SampleWithRoundingOp<ValueT, SamplerT, AccessorT, false, true>
 
   86    static inline void sample(ValueT& value, 
const AccessorT& accessor, 
const Vec3d& position)
 
   88        value = ValueT(SamplerT::sample(accessor, position));
 
   93template <
typename Po
intDataGr
idT, 
typename SamplerT, 
typename FilterT, 
typename InterrupterT>
 
   97    PointDataSampler(
size_t order,
 
   98                     PointDataGridT& points,
 
   99                     const SamplerT& sampler,
 
  100                     const FilterT& filter,
 
  101                     InterrupterT* 
const interrupter,
 
  107        , mInterrupter(interrupter)
 
  112    struct AlignedTransform
 
  114        inline Vec3d transform(
const Vec3d& position)
 const { 
return position; }
 
  118    struct NonAlignedTransform
 
  120        NonAlignedTransform(
const math::Transform& source, 
const math::Transform& target)
 
  122            , mTarget(target) { }
 
  124        inline Vec3d transform(
const Vec3d& position)
 const 
  126            return mSource.worldToIndex(mTarget.indexToWorld(position));
 
  130        const math::Transform& mSource;
 
  131        const math::Transform& mTarget;
 
  135    template <
typename ValueT, 
typename SourceGr
idT, 
typename Gr
idSamplerT>
 
  136    struct SamplerWrapper
 
  138        using ValueType = ValueT;
 
  139        using SourceValueType = 
typename SourceGridT::ValueType;
 
  140        using SourceAccessorT = 
typename SourceGridT::ConstAccessor;
 
  143        static const bool SourceIsBool = std::is_same<SourceValueType, bool>::value ||
 
  144            std::is_same<SourceValueType, ValueMask>::value;
 
  145        static const bool OrderIsZero = SamplerTraits<GridSamplerT>::Order == 0;
 
  146        static const bool IsValid = !SourceIsBool || OrderIsZero;
 
  148        SamplerWrapper(
const SourceGridT& sourceGrid, 
const SamplerT& sampler)
 
  149            : mAccessor(sourceGrid.getConstAccessor())
 
  150            , mSampler(sampler) { }
 
  154        SamplerWrapper(
const SamplerWrapper& other)
 
  155            : mAccessor(other.mAccessor.tree())
 
  156            , mSampler(other.mSampler) { }
 
  158        template <
bool IsVal
idT = IsVal
id>
 
  159        inline typename std::enable_if<IsValidT, ValueT>::type
 
  160        sample(
const Vec3d& position)
 const {
 
  161            return mSampler.template sample<ValueT, GridSamplerT, SourceAccessorT>(
 
  162                mAccessor, position);
 
  165        template <
bool IsVal
idT = IsVal
id>
 
  166        inline typename std::enable_if<!IsValidT, ValueT>::type
 
  167        sample(
const Vec3d& )
 const {
 
  168            OPENVDB_THROW(RuntimeError, 
"Cannot sample bool grid with BoxSampler or QuadraticSampler.");
 
  172        SourceAccessorT mAccessor;
 
  173        const SamplerT& mSampler;
 
  176    template <
typename SamplerWrapperT, 
typename TransformerT>
 
  177    inline void doSample(
const SamplerWrapperT& sampleWrapper, 
const Index targetIndex,
 
  178        const TransformerT& transformer)
 
  180        using PointDataTreeT = 
typename PointDataGridT::TreeType;
 
  181        using LeafT = 
typename PointDataTreeT::LeafNodeType;
 
  182        using LeafManagerT = 
typename tree::LeafManager<PointDataTreeT>;
 
  184        const auto& filter(mFilter);
 
  185        const auto& interrupter(mInterrupter);
 
  187        auto sampleLambda = [targetIndex, &sampleWrapper, &transformer, &filter, &interrupter](
 
  188            LeafT& leaf, 
size_t )
 
  190            using TargetHandleT = AttributeWriteHandle<typename SamplerWrapperT::ValueType>;
 
  192            if (util::wasInterrupted(interrupter)) {
 
  193                thread::cancelGroupExecution();
 
  197            SamplerWrapperT newSampleWrapper(sampleWrapper);
 
  198            auto positionHandle = AttributeHandle<Vec3f>::create(leaf.constAttributeArray(
"P"));
 
  199            auto targetHandle = TargetHandleT::create(leaf.attributeArray(targetIndex));
 
  200            for (
auto iter = leaf.beginIndexOn(filter); iter; ++iter) {
 
  201                const Vec3d position = transformer.transform(
 
  202                    positionHandle->get(*iter) + iter.getCoord().asVec3d());
 
  203                targetHandle->set(*iter, newSampleWrapper.sample(position));
 
  207        LeafManagerT leafManager(mPoints.tree());
 
  209        if (mInterrupter) mInterrupter->start();
 
  211        leafManager.foreach(sampleLambda, mThreaded);
 
  213        if (mInterrupter) mInterrupter->end();
 
  216    template <
typename SourceGr
idT, 
typename SamplerWrapperT>
 
  217    inline void resolveTransform(
const SourceGridT& sourceGrid, 
const SamplerWrapperT& sampleWrapper,
 
  218        const Index targetIndex)
 
  220        const auto& sourceTransform = sourceGrid.constTransform();
 
  221        const auto& pointsTransform = mPoints.constTransform();
 
  223        if (sourceTransform == pointsTransform) {
 
  224            AlignedTransform transformer;
 
  225            doSample(sampleWrapper, targetIndex, transformer);
 
  227            NonAlignedTransform transformer(sourceTransform, pointsTransform);
 
  228            doSample(sampleWrapper, targetIndex, transformer);
 
  232    template <
typename SourceGr
idT, 
typename TargetValueT, 
size_t Order>
 
  233    inline void resolveStaggered(
const SourceGridT& sourceGrid, 
const Index targetIndex)
 
  235        using SamplerWrapperT = SamplerWrapper<TargetValueT, SourceGridT, tools::Sampler<Order, false>>;
 
  236        using StaggeredSamplerWrapperT = SamplerWrapper<TargetValueT, SourceGridT, tools::Sampler<Order, true>>;
 
  238        using SourceValueType = 
typename SourceGridT::ValueType;
 
  239        if (VecTraits<SourceValueType>::Size == 3 && sourceGrid.getGridClass() == GRID_STAGGERED) {
 
  240            StaggeredSamplerWrapperT sampleWrapper(sourceGrid, mSampler);
 
  241            resolveTransform(sourceGrid, sampleWrapper, targetIndex);
 
  243            SamplerWrapperT sampleWrapper(sourceGrid, mSampler);
 
  244            resolveTransform(sourceGrid, sampleWrapper, targetIndex);
 
  249    template <
typename SourceGr
idT, 
typename TargetValueT = 
typename SourceGr
idT::ValueType>
 
  250    inline void sample(
const SourceGridT& sourceGrid, Index targetIndex)
 
  252        using SourceValueType = 
typename SourceGridT::ValueType;
 
  253        static const bool SourceIsMask = std::is_same<SourceValueType, bool>::value ||
 
  254            std::is_same<SourceValueType, ValueMask>::value;
 
  256        if (SourceIsMask || mOrder == 0) {
 
  257            resolveStaggered<SourceGridT, TargetValueT, 0>(sourceGrid, targetIndex);
 
  258        } 
else if (mOrder == 1) {
 
  259            resolveStaggered<SourceGridT, TargetValueT, 1>(sourceGrid, targetIndex);
 
  260        } 
else if (mOrder == 2) {
 
  261            resolveStaggered<SourceGridT, TargetValueT, 2>(sourceGrid, targetIndex);
 
  267    PointDataGridT& mPoints;
 
  268    const SamplerT& mSampler;
 
  269    const FilterT& mFilter;
 
  270    InterrupterT* 
const mInterrupter;
 
  271    const bool mThreaded;
 
  275template <
typename Po
intDataGr
idT, 
typename ValueT>
 
  276struct AppendAttributeOp
 
  278    static void append(PointDataGridT& points, 
const Name& attribute)
 
  280        appendAttribute<ValueT>(points.tree(), attribute);
 
  284template <
typename Po
intDataGr
idT>
 
  285struct AppendAttributeOp<PointDataGridT, DummySampleType>
 
  287    static void append(PointDataGridT&, 
const Name&) { }
 
  297template<
typename ValueT, 
typename SamplerT, 
typename AccessorT>
 
  300    using namespace point_sample_internal;
 
  301    using SourceValueT = 
typename AccessorT::ValueType;
 
  302    static const bool staggered = SamplerTraits<SamplerT>::Staggered;
 
  303    static const bool compatible = CompatibleTypes<SourceValueT, ValueT>::value &&
 
  305    static const bool round =   std::is_floating_point<SourceValueT>::value &&
 
  306                                std::is_integral<ValueT>::value;
 
  308    SampleWithRoundingOp<ValueT, SamplerT, AccessorT, round, compatible>::sample(
 
  309        value, accessor, position);
 
 
  317template<
typename PointDataGridT, 
typename SourceGridT, 
typename TargetValueT,
 
  318    typename SamplerT, 
typename FilterT, 
typename InterrupterT>
 
  321                        const SourceGridT& sourceGrid,
 
  322                        const Name& targetAttribute,
 
  323                        const FilterT& filter,
 
  324                        const SamplerT& sampler,
 
  325                        InterrupterT* 
const interrupter,
 
  328    using point_sample_internal::AppendAttributeOp;
 
  329    using point_sample_internal::PointDataSampler;
 
  332    Name attribute(targetAttribute);
 
  333    if (targetAttribute.empty()) {
 
  334        attribute = sourceGrid.getName();
 
  338    if (attribute == 
"P") {
 
  342    auto leaf = 
points.tree().cbeginLeaf();
 
  345    PointDataSampler<PointDataGridT, SamplerT, FilterT, InterrupterT> pointDataSampler(
 
  346        order, 
points, sampler, filter, interrupter, threaded);
 
  348    const auto& descriptor = leaf->attributeSet().descriptor();
 
  349    size_t targetIndex = descriptor.find(attribute);
 
  352    if (std::is_same<TargetValueT, DummySampleType>::value) {
 
  353        if (!attributeExists) {
 
  356            targetIndex = leaf->attributeSet().descriptor().find(attribute);
 
  360            pointDataSampler.template sample<SourceGridT>(sourceGrid, 
Index(targetIndex));
 
  362            auto targetIdx = 
static_cast<Index>(targetIndex);
 
  364            const Name& targetType = descriptor.valueType(targetIndex);
 
  366                pointDataSampler.template sample<SourceGridT, Vec3f>(sourceGrid, targetIdx);
 
  368                pointDataSampler.template sample<SourceGridT, Vec3d>(sourceGrid, targetIdx);
 
  370                pointDataSampler.template sample<SourceGridT, Vec3i>(sourceGrid, targetIdx);
 
  372                pointDataSampler.template sample<SourceGridT, int8_t>(sourceGrid, targetIdx);
 
  374                pointDataSampler.template sample<SourceGridT, int16_t>(sourceGrid, targetIdx);
 
  376                pointDataSampler.template sample<SourceGridT, int32_t>(sourceGrid, targetIdx);
 
  378                pointDataSampler.template sample<SourceGridT, int64_t>(sourceGrid, targetIdx);
 
  380                pointDataSampler.template sample<SourceGridT, float>(sourceGrid, targetIdx);
 
  382                pointDataSampler.template sample<SourceGridT, double>(sourceGrid, targetIdx);
 
  384                pointDataSampler.template sample<SourceGridT, bool>(sourceGrid, targetIdx);
 
  386                std::ostringstream ostr;
 
  387                ostr << 
"Cannot sample attribute of type - " << targetType;
 
  392        if (!attributeExists) {
 
  395            AppendAttributeOp<PointDataGridT, TargetValueT>::append(
points, attribute);
 
  396            targetIndex = leaf->attributeSet().descriptor().find(attribute);
 
  401            const Name attributeType = descriptor.valueType(targetIndex);
 
  402            if (targetType != attributeType) {
 
  403                std::ostringstream ostr;
 
  404                ostr << 
"Requested attribute type " << targetType << 
" for sampling " 
  405                    << 
" does not match existing attribute type " << attributeType;
 
  411        pointDataSampler.template sample<SourceGridT, TargetValueT>(
 
  412            sourceGrid, 
static_cast<Index>(targetIndex));
 
 
  416template<
typename Po
intDataGr
idT, 
typename SourceGr
idT, 
typename FilterT, 
typename InterrupterT>
 
  418                        const SourceGridT& sourceGrid,
 
  419                        const Name& targetAttribute,
 
  420                        const FilterT& filter,
 
  421                        InterrupterT* 
const interrupter)
 
  424    sampleGrid(0, 
points, sourceGrid, targetAttribute, filter, sampler, interrupter);
 
 
  427template<
typename Po
intDataGr
idT, 
typename SourceGr
idT, 
typename FilterT, 
typename InterrupterT>
 
  429                        const SourceGridT& sourceGrid,
 
  430                        const Name& targetAttribute,
 
  431                        const FilterT& filter,
 
  432                        InterrupterT* 
const interrupter)
 
  435    sampleGrid(1, 
points, sourceGrid, targetAttribute, filter, sampler, interrupter);
 
 
  438template<
typename Po
intDataGr
idT, 
typename SourceGr
idT, 
typename FilterT, 
typename InterrupterT>
 
  440                            const SourceGridT& sourceGrid,
 
  441                            const Name& targetAttribute,
 
  442                            const FilterT& filter,
 
  443                            InterrupterT* 
const interrupter)
 
  446    sampleGrid(2, 
points, sourceGrid, targetAttribute, filter, sampler, interrupter);
 
 
#define OPENVDB_ASSERT(X)
Definition Assert.h:41
Definition Exceptions.h:63
Definition Exceptions.h:64
@ INVALID_POS
Definition AttributeSet.h:42
@ Staggered
Definition NanoVDB.h:293
Vec3< double > Vec3d
Definition Vec3.h:665
Definition AttributeArray.h:42
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 PointSampleImpl.h:319
void appendAttribute(PointDataTreeT &tree, const Name &name, const NamePair &type, const Index strideOrTotalSize=1, const bool constantStride=true, const Metadata *defaultValue=nullptr, const bool hidden=false, const bool transient=false)
Appends a new attribute to the VDB tree (this method does not require a templated AttributeType)
Definition PointAttributeImpl.h:103
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 PointSampleImpl.h:428
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 PointSampleImpl.h:439
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 PointSampleImpl.h:417
std::string Name
Definition Name.h:19
Index32 Index
Definition Types.h:54
const char * typeNameAsString()
Definition Types.h:516
Definition Exceptions.h:13
#define OPENVDB_THROW(exception, message)
Definition Exceptions.h:74
static const int Size
Definition Types.h:246
Definition PointSample.h:86
ValueT sample(const AccessorT &accessor, const Vec3d &position) const
Definition PointSampleImpl.h:298
#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:218