10#ifndef OPENVDB_POINTS_POINT_ADVECT_HAS_BEEN_INCLUDED 
   11#define OPENVDB_POINTS_POINT_ADVECT_HAS_BEEN_INCLUDED 
   41template <
typename PointDataGridT, 
typename VelGridT,
 
   42    typename AdvectFilterT = NullFilter, 
typename FilterT = NullFilter>
 
   43inline void advectPoints(PointDataGridT& points, 
const VelGridT& velocity,
 
   44                         const Index integrationOrder, 
const double dt, 
const Index timeSteps,
 
   45                         const AdvectFilterT& advectFilter = NullFilter(),
 
   46                         const FilterT& filter = NullFilter(),
 
   47                         const bool cached = 
true);
 
   54namespace point_advect_internal {
 
   56enum IntegrationOrder {
 
   57    INTEGRATION_ORDER_FWD_EULER = 1,
 
   58    INTEGRATION_ORDER_RK_2ND,
 
   59    INTEGRATION_ORDER_RK_3RD,
 
   60    INTEGRATION_ORDER_RK_4TH
 
   63template <
typename VelGr
idT, Index IntegrationOrder, 
bool Staggered, 
typename FilterT>
 
   64class AdvectionDeformer
 
   67    using IntegratorT = openvdb::tools::VelocityIntegrator<VelGridT, Staggered>;
 
   69    AdvectionDeformer(
const VelGridT& velocityGrid, 
const double timeStep, 
const int steps,
 
   70                      const FilterT& filter)
 
   71        : mIntegrator(velocityGrid)
 
   76    template <
typename LeafT>
 
   77    void reset(
const LeafT& leaf, 
size_t )
 
   82    template <
typename IndexIterT>
 
   83    void apply(Vec3d& position, 
const IndexIterT& iter)
 const 
   85        if (mFilter.valid(iter)) {
 
   86            for (
int n = 0; n < mSteps; ++n) {
 
   87                mIntegrator.template rungeKutta<IntegrationOrder, openvdb::Vec3d>(
 
   88                    static_cast<typename IntegratorT::ElementType
>(mTimeStep), position);
 
   94    IntegratorT mIntegrator;
 
  101template <
typename Po
intDataGr
idT, 
typename VelGr
idT, 
typename AdvectFilterT, 
typename FilterT>
 
  104    using CachedDeformerT = CachedDeformer<double>;
 
  106    AdvectionOp(PointDataGridT& points, 
const VelGridT& velocity,
 
  107                const Index integrationOrder, 
const double timeStep, 
const Index steps,
 
  108                const AdvectFilterT& advectFilter,
 
  109                const FilterT& filter)
 
  111        , mVelocity(velocity)
 
  112        , mIntegrationOrder(integrationOrder)
 
  113        , mTimeStep(timeStep)
 
  115        , mAdvectFilter(advectFilter)
 
  116        , mFilter(filter) { }
 
  120        mCachedDeformer.reset(
new CachedDeformerT(mCache));
 
  130    template <
int IntegrationOrder, 
bool Staggered>
 
  131    void resolveIntegrationOrder(
bool buildCache)
 
  133        const auto leaf = mPoints.constTree().cbeginLeaf();
 
  137        if (!buildCache && mCachedDeformer) {
 
  138            movePoints(mPoints, *mCachedDeformer, mFilter);
 
  142        NullFilter nullFilter;
 
  148            AdvectionDeformer<VelGridT, IntegrationOrder, Staggered, NullFilter> deformer(
 
  149                mVelocity, mTimeStep, mSteps, nullFilter);
 
  150            if (mFilter.state() == index::ALL && mAdvectFilter.state() == index::ALL) {
 
  151                mCachedDeformer->evaluate(mPoints, deformer, nullFilter);
 
  153                BinaryFilter<AdvectFilterT, FilterT, 
true> binaryFilter(
 
  154                    mAdvectFilter, mFilter);
 
  155                mCachedDeformer->evaluate(mPoints, deformer, binaryFilter);
 
  160            if (mAdvectFilter.state() == index::ALL) {
 
  161                AdvectionDeformer<VelGridT, IntegrationOrder, Staggered, NullFilter> deformer(
 
  162                    mVelocity, mTimeStep, mSteps, nullFilter);
 
  166                AdvectionDeformer<VelGridT, IntegrationOrder, Staggered, AdvectFilterT> deformer(
 
  167                    mVelocity, mTimeStep, mSteps, mAdvectFilter);
 
  173    template <
bool Staggered>
 
  174    void resolveStaggered(
bool buildCache)
 
  176        if (mIntegrationOrder == INTEGRATION_ORDER_FWD_EULER) {
 
  177            resolveIntegrationOrder<1, Staggered>(buildCache);
 
  178        } 
else if (mIntegrationOrder == INTEGRATION_ORDER_RK_2ND) {
 
  179            resolveIntegrationOrder<2, Staggered>(buildCache);
 
  180        } 
else if (mIntegrationOrder == INTEGRATION_ORDER_RK_3RD) {
 
  181            resolveIntegrationOrder<3, Staggered>(buildCache);
 
  182        } 
else if (mIntegrationOrder == INTEGRATION_ORDER_RK_4TH) {
 
  183            resolveIntegrationOrder<4, Staggered>(buildCache);
 
  187    void operator()(
bool buildCache)
 
  190        if (mPoints.constTree().leafCount() == 0)            
return;
 
  193            resolveStaggered<true>(buildCache);
 
  195            resolveStaggered<false>(buildCache);
 
  199    PointDataGridT& mPoints;
 
  200    const VelGridT& mVelocity;
 
  201    const Index mIntegrationOrder;
 
  202    const double mTimeStep;
 
  204    const AdvectFilterT& mAdvectFilter;
 
  205    const FilterT& mFilter;
 
  206    CachedDeformerT::Cache mCache;
 
  207    std::unique_ptr<CachedDeformerT> mCachedDeformer;
 
  217template <
typename Po
intDataGr
idT, 
typename VelGr
idT, 
typename AdvectFilterT, 
typename FilterT>
 
  219                         const Index integrationOrder, 
const double timeStep, 
const Index steps,
 
  220                         const AdvectFilterT& advectFilter,
 
  221                         const FilterT& filter,
 
  224    using namespace point_advect_internal;
 
  226    if (steps == 0)     
return;
 
  228    if (integrationOrder > 4) {
 
  229        throw ValueError{
"Unknown integration order for advecting points."};
 
  232    AdvectionOp<PointDataGridT, VelGridT, AdvectFilterT, FilterT> op(
 
  233        points, velocity, integrationOrder, timeStep, steps,
 
  234        advectFilter, filter);
 
  239    if (cached)     op.cache();
 
 
Attribute Group access and filtering for iteration.
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
Point group manipulation in a VDB Point Grid.
Ability to move VDB Points using a custom deformer.
Defined various multi-threaded utility functions for trees.
Defines two simple wrapper classes for advection velocity fields as well as VelocitySampler and Veloc...
Definition Exceptions.h:65
Definition AttributeArray.h:42
void movePoints(PointDataGridT &points, DeformerT &deformer, const FilterT &filter=NullFilter(), future::Advect *objectNotInUse=nullptr, bool threaded=true)
Move points in a PointDataGrid using a custom deformer.
Definition PointMoveImpl.h:619
void advectPoints(PointDataGridT &points, const VelGridT &velocity, const Index integrationOrder, const double dt, const Index timeSteps, const AdvectFilterT &advectFilter=NullFilter(), const FilterT &filter=NullFilter(), const bool cached=true)
Advect points in a PointDataGrid through a velocity grid.
Definition PointAdvect.h:218
Index32 Index
Definition Types.h:54
@ GRID_STAGGERED
Definition Types.h:457
Definition Exceptions.h:13
#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