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 PointMove.h | ||
7 | /// | ||
8 | /// @brief Ability to move VDB Points using a custom deformer. | ||
9 | /// | ||
10 | /// Deformers used when moving points are in world space by default and must adhere | ||
11 | /// to the interface described in the example below: | ||
12 | /// @code | ||
13 | /// struct MyDeformer | ||
14 | /// { | ||
15 | /// // A reset is performed on each leaf in turn before the points in that leaf are | ||
16 | /// // deformed. A leaf and leaf index (standard leaf traversal order) are supplied as | ||
17 | /// // the arguments, which matches the functor interface for LeafManager::foreach(). | ||
18 | /// template <typename LeafNoteType> | ||
19 | /// void reset(LeafNoteType& leaf, size_t idx); | ||
20 | /// | ||
21 | /// // Evaluate the deformer and modify the given position to generate the deformed | ||
22 | /// // position. An index iterator is supplied as the argument to allow querying the | ||
23 | /// // point offset or containing voxel coordinate. | ||
24 | /// template <typename IndexIterT> | ||
25 | /// void apply(Vec3d& position, const IndexIterT& iter) const; | ||
26 | /// }; | ||
27 | /// @endcode | ||
28 | /// | ||
29 | /// @note The DeformerTraits struct (defined in PointMask.h) can be used to configure | ||
30 | /// a deformer to evaluate in index space. | ||
31 | |||
32 | #ifndef OPENVDB_POINTS_POINT_MOVE_HAS_BEEN_INCLUDED | ||
33 | #define OPENVDB_POINTS_POINT_MOVE_HAS_BEEN_INCLUDED | ||
34 | |||
35 | #include <openvdb/openvdb.h> | ||
36 | |||
37 | #include <openvdb/points/PointDataGrid.h> | ||
38 | #include <openvdb/points/PointMask.h> | ||
39 | |||
40 | #include <tbb/concurrent_vector.h> | ||
41 | |||
42 | #include <algorithm> | ||
43 | #include <iterator> // for std::begin(), std::end() | ||
44 | #include <map> | ||
45 | #include <numeric> // for std::iota() | ||
46 | #include <tuple> | ||
47 | #include <unordered_map> | ||
48 | #include <vector> | ||
49 | |||
50 | class TestPointMove; | ||
51 | |||
52 | |||
53 | namespace openvdb { | ||
54 | OPENVDB_USE_VERSION_NAMESPACE | ||
55 | namespace OPENVDB_VERSION_NAME { | ||
56 | namespace points { | ||
57 | |||
58 | // dummy object for future use | ||
59 | namespace future { struct Advect { }; } | ||
60 | |||
61 | |||
62 | /// @brief Move points in a PointDataGrid using a custom deformer | ||
63 | /// @param points the PointDataGrid containing the points to be moved. | ||
64 | /// @param deformer a custom deformer that defines how to move the points. | ||
65 | /// @param filter an optional index filter | ||
66 | /// @param objectNotInUse for future use, this object is currently ignored | ||
67 | /// @param threaded enable or disable threading (threading is enabled by default) | ||
68 | template <typename PointDataGridT, typename DeformerT, typename FilterT = NullFilter> | ||
69 | inline void movePoints(PointDataGridT& points, | ||
70 | DeformerT& deformer, | ||
71 | const FilterT& filter = NullFilter(), | ||
72 | future::Advect* objectNotInUse = nullptr, | ||
73 | bool threaded = true); | ||
74 | |||
75 | |||
76 | /// @brief Move points in a PointDataGrid using a custom deformer and a new transform | ||
77 | /// @param points the PointDataGrid containing the points to be moved. | ||
78 | /// @param transform target transform to use for the resulting points. | ||
79 | /// @param deformer a custom deformer that defines how to move the points. | ||
80 | /// @param filter an optional index filter | ||
81 | /// @param objectNotInUse for future use, this object is currently ignored | ||
82 | /// @param threaded enable or disable threading (threading is enabled by default) | ||
83 | template <typename PointDataGridT, typename DeformerT, typename FilterT = NullFilter> | ||
84 | inline void movePoints(PointDataGridT& points, | ||
85 | const math::Transform& transform, | ||
86 | DeformerT& deformer, | ||
87 | const FilterT& filter = NullFilter(), | ||
88 | future::Advect* objectNotInUse = nullptr, | ||
89 | bool threaded = true); | ||
90 | |||
91 | |||
92 | // define leaf index in use as 32-bit | ||
93 | namespace point_move_internal { using LeafIndex = Index32; } | ||
94 | |||
95 | |||
96 | /// @brief A Deformer that caches the resulting positions from evaluating another Deformer | ||
97 | template <typename T> | ||
98 | class CachedDeformer | ||
99 | { | ||
100 | public: | ||
101 | using LeafIndex = point_move_internal::LeafIndex; | ||
102 | using Vec3T = typename math::Vec3<T>; | ||
103 | using LeafVecT = std::vector<Vec3T>; | ||
104 | using LeafMapT = std::unordered_map<LeafIndex, Vec3T>; | ||
105 | |||
106 | // Internal data cache to allow the deformer to offer light-weight copying | ||
107 |
1/2✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
3 | struct Cache |
108 | { | ||
109 | 2360 | struct Leaf | |
110 | { | ||
111 | /// @brief clear data buffers and reset counter | ||
112 | void clear() { | ||
113 | vecData.clear(); | ||
114 | mapData.clear(); | ||
115 | 2324 | totalSize = 0; | |
116 | } | ||
117 | |||
118 | LeafVecT vecData; | ||
119 | LeafMapT mapData; | ||
120 | Index totalSize = 0; | ||
121 | }; // struct Leaf | ||
122 | |||
123 | std::vector<Leaf> leafs; | ||
124 | }; // struct Cache | ||
125 | |||
126 | /// Cache is expected to be persistent for the lifetime of the CachedDeformer | ||
127 | explicit CachedDeformer(Cache& cache); | ||
128 | |||
129 | /// Caches the result of evaluating the supplied point grid using the deformer and filter | ||
130 | /// @param grid the points to be moved | ||
131 | /// @param deformer the deformer to apply to the points | ||
132 | /// @param filter the point filter to use when evaluating the points | ||
133 | /// @param threaded enable or disable threading (threading is enabled by default) | ||
134 | template <typename PointDataGridT, typename DeformerT, typename FilterT> | ||
135 | void evaluate(PointDataGridT& grid, DeformerT& deformer, const FilterT& filter, | ||
136 | bool threaded = true); | ||
137 | |||
138 | /// Stores pointers to the vector or map and optionally expands the map into a vector | ||
139 | /// @throw IndexError if idx is out-of-range of the leafs in the cache | ||
140 | template <typename LeafT> | ||
141 | void reset(const LeafT& leaf, size_t idx); | ||
142 | |||
143 | /// Retrieve the new position from the cache | ||
144 | template <typename IndexIterT> | ||
145 | void apply(Vec3d& position, const IndexIterT& iter) const; | ||
146 | |||
147 | private: | ||
148 | friend class ::TestPointMove; | ||
149 | |||
150 | Cache& mCache; | ||
151 | const LeafVecT* mLeafVec = nullptr; | ||
152 | const LeafMapT* mLeafMap = nullptr; | ||
153 | }; // class CachedDeformer | ||
154 | |||
155 | |||
156 | //////////////////////////////////////// | ||
157 | |||
158 | |||
159 | namespace point_move_internal { | ||
160 | |||
161 | using IndexArray = std::vector<Index>; | ||
162 | |||
163 | using IndexTriple = std::tuple<LeafIndex, Index, Index>; | ||
164 | using IndexTripleArray = tbb::concurrent_vector<IndexTriple>; | ||
165 | using GlobalPointIndexMap = std::vector<IndexTripleArray>; | ||
166 | using GlobalPointIndexIndices = std::vector<IndexArray>; | ||
167 | |||
168 | using IndexPair = std::pair<Index, Index>; | ||
169 | using IndexPairArray = std::vector<IndexPair>; | ||
170 | using LocalPointIndexMap = std::vector<IndexPairArray>; | ||
171 | |||
172 | using LeafIndexArray = std::vector<LeafIndex>; | ||
173 | using LeafOffsetArray = std::vector<LeafIndexArray>; | ||
174 | using LeafMap = std::unordered_map<Coord, LeafIndex>; | ||
175 | |||
176 | |||
177 | template <typename DeformerT, typename TreeT, typename FilterT> | ||
178 | struct BuildMoveMapsOp | ||
179 | { | ||
180 | using LeafT = typename TreeT::LeafNodeType; | ||
181 | using LeafArrayT = std::vector<LeafT*>; | ||
182 | using LeafManagerT = typename tree::LeafManager<TreeT>; | ||
183 | |||
184 | 38 | BuildMoveMapsOp(const DeformerT& deformer, | |
185 | GlobalPointIndexMap& globalMoveLeafMap, | ||
186 | LocalPointIndexMap& localMoveLeafMap, | ||
187 | const LeafMap& targetLeafMap, | ||
188 | const math::Transform& targetTransform, | ||
189 | const math::Transform& sourceTransform, | ||
190 | const FilterT& filter) | ||
191 | : mDeformer(deformer) | ||
192 | , mGlobalMoveLeafMap(globalMoveLeafMap) | ||
193 | , mLocalMoveLeafMap(localMoveLeafMap) | ||
194 | , mTargetLeafMap(targetLeafMap) | ||
195 | , mTargetTransform(targetTransform) | ||
196 | , mSourceTransform(sourceTransform) | ||
197 | 38 | , mFilter(filter) { } | |
198 | |||
199 | 6124 | void operator()(LeafT& leaf, size_t idx) const | |
200 | { | ||
201 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
4834 | DeformerT deformer(mDeformer); |
202 |
1/2✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
|
4732 | deformer.reset(leaf, idx); |
203 | |||
204 | // determine source leaf node origin and offset in the source leaf vector | ||
205 | |||
206 | 6124 | Coord sourceLeafOrigin = leaf.origin(); | |
207 | |||
208 |
3/6✓ Branch 1 taken 3062 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3062 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3062 times.
✗ Branch 8 not taken.
|
12196 | auto sourceHandle = AttributeWriteHandle<Vec3f>::create(leaf.attributeArray("P")); |
209 | |||
210 |
4/5✓ Branch 0 taken 5491261 times.
✓ Branch 1 taken 3062 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
✓ Branch 4 taken 26 times.
|
21971288 | for (auto iter = leaf.beginIndexOn(mFilter); iter; iter++) { |
211 | |||
212 | const bool useIndexSpace = DeformerTraits<DeformerT>::IndexSpace; | ||
213 | |||
214 | // extract index-space position and apply index-space deformation (if applicable) | ||
215 | |||
216 |
2/4✓ Branch 1 taken 5491278 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 5491278 times.
✗ Branch 6 not taken.
|
10982556 | Vec3d positionIS = sourceHandle->get(*iter) + iter.getCoord().asVec3d(); |
217 | if (useIndexSpace) { | ||
218 | deformer.apply(positionIS, iter); | ||
219 | } | ||
220 | |||
221 | // transform to world-space position and apply world-space deformation (if applicable) | ||
222 | |||
223 |
1/2✓ Branch 1 taken 5491278 times.
✗ Branch 2 not taken.
|
10982556 | Vec3d positionWS = mSourceTransform.indexToWorld(positionIS); |
224 | if (!useIndexSpace) { | ||
225 |
1/2✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
|
7674268 | deformer.apply(positionWS, iter); |
226 | } | ||
227 | |||
228 | // transform to index-space position of target grid | ||
229 | |||
230 |
1/2✓ Branch 1 taken 5491278 times.
✗ Branch 2 not taken.
|
10982556 | positionIS = mTargetTransform.worldToIndex(positionWS); |
231 | |||
232 | // determine target voxel and offset | ||
233 | |||
234 | 10982556 | Coord targetVoxel = Coord::round(positionIS); | |
235 | 10982556 | Index targetOffset = LeafT::coordToOffset(targetVoxel); | |
236 | |||
237 | // set new local position in source transform space (if point has been deformed) | ||
238 | |||
239 | Vec3d voxelPosition(positionIS - targetVoxel.asVec3d()); | ||
240 |
1/2✓ Branch 2 taken 5491278 times.
✗ Branch 3 not taken.
|
10982556 | sourceHandle->set(*iter, voxelPosition); |
241 | |||
242 | // determine target leaf node origin and offset in the target leaf vector | ||
243 | |||
244 | 10982556 | Coord targetLeafOrigin = targetVoxel & ~(LeafT::DIM - 1); | |
245 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 5491278 times.
|
10982556 | assert(mTargetLeafMap.find(targetLeafOrigin) != mTargetLeafMap.end()); |
246 |
3/4✓ Branch 1 taken 5491278 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 491191 times.
✓ Branch 4 taken 5000087 times.
|
10982556 | const LeafIndex targetLeafOffset(mTargetLeafMap.at(targetLeafOrigin)); |
247 | |||
248 | // insert into move map based on whether point ends up in a new leaf node or not | ||
249 | |||
250 | if (targetLeafOrigin == sourceLeafOrigin) { | ||
251 |
1/2✓ Branch 2 taken 41680 times.
✗ Branch 3 not taken.
|
83360 | mLocalMoveLeafMap[targetLeafOffset].emplace_back(targetOffset, *iter); |
252 | } | ||
253 | else { | ||
254 |
1/4✓ Branch 2 taken 5449598 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
10899196 | mGlobalMoveLeafMap[targetLeafOffset].push_back(IndexTriple( |
255 | 10899196 | LeafIndex(static_cast<LeafIndex>(idx)), targetOffset, *iter)); | |
256 | } | ||
257 | } | ||
258 | } | ||
259 | |||
260 | private: | ||
261 | const DeformerT& mDeformer; | ||
262 | GlobalPointIndexMap& mGlobalMoveLeafMap; | ||
263 | LocalPointIndexMap& mLocalMoveLeafMap; | ||
264 | const LeafMap& mTargetLeafMap; | ||
265 | const math::Transform& mTargetTransform; | ||
266 | const math::Transform& mSourceTransform; | ||
267 | const FilterT& mFilter; | ||
268 | }; // struct BuildMoveMapsOp | ||
269 | |||
270 | template <typename LeafT> | ||
271 | inline Index | ||
272 | 9328518 | indexOffsetFromVoxel(const Index voxelOffset, const LeafT& leaf, IndexArray& offsets) | |
273 | { | ||
274 | // compute the target point index by summing the point index of the previous | ||
275 | // voxel with the current number of points added to this voxel, tracked by the | ||
276 | // offsets array | ||
277 | |||
278 |
2/2✓ Branch 0 taken 9293419 times.
✓ Branch 1 taken 35099 times.
|
9328518 | Index targetOffset = offsets[voxelOffset]++; |
279 |
2/2✓ Branch 0 taken 9293419 times.
✓ Branch 1 taken 35099 times.
|
9328518 | if (voxelOffset > 0) { |
280 | 9293419 | targetOffset += static_cast<Index>(leaf.getValue(voxelOffset - 1)); | |
281 | } | ||
282 | 9328518 | return targetOffset; | |
283 | } | ||
284 | |||
285 | |||
286 | template <typename TreeT> | ||
287 | struct GlobalMovePointsOp | ||
288 | { | ||
289 | using LeafT = typename TreeT::LeafNodeType; | ||
290 | using LeafArrayT = std::vector<LeafT*>; | ||
291 | using LeafManagerT = typename tree::LeafManager<TreeT>; | ||
292 | using AttributeArrays = std::vector<AttributeArray*>; | ||
293 | |||
294 | 90 | GlobalMovePointsOp(LeafOffsetArray& offsetMap, | |
295 | LeafManagerT& sourceLeafManager, | ||
296 | const Index attributeIndex, | ||
297 | const GlobalPointIndexMap& moveLeafMap, | ||
298 | const GlobalPointIndexIndices& moveLeafIndices) | ||
299 | : mOffsetMap(offsetMap) | ||
300 | , mSourceLeafManager(sourceLeafManager) | ||
301 | , mAttributeIndex(attributeIndex) | ||
302 | , mMoveLeafMap(moveLeafMap) | ||
303 | 90 | , mMoveLeafIndices(moveLeafIndices) { } | |
304 | |||
305 | // A CopyIterator is designed to use the indices in a GlobalPointIndexMap for this leaf | ||
306 | // and match the interface required for AttributeArray::copyValues() | ||
307 | struct CopyIterator | ||
308 | { | ||
309 | 4866 | CopyIterator(const LeafT& leaf, const IndexArray& sortedIndices, | |
310 | const IndexTripleArray& moveIndices, IndexArray& offsets) | ||
311 | : mLeaf(leaf) | ||
312 | , mSortedIndices(sortedIndices) | ||
313 | , mMoveIndices(moveIndices) | ||
314 | 4866 | , mOffsets(offsets) { } | |
315 | |||
316 |
2/2✓ Branch 0 taken 9281752 times.
✓ Branch 1 taken 14545 times.
|
9296297 | operator bool() const { return bool(mIt); } |
317 | |||
318 | void reset(Index startIndex, Index endIndex) | ||
319 | { | ||
320 | 14545 | mIndex = startIndex; | |
321 | 14545 | mEndIndex = endIndex; | |
322 | 14545 | this->advance(); | |
323 | } | ||
324 | |||
325 | CopyIterator& operator++() | ||
326 | { | ||
327 | 9281752 | this->advance(); | |
328 | 9281752 | return *this; | |
329 | } | ||
330 | |||
331 | 9286618 | Index leafIndex(Index i) const | |
332 | { | ||
333 |
2/2✓ Branch 0 taken 9281752 times.
✓ Branch 1 taken 4866 times.
|
9286618 | if (i < mSortedIndices.size()) { |
334 | 9281752 | return std::get<0>(this->leafIndexTriple(i)); | |
335 | } | ||
336 | return std::numeric_limits<Index>::max(); | ||
337 | } | ||
338 | |||
339 | Index sourceIndex() const | ||
340 | { | ||
341 | assert(mIt); | ||
342 | 9281719 | return std::get<2>(*mIt); | |
343 | } | ||
344 | |||
345 | 9281752 | Index targetIndex() const | |
346 | { | ||
347 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9281752 times.
|
9281752 | assert(mIt); |
348 | 9281752 | return indexOffsetFromVoxel(std::get<1>(*mIt), mLeaf, mOffsets); | |
349 | } | ||
350 | |||
351 | private: | ||
352 | 9296297 | void advance() | |
353 | { | ||
354 |
3/4✓ Branch 0 taken 9281752 times.
✓ Branch 1 taken 14545 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9281752 times.
|
9296297 | if (mIndex >= mEndIndex || mIndex >= mSortedIndices.size()) { |
355 | 14545 | mIt = nullptr; | |
356 | } | ||
357 | else { | ||
358 | 9281752 | mIt = &this->leafIndexTriple(mIndex); | |
359 | } | ||
360 | 9296297 | ++mIndex; | |
361 | 9296297 | } | |
362 | |||
363 | const IndexTriple& leafIndexTriple(Index i) const | ||
364 | { | ||
365 | 18563504 | return mMoveIndices[mSortedIndices[i]]; | |
366 | } | ||
367 | |||
368 | private: | ||
369 | const LeafT& mLeaf; | ||
370 | Index mIndex; | ||
371 | Index mEndIndex; | ||
372 | const IndexArray& mSortedIndices; | ||
373 | const IndexTripleArray& mMoveIndices; | ||
374 | IndexArray& mOffsets; | ||
375 | const IndexTriple* mIt = nullptr; | ||
376 | }; // struct CopyIterator | ||
377 | |||
378 | 4994 | void operator()(LeafT& leaf, size_t idx) const | |
379 | { | ||
380 | 4994 | const IndexTripleArray& moveIndices = mMoveLeafMap[idx]; | |
381 |
2/2✓ Branch 0 taken 128 times.
✓ Branch 1 taken 4866 times.
|
4994 | if (moveIndices.empty()) return; |
382 | 4866 | const IndexArray& sortedIndices = mMoveLeafIndices[idx]; | |
383 | |||
384 | // extract per-voxel offsets for this leaf | ||
385 | |||
386 | 4866 | LeafIndexArray& offsets = mOffsetMap[idx]; | |
387 | |||
388 | // extract target array and ensure data is out-of-core and non-uniform | ||
389 | |||
390 | 4866 | auto& targetArray = leaf.attributeArray(mAttributeIndex); | |
391 | 4866 | targetArray.loadData(); | |
392 | 4866 | targetArray.expand(); | |
393 | |||
394 | // perform the copy | ||
395 | |||
396 | CopyIterator copyIterator(leaf, sortedIndices, moveIndices, offsets); | ||
397 | |||
398 | // use the sorted indices to track the index of the source leaf | ||
399 | |||
400 | 4866 | Index sourceLeafIndex = copyIterator.leafIndex(0); | |
401 | Index startIndex = 0; | ||
402 | |||
403 |
2/2✓ Branch 0 taken 9281752 times.
✓ Branch 1 taken 4866 times.
|
9286618 | for (size_t i = 1; i <= sortedIndices.size(); i++) { |
404 | 9281752 | Index endIndex = static_cast<Index>(i); | |
405 | 9281752 | Index newSourceLeafIndex = copyIterator.leafIndex(endIndex); | |
406 | |||
407 | // when it changes, do a batch-copy of all the indices that lie within this range | ||
408 | // TODO: this step could use nested parallelization for cases where there are a | ||
409 | // large number of points being moved per attribute | ||
410 | |||
411 |
2/2✓ Branch 0 taken 14545 times.
✓ Branch 1 taken 9267207 times.
|
9281752 | if (newSourceLeafIndex > sourceLeafIndex) { |
412 | copyIterator.reset(startIndex, endIndex); | ||
413 | |||
414 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 14545 times.
|
14545 | const LeafT& sourceLeaf = mSourceLeafManager.leaf(sourceLeafIndex); |
415 | 14545 | const auto& sourceArray = sourceLeaf.constAttributeArray(mAttributeIndex); | |
416 | 14545 | sourceArray.loadData(); | |
417 | |||
418 | 14545 | targetArray.copyValuesUnsafe(sourceArray, copyIterator); | |
419 | |||
420 | sourceLeafIndex = newSourceLeafIndex; | ||
421 | startIndex = endIndex; | ||
422 | } | ||
423 | } | ||
424 | } | ||
425 | |||
426 | private: | ||
427 | LeafOffsetArray& mOffsetMap; | ||
428 | LeafManagerT& mSourceLeafManager; | ||
429 | const Index mAttributeIndex; | ||
430 | const GlobalPointIndexMap& mMoveLeafMap; | ||
431 | const GlobalPointIndexIndices& mMoveLeafIndices; | ||
432 | }; // struct GlobalMovePointsOp | ||
433 | |||
434 | |||
435 | template <typename TreeT> | ||
436 | struct LocalMovePointsOp | ||
437 | { | ||
438 | using LeafT = typename TreeT::LeafNodeType; | ||
439 | using LeafArrayT = std::vector<LeafT*>; | ||
440 | using LeafManagerT = typename tree::LeafManager<TreeT>; | ||
441 | using AttributeArrays = std::vector<AttributeArray*>; | ||
442 | |||
443 | 90 | LocalMovePointsOp( LeafOffsetArray& offsetMap, | |
444 | const LeafIndexArray& sourceIndices, | ||
445 | LeafManagerT& sourceLeafManager, | ||
446 | const Index attributeIndex, | ||
447 | const LocalPointIndexMap& moveLeafMap) | ||
448 | : mOffsetMap(offsetMap) | ||
449 | , mSourceIndices(sourceIndices) | ||
450 | , mSourceLeafManager(sourceLeafManager) | ||
451 | , mAttributeIndex(attributeIndex) | ||
452 | 90 | , mMoveLeafMap(moveLeafMap) { } | |
453 | |||
454 | // A CopyIterator is designed to use the indices in a LocalPointIndexMap for this leaf | ||
455 | // and match the interface required for AttributeArray::copyValues() | ||
456 | struct CopyIterator | ||
457 | { | ||
458 | 184 | CopyIterator(const LeafT& leaf, const IndexPairArray& indices, IndexArray& offsets) | |
459 | : mLeaf(leaf) | ||
460 | , mIndices(indices) | ||
461 | 184 | , mOffsets(offsets) { } | |
462 | |||
463 |
2/2✓ Branch 0 taken 46766 times.
✓ Branch 1 taken 184 times.
|
46950 | operator bool() const { return mIndex < static_cast<int>(mIndices.size()); } |
464 | |||
465 | 46766 | CopyIterator& operator++() { ++mIndex; return *this; } | |
466 | |||
467 | Index sourceIndex() const | ||
468 | { | ||
469 | 46730 | return mIndices[mIndex].second; | |
470 | } | ||
471 | |||
472 | 46766 | Index targetIndex() const | |
473 | { | ||
474 | 46766 | return indexOffsetFromVoxel(mIndices[mIndex].first, mLeaf, mOffsets); | |
475 | } | ||
476 | |||
477 | private: | ||
478 | const LeafT& mLeaf; | ||
479 | const IndexPairArray& mIndices; | ||
480 | IndexArray& mOffsets; | ||
481 | int mIndex = 0; | ||
482 | }; // struct CopyIterator | ||
483 | |||
484 | 4994 | void operator()(LeafT& leaf, size_t idx) const | |
485 | { | ||
486 |
2/2✓ Branch 0 taken 4810 times.
✓ Branch 1 taken 184 times.
|
4994 | const IndexPairArray& moveIndices = mMoveLeafMap[idx]; |
487 |
2/2✓ Branch 0 taken 4810 times.
✓ Branch 1 taken 184 times.
|
4994 | if (moveIndices.empty()) return; |
488 | |||
489 | // extract per-voxel offsets for this leaf | ||
490 | |||
491 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 184 times.
|
184 | LeafIndexArray& offsets = mOffsetMap[idx]; |
492 | |||
493 | // extract source array that has the same origin as the target leaf | ||
494 | |||
495 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 184 times.
|
184 | assert(idx < mSourceIndices.size()); |
496 | 184 | const Index sourceLeafOffset(mSourceIndices[idx]); | |
497 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 184 times.
|
184 | LeafT& sourceLeaf = mSourceLeafManager.leaf(sourceLeafOffset); |
498 | 184 | const auto& sourceArray = sourceLeaf.constAttributeArray(mAttributeIndex); | |
499 | 184 | sourceArray.loadData(); | |
500 | |||
501 | // extract target array and ensure data is out-of-core and non-uniform | ||
502 | |||
503 | 184 | auto& targetArray = leaf.attributeArray(mAttributeIndex); | |
504 | 184 | targetArray.loadData(); | |
505 | 184 | targetArray.expand(); | |
506 | |||
507 | // perform the copy | ||
508 | |||
509 | CopyIterator copyIterator(leaf, moveIndices, offsets); | ||
510 | 184 | targetArray.copyValuesUnsafe(sourceArray, copyIterator); | |
511 | } | ||
512 | |||
513 | private: | ||
514 | LeafOffsetArray& mOffsetMap; | ||
515 | const LeafIndexArray& mSourceIndices; | ||
516 | LeafManagerT& mSourceLeafManager; | ||
517 | const Index mAttributeIndex; | ||
518 | const LocalPointIndexMap& mMoveLeafMap; | ||
519 | }; // struct LocalMovePointsOp | ||
520 | |||
521 | |||
522 | } // namespace point_move_internal | ||
523 | |||
524 | |||
525 | //////////////////////////////////////// | ||
526 | |||
527 | |||
528 | template <typename PointDataGridT, typename DeformerT, typename FilterT> | ||
529 | 76 | inline void movePoints( PointDataGridT& points, | |
530 | const math::Transform& transform, | ||
531 | DeformerT& deformer, | ||
532 | const FilterT& filter, | ||
533 | future::Advect* objectNotInUse, | ||
534 | bool threaded) | ||
535 | { | ||
536 | using LeafIndex = point_move_internal::LeafIndex; | ||
537 | using PointDataTreeT = typename PointDataGridT::TreeType; | ||
538 | using LeafT = typename PointDataTreeT::LeafNodeType; | ||
539 | using LeafManagerT = typename tree::LeafManager<PointDataTreeT>; | ||
540 | |||
541 | using namespace point_move_internal; | ||
542 | |||
543 | // this object is for future use only | ||
544 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
|
76 | assert(!objectNotInUse); |
545 | (void)objectNotInUse; | ||
546 | |||
547 | PointDataTreeT& tree = points.tree(); | ||
548 | |||
549 | // early exit if no LeafNodes | ||
550 | |||
551 | auto iter = tree.cbeginLeaf(); | ||
552 | |||
553 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
|
76 | if (!iter) return; |
554 | |||
555 | // build voxel topology taking into account any point group deletion | ||
556 | |||
557 | 76 | auto newPoints = point_mask_internal::convertPointsToScalar<PointDataGridT>( | |
558 | points, transform, filter, deformer, threaded); | ||
559 | auto& newTree = newPoints->tree(); | ||
560 | |||
561 | // create leaf managers for both trees | ||
562 | |||
563 |
1/2✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
|
152 | LeafManagerT sourceLeafManager(tree); |
564 |
1/2✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
|
152 | LeafManagerT targetLeafManager(newTree); |
565 | |||
566 | // extract the existing attribute set | ||
567 |
1/2✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
|
76 | const auto& existingAttributeSet = points.tree().cbeginLeaf()->attributeSet(); |
568 | |||
569 | // build a coord -> index map for looking up target leafs by origin and a faster | ||
570 | // unordered map for finding the source index from a target index | ||
571 | |||
572 | LeafMap targetLeafMap; | ||
573 |
1/2✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
|
76 | LeafIndexArray sourceIndices(targetLeafManager.leafCount(), |
574 |
2/4✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 38 times.
✗ Branch 5 not taken.
|
76 | std::numeric_limits<LeafIndex>::max()); |
575 | |||
576 |
1/4✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
152 | LeafOffsetArray offsetMap(targetLeafManager.leafCount()); |
577 | |||
578 | { | ||
579 | LeafMap sourceLeafMap; | ||
580 | auto sourceRange = sourceLeafManager.leafRange(); | ||
581 |
2/2✓ Branch 1 taken 3062 times.
✓ Branch 2 taken 38 times.
|
6200 | for (auto leaf = sourceRange.begin(); leaf; ++leaf) { |
582 |
1/2✓ Branch 1 taken 3062 times.
✗ Branch 2 not taken.
|
6124 | sourceLeafMap.insert({leaf->origin(), LeafIndex(static_cast<LeafIndex>(leaf.pos()))}); |
583 | } | ||
584 | auto targetRange = targetLeafManager.leafRange(); | ||
585 |
2/2✓ Branch 1 taken 2489 times.
✓ Branch 2 taken 38 times.
|
5054 | for (auto leaf = targetRange.begin(); leaf; ++leaf) { |
586 |
1/2✓ Branch 1 taken 2489 times.
✗ Branch 2 not taken.
|
4978 | targetLeafMap.insert({leaf->origin(), LeafIndex(static_cast<LeafIndex>(leaf.pos()))}); |
587 | } | ||
588 | |||
589 | // acquire registry lock to avoid locking when appending attributes in parallel | ||
590 | |||
591 |
1/2✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
|
76 | AttributeArray::ScopedRegistryLock lock; |
592 | |||
593 | // perform four independent per-leaf operations in parallel | ||
594 |
2/6✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 38 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
76 | targetLeafManager.foreach( |
595 | 7467 | [&](LeafT& leaf, size_t idx) { | |
596 | // map frequency => cumulative histogram | ||
597 | 2489 | auto* buffer = leaf.buffer().data(); | |
598 |
22/52✓ Branch 0 taken 4599 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 4599 times.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 511 times.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 2044 times.
✓ Branch 9 taken 4 times.
✓ Branch 10 taken 511 times.
✓ Branch 11 taken 1 times.
✓ Branch 12 taken 2555 times.
✓ Branch 13 taken 5 times.
✓ Branch 14 taken 3066 times.
✓ Branch 15 taken 6 times.
✓ Branch 16 taken 4088 times.
✓ Branch 17 taken 8 times.
✓ Branch 18 taken 12264 times.
✓ Branch 19 taken 24 times.
✗ 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 taken 3066 times.
✓ Branch 33 taken 6 times.
✗ 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 not taken.
✗ Branch 49 not taken.
✓ Branch 50 taken 1234576 times.
✓ Branch 51 taken 2416 times.
|
1274368 | for (Index i = 1; i < leaf.buffer().size(); i++) { |
599 | 1271879 | buffer[i] = buffer[i-1] + buffer[i]; | |
600 | } | ||
601 | // replace attribute set with a copy of the existing one | ||
602 | 2489 | leaf.replaceAttributeSet( | |
603 |
11/52✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 7 taken 9 times.
✗ Branch 8 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✓ Branch 22 taken 4 times.
✗ Branch 23 not taken.
✓ Branch 27 taken 1 times.
✗ Branch 28 not taken.
✓ Branch 32 taken 5 times.
✗ Branch 33 not taken.
✓ Branch 37 taken 6 times.
✗ Branch 38 not taken.
✓ Branch 42 taken 8 times.
✗ Branch 43 not taken.
✓ Branch 47 taken 24 times.
✗ Branch 48 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 57 not taken.
✗ Branch 58 not taken.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 72 not taken.
✗ Branch 73 not taken.
✗ Branch 77 not taken.
✗ Branch 78 not taken.
✓ Branch 82 taken 6 times.
✗ Branch 83 not taken.
✗ Branch 87 not taken.
✗ Branch 88 not taken.
✗ Branch 92 not taken.
✗ Branch 93 not taken.
✗ Branch 97 not taken.
✗ Branch 98 not taken.
✗ Branch 102 not taken.
✗ Branch 103 not taken.
✗ Branch 107 not taken.
✗ Branch 108 not taken.
✗ Branch 112 not taken.
✗ Branch 113 not taken.
✗ Branch 117 not taken.
✗ Branch 118 not taken.
✗ Branch 122 not taken.
✗ Branch 123 not taken.
✓ Branch 127 taken 2416 times.
✗ Branch 128 not taken.
|
2489 | new AttributeSet(existingAttributeSet, leaf.getLastValue(), &lock), |
604 | /*allowMismatchingDescriptors=*/true); | ||
605 | // store the index of the source leaf in a corresponding target leaf array | ||
606 |
17/52✓ Branch 0 taken 5 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 3 times.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 4 times.
✓ Branch 13 taken 1 times.
✓ Branch 14 taken 2 times.
✓ Branch 15 taken 4 times.
✓ Branch 16 taken 4 times.
✓ Branch 17 taken 4 times.
✓ Branch 18 taken 24 times.
✗ 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 taken 6 times.
✗ 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 not taken.
✗ Branch 49 not taken.
✓ Branch 50 taken 2136 times.
✓ Branch 51 taken 280 times.
|
2489 | const auto it = sourceLeafMap.find(leaf.origin()); |
607 |
17/52✓ Branch 0 taken 5 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 3 times.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 4 times.
✓ Branch 13 taken 1 times.
✓ Branch 14 taken 2 times.
✓ Branch 15 taken 4 times.
✓ Branch 16 taken 4 times.
✓ Branch 17 taken 4 times.
✓ Branch 18 taken 24 times.
✗ 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 taken 6 times.
✗ 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 not taken.
✗ Branch 49 not taken.
✓ Branch 50 taken 2136 times.
✓ Branch 51 taken 280 times.
|
2489 | if (it != sourceLeafMap.end()) { |
608 | 2192 | sourceIndices[idx] = it->second; | |
609 | } | ||
610 | // allocate offset maps | ||
611 | 2489 | offsetMap[idx].resize(LeafT::SIZE); | |
612 | }, | ||
613 | threaded); | ||
614 | } | ||
615 | |||
616 | // moving leaf | ||
617 | |||
618 |
2/4✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 38 times.
✗ Branch 5 not taken.
|
152 | GlobalPointIndexMap globalMoveLeafMap(targetLeafManager.leafCount()); |
619 |
3/5✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 32 times.
✗ Branch 5 not taken.
|
152 | LocalPointIndexMap localMoveLeafMap(targetLeafManager.leafCount()); |
620 | |||
621 | // build global and local move leaf maps and update local positions | ||
622 | |||
623 | if (filter.state() == index::ALL) { | ||
624 | NullFilter nullFilter; | ||
625 | BuildMoveMapsOp<DeformerT, PointDataTreeT, NullFilter> op(deformer, | ||
626 | globalMoveLeafMap, localMoveLeafMap, targetLeafMap, | ||
627 | transform, points.transform(), nullFilter); | ||
628 |
1/2✓ Branch 1 taken 29 times.
✗ Branch 2 not taken.
|
58 | sourceLeafManager.foreach(op, threaded); |
629 | } else { | ||
630 | BuildMoveMapsOp<DeformerT, PointDataTreeT, FilterT> op(deformer, | ||
631 | globalMoveLeafMap, localMoveLeafMap, targetLeafMap, | ||
632 | transform, points.transform(), filter); | ||
633 |
1/2✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
|
18 | sourceLeafManager.foreach(op, threaded); |
634 | } | ||
635 | |||
636 | // build a sorted index vector for each leaf that references the global move map | ||
637 | // indices in order of their source leafs and voxels to ensure determinism in the | ||
638 | // resulting point orders | ||
639 | |||
640 |
1/2✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
|
76 | GlobalPointIndexIndices globalMoveLeafIndices(globalMoveLeafMap.size()); |
641 | |||
642 |
1/2✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
|
76 | targetLeafManager.foreach( |
643 | 4925 | [&](LeafT& /*leaf*/, size_t idx) { | |
644 | const IndexTripleArray& moveIndices = globalMoveLeafMap[idx]; | ||
645 |
18/52✓ Branch 0 taken 6 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 3 times.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 1 times.
✓ Branch 12 taken 1 times.
✓ Branch 13 taken 4 times.
✓ Branch 14 taken 4 times.
✓ Branch 15 taken 2 times.
✓ Branch 16 taken 4 times.
✓ Branch 17 taken 4 times.
✓ Branch 18 taken 24 times.
✗ 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 taken 6 times.
✗ 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 not taken.
✗ Branch 49 not taken.
✓ Branch 50 taken 2387 times.
✓ Branch 51 taken 29 times.
|
2489 | if (moveIndices.empty()) return; |
646 | |||
647 | IndexArray& sortedIndices = globalMoveLeafIndices[idx]; | ||
648 | 2436 | sortedIndices.resize(moveIndices.size()); | |
649 | 2436 | std::iota(std::begin(sortedIndices), std::end(sortedIndices), 0); | |
650 | 2436 | std::sort(std::begin(sortedIndices), std::end(sortedIndices), | |
651 | 69917894 | [&](int i, int j) | |
652 | { | ||
653 | 89703025 | const Index& indexI0(std::get<0>(moveIndices[i])); | |
654 | 89703025 | const Index& indexJ0(std::get<0>(moveIndices[j])); | |
655 |
8/52✓ Branch 0 taken 18 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✗ 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 not taken.
✗ Branch 17 not taken.
✓ Branch 18 taken 25647088 times.
✓ Branch 19 taken 14566865 times.
✗ 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 not taken.
✗ Branch 49 not taken.
✓ Branch 50 taken 46630534 times.
✓ Branch 51 taken 2858508 times.
|
89703025 | if (indexI0 < indexJ0) return true; |
656 |
9/52✓ Branch 0 taken 6 times.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 4 times.
✗ 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 not taken.
✗ Branch 17 not taken.
✓ Branch 18 taken 23353873 times.
✓ Branch 19 taken 2293215 times.
✗ 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 not taken.
✗ Branch 49 not taken.
✓ Branch 50 taken 46564013 times.
✓ Branch 51 taken 66521 times.
|
72277650 | if (indexI0 > indexJ0) return false; |
657 | 69917894 | return std::get<2>(moveIndices[i]) < std::get<2>(moveIndices[j]); | |
658 | } | ||
659 | ); | ||
660 | }, | ||
661 | threaded); | ||
662 | |||
663 |
2/2✓ Branch 0 taken 90 times.
✓ Branch 1 taken 38 times.
|
256 | for (const auto& it : existingAttributeSet.descriptor().map()) { |
664 | |||
665 | 180 | const Index attributeIndex = static_cast<Index>(it.second); | |
666 | |||
667 | // zero offsets | ||
668 |
1/2✓ Branch 1 taken 90 times.
✗ Branch 2 not taken.
|
180 | targetLeafManager.foreach( |
669 | 9988 | [&offsetMap](const LeafT& /*leaf*/, size_t idx) { | |
670 | 4994 | std::fill(offsetMap[idx].begin(), offsetMap[idx].end(), 0); | |
671 | }, | ||
672 | threaded); | ||
673 | |||
674 | // move points between leaf nodes | ||
675 | |||
676 | GlobalMovePointsOp<PointDataTreeT> globalMoveOp(offsetMap, | ||
677 | sourceLeafManager, attributeIndex, globalMoveLeafMap, globalMoveLeafIndices); | ||
678 |
1/2✓ Branch 1 taken 90 times.
✗ Branch 2 not taken.
|
180 | targetLeafManager.foreach(globalMoveOp, threaded); |
679 | |||
680 | // move points within leaf nodes | ||
681 | |||
682 | LocalMovePointsOp<PointDataTreeT> localMoveOp(offsetMap, | ||
683 | sourceIndices, sourceLeafManager, attributeIndex, localMoveLeafMap); | ||
684 |
1/2✓ Branch 1 taken 90 times.
✗ Branch 2 not taken.
|
180 | targetLeafManager.foreach(localMoveOp, threaded); |
685 | } | ||
686 | |||
687 |
2/6✓ Branch 2 taken 38 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 38 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
|
152 | points.setTree(newPoints->treePtr()); |
688 | } | ||
689 | |||
690 | |||
691 | template <typename PointDataGridT, typename DeformerT, typename FilterT> | ||
692 | inline void movePoints( PointDataGridT& points, | ||
693 | DeformerT& deformer, | ||
694 | const FilterT& filter, | ||
695 | future::Advect* objectNotInUse, | ||
696 | bool threaded) | ||
697 | { | ||
698 |
21/66✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 1 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✓ Branch 28 taken 1 times.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✓ Branch 31 taken 1 times.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✓ Branch 34 taken 1 times.
✗ Branch 35 not taken.
✓ Branch 37 taken 1 times.
✗ Branch 38 not taken.
✓ Branch 40 taken 1 times.
✗ Branch 41 not taken.
✓ Branch 43 taken 1 times.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✓ Branch 46 taken 1 times.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✓ Branch 49 taken 1 times.
✗ Branch 50 not taken.
✗ Branch 51 not taken.
✓ Branch 52 taken 1 times.
✗ Branch 53 not taken.
✗ Branch 54 not taken.
✓ Branch 55 taken 1 times.
✗ Branch 56 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.
|
35 | movePoints(points, points.transform(), deformer, filter, objectNotInUse, threaded); |
699 | 25 | } | |
700 | |||
701 | |||
702 | //////////////////////////////////////// | ||
703 | |||
704 | |||
705 | template <typename T> | ||
706 | 14 | CachedDeformer<T>::CachedDeformer(Cache& cache) | |
707 | 14 | : mCache(cache) { } | |
708 | |||
709 | |||
710 | template <typename T> | ||
711 | template <typename PointDataGridT, typename DeformerT, typename FilterT> | ||
712 | 30 | void CachedDeformer<T>::evaluate(PointDataGridT& grid, DeformerT& deformer, const FilterT& filter, | |
713 | bool threaded) | ||
714 | { | ||
715 | using TreeT = typename PointDataGridT::TreeType; | ||
716 | using LeafT = typename TreeT::LeafNodeType; | ||
717 | using LeafManagerT = typename tree::LeafManager<TreeT>; | ||
718 | 60 | LeafManagerT leafManager(grid.tree()); | |
719 | |||
720 | // initialize cache | ||
721 |
1/2✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
|
30 | auto& leafs = mCache.leafs; |
722 |
1/2✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
|
30 | leafs.resize(leafManager.leafCount()); |
723 | |||
724 | const auto& transform = grid.transform(); | ||
725 | |||
726 | // insert deformed positions into the cache | ||
727 | |||
728 | 4757 | auto cachePositionsOp = [&](const LeafT& leaf, size_t idx) { | |
729 | |||
730 | const Index64 totalPointCount = leaf.pointCount(); | ||
731 |
9/32✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 3 times.
✗ 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 not taken.
✓ Branch 17 taken 2303 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 3 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 3 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 3 times.
✗ 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.
|
2365 | if (totalPointCount == 0) return; |
732 | |||
733 | // deformer is copied to ensure that it is unique per-thread | ||
734 | |||
735 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | DeformerT newDeformer(deformer); |
736 | |||
737 | newDeformer.reset(leaf, idx); | ||
738 | |||
739 |
28/103✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 41 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 41 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 3 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 3 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✓ Branch 16 taken 3 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 3 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✓ Branch 22 taken 3 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 3 times.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✓ Branch 28 taken 3 times.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✓ Branch 31 taken 3 times.
✗ Branch 32 not taken.
✓ Branch 33 taken 3 times.
✗ Branch 34 not taken.
✗ Branch 36 not taken.
✓ Branch 37 taken 3 times.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✓ Branch 40 taken 3 times.
✗ Branch 41 not taken.
✓ Branch 42 taken 1 times.
✓ Branch 43 taken 2 times.
✗ Branch 44 not taken.
✗ Branch 45 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 54 not taken.
✗ Branch 55 not taken.
✗ Branch 57 not taken.
✗ Branch 58 not taken.
✗ Branch 60 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✓ Branch 65 taken 2303 times.
✗ Branch 66 not taken.
✓ Branch 68 taken 2303 times.
✗ Branch 69 not taken.
✗ Branch 70 not taken.
✓ Branch 71 taken 2303 times.
✓ Branch 73 taken 3 times.
✗ Branch 74 not taken.
✓ Branch 76 taken 3 times.
✗ Branch 77 not taken.
✗ Branch 78 not taken.
✓ Branch 79 taken 3 times.
✓ Branch 81 taken 3 times.
✗ Branch 82 not taken.
✓ Branch 84 taken 3 times.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✓ Branch 87 taken 3 times.
✓ Branch 89 taken 3 times.
✗ Branch 90 not taken.
✓ Branch 92 taken 3 times.
✗ Branch 93 not taken.
✗ Branch 94 not taken.
✓ Branch 95 taken 3 times.
✗ Branch 97 not taken.
✗ Branch 98 not taken.
✗ Branch 100 not taken.
✗ Branch 101 not taken.
✗ Branch 102 not taken.
✗ Branch 103 not taken.
✗ Branch 105 not taken.
✗ Branch 106 not taken.
✗ Branch 108 not taken.
✗ Branch 109 not taken.
✗ Branch 110 not taken.
✗ Branch 111 not taken.
✗ Branch 113 not taken.
✗ Branch 114 not taken.
✗ Branch 116 not taken.
✗ Branch 117 not taken.
✗ Branch 118 not taken.
✗ Branch 119 not taken.
✗ Branch 121 not taken.
✗ Branch 122 not taken.
✗ Branch 124 not taken.
✗ Branch 125 not taken.
✗ Branch 126 not taken.
✗ Branch 127 not taken.
|
7095 | auto handle = AttributeHandle<Vec3f>::create(leaf.constAttributeArray("P")); |
740 | |||
741 | auto& cache = leafs[idx]; | ||
742 | cache.clear(); | ||
743 | |||
744 | // only insert into a vector directly if the filter evaluates all points | ||
745 | // and all points are stored in active voxels | ||
746 |
8/48✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3 times.
✗ 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 not taken.
✗ Branch 17 not taken.
✗ 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 taken 2303 times.
✗ Branch 33 not taken.
✓ Branch 34 taken 3 times.
✗ Branch 35 not taken.
✓ Branch 36 taken 3 times.
✗ Branch 37 not taken.
✓ Branch 38 taken 3 times.
✗ 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.
|
2330 | const bool useVector = filter.state() == index::ALL && |
747 |
14/64✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 3 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 3 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 3 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 3 times.
✗ Branch 19 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✓ Branch 41 taken 2303 times.
✗ Branch 42 not taken.
✓ Branch 43 taken 2303 times.
✗ Branch 44 not taken.
✓ Branch 46 taken 3 times.
✗ Branch 47 not taken.
✓ Branch 48 taken 3 times.
✗ Branch 49 not taken.
✓ Branch 51 taken 3 times.
✗ Branch 52 not taken.
✓ Branch 53 taken 3 times.
✗ Branch 54 not taken.
✓ Branch 56 taken 3 times.
✗ Branch 57 not taken.
✓ Branch 58 taken 3 times.
✗ Branch 59 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✗ Branch 64 not taken.
✗ Branch 66 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 69 not taken.
✗ Branch 71 not taken.
✗ Branch 72 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 78 not taken.
✗ Branch 79 not taken.
|
4642 | (leaf.isDense() || (leaf.onPointCount() == leaf.pointCount())); |
748 | if (useVector) { | ||
749 |
7/32✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 3 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.
✓ Branch 25 taken 2303 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 3 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 3 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 3 times.
✗ 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.
|
2321 | cache.vecData.resize(totalPointCount); |
750 | } | ||
751 | |||
752 |
18/50✓ Branch 0 taken 5003 times.
✓ Branch 1 taken 41 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 4 times.
✓ Branch 7 taken 3 times.
✓ Branch 8 taken 4 times.
✓ Branch 9 taken 3 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✓ Branch 40 taken 3827080 times.
✓ Branch 41 taken 2303 times.
✓ Branch 42 taken 4 times.
✓ Branch 43 taken 3 times.
✓ Branch 44 taken 4 times.
✓ Branch 45 taken 3 times.
✓ Branch 46 taken 4 times.
✓ Branch 47 taken 3 times.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
|
7666584 | for (auto iter = leaf.beginIndexOn(filter); iter; iter++) { |
753 | |||
754 | // extract index-space position and apply index-space deformation (if defined) | ||
755 | |||
756 |
27/96✓ Branch 1 taken 5003 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 5003 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 5003 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 4 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 4 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 4 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 1 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 4 times.
✗ Branch 32 not taken.
✓ Branch 35 taken 4 times.
✗ Branch 36 not taken.
✓ Branch 38 taken 4 times.
✗ Branch 39 not taken.
✓ Branch 41 taken 4 times.
✗ Branch 42 not taken.
✓ Branch 45 taken 4 times.
✗ Branch 46 not taken.
✓ Branch 48 taken 4 times.
✗ Branch 49 not taken.
✗ Branch 51 not taken.
✗ Branch 52 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 65 not taken.
✗ Branch 66 not taken.
✗ Branch 68 not taken.
✗ Branch 69 not taken.
✗ Branch 71 not taken.
✗ Branch 72 not taken.
✗ Branch 75 not taken.
✗ Branch 76 not taken.
✗ Branch 78 not taken.
✗ Branch 79 not taken.
✓ Branch 81 taken 3827080 times.
✗ Branch 82 not taken.
✓ Branch 85 taken 3827080 times.
✗ Branch 86 not taken.
✓ Branch 88 taken 3827080 times.
✗ Branch 89 not taken.
✓ Branch 91 taken 4 times.
✗ Branch 92 not taken.
✓ Branch 95 taken 4 times.
✗ Branch 96 not taken.
✓ Branch 98 taken 4 times.
✗ Branch 99 not taken.
✓ Branch 101 taken 4 times.
✗ Branch 102 not taken.
✓ Branch 105 taken 4 times.
✗ Branch 106 not taken.
✓ Branch 108 taken 4 times.
✗ Branch 109 not taken.
✓ Branch 111 taken 4 times.
✗ Branch 112 not taken.
✓ Branch 115 taken 4 times.
✗ Branch 116 not taken.
✓ Branch 118 taken 4 times.
✗ Branch 119 not taken.
✗ Branch 121 not taken.
✗ Branch 122 not taken.
✗ Branch 125 not taken.
✗ Branch 126 not taken.
✗ Branch 128 not taken.
✗ Branch 129 not taken.
✗ Branch 131 not taken.
✗ Branch 132 not taken.
✗ Branch 135 not taken.
✗ Branch 136 not taken.
✗ Branch 138 not taken.
✗ Branch 139 not taken.
✗ Branch 141 not taken.
✗ Branch 142 not taken.
✗ Branch 145 not taken.
✗ Branch 146 not taken.
✗ Branch 148 not taken.
✗ Branch 149 not taken.
✗ Branch 151 not taken.
✗ Branch 152 not taken.
✗ Branch 155 not taken.
✗ Branch 156 not taken.
✗ Branch 158 not taken.
✗ Branch 159 not taken.
|
3832108 | Vec3d position = handle->get(*iter) + iter.getCoord().asVec3d(); |
757 | |||
758 | // if deformer is designed to be used in index-space, perform deformation prior | ||
759 | // to transforming position to world-space, otherwise perform deformation afterwards | ||
760 | |||
761 | if (DeformerTraits<DeformerT>::IndexSpace) { | ||
762 | newDeformer.apply(position, iter); | ||
763 | position = transform.indexToWorld(position); | ||
764 | } | ||
765 | else { | ||
766 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 5000 times.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
|
3832100 | position = transform.indexToWorld(position); |
767 | 4 | newDeformer.apply(position, iter); | |
768 | } | ||
769 | |||
770 | // insert new position into the cache | ||
771 | |||
772 |
8/32✗ Branch 0 not taken.
✓ Branch 1 taken 5003 times.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✗ 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 3827080 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 4 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 4 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 4 times.
✗ 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.
|
3832107 | if (useVector) { |
773 | 3827104 | cache.vecData[*iter] = static_cast<Vec3T>(position); | |
774 | } | ||
775 | else { | ||
776 |
2/56✓ Branch 2 taken 5003 times.
✗ Branch 3 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 51 not taken.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✗ Branch 57 not taken.
✗ Branch 60 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✗ Branch 66 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 69 not taken.
✗ Branch 72 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✗ Branch 75 not taken.
✗ Branch 78 not taken.
✗ Branch 79 not taken.
✗ Branch 80 not taken.
✗ Branch 81 not taken.
✗ Branch 84 not taken.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✗ Branch 87 not taken.
|
5004 | cache.mapData.insert({*iter, static_cast<Vec3T>(position)}); |
777 | } | ||
778 | } | ||
779 | |||
780 | // store the total number of points to allow use of an expanded vector on access | ||
781 | |||
782 |
11/32✓ Branch 0 taken 35 times.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 3 times.
✗ 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 not taken.
✓ Branch 17 taken 2303 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 3 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 3 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 3 times.
✗ 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.
|
2365 | if (!cache.mapData.empty()) { |
783 | 36 | cache.totalSize = static_cast<Index>(totalPointCount); | |
784 | } | ||
785 | }; | ||
786 | |||
787 |
1/2✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
|
30 | leafManager.foreach(cachePositionsOp, threaded); |
788 | 30 | } | |
789 | |||
790 | |||
791 | template <typename T> | ||
792 | template <typename LeafT> | ||
793 | 4718 | void CachedDeformer<T>::reset(const LeafT& /*leaf*/, size_t idx) | |
794 | { | ||
795 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4714 times.
|
4718 | if (idx >= mCache.leafs.size()) { |
796 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
2 | if (mCache.leafs.empty()) { |
797 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
4 | throw IndexError("No leafs in cache, perhaps CachedDeformer has not been evaluated?"); |
798 | } else { | ||
799 | ✗ | throw IndexError("Leaf index is out-of-range of cache leafs."); | |
800 | } | ||
801 | } | ||
802 | auto& cache = mCache.leafs[idx]; | ||
803 |
2/2✓ Branch 0 taken 71 times.
✓ Branch 1 taken 4643 times.
|
4716 | if (!cache.mapData.empty()) { |
804 | 72 | mLeafMap = &cache.mapData; | |
805 | 72 | mLeafVec = nullptr; | |
806 | } | ||
807 | else { | ||
808 | 4644 | mLeafVec = &cache.vecData; | |
809 | 4644 | mLeafMap = nullptr; | |
810 | } | ||
811 | 4716 | } | |
812 | |||
813 | |||
814 | template <typename T> | ||
815 | template <typename IndexIterT> | ||
816 | 7674212 | void CachedDeformer<T>::apply(Vec3d& position, const IndexIterT& iter) const | |
817 | { | ||
818 | 7674208 | assert(*iter >= 0); | |
819 | |||
820 | 7674212 | if (mLeafMap) { | |
821 | 20009 | auto it = mLeafMap->find(*iter); | |
822 | 20009 | if (it == mLeafMap->end()) return; | |
823 | 10007 | position = static_cast<openvdb::Vec3d>(it->second); | |
824 | } | ||
825 | else { | ||
826 | 7654203 | assert(mLeafVec); | |
827 | |||
828 | 7654203 | if (mLeafVec->empty()) return; | |
829 | 7654194 | assert(*iter < mLeafVec->size()); | |
830 | 7654194 | position = static_cast<openvdb::Vec3d>((*mLeafVec)[*iter]); | |
831 | } | ||
832 | } | ||
833 | |||
834 | |||
835 | } // namespace points | ||
836 | } // namespace OPENVDB_VERSION_NAME | ||
837 | } // namespace openvdb | ||
838 | |||
839 | #endif // OPENVDB_POINTS_POINT_MOVE_HAS_BEEN_INCLUDED | ||
840 |