OpenVDB  6.1.0
points/PointAdvect.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2018 DreamWorks Animation LLC
4 //
5 // All rights reserved. This software is distributed under the
6 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
7 //
8 // Redistributions of source code must retain the above copyright
9 // and license notice and the following restrictions and disclaimer.
10 //
11 // * Neither the name of DreamWorks Animation nor the names of
12 // its contributors may be used to endorse or promote products derived
13 // from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE
27 // LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00.
28 //
30 
36 
37 #ifndef OPENVDB_POINTS_POINT_ADVECT_HAS_BEEN_INCLUDED
38 #define OPENVDB_POINTS_POINT_ADVECT_HAS_BEEN_INCLUDED
39 
40 #include <openvdb/openvdb.h>
41 #include <openvdb/tools/Prune.h>
43 
48 
49 #include <memory>
50 
51 
52 namespace openvdb {
54 namespace OPENVDB_VERSION_NAME {
55 namespace points {
56 
57 
68 template <typename PointDataGridT, typename VelGridT,
69  typename AdvectFilterT = NullFilter, typename FilterT = NullFilter>
70 inline void advectPoints(PointDataGridT& points, const VelGridT& velocity,
71  const Index integrationOrder, const double dt, const Index timeSteps,
72  const AdvectFilterT& advectFilter = NullFilter(),
73  const FilterT& filter = NullFilter(),
74  const bool cached = true);
75 
76 
78 
79 
80 namespace point_advect_internal {
81 
87 };
88 
89 template <typename VelGridT, Index IntegrationOrder, bool Staggered, typename FilterT>
91 {
92 public:
93  using IntegratorT = openvdb::tools::VelocityIntegrator<VelGridT, Staggered>;
94 
95  AdvectionDeformer(const VelGridT& velocityGrid, const double timeStep, const int steps,
96  const FilterT& filter)
97  : mIntegrator(velocityGrid)
98  , mTimeStep(timeStep)
99  , mSteps(steps)
100  , mFilter(filter) { }
101 
102  template <typename LeafT>
103  void reset(const LeafT& leaf, size_t /*idx*/)
104  {
105  mFilter.reset(leaf);
106  }
107 
108  template <typename IndexIterT>
109  void apply(Vec3d& position, const IndexIterT& iter) const
110  {
111  if (mFilter.valid(iter)) {
112  for (int n = 0; n < mSteps; ++n) {
113  mIntegrator.template rungeKutta<IntegrationOrder, openvdb::Vec3d>(
114  static_cast<typename IntegratorT::ElementType>(mTimeStep), position);
115  }
116  }
117  }
118 
119 private:
120  IntegratorT mIntegrator;
121  double mTimeStep;
122  const int mSteps;
123  FilterT mFilter;
124 }; // class AdvectionDeformer
125 
126 
127 template <typename PointDataGridT, typename VelGridT, typename AdvectFilterT, typename FilterT>
129 {
131 
132  AdvectionOp(PointDataGridT& points, const VelGridT& velocity,
133  const Index integrationOrder, const double timeStep, const Index steps,
134  const AdvectFilterT& advectFilter,
135  const FilterT& filter)
136  : mPoints(points)
137  , mVelocity(velocity)
138  , mIntegrationOrder(integrationOrder)
139  , mTimeStep(timeStep)
140  , mSteps(steps)
141  , mAdvectFilter(advectFilter)
142  , mFilter(filter) { }
143 
144  void cache()
145  {
146  mCachedDeformer.reset(new CachedDeformerT(mCache));
147  (*this)(true);
148  }
149 
150  void advect()
151  {
152  (*this)(false);
153  }
154 
155 private:
156  template <int IntegrationOrder, bool Staggered>
157  void resolveIntegrationOrder(bool buildCache)
158  {
159  const auto leaf = mPoints.constTree().cbeginLeaf();
160  if (!leaf) return;
161 
162  // move points according to the pre-computed cache
163  if (!buildCache && mCachedDeformer) {
164  movePoints(mPoints, *mCachedDeformer, mFilter);
165  return;
166  }
167 
168  NullFilter nullFilter;
169 
170  if (buildCache) {
171  // disable group filtering from the advection deformer and perform group filtering
172  // in the cache deformer instead, this restricts the cache to just containing
173  // positions from points which are both deforming *and* are not being deleted
175  mVelocity, mTimeStep, mSteps, nullFilter);
176  if (mFilter.state() == index::ALL && mAdvectFilter.state() == index::ALL) {
177  mCachedDeformer->evaluate(mPoints, deformer, nullFilter);
178  } else {
179  BinaryFilter<AdvectFilterT, FilterT, /*And=*/true> binaryFilter(
180  mAdvectFilter, mFilter);
181  mCachedDeformer->evaluate(mPoints, deformer, binaryFilter);
182  }
183  }
184  else {
185  // revert to NullFilter if all points are being evaluated
186  if (mAdvectFilter.state() == index::ALL) {
188  mVelocity, mTimeStep, mSteps, nullFilter);
189  movePoints(mPoints, deformer, mFilter);
190  }
191  else {
193  mVelocity, mTimeStep, mSteps, mAdvectFilter);
194  movePoints(mPoints, deformer, mFilter);
195  }
196  }
197  }
198 
199  template <bool Staggered>
200  void resolveStaggered(bool buildCache)
201  {
202  if (mIntegrationOrder == INTEGRATION_ORDER_FWD_EULER) {
203  resolveIntegrationOrder<1, Staggered>(buildCache);
204  } else if (mIntegrationOrder == INTEGRATION_ORDER_RK_2ND) {
205  resolveIntegrationOrder<2, Staggered>(buildCache);
206  } else if (mIntegrationOrder == INTEGRATION_ORDER_RK_3RD) {
207  resolveIntegrationOrder<3, Staggered>(buildCache);
208  } else if (mIntegrationOrder == INTEGRATION_ORDER_RK_4TH) {
209  resolveIntegrationOrder<4, Staggered>(buildCache);
210  }
211  }
212 
213  void operator()(bool buildCache)
214  {
215  // early-exit if no leafs
216  if (mPoints.constTree().leafCount() == 0) return;
217 
218  if (mVelocity.getGridClass() == openvdb::GRID_STAGGERED) {
219  resolveStaggered<true>(buildCache);
220  } else {
221  resolveStaggered<false>(buildCache);
222  }
223  }
224 
225  PointDataGridT& mPoints;
226  const VelGridT& mVelocity;
227  const Index mIntegrationOrder;
228  const double mTimeStep;
229  const Index mSteps;
230  const AdvectFilterT& mAdvectFilter;
231  const FilterT& mFilter;
232  CachedDeformerT::Cache mCache;
233  std::unique_ptr<CachedDeformerT> mCachedDeformer;
234 }; // struct AdvectionOp
235 
236 } // namespace point_advect_internal
237 
238 
240 
241 
242 template <typename PointDataGridT, typename VelGridT, typename AdvectFilterT, typename FilterT>
243 inline void advectPoints(PointDataGridT& points, const VelGridT& velocity,
244  const Index integrationOrder, const double timeStep, const Index steps,
245  const AdvectFilterT& advectFilter,
246  const FilterT& filter,
247  const bool cached)
248 {
249  using namespace point_advect_internal;
250 
251  if (steps == 0) return;
252 
253  if (integrationOrder > 4) {
254  throw ValueError{"Unknown integration order for advecting points."};
255  }
256 
257  AdvectionOp<PointDataGridT, VelGridT, AdvectFilterT, FilterT> op(
258  points, velocity, integrationOrder, timeStep, steps,
259  advectFilter, filter);
260 
261  // if caching is enabled, sample the velocity field using a CachedDeformer to store the
262  // intermediate positions before moving the points, this uses more memory but typically
263  // results in faster overall performance
264  if (cached) op.cache();
265 
266  // advect the points
267  op.advect();
268 }
269 
270 } // namespace points
271 } // namespace OPENVDB_VERSION_NAME
272 } // namespace openvdb
273 
274 #endif // OPENVDB_POINTS_POINT_ADVECT_HAS_BEEN_INCLUDED
275 
276 // Copyright (c) 2012-2018 DreamWorks Animation LLC
277 // All rights reserved. This software is distributed under the
278 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
A Deformer that caches the resulting positions from evaluating another Deformer.
Definition: PointMove.h:125
Attribute Group access and filtering for iteration.
Defines two simple wrapper classes for advection velocity fields as well as VelocitySampler and Veloc...
AdvectionOp(PointDataGridT &points, const VelGridT &velocity, const Index integrationOrder, const double timeStep, const Index steps, const AdvectFilterT &advectFilter, const FilterT &filter)
Definition: points/PointAdvect.h:132
A no-op filter that can be used when iterating over all indices.
Definition: IndexIterator.h:77
Defined various multi-threaded utility functions for trees.
void apply(Vec3d &position, const IndexIterT &iter) const
Definition: points/PointAdvect.h:109
Point group manipulation in a VDB Point Grid.
Vec3< double > Vec3d
Definition: Vec3.h:689
void cache()
Definition: points/PointAdvect.h:144
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:1112
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:125
Index32 Index
Definition: Types.h:61
void reset(const LeafT &leaf, size_t)
Definition: points/PointAdvect.h:103
Definition: Exceptions.h:40
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: points/PointAdvect.h:243
Definition: IndexIterator.h:70
Ability to move VDB Points using a custom deformer.
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
openvdb::tools::VelocityIntegrator< VelGridT, Staggered > IntegratorT
Definition: points/PointAdvect.h:93
Definition: IndexFilter.h:529
Definition: Types.h:506
Definition: Exceptions.h:92
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:177
AdvectionDeformer(const VelGridT &velocityGrid, const double timeStep, const int steps, const FilterT &filter)
Definition: points/PointAdvect.h:95
IntegrationOrder
Definition: points/PointAdvect.h:82
void advect()
Definition: points/PointAdvect.h:150