32 #ifndef OPENVDB_POINTS_POINT_MOVE_HAS_BEEN_INCLUDED
33 #define OPENVDB_POINTS_POINT_MOVE_HAS_BEEN_INCLUDED
40 #include <tbb/concurrent_vector.h>
47 #include <unordered_map>
59 namespace future {
struct Advect { }; }
68 template <
typename Po
intDataGr
idT,
typename DeformerT,
typename FilterT = NullFilter>
73 bool threaded =
true);
83 template <
typename Po
intDataGr
idT,
typename DeformerT,
typename FilterT = NullFilter>
89 bool threaded =
true);
104 using LeafMapT = std::unordered_map<LeafIndex, Vec3T>;
134 template <
typename Po
intDataGr
idT,
typename DeformerT,
typename FilterT>
135 void evaluate(PointDataGridT& grid, DeformerT& deformer,
const FilterT& filter,
136 bool threaded =
true);
140 template <
typename LeafT>
141 void reset(
const LeafT& leaf,
size_t idx);
144 template <
typename IndexIterT>
145 void apply(
Vec3d& position,
const IndexIterT& iter)
const;
148 friend class ::TestPointMove;
159 namespace point_move_internal {
174 using LeafMap = std::unordered_map<Coord, LeafIndex>;
177 template <
typename DeformerT,
typename TreeT,
typename FilterT>
180 using LeafT =
typename TreeT::LeafNodeType;
190 const FilterT& filter)
191 : mDeformer(deformer)
192 , mGlobalMoveLeafMap(globalMoveLeafMap)
193 , mLocalMoveLeafMap(localMoveLeafMap)
194 , mTargetLeafMap(targetLeafMap)
195 , mTargetTransform(targetTransform)
196 , mSourceTransform(sourceTransform)
197 , mFilter(filter) { }
201 DeformerT deformer(mDeformer);
202 deformer.reset(leaf, idx);
206 Coord sourceLeafOrigin = leaf.origin();
210 for (
auto iter = leaf.beginIndexOn(mFilter); iter; iter++) {
216 Vec3d positionIS = sourceHandle->get(*iter) + iter.getCoord().asVec3d();
218 deformer.apply(positionIS, iter);
223 Vec3d positionWS = mSourceTransform.indexToWorld(positionIS);
224 if (!useIndexSpace) {
225 deformer.apply(positionWS, iter);
230 positionIS = mTargetTransform.worldToIndex(positionWS);
235 Index targetOffset = LeafT::coordToOffset(targetVoxel);
239 Vec3d voxelPosition(positionIS - targetVoxel.
asVec3d());
240 sourceHandle->set(*iter, voxelPosition);
244 Coord targetLeafOrigin = targetVoxel & ~(LeafT::DIM - 1);
245 assert(mTargetLeafMap.find(targetLeafOrigin) != mTargetLeafMap.end());
246 const LeafIndex targetLeafOffset(mTargetLeafMap.at(targetLeafOrigin));
250 if (targetLeafOrigin == sourceLeafOrigin) {
251 mLocalMoveLeafMap[targetLeafOffset].emplace_back(targetOffset, *iter);
254 mGlobalMoveLeafMap[targetLeafOffset].push_back(
IndexTriple(
261 const DeformerT& mDeformer;
267 const FilterT& mFilter;
270 template <
typename LeafT>
278 Index targetOffset = offsets[voxelOffset]++;
279 if (voxelOffset > 0) {
280 targetOffset +=
static_cast<Index>(leaf.getValue(voxelOffset - 1));
286 #if OPENVDB_ABI_VERSION_NUMBER >= 6
289 template <
typename TreeT>
292 using LeafT =
typename TreeT::LeafNodeType;
299 const Index attributeIndex,
302 : mOffsetMap(offsetMap)
303 , mSourceLeafManager(sourceLeafManager)
304 , mAttributeIndex(attributeIndex)
305 , mMoveLeafMap(moveLeafMap)
306 , mMoveLeafIndices(moveLeafIndices) { }
315 , mSortedIndices(sortedIndices)
316 , mMoveIndices(moveIndices)
317 , mOffsets(offsets) { }
319 operator bool()
const {
return bool(mIt); }
324 mEndIndex = endIndex;
336 if (i < mSortedIndices.size()) {
337 return std::get<0>(this->leafIndexTriple(i));
345 return std::get<2>(*mIt);
357 if (mIndex >= mEndIndex || mIndex >= mSortedIndices.size()) {
361 mIt = &this->leafIndexTriple(mIndex);
368 return mMoveIndices[mSortedIndices[i]];
384 if (moveIndices.empty())
return;
385 const IndexArray& sortedIndices = mMoveLeafIndices[idx];
393 auto& targetArray = leaf.attributeArray(mAttributeIndex);
394 targetArray.loadData();
395 targetArray.expand();
399 CopyIterator copyIterator(leaf, sortedIndices, moveIndices, offsets);
404 Index startIndex = 0;
406 for (
size_t i = 1; i <= sortedIndices.size(); i++) {
414 if (newSourceLeafIndex > sourceLeafIndex) {
415 copyIterator.
reset(startIndex, endIndex);
417 const LeafT& sourceLeaf = mSourceLeafManager.leaf(sourceLeafIndex);
418 const auto& sourceArray = sourceLeaf.constAttributeArray(mAttributeIndex);
419 sourceArray.loadData();
421 targetArray.copyValuesUnsafe(sourceArray, copyIterator);
423 sourceLeafIndex = newSourceLeafIndex;
424 startIndex = endIndex;
431 LeafManagerT& mSourceLeafManager;
432 const Index mAttributeIndex;
438 template <
typename TreeT>
441 using LeafT =
typename TreeT::LeafNodeType;
449 const Index attributeIndex,
451 : mOffsetMap(offsetMap)
452 , mSourceIndices(sourceIndices)
453 , mSourceLeafManager(sourceLeafManager)
454 , mAttributeIndex(attributeIndex)
455 , mMoveLeafMap(moveLeafMap) { }
464 , mOffsets(offsets) { }
466 operator bool()
const {
return mIndex < static_cast<int>(mIndices.size()); }
472 return mIndices[mIndex].second;
490 if (moveIndices.empty())
return;
498 assert(idx < mSourceIndices.size());
499 const Index sourceLeafOffset(mSourceIndices[idx]);
500 LeafT& sourceLeaf = mSourceLeafManager.leaf(sourceLeafOffset);
501 const auto& sourceArray = sourceLeaf.constAttributeArray(mAttributeIndex);
502 sourceArray.loadData();
506 auto& targetArray = leaf.attributeArray(mAttributeIndex);
507 targetArray.loadData();
508 targetArray.expand();
513 targetArray.copyValuesUnsafe(sourceArray, copyIterator);
519 LeafManagerT& mSourceLeafManager;
520 const Index mAttributeIndex;
536 template<
typename ValueType,
typename OpType>
537 struct ArrayProcessor {
538 static inline void call(OpType& op,
const AttributeArray& array) {
539 op.template operator()<ValueType>(array);
546 template<
typename ArrayType,
typename OpType>
548 processTypedArray(
const ArrayType& array, OpType& op)
551 using namespace openvdb::math;
552 if (array.template hasValueType<bool>()) ArrayProcessor<bool, OpType>::call(op, array);
553 else if (array.template hasValueType<int16_t>()) ArrayProcessor<int16_t, OpType>::call(op, array);
554 else if (array.template hasValueType<int32_t>()) ArrayProcessor<int32_t, OpType>::call(op, array);
555 else if (array.template hasValueType<int64_t>()) ArrayProcessor<int64_t, OpType>::call(op, array);
556 else if (array.template hasValueType<float>()) ArrayProcessor<float, OpType>::call(op, array);
557 else if (array.template hasValueType<double>()) ArrayProcessor<double, OpType>::call(op, array);
558 else if (array.template hasValueType<
Vec3<int32_t>>()) ArrayProcessor<Vec3<int32_t>, OpType>::call(op, array);
559 else if (array.template hasValueType<
Vec3<float>>()) ArrayProcessor<Vec3<float>, OpType>::call(op, array);
560 else if (array.template hasValueType<
Vec3<double>>()) ArrayProcessor<Vec3<double>, OpType>::call(op, array);
561 else if (array.template hasValueType<GroupType>()) ArrayProcessor<GroupType, OpType>::call(op, array);
562 else if (array.template hasValueType<Index>()) ArrayProcessor<Index, OpType>::call(op, array);
563 else if (array.template hasValueType<
Mat3<float>>()) ArrayProcessor<Mat3<float>, OpType>::call(op, array);
564 else if (array.template hasValueType<
Mat3<double>>()) ArrayProcessor<Mat3<double>, OpType>::call(op, array);
565 else if (array.template hasValueType<
Mat4<float>>()) ArrayProcessor<Mat4<float>, OpType>::call(op, array);
566 else if (array.template hasValueType<
Mat4<double>>()) ArrayProcessor<Mat4<double>, OpType>::call(op, array);
567 else if (array.template hasValueType<
Quat<float>>()) ArrayProcessor<Quat<float>, OpType>::call(op, array);
568 else if (array.template hasValueType<
Quat<double>>()) ArrayProcessor<Quat<double>, OpType>::call(op, array);
575 struct AttributeHandles
577 using HandleArray = std::vector<AttributeHandle<int>::Ptr>;
579 AttributeHandles(
const size_t size)
580 : mHandles() { mHandles.reserve(size); }
582 AttributeArray& getArray(
const Index leafOffset)
584 auto* handle =
reinterpret_cast<AttributeWriteHandle<int>*
>(mHandles[leafOffset].get());
586 return handle->array();
589 const AttributeArray& getConstArray(
const Index leafOffset)
const
591 const auto* handle = mHandles[leafOffset].get();
593 return handle->array();
596 template <
typename ValueT>
597 AttributeHandle<ValueT>& getHandle(
const Index leafOffset)
599 auto* handle =
reinterpret_cast<AttributeHandle<ValueT>*
>(mHandles[leafOffset].get());
604 template <
typename ValueT>
605 AttributeWriteHandle<ValueT>& getWriteHandle(
const Index leafOffset)
607 auto* handle =
reinterpret_cast<AttributeWriteHandle<ValueT>*
>(mHandles[leafOffset].get());
615 CacheHandleOp(HandleArray& handles)
616 : mHandles(handles) { }
618 template<
typename ValueT>
619 void operator()(
const AttributeArray& array)
const
621 auto* handleAsInt =
reinterpret_cast<AttributeHandle<int>*
>(
622 new AttributeHandle<ValueT>(array));
623 mHandles.emplace_back(handleAsInt);
627 HandleArray& mHandles;
630 template <
typename LeafRangeT>
631 void cache(
const LeafRangeT& range,
const Index attributeIndex)
633 using namespace openvdb::math;
636 CacheHandleOp op(mHandles);
638 for (
auto leaf = range.begin(); leaf; ++leaf) {
639 const auto& array = leaf->constAttributeArray(attributeIndex);
640 processTypedArray(array, op);
645 HandleArray mHandles;
649 template <
typename TreeT>
650 struct GlobalMovePointsOp
652 using LeafT =
typename TreeT::LeafNodeType;
653 using LeafArrayT = std::vector<LeafT*>;
657 AttributeHandles& targetHandles,
658 AttributeHandles& sourceHandles,
659 const Index attributeIndex,
662 : mOffsetMap(offsetMap)
663 , mTargetHandles(targetHandles)
664 , mSourceHandles(sourceHandles)
665 , mAttributeIndex(attributeIndex)
666 , mMoveLeafMap(moveLeafMap)
667 , mMoveLeafIndices(moveLeafIndices) { }
669 struct PerformTypedMoveOp
671 PerformTypedMoveOp(AttributeHandles& targetHandles, AttributeHandles& sourceHandles,
672 Index targetOffset,
const LeafT& targetLeaf,
675 : mTargetHandles(targetHandles)
676 , mSourceHandles(sourceHandles)
677 , mTargetOffset(targetOffset)
678 , mTargetLeaf(targetLeaf)
681 , mSortedIndices(sortedIndices) { }
683 template<
typename ValueT>
684 void operator()(
const AttributeArray&)
const
686 auto& targetHandle = mTargetHandles.getWriteHandle<ValueT>(mTargetOffset);
687 targetHandle.expand();
689 for (
const auto& index : mSortedIndices) {
690 const auto& it = mIndices[index];
691 const auto& sourceHandle = mSourceHandles.getHandle<ValueT>(std::get<0>(it));
693 for (
Index i = 0; i < sourceHandle.stride(); i++) {
694 ValueT sourceValue = sourceHandle.get(std::get<2>(it), i);
695 targetHandle.set(targetIndex, i, sourceValue);
701 AttributeHandles& mTargetHandles;
702 AttributeHandles& mSourceHandles;
704 const LeafT& mTargetLeaf;
710 void performMove(
Index targetOffset,
const LeafT& targetLeaf,
714 auto& targetArray = mTargetHandles.getArray(targetOffset);
715 targetArray.loadData();
716 targetArray.expand();
718 for (
const auto& index : sortedIndices) {
719 const auto& it = indices[index];
721 const auto& sourceArray = mSourceHandles.getConstArray(std::get<0>(it));
723 const Index sourceOffset = std::get<2>(it);
726 targetArray.set(targetOffset, sourceArray, sourceOffset);
730 void operator()(LeafT& leaf,
size_t aIdx)
const
733 const auto& moveIndices = mMoveLeafMap[aIdx];
734 if (moveIndices.empty())
return;
735 const auto& sortedIndices = mMoveLeafIndices[aIdx];
739 auto& offsets = mOffsetMap[aIdx];
741 const auto& array = leaf.constAttributeArray(mAttributeIndex);
743 PerformTypedMoveOp op(mTargetHandles, mSourceHandles, idx, leaf, offsets,
744 moveIndices, sortedIndices);
745 if (!processTypedArray(array, op)) {
746 this->performMove(idx, leaf, offsets, moveIndices, sortedIndices);
752 AttributeHandles& mTargetHandles;
753 AttributeHandles& mSourceHandles;
754 const Index mAttributeIndex;
760 template <
typename TreeT>
761 struct LocalMovePointsOp
763 using LeafT =
typename TreeT::LeafNodeType;
764 using LeafArrayT = std::vector<LeafT*>;
768 AttributeHandles& targetHandles,
770 AttributeHandles& sourceHandles,
771 const Index attributeIndex,
773 : mOffsetMap(offsetMap)
774 , mTargetHandles(targetHandles)
775 , mSourceIndices(sourceIndices)
776 , mSourceHandles(sourceHandles)
777 , mAttributeIndex(attributeIndex)
778 , mMoveLeafMap(moveLeafMap) { }
780 struct PerformTypedMoveOp
782 PerformTypedMoveOp(AttributeHandles& targetHandles, AttributeHandles& sourceHandles,
783 Index targetOffset,
Index sourceOffset,
const LeafT& targetLeaf,
785 : mTargetHandles(targetHandles)
786 , mSourceHandles(sourceHandles)
787 , mTargetOffset(targetOffset)
788 , mSourceOffset(sourceOffset)
789 , mTargetLeaf(targetLeaf)
791 , mIndices(indices) { }
793 template<
typename ValueT>
794 void operator()(
const AttributeArray&)
const
796 auto& targetHandle = mTargetHandles.getWriteHandle<ValueT>(mTargetOffset);
797 const auto& sourceHandle = mSourceHandles.getHandle<ValueT>(mSourceOffset);
799 targetHandle.expand();
801 for (
const auto& it : mIndices) {
803 for (
Index i = 0; i < sourceHandle.stride(); i++) {
804 ValueT sourceValue = sourceHandle.get(it.second, i);
805 targetHandle.set(targetIndex, i, sourceValue);
811 AttributeHandles& mTargetHandles;
812 AttributeHandles& mSourceHandles;
815 const LeafT& mTargetLeaf;
820 template <
typename ValueT>
821 void performTypedMove(
Index sourceOffset,
Index targetOffset,
const LeafT& targetLeaf,
824 auto& targetHandle = mTargetHandles.getWriteHandle<ValueT>(targetOffset);
825 const auto& sourceHandle = mSourceHandles.getHandle<ValueT>(sourceOffset);
827 targetHandle.expand();
829 for (
const auto& it : indices) {
831 for (
Index i = 0; i < sourceHandle.stride(); i++) {
832 ValueT sourceValue = sourceHandle.get(it.second, i);
833 targetHandle.set(tgtOffset, i, sourceValue);
838 void performMove(
Index targetOffset,
Index sourceOffset,
const LeafT& targetLeaf,
841 auto& targetArray = mTargetHandles.getArray(targetOffset);
842 const auto& sourceArray = mSourceHandles.getConstArray(sourceOffset);
844 for (
const auto& it : indices) {
845 const Index sourceOffset = it.second;
848 targetArray.set(targetOffset, sourceArray, sourceOffset);
852 void operator()(
const LeafT& leaf,
size_t aIdx)
const
855 const auto& moveIndices = mMoveLeafMap.at(aIdx);
856 if (moveIndices.empty())
return;
860 auto& offsets = mOffsetMap[aIdx];
864 assert(aIdx < mSourceIndices.size());
865 const Index sourceOffset(mSourceIndices[aIdx]);
867 const auto& array = leaf.constAttributeArray(mAttributeIndex);
869 PerformTypedMoveOp op(mTargetHandles, mSourceHandles,
870 idx, sourceOffset, leaf, offsets, moveIndices);
871 if (!processTypedArray(array, op)) {
872 this->performMove(idx, sourceOffset, leaf, offsets, moveIndices);
878 AttributeHandles& mTargetHandles;
880 AttributeHandles& mSourceHandles;
881 const Index mAttributeIndex;
895 template <
typename Po
intDataGr
idT,
typename DeformerT,
typename FilterT>
899 const FilterT& filter,
904 using PointDataTreeT =
typename PointDataGridT::TreeType;
905 using LeafT =
typename PointDataTreeT::LeafNodeType;
908 using namespace point_move_internal;
911 assert(!objectNotInUse);
912 (void)objectNotInUse;
914 PointDataTreeT& tree = points.tree();
924 auto newPoints = point_mask_internal::convertPointsToScalar<PointDataGrid>(
925 points, transform, filter, deformer, threaded);
926 auto& newTree = newPoints->tree();
930 LeafManagerT sourceLeafManager(tree);
931 LeafManagerT targetLeafManager(newTree);
934 const auto& existingAttributeSet = points.tree().cbeginLeaf()->attributeSet();
947 auto sourceRange = sourceLeafManager.leafRange();
948 for (
auto leaf = sourceRange.begin(); leaf; ++leaf) {
949 sourceLeafMap.insert({leaf->origin(),
LeafIndex(
static_cast<LeafIndex>(leaf.pos()))});
951 auto targetRange = targetLeafManager.leafRange();
952 for (
auto leaf = targetRange.begin(); leaf; ++leaf) {
953 targetLeafMap.insert({leaf->origin(),
LeafIndex(
static_cast<LeafIndex>(leaf.pos()))});
961 targetLeafManager.foreach(
962 [&](LeafT& leaf,
size_t idx) {
964 auto* buffer = leaf.buffer().data();
965 for (
Index i = 1; i < leaf.buffer().size(); i++) {
966 buffer[i] = buffer[i-1] + buffer[i];
969 leaf.replaceAttributeSet(
970 new AttributeSet(existingAttributeSet, leaf.getLastValue(), &lock),
973 const auto it = sourceLeafMap.find(leaf.origin());
974 if (it != sourceLeafMap.end()) {
975 sourceIndices[idx] = it->second;
978 offsetMap[idx].resize(LeafT::SIZE);
992 BuildMoveMapsOp<DeformerT, PointDataTreeT, NullFilter> op(deformer,
993 globalMoveLeafMap, localMoveLeafMap, targetLeafMap,
994 transform, points.transform(), nullFilter);
995 sourceLeafManager.foreach(op, threaded);
997 BuildMoveMapsOp<DeformerT, PointDataTreeT, FilterT> op(deformer,
998 globalMoveLeafMap, localMoveLeafMap, targetLeafMap,
999 transform, points.transform(), filter);
1000 sourceLeafManager.foreach(op, threaded);
1009 targetLeafManager.foreach(
1010 [&](LeafT& ,
size_t idx) {
1012 if (moveIndices.empty())
return;
1014 IndexArray& sortedIndices = globalMoveLeafIndices[idx];
1015 sortedIndices.resize(moveIndices.size());
1016 std::iota(std::begin(sortedIndices), std::end(sortedIndices), 0);
1017 std::sort(std::begin(sortedIndices), std::end(sortedIndices),
1020 const Index& indexI0(std::get<0>(moveIndices[i]));
1021 const Index& indexJ0(std::get<0>(moveIndices[j]));
1022 if (indexI0 < indexJ0) return true;
1023 if (indexI0 > indexJ0) return false;
1024 return std::get<2>(moveIndices[i]) < std::get<2>(moveIndices[j]);
1030 #if OPENVDB_ABI_VERSION_NUMBER < 6
1032 AttributeHandles sourceHandles(sourceLeafManager.leafCount());
1033 AttributeHandles targetHandles(targetLeafManager.leafCount());
1036 for (
const auto& it : existingAttributeSet.descriptor().map()) {
1038 const Index attributeIndex =
static_cast<Index>(it.second);
1041 targetLeafManager.foreach(
1042 [&offsetMap](
const LeafT& ,
size_t idx) {
1043 std::fill(offsetMap[idx].begin(), offsetMap[idx].end(), 0);
1047 #if OPENVDB_ABI_VERSION_NUMBER >= 6
1051 GlobalMovePointsOp<PointDataTreeT> globalMoveOp(offsetMap,
1052 sourceLeafManager, attributeIndex, globalMoveLeafMap, globalMoveLeafIndices);
1053 targetLeafManager.foreach(globalMoveOp, threaded);
1057 LocalMovePointsOp<PointDataTreeT> localMoveOp(offsetMap,
1058 sourceIndices, sourceLeafManager, attributeIndex, localMoveLeafMap);
1059 targetLeafManager.foreach(localMoveOp, threaded);
1063 sourceHandles.cache(sourceLeafManager.leafRange(), attributeIndex);
1064 targetHandles.cache(targetLeafManager.leafRange(), attributeIndex);
1068 GlobalMovePointsOp<PointDataTreeT> globalMoveOp(offsetMap, targetHandles,
1069 sourceHandles, attributeIndex, globalMoveLeafMap, globalMoveLeafIndices);
1070 targetLeafManager.foreach(globalMoveOp, threaded);
1074 LocalMovePointsOp<PointDataTreeT> localMoveOp(offsetMap, targetHandles,
1075 sourceIndices, sourceHandles,
1076 attributeIndex, localMoveLeafMap);
1077 targetLeafManager.foreach(localMoveOp, threaded);
1081 points.setTree(newPoints->treePtr());
1085 template <
typename Po
intDataGr
idT,
typename DeformerT,
typename FilterT>
1087 DeformerT& deformer,
1088 const FilterT& filter,
1092 movePoints(points, points.transform(), deformer, filter, objectNotInUse, threaded);
1099 template <
typename T>
1104 template <
typename T>
1105 template <
typename Po
intDataGr
idT,
typename DeformerT,
typename FilterT>
1109 using TreeT =
typename PointDataGridT::TreeType;
1110 using LeafT =
typename TreeT::LeafNodeType;
1112 LeafManagerT leafManager(grid.tree());
1115 auto& leafs = mCache.leafs;
1116 leafs.resize(leafManager.leafCount());
1118 const auto& transform = grid.transform();
1122 auto cachePositionsOp = [&](
const LeafT& leaf,
size_t idx) {
1124 const Index64 totalPointCount = leaf.pointCount();
1125 if (totalPointCount == 0)
return;
1129 DeformerT newDeformer(deformer);
1131 newDeformer.reset(leaf, idx);
1135 auto& cache = leafs[idx];
1140 const bool useVector = filter.state() ==
index::ALL &&
1141 (leaf.isDense() || (leaf.onPointCount() == leaf.pointCount()));
1143 cache.vecData.resize(totalPointCount);
1146 for (
auto iter = leaf.beginIndexOn(filter); iter; iter++) {
1150 Vec3d position = handle->get(*iter) + iter.getCoord().asVec3d();
1156 newDeformer.apply(position, iter);
1161 newDeformer.apply(position, iter);
1167 cache.vecData[*iter] =
static_cast<Vec3T>(position);
1170 cache.mapData.insert({*iter,
static_cast<Vec3T>(position)});
1176 if (!cache.mapData.empty()) {
1177 cache.totalSize =
static_cast<Index>(totalPointCount);
1181 leafManager.foreach(cachePositionsOp, threaded);
1185 template <
typename T>
1186 template <
typename LeafT>
1189 if (idx >= mCache.leafs.size()) {
1190 if (mCache.leafs.empty()) {
1191 throw IndexError(
"No leafs in cache, perhaps CachedDeformer has not been evaluated?");
1193 throw IndexError(
"Leaf index is out-of-range of cache leafs.");
1196 auto& cache = mCache.leafs[idx];
1197 if (!cache.mapData.empty()) {
1198 mLeafMap = &cache.mapData;
1202 mLeafVec = &cache.vecData;
1208 template <
typename T>
1209 template <
typename IndexIterT>
1215 auto it = mLeafMap->find(*iter);
1216 if (it == mLeafMap->end())
return;
1222 if (mLeafVec->empty())
return;
1223 assert(*iter < mLeafVec->size());
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
Methods for extracting masks from VDB Point grids.
Definition: openvdb/Exceptions.h:57
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:26
Vec3d asVec3d() const
Definition: Coord.h:144
static Coord round(const Vec3< T > &xyz)
Return xyz rounded to the closest integer coordinates (cell centered conversion).
Definition: Coord.h:51
3x3 matrix class.
Definition: Mat3.h:29
4x4 -matrix class.
Definition: Mat4.h:24
Definition: AttributeArray.h:119
Base class for storing attribute data.
Definition: AttributeArray.h:93
static Ptr create(const AttributeArray &array, const bool collapseOnDestruction=true)
Definition: AttributeArray.h:2116
Ordered collection of uniquely-named attribute arrays.
Definition: AttributeSet.h:39
Write-able version of AttributeHandle.
Definition: AttributeArray.h:915
A no-op filter that can be used when iterating over all indices.
Definition: IndexIterator.h:51
Base class for tree-traversal iterators over all leaf nodes (but not leaf voxels)
Definition: TreeIterator.h:1187
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition: LeafManager.h:85
Vec3< double > Vec3d
Definition: Vec3.h:668
@ ALL
Definition: IndexIterator.h:43
Index32 LeafIndex
Definition: PointMove.h:93
std::vector< IndexTripleArray > GlobalPointIndexMap
Definition: PointMove.h:165
std::vector< IndexPair > IndexPairArray
Definition: PointMove.h:169
std::unordered_map< Coord, LeafIndex > LeafMap
Definition: PointMove.h:174
std::vector< IndexPairArray > LocalPointIndexMap
Definition: PointMove.h:170
std::vector< LeafIndex > LeafIndexArray
Definition: PointMove.h:172
Index indexOffsetFromVoxel(const Index voxelOffset, const LeafT &leaf, IndexArray &offsets)
Definition: PointMove.h:272
std::vector< LeafIndexArray > LeafOffsetArray
Definition: PointMove.h:173
std::vector< IndexArray > GlobalPointIndexIndices
Definition: PointMove.h:166
tbb::concurrent_vector< IndexTriple > IndexTripleArray
Definition: PointMove.h:164
std::vector< Index > IndexArray
Definition: PointMove.h:161
std::pair< Index, Index > IndexPair
Definition: PointMove.h:168
std::tuple< LeafIndex, Index, Index > IndexTriple
Definition: PointMove.h:163
void movePoints(PointDataGridT &points, const math::Transform &transform, DeformerT &deformer, const FilterT &filter=NullFilter(), future::Advect *objectNotInUse=nullptr, bool threaded=true)
Move points in a PointDataGrid using a custom deformer and a new transform.
Definition: PointMove.h:896
Index32 Index
Definition: openvdb/Types.h:32
uint32_t Index32
Definition: openvdb/Types.h:30
uint64_t Index64
Definition: openvdb/Types.h:31
Definition: openvdb/Exceptions.h:13
Definition: PointMove.h:59
Definition: PointMove.h:179
std::vector< LeafT * > LeafArrayT
Definition: PointMove.h:181
void operator()(LeafT &leaf, size_t idx) const
Definition: PointMove.h:199
typename tree::LeafManager< TreeT > LeafManagerT
Definition: PointMove.h:182
typename TreeT::LeafNodeType LeafT
Definition: PointMove.h:180
BuildMoveMapsOp(const DeformerT &deformer, GlobalPointIndexMap &globalMoveLeafMap, LocalPointIndexMap &localMoveLeafMap, const LeafMap &targetLeafMap, const math::Transform &targetTransform, const math::Transform &sourceTransform, const FilterT &filter)
Definition: PointMove.h:184
Definition: PointMove.h:311
void reset(Index startIndex, Index endIndex)
Definition: PointMove.h:321
CopyIterator & operator++()
Definition: PointMove.h:328
Index targetIndex() const
Definition: PointMove.h:348
Index leafIndex(Index i) const
Definition: PointMove.h:334
CopyIterator(const LeafT &leaf, const IndexArray &sortedIndices, const IndexTripleArray &moveIndices, IndexArray &offsets)
Definition: PointMove.h:312
Index sourceIndex() const
Definition: PointMove.h:342
Definition: PointMove.h:291
std::vector< LeafT * > LeafArrayT
Definition: PointMove.h:293
void operator()(LeafT &leaf, size_t idx) const
Definition: PointMove.h:381
std::vector< AttributeArray * > AttributeArrays
Definition: PointMove.h:295
typename tree::LeafManager< TreeT > LeafManagerT
Definition: PointMove.h:294
typename TreeT::LeafNodeType LeafT
Definition: PointMove.h:292
GlobalMovePointsOp(LeafOffsetArray &offsetMap, LeafManagerT &sourceLeafManager, const Index attributeIndex, const GlobalPointIndexMap &moveLeafMap, const GlobalPointIndexIndices &moveLeafIndices)
Definition: PointMove.h:297
Definition: PointMove.h:460
CopyIterator & operator++()
Definition: PointMove.h:468
Index targetIndex() const
Definition: PointMove.h:475
CopyIterator(const LeafT &leaf, const IndexPairArray &indices, IndexArray &offsets)
Definition: PointMove.h:461
Index sourceIndex() const
Definition: PointMove.h:470
Definition: PointMove.h:440
std::vector< LeafT * > LeafArrayT
Definition: PointMove.h:442
void operator()(LeafT &leaf, size_t idx) const
Definition: PointMove.h:487
LocalMovePointsOp(LeafOffsetArray &offsetMap, const LeafIndexArray &sourceIndices, LeafManagerT &sourceLeafManager, const Index attributeIndex, const LocalPointIndexMap &moveLeafMap)
Definition: PointMove.h:446
std::vector< AttributeArray * > AttributeArrays
Definition: PointMove.h:444
typename tree::LeafManager< TreeT > LeafManagerT
Definition: PointMove.h:443
typename TreeT::LeafNodeType LeafT
Definition: PointMove.h:441
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:101
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:153