OpenVDB: PointAdvect.h Source File

OpenVDB 6.0.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>
42 #include <openvdb/tools/VelocityFields.h>
43
44 #include <openvdb/points/AttributeGroup.h>
45 #include <openvdb/points/PointDataGrid.h>
46 #include <openvdb/points/PointGroup.h>
47 #include <openvdb/points/PointMove.h>
48
49 #include <memory>
50
51
52 namespace openvdb {
53 OPENVDB_USE_VERSION_NAMESPACE
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
82 enum IntegrationOrder {
83 INTEGRATION_ORDER_FWD_EULER = 1,
84 INTEGRATION_ORDER_RK_2ND,
85 INTEGRATION_ORDER_RK_3RD,
86 INTEGRATION_ORDER_RK_4TH
87 };
88
89 template <typename VelGridT, Index IntegrationOrder, bool Staggered, typename FilterT>
90 class AdvectionDeformer
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>
128 struct AdvectionOp
129 {
130 using CachedDeformerT = CachedDeformer<double>;
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
174 AdvectionDeformer<VelGridT, IntegrationOrder, Staggered, NullFilter> deformer(
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) {
187 AdvectionDeformer<VelGridT, IntegrationOrder, Staggered, NullFilter> deformer(
188 mVelocity, mTimeStep, mSteps, nullFilter);
189 movePoints(mPoints, deformer, mFilter);
190 }
191 else {
192 AdvectionDeformer<VelGridT, IntegrationOrder, Staggered, AdvectFilterT> deformer(
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/ )
openvdb::v6_0::points::NullFilter
A no-op filter that can be used when iterating over all indices.
Definition: IndexIterator.h:77
AttributeGroup.h
Attribute Group access and filtering for iteration.
openvdb::v6_0::points::point_advect_internal::AdvectionDeformer
Definition: points/PointAdvect.h:90
openvdb::v6_0::Index
Index32 Index
Definition: Types.h:61
openvdb::v6_0::points::point_advect_internal::INTEGRATION_ORDER_RK_4TH
Definition: points/PointAdvect.h:86
VelocityFields.h
Defines two simple wrapper classes for advection velocity fields as well as VelocitySampler and Veloc...
openvdb::v6_0::points::point_advect_internal::AdvectionOp::advect
void advect()
Definition: points/PointAdvect.h:150
openvdb::v6_0::points::point_advect_internal::AdvectionOp::cache
void cache()
Definition: points/PointAdvect.h:144
openvdb.h
openvdb::v6_0::math::Vec3d
Vec3< double > Vec3d
Definition: Vec3.h:679
openvdb::v6_0::GRID_STAGGERED
Definition: Types.h:279
Prune.h
Defined various multi-threaded utility functions for trees.
PointGroup.h
Point group manipulation in a VDB Point Grid.
openvdb::v6_0::points::CachedDeformer
A Deformer that caches the resulting positions from evaluating another Deformer.
Definition: PointMove.h:125
openvdb::v6_0::points::movePoints
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:817
openvdb::v6_0::points::point_advect_internal::INTEGRATION_ORDER_RK_3RD
Definition: points/PointAdvect.h:85
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:136
openvdb::v6_0::points::point_advect_internal::AdvectionDeformer::reset
void reset(const LeafT &leaf, size_t)
Definition: points/PointAdvect.h:103
openvdb::v6_0::points::point_advect_internal::INTEGRATION_ORDER_RK_2ND
Definition: points/PointAdvect.h:84
openvdb::v6_0::points::point_advect_internal::AdvectionDeformer::apply
void apply(Vec3d &position, const IndexIterT &iter) const
Definition: points/PointAdvect.h:109
openvdb::v6_0::points::point_advect_internal::AdvectionOp
Definition: points/PointAdvect.h:128
openvdb
Definition: Exceptions.h:40
openvdb::v6_0::points::point_advect_internal::IntegrationOrder
IntegrationOrder
Definition: points/PointAdvect.h:82
openvdb::v6_0::points::advectPoints
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
openvdb::v6_0::points::point_advect_internal::AdvectionOp::AdvectionOp
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
openvdb::v6_0::points::point_advect_internal::AdvectionDeformer::IntegratorT
openvdb::tools::VelocityIntegrator< VelGridT, Staggered > IntegratorT
Definition: points/PointAdvect.h:93
PointMove.h
Ability to move VDB Points using a custom deformer.
openvdb::v6_0::points::index::ALL
Definition: IndexIterator.h:70
PointDataGrid.h
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
openvdb::v6_0::ValueError
Definition: Exceptions.h:92
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:188
openvdb::v6_0::points::point_advect_internal::INTEGRATION_ORDER_FWD_EULER
Definition: points/PointAdvect.h:83
openvdb::v6_0::points::point_advect_internal::AdvectionDeformer::AdvectionDeformer
AdvectionDeformer(const VelGridT &velocityGrid, const double timeStep, const int steps, const FilterT &filter)
Definition: points/PointAdvect.h:95