9 #ifndef OPENVDB_POINTS_POINT_MOVE_IMPL_HAS_BEEN_INCLUDED 10 #define OPENVDB_POINTS_POINT_MOVE_IMPL_HAS_BEEN_INCLUDED 31 using LeafMapT = std::unordered_map<LeafIndex, Vec3T>;
61 template <
typename Po
intDataGr
idT,
typename DeformerT,
typename FilterT>
62 void evaluate(PointDataGridT& grid, DeformerT& deformer,
const FilterT& filter,
67 template <
typename LeafT>
68 void reset(
const LeafT& leaf,
size_t idx);
71 template <
typename IndexIterT>
72 void apply(Vec3d& position,
const IndexIterT& iter)
const;
75 friend class ::TestPointMove;
86 namespace point_move_internal {
101 using LeafMap = std::unordered_map<Coord, LeafIndex>;
104 template <
typename DeformerT,
typename TreeT,
typename FilterT>
107 using LeafT =
typename TreeT::LeafNodeType;
117 const FilterT& filter)
118 : mDeformer(deformer)
119 , mGlobalMoveLeafMap(globalMoveLeafMap)
120 , mLocalMoveLeafMap(localMoveLeafMap)
121 , mTargetLeafMap(targetLeafMap)
122 , mTargetTransform(targetTransform)
123 , mSourceTransform(sourceTransform)
124 , mFilter(filter) { }
128 DeformerT deformer(mDeformer);
129 deformer.reset(leaf, idx);
133 Coord sourceLeafOrigin = leaf.origin();
137 for (
auto iter = leaf.beginIndexOn(mFilter); iter; iter++) {
143 Vec3d positionIS = sourceHandle->get(*iter) + iter.getCoord().asVec3d();
145 deformer.apply(positionIS, iter);
150 Vec3d positionWS = mSourceTransform.indexToWorld(positionIS);
151 if (!useIndexSpace) {
152 deformer.apply(positionWS, iter);
157 positionIS = mTargetTransform.worldToIndex(positionWS);
161 Coord targetVoxel = Coord::round(positionIS);
162 Index targetOffset = LeafT::coordToOffset(targetVoxel);
166 Vec3d voxelPosition(positionIS - targetVoxel.asVec3d());
167 sourceHandle->set(*iter, voxelPosition);
171 Coord targetLeafOrigin = targetVoxel & ~(LeafT::DIM - 1);
172 OPENVDB_ASSERT(mTargetLeafMap.find(targetLeafOrigin) != mTargetLeafMap.end());
173 const LeafIndex targetLeafOffset(mTargetLeafMap.at(targetLeafOrigin));
177 if (targetLeafOrigin == sourceLeafOrigin) {
178 mLocalMoveLeafMap[targetLeafOffset].emplace_back(targetOffset, *iter);
181 mGlobalMoveLeafMap[targetLeafOffset].push_back(
IndexTriple(
182 LeafIndex(static_cast<LeafIndex>(idx)), targetOffset, *iter));
188 const DeformerT& mDeformer;
194 const FilterT& mFilter;
197 template <
typename LeafT>
205 Index targetOffset = offsets[voxelOffset]++;
206 if (voxelOffset > 0) {
207 targetOffset +=
static_cast<Index>(leaf.getValue(voxelOffset - 1));
213 template <
typename TreeT>
216 using LeafT =
typename TreeT::LeafNodeType;
223 const Index attributeIndex,
226 : mOffsetMap(offsetMap)
227 , mSourceLeafManager(sourceLeafManager)
228 , mAttributeIndex(attributeIndex)
229 , mMoveLeafMap(moveLeafMap)
230 , mMoveLeafIndices(moveLeafIndices) { }
239 , mSortedIndices(sortedIndices)
240 , mMoveIndices(moveIndices)
241 , mOffsets(offsets) { }
248 mEndIndex = endIndex;
260 if (i < mSortedIndices.size()) {
261 return std::get<0>(this->leafIndexTriple(i));
269 return std::get<2>(*mIt);
281 if (mIndex >= mEndIndex || mIndex >= mSortedIndices.size()) {
285 mIt = &this->leafIndexTriple(mIndex);
292 return mMoveIndices[mSortedIndices[i]];
308 if (moveIndices.empty())
return;
309 const IndexArray& sortedIndices = mMoveLeafIndices[idx];
317 auto& targetArray = leaf.attributeArray(mAttributeIndex);
318 targetArray.loadData();
319 targetArray.expand();
323 CopyIterator copyIterator(leaf, sortedIndices, moveIndices, offsets);
328 Index startIndex = 0;
330 for (
size_t i = 1; i <= sortedIndices.size(); i++) {
338 if (newSourceLeafIndex > sourceLeafIndex) {
339 copyIterator.
reset(startIndex, endIndex);
341 const LeafT& sourceLeaf = mSourceLeafManager.leaf(sourceLeafIndex);
342 const auto& sourceArray = sourceLeaf.constAttributeArray(mAttributeIndex);
343 sourceArray.loadData();
345 targetArray.copyValuesUnsafe(sourceArray, copyIterator);
347 sourceLeafIndex = newSourceLeafIndex;
348 startIndex = endIndex;
356 const Index mAttributeIndex;
362 template <
typename TreeT>
365 using LeafT =
typename TreeT::LeafNodeType;
373 const Index attributeIndex,
375 : mOffsetMap(offsetMap)
376 , mSourceIndices(sourceIndices)
377 , mSourceLeafManager(sourceLeafManager)
378 , mAttributeIndex(attributeIndex)
379 , mMoveLeafMap(moveLeafMap) { }
388 , mOffsets(offsets) { }
390 operator bool()
const {
return mIndex < static_cast<int>(mIndices.size()); }
396 return mIndices[mIndex].second;
414 if (moveIndices.empty())
return;
423 const Index sourceLeafOffset(mSourceIndices[idx]);
424 LeafT& sourceLeaf = mSourceLeafManager.leaf(sourceLeafOffset);
425 const auto& sourceArray = sourceLeaf.constAttributeArray(mAttributeIndex);
426 sourceArray.loadData();
430 auto& targetArray = leaf.attributeArray(mAttributeIndex);
431 targetArray.loadData();
432 targetArray.expand();
437 targetArray.copyValuesUnsafe(sourceArray, copyIterator);
444 const Index mAttributeIndex;
455 template <
typename Po
intDataGr
idT,
typename DeformerT,
typename FilterT>
459 const FilterT& filter,
464 using PointDataTreeT =
typename PointDataGridT::TreeType;
465 using LeafT =
typename PointDataTreeT::LeafNodeType;
468 using namespace point_move_internal;
472 (void)objectNotInUse;
474 PointDataTreeT& tree = points.tree();
478 auto iter = tree.cbeginLeaf();
484 auto newPoints = point_mask_internal::convertPointsToScalar<PointDataGridT>(
485 points, transform, filter, deformer,
threaded);
486 auto& newTree = newPoints->tree();
490 LeafManagerT sourceLeafManager(tree);
491 LeafManagerT targetLeafManager(newTree);
494 const auto& existingAttributeSet = points.tree().cbeginLeaf()->attributeSet();
507 auto sourceRange = sourceLeafManager.leafRange();
508 for (
auto leaf = sourceRange.begin(); leaf; ++leaf) {
509 sourceLeafMap.insert({leaf->origin(),
LeafIndex(static_cast<LeafIndex>(leaf.pos()))});
511 auto targetRange = targetLeafManager.leafRange();
512 for (
auto leaf = targetRange.begin(); leaf; ++leaf) {
513 targetLeafMap.insert({leaf->origin(),
LeafIndex(static_cast<LeafIndex>(leaf.pos()))});
521 targetLeafManager.foreach(
522 [&](LeafT& leaf,
size_t idx) {
524 auto* buffer = leaf.buffer().data();
525 for (
Index i = 1; i < leaf.buffer().size(); i++) {
526 buffer[i] = buffer[i-1] + buffer[i];
529 leaf.replaceAttributeSet(
530 new AttributeSet(existingAttributeSet, leaf.getLastValue(), &lock),
533 const auto it = sourceLeafMap.find(leaf.origin());
534 if (it != sourceLeafMap.end()) {
535 sourceIndices[idx] = it->second;
538 offsetMap[idx].resize(LeafT::SIZE);
552 BuildMoveMapsOp<DeformerT, PointDataTreeT, NullFilter>
op(deformer,
553 globalMoveLeafMap, localMoveLeafMap, targetLeafMap,
554 transform, points.transform(), nullFilter);
555 sourceLeafManager.foreach(
op, threaded);
557 BuildMoveMapsOp<DeformerT, PointDataTreeT, FilterT>
op(deformer,
558 globalMoveLeafMap, localMoveLeafMap, targetLeafMap,
559 transform, points.transform(), filter);
560 sourceLeafManager.foreach(
op, threaded);
569 targetLeafManager.foreach(
570 [&](LeafT& ,
size_t idx) {
572 if (moveIndices.empty())
return;
574 IndexArray& sortedIndices = globalMoveLeafIndices[idx];
575 sortedIndices.resize(moveIndices.size());
576 std::iota(std::begin(sortedIndices), std::end(sortedIndices), 0);
577 std::sort(std::begin(sortedIndices), std::end(sortedIndices),
580 const Index& indexI0(std::get<0>(moveIndices[i]));
581 const Index& indexJ0(std::get<0>(moveIndices[j]));
582 if (indexI0 < indexJ0)
return true;
583 if (indexI0 > indexJ0)
return false;
584 return std::get<2>(moveIndices[i]) < std::get<2>(moveIndices[j]);
590 for (
const auto& it : existingAttributeSet.descriptor().map()) {
592 const Index attributeIndex =
static_cast<Index>(it.second);
595 targetLeafManager.foreach(
596 [&offsetMap](
const LeafT& ,
size_t idx) {
597 std::fill(offsetMap[idx].begin(), offsetMap[idx].end(), 0);
603 GlobalMovePointsOp<PointDataTreeT> globalMoveOp(offsetMap,
604 sourceLeafManager, attributeIndex, globalMoveLeafMap, globalMoveLeafIndices);
605 targetLeafManager.foreach(globalMoveOp, threaded);
609 LocalMovePointsOp<PointDataTreeT> localMoveOp(offsetMap,
610 sourceIndices, sourceLeafManager, attributeIndex, localMoveLeafMap);
611 targetLeafManager.foreach(localMoveOp, threaded);
614 points.setTree(newPoints->treePtr());
618 template <
typename Po
intDataGr
idT,
typename DeformerT,
typename FilterT>
621 const FilterT& filter,
632 template <
typename T>
637 template <
typename T>
638 template <
typename Po
intDataGr
idT,
typename DeformerT,
typename FilterT>
642 using TreeT =
typename PointDataGridT::TreeType;
643 using LeafT =
typename TreeT::LeafNodeType;
645 LeafManagerT leafManager(grid.tree());
648 auto& leafs = mCache.
leafs;
649 leafs.resize(leafManager.leafCount());
651 const auto& transform = grid.transform();
655 auto cachePositionsOp = [&](
const LeafT& leaf,
size_t idx) {
657 const Index64 totalPointCount = leaf.pointCount();
658 if (totalPointCount == 0)
return;
662 DeformerT newDeformer(deformer);
664 newDeformer.reset(leaf, idx);
668 auto& cache = leafs[idx];
673 const bool useVector = filter.state() ==
index::ALL &&
674 (leaf.isDense() || (leaf.onPointCount() == leaf.pointCount()));
676 cache.vecData.resize(totalPointCount);
679 for (
auto iter = leaf.beginIndexOn(filter); iter; iter++) {
683 Vec3d position = handle->get(*iter) + iter.getCoord().asVec3d();
689 newDeformer.apply(position, iter);
690 position = transform.indexToWorld(position);
693 position = transform.indexToWorld(position);
694 newDeformer.apply(position, iter);
700 cache.vecData[*iter] =
static_cast<Vec3T>(position);
703 cache.mapData.insert({*iter,
static_cast<Vec3T>(position)});
709 if (!cache.mapData.empty()) {
710 cache.totalSize =
static_cast<Index>(totalPointCount);
714 leafManager.foreach(cachePositionsOp, threaded);
718 template <
typename T>
719 template <
typename LeafT>
722 if (idx >= mCache.
leafs.size()) {
723 if (mCache.
leafs.empty()) {
724 throw IndexError(
"No leafs in cache, perhaps CachedDeformer has not been evaluated?");
726 throw IndexError(
"Leaf index is out-of-range of cache leafs.");
729 auto& cache = mCache.
leafs[idx];
730 if (!cache.mapData.empty()) {
731 mLeafMap = &cache.mapData;
735 mLeafVec = &cache.vecData;
741 template <
typename T>
742 template <
typename IndexIterT>
748 auto it = mLeafMap->find(*iter);
749 if (it == mLeafMap->end())
return;
750 position =
static_cast<openvdb::Vec3d
>(it->second);
755 if (mLeafVec->empty())
return;
757 position =
static_cast<openvdb::Vec3d
>((*mLeafVec)[*iter]);
766 #endif // OPENVDB_POINTS_POINT_MOVE_IMPL_HAS_BEEN_INCLUDED std::unordered_map< Coord, LeafIndex > LeafMap
Definition: PointMoveImpl.h:101
std::tuple< LeafIndex, Index, Index > IndexTriple
Definition: PointMoveImpl.h:90
CopyIterator & operator++()
Definition: PointMoveImpl.h:252
typename TreeT::LeafNodeType LeafT
Definition: PointMoveImpl.h:216
CopyIterator & operator++()
Definition: PointMoveImpl.h:392
std::vector< LeafT * > LeafArrayT
Definition: PointMoveImpl.h:366
Definition: Exceptions.h:57
void operator()(LeafT &leaf, size_t idx) const
Definition: PointMoveImpl.h:411
Definition: PointMove.h:57
uint64_t Index64
Definition: Types.h:53
Index indexOffsetFromVoxel(const Index voxelOffset, const LeafT &leaf, IndexArray &offsets)
Definition: PointMoveImpl.h:199
Definition: PointMoveImpl.h:105
Index leafIndex(Index i) const
Definition: PointMoveImpl.h:258
LocalMovePointsOp(LeafOffsetArray &offsetMap, const LeafIndexArray &sourceIndices, LeafManagerT &sourceLeafManager, const Index attributeIndex, const LocalPointIndexMap &moveLeafMap)
Definition: PointMoveImpl.h:370
std::vector< LeafT * > LeafArrayT
Definition: PointMoveImpl.h:108
Index sourceIndex() const
Definition: PointMoveImpl.h:266
Index32 LeafIndex
Definition: PointMoveImpl.h:20
Index32 Index
Definition: Types.h:54
void movePoints(PointDataGridT &points, DeformerT &deformer, const FilterT &filter=NullFilter(), future::Advect *objectNotInUse=nullptr, bool threaded=true)
Move points in a PointDataGrid using a custom deformer.
Definition: PointMoveImpl.h:619
Definition: IndexIterator.h:44
GlobalMovePointsOp(LeafOffsetArray &offsetMap, LeafManagerT &sourceLeafManager, const Index attributeIndex, const GlobalPointIndexMap &moveLeafMap, const GlobalPointIndexIndices &moveLeafIndices)
Definition: PointMoveImpl.h:221
Definition: PointMoveImpl.h:214
std::pair< Index, Index > IndexPair
Definition: PointMoveImpl.h:95
std::vector< LeafIndex > LeafIndexArray
Definition: PointMoveImpl.h:99
std::vector< IndexTripleArray > GlobalPointIndexMap
Definition: PointMoveImpl.h:92
#define OPENVDB_ASSERT(X)
Definition: Assert.h:41
typename tree::LeafManager< TreeT > LeafManagerT
Definition: PointMoveImpl.h:109
typename TreeT::LeafNodeType LeafT
Definition: PointMoveImpl.h:365
CopyIterator(const LeafT &leaf, const IndexPairArray &indices, IndexArray &offsets)
Definition: PointMoveImpl.h:385
std::vector< IndexPair > IndexPairArray
Definition: PointMoveImpl.h:96
BuildMoveMapsOp(const DeformerT &deformer, GlobalPointIndexMap &globalMoveLeafMap, LocalPointIndexMap &localMoveLeafMap, const LeafMap &targetLeafMap, const math::Transform &targetTransform, const math::Transform &sourceTransform, const FilterT &filter)
Definition: PointMoveImpl.h:111
Write-able version of AttributeHandle.
Definition: AttributeArray.h:834
Definition: Exceptions.h:13
Index targetIndex() const
Definition: PointMoveImpl.h:399
tbb::concurrent_vector< IndexTriple > IndexTripleArray
Definition: PointMoveImpl.h:91
Definition: PointMoveImpl.h:383
std::vector< LeafT * > LeafArrayT
Definition: PointMoveImpl.h:217
typename tree::LeafManager< TreeT > LeafManagerT
Definition: PointMoveImpl.h:218
CopyIterator(const LeafT &leaf, const IndexArray &sortedIndices, const IndexTripleArray &moveIndices, IndexArray &offsets)
Definition: PointMoveImpl.h:236
Definition: PointMoveImpl.h:234
std::vector< IndexPairArray > LocalPointIndexMap
Definition: PointMoveImpl.h:97
uint32_t Index32
Definition: Types.h:52
Definition: AttributeArray.h:119
Definition: PointMoveImpl.h:363
void operator()(LeafT &leaf, size_t idx) const
Definition: PointMoveImpl.h:126
std::vector< AttributeArray * > AttributeArrays
Definition: PointMoveImpl.h:219
static Ptr create(const AttributeArray &array, const bool collapseOnDestruction=true)
Definition: AttributeArray.h:1984
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition: LeafManager.h:85
Index sourceIndex() const
Definition: PointMoveImpl.h:394
typename TreeT::LeafNodeType LeafT
Definition: PointMoveImpl.h:107
void operator()(LeafT &leaf, size_t idx) const
Definition: PointMoveImpl.h:305
Ordered collection of uniquely-named attribute arrays.
Definition: AttributeSet.h:39
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:121
void reset(Index startIndex, Index endIndex)
Definition: PointMoveImpl.h:245
std::vector< Index > IndexArray
Definition: PointMoveImpl.h:88
typename tree::LeafManager< TreeT > LeafManagerT
Definition: PointMoveImpl.h:367
std::vector< LeafIndexArray > LeafOffsetArray
Definition: PointMoveImpl.h:100
std::vector< IndexArray > GlobalPointIndexIndices
Definition: PointMoveImpl.h:93
std::vector< AttributeArray * > AttributeArrays
Definition: PointMoveImpl.h:368
Index targetIndex() const
Definition: PointMoveImpl.h:272
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:218
A no-op filter that can be used when iterating over all indices.
Definition: IndexIterator.h:51