OpenVDB 7.0.0

points/PointAdvect.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3
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>
15 #include <openvdb/tools/VelocityFields.h>
16
17 #include <openvdb/points/AttributeGroup.h>
18 #include <openvdb/points/PointDataGrid.h>
19 #include <openvdb/points/PointGroup.h>
20 #include <openvdb/points/PointMove.h>
21
22 #include <memory>
23
24
25 namespace openvdb {
26 OPENVDB_USE_VERSION_NAMESPACE
27 namespace OPENVDB_VERSION_NAME {
28 namespace points {
29
30
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
51
52
53 namespace point_advect_internal {
54
55 enum IntegrationOrder {
56 INTEGRATION_ORDER_FWD_EULER = 1,
57 INTEGRATION_ORDER_RK_2ND,
58 INTEGRATION_ORDER_RK_3RD,
59 INTEGRATION_ORDER_RK_4TH
60 };
61
62 template <typename VelGridT, Index IntegrationOrder, bool Staggered, typename FilterT>
63 class AdvectionDeformer
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>
101 struct AdvectionOp
102 {
103 using CachedDeformerT = CachedDeformer<double>;
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
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
openvdb::v7_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:1090
openvdb::v7_0::points::point_advect_internal::AdvectionOp
Definition: points/PointAdvect.h:101
PointGroup.h
Point group manipulation in a VDB Point Grid.
openvdb::v7_0::points::point_advect_internal::AdvectionDeformer::apply
void apply(Vec3d &position, const IndexIterT &iter) const
Definition: points/PointAdvect.h:82
openvdb::v7_0::GRID_STAGGERED
Definition: Types.h:456
openvdb::v7_0::points::point_advect_internal::INTEGRATION_ORDER_RK_2ND
Definition: points/PointAdvect.h:57
VelocityFields.h
Defines two simple wrapper classes for advection velocity fields as well as VelocitySampler and Veloc...
PointMove.h
Ability to move VDB Points using a custom deformer.
openvdb::v7_0::points::point_advect_internal::INTEGRATION_ORDER_RK_4TH
Definition: points/PointAdvect.h:59
openvdb::v7_0::points::point_advect_internal::AdvectionDeformer::AdvectionDeformer
AdvectionDeformer(const VelGridT &velocityGrid, const double timeStep, const int steps, const FilterT &filter)
Definition: points/PointAdvect.h:68
openvdb::v7_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:216
openvdb::v7_0::points::point_advect_internal::AdvectionOp::advect
void advect()
Definition: points/PointAdvect.h:123
openvdb::v7_0::math::Vec3d
Vec3< double > Vec3d
Definition: Vec3.h:662
openvdb::v7_0::points::point_advect_internal::INTEGRATION_ORDER_RK_3RD
Definition: points/PointAdvect.h:58
openvdb::v7_0::points::point_advect_internal::AdvectionDeformer
Definition: points/PointAdvect.h:63
AttributeGroup.h
Attribute Group access and filtering for iteration.
PointDataGrid.h
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
Prune.h
Defined various multi-threaded utility functions for trees.
openvdb::v7_0::points::point_advect_internal::IntegrationOrder
IntegrationOrder
Definition: points/PointAdvect.h:55
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:154
openvdb::v7_0::points::NullFilter
A no-op filter that can be used when iterating over all indices.
Definition: IndexIterator.h:50
openvdb::v7_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:105
openvdb::v7_0::Index
Index32 Index
Definition: Types.h:31
openvdb::v7_0::points::CachedDeformer
A Deformer that caches the resulting positions from evaluating another Deformer.
Definition: PointMove.h:98
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:102
openvdb::v7_0::points::point_advect_internal::AdvectionOp::cache
void cache()
Definition: points/PointAdvect.h:117
openvdb::v7_0::points::index::ALL
Definition: IndexIterator.h:43
openvdb::v7_0::points::point_advect_internal::AdvectionDeformer::IntegratorT
openvdb::tools::VelocityIntegrator< VelGridT, Staggered > IntegratorT
Definition: points/PointAdvect.h:66
openvdb::v7_0::ValueError
Definition: Exceptions.h:65
openvdb::v7_0::points::point_advect_internal::AdvectionDeformer::reset
void reset(const LeafT &leaf, size_t)
Definition: points/PointAdvect.h:76
openvdb
Definition: Exceptions.h:13
openvdb.h
openvdb::v7_0::points::point_advect_internal::INTEGRATION_ORDER_FWD_EULER
Definition: points/PointAdvect.h:56