| 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 |