GCC Code Coverage Report


Directory: ./
File: openvdb/openvdb/points/PointAdvect.h
Date: 2022-07-25 17:40:05
Exec Total Coverage
Lines: 57 58 98.3%
Functions: 13 48 27.1%
Branches: 70 414 16.9%

Line Branch Exec Source
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>
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
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 /// @cond OPENVDB_DOCS_INTERNAL
53
54 namespace point_advect_internal {
55
56 enum IntegrationOrder {
57 INTEGRATION_ORDER_FWD_EULER = 1,
58 INTEGRATION_ORDER_RK_2ND,
59 INTEGRATION_ORDER_RK_3RD,
60 INTEGRATION_ORDER_RK_4TH
61 };
62
63 template <typename VelGridT, Index IntegrationOrder, bool Staggered, typename FilterT>
64
7/96
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✓ Branch 34 taken 3 times.
✗ Branch 35 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✗ Branch 50 not taken.
✗ Branch 51 not taken.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✗ Branch 66 not taken.
✗ Branch 67 not taken.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 74 not taken.
✗ Branch 75 not taken.
✗ Branch 78 not taken.
✗ Branch 79 not taken.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✗ Branch 86 not taken.
✗ Branch 87 not taken.
✗ Branch 90 not taken.
✗ Branch 91 not taken.
✗ Branch 94 not taken.
✗ Branch 95 not taken.
✓ Branch 98 taken 3 times.
✗ Branch 99 not taken.
✗ Branch 102 not taken.
✗ Branch 103 not taken.
✗ Branch 106 not taken.
✗ Branch 107 not taken.
✗ Branch 110 not taken.
✗ Branch 111 not taken.
✗ Branch 114 not taken.
✗ Branch 115 not taken.
✗ Branch 118 not taken.
✗ Branch 119 not taken.
✗ Branch 122 not taken.
✗ Branch 123 not taken.
✗ Branch 126 not taken.
✗ Branch 127 not taken.
✓ Branch 130 taken 9 times.
✗ Branch 131 not taken.
✗ Branch 134 not taken.
✗ Branch 135 not taken.
✗ Branch 138 not taken.
✗ Branch 139 not taken.
✗ Branch 142 not taken.
✗ Branch 143 not taken.
✗ Branch 146 not taken.
✗ Branch 147 not taken.
✗ Branch 150 not taken.
✗ Branch 151 not taken.
✗ Branch 154 not taken.
✗ Branch 155 not taken.
✗ Branch 158 not taken.
✗ Branch 159 not taken.
✓ Branch 162 taken 2303 times.
✗ Branch 163 not taken.
✓ Branch 166 taken 3 times.
✗ Branch 167 not taken.
✓ Branch 170 taken 3 times.
✗ Branch 171 not taken.
✓ Branch 174 taken 3 times.
✗ Branch 175 not taken.
✗ Branch 178 not taken.
✗ Branch 179 not taken.
✗ Branch 182 not taken.
✗ Branch 183 not taken.
✗ Branch 186 not taken.
✗ Branch 187 not taken.
✗ Branch 190 not taken.
✗ Branch 191 not taken.
2327 class AdvectionDeformer
65 {
66 public:
67 using IntegratorT = openvdb::tools::VelocityIntegrator<VelGridT, Staggered>;
68
69 13 AdvectionDeformer(const VelGridT& velocityGrid, const double timeStep, const int steps,
70 const FilterT& filter)
71 : mIntegrator(velocityGrid)
72 , mTimeStep(timeStep)
73 , mSteps(steps)
74
4/16
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
9 , mFilter(filter) { }
75
76 template <typename LeafT>
77 void reset(const LeafT& leaf, size_t /*idx*/)
78 {
79
2/64
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✓ Branch 49 taken 3 times.
✗ Branch 50 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 79 not taken.
✗ Branch 80 not taken.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✗ Branch 88 not taken.
✗ Branch 89 not taken.
✗ Branch 91 not taken.
✗ Branch 92 not taken.
✗ Branch 94 not taken.
✗ Branch 95 not taken.
6 mFilter.reset(leaf);
80 6 }
81
82 template <typename IndexIterT>
83 12 void apply(Vec3d& position, const IndexIterT& iter) const
84 {
85
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 4 times.
12 if (mFilter.valid(iter)) {
86
16/96
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✓ Branch 16 taken 4 times.
✓ Branch 17 taken 4 times.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✓ Branch 48 taken 4 times.
✓ Branch 49 taken 4 times.
✗ Branch 50 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✗ Branch 57 not taken.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
✗ Branch 60 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✓ Branch 64 taken 3 times.
✓ Branch 65 taken 3 times.
✗ Branch 66 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 69 not taken.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 72 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✗ Branch 75 not taken.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 78 not taken.
✗ Branch 79 not taken.
✓ Branch 80 taken 19135764 times.
✓ Branch 81 taken 3827080 times.
✓ Branch 82 taken 4 times.
✓ Branch 83 taken 4 times.
✓ Branch 84 taken 4 times.
✓ Branch 85 taken 4 times.
✓ Branch 86 taken 4 times.
✓ Branch 87 taken 4 times.
✗ Branch 88 not taken.
✗ Branch 89 not taken.
✗ Branch 90 not taken.
✗ Branch 91 not taken.
✗ Branch 92 not taken.
✗ Branch 93 not taken.
✗ Branch 94 not taken.
✗ Branch 95 not taken.
22962898 for (int n = 0; n < mSteps; ++n) {
87 19135791 mIntegrator.template rungeKutta<IntegrationOrder, openvdb::Vec3d>(
88
7/96
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✓ Branch 25 taken 4 times.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✓ Branch 73 taken 4 times.
✗ Branch 74 not taken.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 79 not taken.
✗ Branch 80 not taken.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✗ Branch 88 not taken.
✗ Branch 89 not taken.
✗ Branch 91 not taken.
✗ Branch 92 not taken.
✗ Branch 94 not taken.
✗ Branch 95 not taken.
✓ Branch 97 taken 3 times.
✗ Branch 98 not taken.
✗ Branch 100 not taken.
✗ Branch 101 not taken.
✗ Branch 103 not taken.
✗ Branch 104 not taken.
✗ Branch 106 not taken.
✗ Branch 107 not taken.
✗ Branch 109 not taken.
✗ Branch 110 not taken.
✗ Branch 112 not taken.
✗ Branch 113 not taken.
✗ Branch 115 not taken.
✗ Branch 116 not taken.
✗ Branch 118 not taken.
✗ Branch 119 not taken.
✓ Branch 121 taken 19135764 times.
✗ Branch 122 not taken.
✓ Branch 124 taken 4 times.
✗ Branch 125 not taken.
✓ Branch 127 taken 4 times.
✗ Branch 128 not taken.
✓ Branch 130 taken 4 times.
✗ Branch 131 not taken.
✗ Branch 133 not taken.
✗ Branch 134 not taken.
✗ Branch 136 not taken.
✗ Branch 137 not taken.
✗ Branch 139 not taken.
✗ Branch 140 not taken.
✗ Branch 142 not taken.
✗ Branch 143 not taken.
19135791 static_cast<typename IntegratorT::ElementType>(mTimeStep), position);
89 }
90 }
91 }
92
93 private:
94 IntegratorT mIntegrator;
95 double mTimeStep;
96 const int mSteps;
97 FilterT mFilter;
98 }; // class AdvectionDeformer
99
100
101 template <typename PointDataGridT, typename VelGridT, typename AdvectFilterT, typename FilterT>
102 struct AdvectionOp
103 {
104 using CachedDeformerT = CachedDeformer<double>;
105
106 13 AdvectionOp(PointDataGridT& points, const VelGridT& velocity,
107 const Index integrationOrder, const double timeStep, const Index steps,
108 const AdvectFilterT& advectFilter,
109 const FilterT& filter)
110 : mPoints(points)
111 , mVelocity(velocity)
112 , mIntegrationOrder(integrationOrder)
113 , mTimeStep(timeStep)
114 , mSteps(steps)
115 , mAdvectFilter(advectFilter)
116
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
13 , mFilter(filter) { }
117
118 22 void cache()
119 {
120 22 mCachedDeformer.reset(new CachedDeformerT(mCache));
121 22 (*this)(true);
122 22 }
123
124 void advect()
125 {
126
2/4
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
13 (*this)(false);
127 13 }
128
129 private:
130 template <int IntegrationOrder, bool Staggered>
131 44 void resolveIntegrationOrder(bool buildCache)
132 {
133 44 const auto leaf = mPoints.constTree().cbeginLeaf();
134
1/2
✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
64 if (!leaf) return;
135
136 // move points according to the pre-computed cache
137
4/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 2 times.
44 if (!buildCache && mCachedDeformer) {
138 20 movePoints(mPoints, *mCachedDeformer, mFilter);
139 20 return;
140 }
141
142 NullFilter nullFilter;
143
144
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 2 times.
24 if (buildCache) {
145 // disable group filtering from the advection deformer and perform group filtering
146 // in the cache deformer instead, this restricts the cache to just containing
147 // positions from points which are both deforming *and* are not being deleted
148 20 AdvectionDeformer<VelGridT, IntegrationOrder, Staggered, NullFilter> deformer(
149 20 mVelocity, mTimeStep, mSteps, nullFilter);
150
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
8 if (mFilter.state() == index::ALL && mAdvectFilter.state() == index::ALL) {
151
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
14 mCachedDeformer->evaluate(mPoints, deformer, nullFilter);
152 } else {
153
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
6 BinaryFilter<AdvectFilterT, FilterT, /*And=*/true> binaryFilter(
154 mAdvectFilter, mFilter);
155
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
6 mCachedDeformer->evaluate(mPoints, deformer, binaryFilter);
156 }
157 }
158 else {
159 // revert to NullFilter if all points are being evaluated
160
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
4 if (mAdvectFilter.state() == index::ALL) {
161 2 AdvectionDeformer<VelGridT, IntegrationOrder, Staggered, NullFilter> deformer(
162 2 mVelocity, mTimeStep, mSteps, nullFilter);
163
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 movePoints(mPoints, deformer, mFilter);
164 }
165 else {
166 2 AdvectionDeformer<VelGridT, IntegrationOrder, Staggered, AdvectFilterT> deformer(
167 2 mVelocity, mTimeStep, mSteps, mAdvectFilter);
168
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 movePoints(mPoints, deformer, mFilter);
169 }
170 }
171 }
172
173 template <bool Staggered>
174 48 void resolveStaggered(bool buildCache)
175 {
176
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 22 times.
48 if (mIntegrationOrder == INTEGRATION_ORDER_FWD_EULER) {
177 4 resolveIntegrationOrder<1, Staggered>(buildCache);
178
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 20 times.
44 } else if (mIntegrationOrder == INTEGRATION_ORDER_RK_2ND) {
179 4 resolveIntegrationOrder<2, Staggered>(buildCache);
180
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 18 times.
40 } else if (mIntegrationOrder == INTEGRATION_ORDER_RK_3RD) {
181 4 resolveIntegrationOrder<3, Staggered>(buildCache);
182
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 2 times.
36 } else if (mIntegrationOrder == INTEGRATION_ORDER_RK_4TH) {
183 32 resolveIntegrationOrder<4, Staggered>(buildCache);
184 }
185 }
186
187 48 void operator()(bool buildCache)
188 {
189 // early-exit if no leafs
190
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
48 if (mPoints.constTree().leafCount() == 0) return;
191
192
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
48 if (mVelocity.getGridClass() == openvdb::GRID_STAGGERED) {
193 resolveStaggered<true>(buildCache);
194 } else {
195 48 resolveStaggered<false>(buildCache);
196 }
197 }
198
199 PointDataGridT& mPoints;
200 const VelGridT& mVelocity;
201 const Index mIntegrationOrder;
202 const double mTimeStep;
203 const Index mSteps;
204 const AdvectFilterT& mAdvectFilter;
205 const FilterT& mFilter;
206 CachedDeformerT::Cache mCache;
207 std::unique_ptr<CachedDeformerT> mCachedDeformer;
208 }; // struct AdvectionOp
209
210 } // namespace point_advect_internal
211
212 /// @endcond
213
214 ////////////////////////////////////////
215
216
217 template <typename PointDataGridT, typename VelGridT, typename AdvectFilterT, typename FilterT>
218 14 inline void advectPoints(PointDataGridT& points, const VelGridT& velocity,
219 const Index integrationOrder, const double timeStep, const Index steps,
220 const AdvectFilterT& advectFilter,
221 const FilterT& filter,
222 const bool cached)
223 {
224 using namespace point_advect_internal;
225
226 14 if (steps == 0) return;
227
228 14 if (integrationOrder > 4) {
229 2 throw ValueError{"Unknown integration order for advecting points."};
230 }
231
232 13 AdvectionOp<PointDataGridT, VelGridT, AdvectFilterT, FilterT> op(
233 points, velocity, integrationOrder, timeStep, steps,
234 advectFilter, filter);
235
236 // if caching is enabled, sample the velocity field using a CachedDeformer to store the
237 // intermediate positions before moving the points, this uses more memory but typically
238 // results in faster overall performance
239 13 if (cached) op.cache();
240
241 // advect the points
242 op.advect();
243 }
244
245 } // namespace points
246 } // namespace OPENVDB_VERSION_NAME
247 } // namespace openvdb
248
249 #endif // OPENVDB_POINTS_POINT_ADVECT_HAS_BEEN_INCLUDED
250