HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PointAdvect.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 Dan Bailey
5 ///
6 /// @file points/PointAdvect.h
7 ///
8 /// @brief Ability to advect VDB Points through a velocity field.
9 
10 #ifndef OPENVDB_POINTS_POINT_ADVECT_HAS_BEEN_INCLUDED
11 #define OPENVDB_POINTS_POINT_ADVECT_HAS_BEEN_INCLUDED
12 
13 #include <openvdb/openvdb.h>
14 #include <openvdb/tools/Prune.h>
16 
21 
22 #include <memory>
23 
24 
25 namespace openvdb {
27 namespace OPENVDB_VERSION_NAME {
28 namespace points {
29 
30 
31 /// @brief Advect points in a PointDataGrid through a velocity grid
32 /// @param points the PointDataGrid containing the points to be advected.
33 /// @param velocity a velocity grid to be sampled.
34 /// @param integrationOrder the integration scheme to use (1 is forward euler, 4 is runge-kutta 4th)
35 /// @param dt delta time.
36 /// @param timeSteps number of advection steps to perform.
37 /// @param advectFilter an optional advection index filter (moves a subset of the points)
38 /// @param filter an optional index filter (deletes a subset of the points)
39 /// @param cached caches velocity interpolation for faster performance, disable to use
40 /// less memory (default is on).
41 template <typename PointDataGridT, typename VelGridT,
42  typename AdvectFilterT = NullFilter, typename FilterT = NullFilter>
43 inline 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);
48 
49 
50 ////////////////////////////////////////
51 
52 
53 namespace point_advect_internal {
54 
60 };
61 
62 template <typename VelGridT, Index IntegrationOrder, bool Staggered, typename FilterT>
64 {
65 public:
66  using IntegratorT = openvdb::tools::VelocityIntegrator<VelGridT, Staggered>;
67 
68  AdvectionDeformer(const VelGridT& velocityGrid, const double timeStep, const int steps,
69  const FilterT& filter)
70  : mIntegrator(velocityGrid)
71  , mTimeStep(timeStep)
72  , mSteps(steps)
73  , mFilter(filter) { }
74 
75  template <typename LeafT>
76  void reset(const LeafT& leaf, size_t /*idx*/)
77  {
78  mFilter.reset(leaf);
79  }
80 
81  template <typename IndexIterT>
82  void apply(Vec3d& position, const IndexIterT& iter) const
83  {
84  if (mFilter.valid(iter)) {
85  for (int n = 0; n < mSteps; ++n) {
86  mIntegrator.template rungeKutta<IntegrationOrder, openvdb::Vec3d>(
87  static_cast<typename IntegratorT::ElementType>(mTimeStep), position);
88  }
89  }
90  }
91 
92 private:
93  IntegratorT mIntegrator;
94  double mTimeStep;
95  const int mSteps;
96  FilterT mFilter;
97 }; // class AdvectionDeformer
98 
99 
100 template <typename PointDataGridT, typename VelGridT, typename AdvectFilterT, typename FilterT>
102 {
104 
105  AdvectionOp(PointDataGridT& points, const VelGridT& velocity,
106  const Index integrationOrder, const double timeStep, const Index steps,
107  const AdvectFilterT& advectFilter,
108  const FilterT& filter)
109  : mPoints(points)
110  , mVelocity(velocity)
111  , mIntegrationOrder(integrationOrder)
112  , mTimeStep(timeStep)
113  , mSteps(steps)
114  , mAdvectFilter(advectFilter)
115  , mFilter(filter) { }
116 
117  void cache()
118  {
119  mCachedDeformer.reset(new CachedDeformerT(mCache));
120  (*this)(true);
121  }
122 
123  void advect()
124  {
125  (*this)(false);
126  }
127 
128 private:
129  template <int IntegrationOrder, bool Staggered>
130  void resolveIntegrationOrder(bool buildCache)
131  {
132  const auto leaf = mPoints.constTree().cbeginLeaf();
133  if (!leaf) return;
134 
135  // move points according to the pre-computed cache
136  if (!buildCache && mCachedDeformer) {
137  movePoints(mPoints, *mCachedDeformer, mFilter);
138  return;
139  }
140 
141  NullFilter nullFilter;
142 
143  if (buildCache) {
144  // disable group filtering from the advection deformer and perform group filtering
145  // in the cache deformer instead, this restricts the cache to just containing
146  // positions from points which are both deforming *and* are not being deleted
147  AdvectionDeformer<VelGridT, IntegrationOrder, Staggered, NullFilter> deformer(
148  mVelocity, mTimeStep, mSteps, nullFilter);
149  if (mFilter.state() == index::ALL && mAdvectFilter.state() == index::ALL) {
150  mCachedDeformer->evaluate(mPoints, deformer, nullFilter);
151  } else {
152  BinaryFilter<AdvectFilterT, FilterT, /*And=*/true> binaryFilter(
153  mAdvectFilter, mFilter);
154  mCachedDeformer->evaluate(mPoints, deformer, binaryFilter);
155  }
156  }
157  else {
158  // revert to NullFilter if all points are being evaluated
159  if (mAdvectFilter.state() == index::ALL) {
160  AdvectionDeformer<VelGridT, IntegrationOrder, Staggered, NullFilter> deformer(
161  mVelocity, mTimeStep, mSteps, nullFilter);
162  movePoints(mPoints, deformer, mFilter);
163  }
164  else {
165  AdvectionDeformer<VelGridT, IntegrationOrder, Staggered, AdvectFilterT> deformer(
166  mVelocity, mTimeStep, mSteps, mAdvectFilter);
167  movePoints(mPoints, deformer, mFilter);
168  }
169  }
170  }
171 
172  template <bool Staggered>
173  void resolveStaggered(bool buildCache)
174  {
175  if (mIntegrationOrder == INTEGRATION_ORDER_FWD_EULER) {
176  resolveIntegrationOrder<1, Staggered>(buildCache);
177  } else if (mIntegrationOrder == INTEGRATION_ORDER_RK_2ND) {
178  resolveIntegrationOrder<2, Staggered>(buildCache);
179  } else if (mIntegrationOrder == INTEGRATION_ORDER_RK_3RD) {
180  resolveIntegrationOrder<3, Staggered>(buildCache);
181  } else if (mIntegrationOrder == INTEGRATION_ORDER_RK_4TH) {
182  resolveIntegrationOrder<4, Staggered>(buildCache);
183  }
184  }
185 
186  void operator()(bool buildCache)
187  {
188  // early-exit if no leafs
189  if (mPoints.constTree().leafCount() == 0) return;
190 
191  if (mVelocity.getGridClass() == openvdb::GRID_STAGGERED) {
192  resolveStaggered<true>(buildCache);
193  } else {
194  resolveStaggered<false>(buildCache);
195  }
196  }
197 
198  PointDataGridT& mPoints;
199  const VelGridT& mVelocity;
200  const Index mIntegrationOrder;
201  const double mTimeStep;
202  const Index mSteps;
203  const AdvectFilterT& mAdvectFilter;
204  const FilterT& mFilter;
205  CachedDeformerT::Cache mCache;
206  std::unique_ptr<CachedDeformerT> mCachedDeformer;
207 }; // struct AdvectionOp
208 
209 } // namespace point_advect_internal
210 
211 
212 ////////////////////////////////////////
213 
214 
215 template <typename PointDataGridT, typename VelGridT, typename AdvectFilterT, typename FilterT>
216 inline void advectPoints(PointDataGridT& points, const VelGridT& velocity,
217  const Index integrationOrder, const double timeStep, const Index steps,
218  const AdvectFilterT& advectFilter,
219  const FilterT& filter,
220  const bool cached)
221 {
222  using namespace point_advect_internal;
223 
224  if (steps == 0) return;
225 
226  if (integrationOrder > 4) {
227  throw ValueError{"Unknown integration order for advecting points."};
228  }
229 
230  AdvectionOp<PointDataGridT, VelGridT, AdvectFilterT, FilterT> op(
231  points, velocity, integrationOrder, timeStep, steps,
232  advectFilter, filter);
233 
234  // if caching is enabled, sample the velocity field using a CachedDeformer to store the
235  // intermediate positions before moving the points, this uses more memory but typically
236  // results in faster overall performance
237  if (cached) op.cache();
238 
239  // advect the points
240  op.advect();
241 }
242 
243 } // namespace points
244 } // namespace OPENVDB_VERSION_NAME
245 } // namespace openvdb
246 
247 #endif // OPENVDB_POINTS_POINT_ADVECT_HAS_BEEN_INCLUDED
AdvectionDeformer(const VelGridT &velocityGrid, const double timeStep, const int steps, const FilterT &filter)
Definition: PointAdvect.h:68
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: PointMove.h:1086
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:216
Point group manipulation in a VDB Point Grid.
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:167
A no-op filter that can be used when iterating over all indices.
Definition: IndexIterator.h:50
openvdb::tools::VelocityIntegrator< VelGridT, Staggered > IntegratorT
Definition: PointAdvect.h:66
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glew.h:2981
A Deformer that caches the resulting positions from evaluating another Deformer.
Definition: PointMove.h:98
GLsizei n
Definition: glew.h:4040
Defined various multi-threaded utility functions for trees.
Ability to move VDB Points using a custom deformer.
Defines two simple wrapper classes for advection velocity fields as well as VelocitySampler and Veloc...
void apply(Vec3d &position, const IndexIterT &iter) const
Definition: PointAdvect.h:82
Attribute Group access and filtering for iteration.
GLuint GLdouble GLdouble GLint GLint const GLdouble * points
Definition: glew.h:3446
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:113
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
AdvectionOp(PointDataGridT &points, const VelGridT &velocity, const Index integrationOrder, const double timeStep, const Index steps, const AdvectFilterT &advectFilter, const FilterT &filter)
Definition: PointAdvect.h:105