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,
 
   63        bool threaded = 
true);
 
   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;
 
 
  101using LeafMap = std::unordered_map<Coord, LeafIndex>;
 
  104template <
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);
 
  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(
 
 
  188    const DeformerT& mDeformer;
 
  194    const FilterT& mFilter;
 
 
  197template <
typename LeafT>
 
  205    Index targetOffset = offsets[voxelOffset]++;
 
  206    if (voxelOffset > 0) {
 
  207        targetOffset += 
static_cast<Index>(leaf.getValue(voxelOffset - 1));
 
 
  213template <
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) { }
 
 
  243        operator bool()
 const { 
return bool(mIt); }
 
  248            mEndIndex = endIndex;
 
 
  260            if (i < mSortedIndices.size()) {
 
  261                return std::get<0>(this->leafIndexTriple(i));
 
  263            return std::numeric_limits<Index>::max();
 
 
  269            return std::get<2>(*mIt);
 
 
  281            if (mIndex >= mEndIndex || mIndex >= mSortedIndices.size()) {
 
  285                mIt = &this->leafIndexTriple(mIndex);
 
  290        const IndexTriple& leafIndexTriple(
Index i)
 const 
  292            return mMoveIndices[mSortedIndices[i]];
 
  299        const IndexArray& mSortedIndices;
 
  300        const IndexTripleArray& mMoveIndices;
 
  301        IndexArray& mOffsets;
 
  302        const IndexTriple* mIt = 
nullptr;
 
 
  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;
 
 
  355    LeafManagerT& mSourceLeafManager;
 
  356    const Index mAttributeIndex;
 
 
  362template <
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);
 
 
  443    LeafManagerT& mSourceLeafManager;
 
  444    const Index mAttributeIndex;
 
 
  455template <
typename Po
intDataGr
idT, 
typename DeformerT, 
typename FilterT>
 
  459                        const FilterT& filter,
 
  464    using PointDataTreeT = 
typename PointDataGridT::TreeType;
 
  465    using LeafT = 
typename PointDataTreeT::LeafNodeType;
 
  472    (void)objectNotInUse;
 
  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();
 
  499    LeafMap targetLeafMap;
 
  500    LeafIndexArray sourceIndices(targetLeafManager.leafCount(),
 
  501        std::numeric_limits<LeafIndex>::max());
 
  503    LeafOffsetArray offsetMap(targetLeafManager.leafCount());
 
  506        LeafMap sourceLeafMap;
 
  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);
 
  545    GlobalPointIndexMap globalMoveLeafMap(targetLeafManager.leafCount());
 
  546    LocalPointIndexMap localMoveLeafMap(targetLeafManager.leafCount());
 
  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);
 
  567    GlobalPointIndexIndices globalMoveLeafIndices(globalMoveLeafMap.size());
 
  569    targetLeafManager.foreach(
 
  570        [&](LeafT& , 
size_t idx) {
 
  571            const IndexTripleArray& moveIndices = globalMoveLeafMap[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());
 
 
  618template <
typename Po
intDataGr
idT, 
typename DeformerT, 
typename FilterT>
 
  621                        const FilterT& filter,
 
 
  638template <
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);
 
 
  719template <
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;
 
 
  742template <
typename IndexIterT>
 
  748        auto it = mLeafMap->find(*iter);
 
  749        if (it == mLeafMap->end())      
return;
 
  755        if (mLeafVec->empty())          
return;
 
 
#define OPENVDB_ASSERT(X)
Definition Assert.h:41
static Coord round(const Vec3< T > &xyz)
Return xyz rounded to the closest integer coordinates (cell centered conversion).
Definition Coord.h:51
Definition Exceptions.h:57
Signed (x, y, z) 32-bit integer coordinates.
Definition Coord.h:26
Vec3d asVec3d() const
Definition Coord.h:144
Definition AttributeArray.h:120
static Ptr create(const AttributeArray &array, const bool collapseOnDestruction=true)
Definition AttributeArray.h:1984
Ordered collection of uniquely-named attribute arrays.
Definition AttributeSet.h:40
static Ptr create(AttributeArray &array, const bool expand=true)
Definition AttributeArray.h:2104
A no-op filter that can be used when iterating over all indices.
Definition IndexIterator.h:52
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition LeafManager.h:86
Vec3< double > Vec3d
Definition Vec3.h:665
@ ALL
Definition IndexIterator.h:44
Definition PointMoveImpl.h:20
Index32 LeafIndex
Definition PointMoveImpl.h:20
std::vector< IndexTripleArray > GlobalPointIndexMap
Definition PointMoveImpl.h:92
std::vector< IndexPair > IndexPairArray
Definition PointMoveImpl.h:96
std::unordered_map< Coord, LeafIndex > LeafMap
Definition PointMoveImpl.h:101
std::vector< IndexPairArray > LocalPointIndexMap
Definition PointMoveImpl.h:97
std::vector< LeafIndex > LeafIndexArray
Definition PointMoveImpl.h:99
std::vector< LeafIndexArray > LeafOffsetArray
Definition PointMoveImpl.h:100
std::vector< IndexArray > GlobalPointIndexIndices
Definition PointMoveImpl.h:93
tbb::concurrent_vector< IndexTriple > IndexTripleArray
Definition PointMoveImpl.h:91
Index indexOffsetFromVoxel(const Index voxelOffset, const LeafT &leaf, IndexArray &offsets)
Definition PointMoveImpl.h:199
std::vector< Index > IndexArray
Definition PointMoveImpl.h:88
std::pair< Index, Index > IndexPair
Definition PointMoveImpl.h:95
std::tuple< LeafIndex, Index, Index > IndexTriple
Definition PointMoveImpl.h:90
Definition AttributeArray.h:42
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 PointDataGrid.h:170
Index32 Index
Definition Types.h:54
uint32_t Index32
Definition Types.h:52
uint64_t Index64
Definition Types.h:53
Definition Exceptions.h:13
Definition PointMove.h:57
std::vector< LeafT * > LeafArrayT
Definition PointMoveImpl.h:108
void operator()(LeafT &leaf, size_t idx) const
Definition PointMoveImpl.h:126
typename tree::LeafManager< TreeT > LeafManagerT
Definition PointMoveImpl.h:109
typename TreeT::LeafNodeType LeafT
Definition PointMoveImpl.h:107
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
Definition PointMoveImpl.h:235
void reset(Index startIndex, Index endIndex)
Definition PointMoveImpl.h:245
Index targetIndex() const
Definition PointMoveImpl.h:272
Index leafIndex(Index i) const
Definition PointMoveImpl.h:258
CopyIterator & operator++()
Definition PointMoveImpl.h:252
CopyIterator(const LeafT &leaf, const IndexArray &sortedIndices, const IndexTripleArray &moveIndices, IndexArray &offsets)
Definition PointMoveImpl.h:236
Index sourceIndex() const
Definition PointMoveImpl.h:266
std::vector< LeafT * > LeafArrayT
Definition PointMoveImpl.h:217
void operator()(LeafT &leaf, size_t idx) const
Definition PointMoveImpl.h:305
std::vector< AttributeArray * > AttributeArrays
Definition PointMoveImpl.h:219
typename tree::LeafManager< TreeT > LeafManagerT
Definition PointMoveImpl.h:218
typename TreeT::LeafNodeType LeafT
Definition PointMoveImpl.h:216
GlobalMovePointsOp(LeafOffsetArray &offsetMap, LeafManagerT &sourceLeafManager, const Index attributeIndex, const GlobalPointIndexMap &moveLeafMap, const GlobalPointIndexIndices &moveLeafIndices)
Definition PointMoveImpl.h:221
Definition PointMoveImpl.h:384
Index targetIndex() const
Definition PointMoveImpl.h:399
CopyIterator & operator++()
Definition PointMoveImpl.h:392
CopyIterator(const LeafT &leaf, const IndexPairArray &indices, IndexArray &offsets)
Definition PointMoveImpl.h:385
Index sourceIndex() const
Definition PointMoveImpl.h:394
std::vector< LeafT * > LeafArrayT
Definition PointMoveImpl.h:366
void operator()(LeafT &leaf, size_t idx) const
Definition PointMoveImpl.h:411
LocalMovePointsOp(LeafOffsetArray &offsetMap, const LeafIndexArray &sourceIndices, LeafManagerT &sourceLeafManager, const Index attributeIndex, const LocalPointIndexMap &moveLeafMap)
Definition PointMoveImpl.h:370
std::vector< AttributeArray * > AttributeArrays
Definition PointMoveImpl.h:368
typename tree::LeafManager< TreeT > LeafManagerT
Definition PointMoveImpl.h:367
typename TreeT::LeafNodeType LeafT
Definition PointMoveImpl.h:365
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:218