Пример #1
0
void
Hd_PrimTypeIndex<PrimType>::GetPrimSubtree(const TfToken &typeId,
                                           const SdfPath &rootPath,
                                           SdfPathVector *outPaths)
{
    HD_TRACE_FUNCTION();
    HF_MALLOC_TAG_FUNCTION();

    typename _TypeIndex::const_iterator typeIt = _index.find(typeId);
    if (typeIt ==_index.end()) {
        TF_CODING_ERROR("Unsupported prim type: %s", typeId.GetText());
        return;
    }

    _PrimTypeEntry &typeEntry = _entries[typeIt->second];

    HdPrimGather gather;
    gather.Subtree(typeEntry.primIds.GetIds(), rootPath, outPaths);
}
Пример #2
0
void
HdDirtyList::_UpdateIDs(SdfPathVector* ids, HdDirtyBits mask)
{
    HD_TRACE_FUNCTION();
    HD_PERF_COUNTER_INCR(HdPerfTokens->dirtyListsRebuilt);

    
    const SdfPathVector &paths        = _renderIndex.GetRprimIds();
    const SdfPathVector &includePaths = _collection.GetRootPaths();
    const SdfPathVector &excludePaths = _collection.GetExcludePaths();

    _FilterParam filterParam = {_collection, _renderIndex, mask};

    HdPrimGather gather;

    gather.PredicatedFilter(paths,
                  includePaths,
                  excludePaths,
                  _DirtyListFilterPredicate,
                  &filterParam,
                  ids);
}
Пример #3
0
bool
HdDirtyList::ApplyEdit(HdRprimCollection const& col)
{
    HD_TRACE_FUNCTION();

    // Don't attempt to transition dirty lists where the collection
    // fundamentally changed, we can't reused filtered paths in those cases.
    //
    // when repr changes, don't reuse the dirty list, since the required
    // DirtyBits may change.
    if (col.GetName() != _collection.GetName()
        || col.GetReprName() != _collection.GetReprName()
        || col.IsForcedRepr() != _collection.IsForcedRepr()
        || col.GetRenderTags() != _collection.GetRenderTags()) {
        return false;
    }

    // Also don't attempt to fix-up dirty lists when the collection is radically
    // different in terms of root paths; here a heuristic of 100 root paths is
    // used as a threshold for when we will stop attempting to fix the list.
    if (std::abs(int(col.GetRootPaths().size()) -
                 int(_collection.GetRootPaths().size())) > 100) {
        return false;
    }

    // If the either the old or new collection has Exclude paths do
    // the full rebuild.
    if (!col.GetExcludePaths().empty() ||
        !_collection.GetExcludePaths().empty()) {
        return false;
    }

    // If the varying state has changed - Rebuild the base list
    // before adding the new items
    HdChangeTracker &changeTracker = _renderIndex.GetChangeTracker();

    unsigned int currentVaryingStateVersion =
                                         changeTracker.GetVaryingStateVersion();

    if (_varyingStateVersion != currentVaryingStateVersion) {
           TF_DEBUG(HD_DIRTY_LIST).Msg("DirtyList(%p): varying state changed "
                   "(%s, %d -> %d)\n",
                   (void*)this,
                   _collection.GetName().GetText(),
                   _varyingStateVersion,
                   currentVaryingStateVersion);

           // populate only varying prims in the collection
           _UpdateIDs(&_dirtyIds, HdChangeTracker::Varying);
           _varyingStateVersion = currentVaryingStateVersion;
    }

    SdfPathVector added, removed;
    typedef SdfPathVector::const_iterator ITR;
    ITR newI = col.GetRootPaths().cbegin();
    ITR newEnd = col.GetRootPaths().cend();
    ITR oldI = _collection.GetRootPaths().cbegin();
    ITR oldEnd = _collection.GetRootPaths().cend();
    HdRenderIndex& index = _renderIndex;
    TfToken const & repr = col.GetReprName();

    TF_DEBUG(HD_DIRTY_LIST).Msg("DirtyList(%p): ApplyEdit\n", (void*)this);

    if (TfDebug::IsEnabled(HD_DIRTY_LIST)) {
        std::cout << "  Old Collection: " << std::endl;
        for (auto const& i : _collection.GetRootPaths()) {
            std::cout << "    " << i << std::endl;
        }
        std::cout << "  Old _dirtyIds: " << std::endl;
        for (auto const& i : _dirtyIds) {
            std::cout << "    " << i << std::endl;
        }
    }

    const SdfPathVector &paths = _renderIndex.GetRprimIds();

    while (newI != newEnd || oldI != oldEnd) {
        if (newI != newEnd && oldI != oldEnd && *newI == *oldI) {
            ++newI;
            ++oldI;
            continue;
        }
        // If any paths in the two sets are prefixed by one another, the logic
        // below doesn't work, since the subtree has to be fixed up (it's not
        // just a simple prefix scan). In these cases, we'll just rebuild the
        // entire list.
        if (newI != newEnd && oldI != oldEnd && newI->HasPrefix(*oldI)) {
            return false;          
        }
        if (newI != newEnd && oldI != oldEnd && oldI->HasPrefix(*newI)) {
            return false;          
        }
        if (newI != newEnd && (oldI == oldEnd || *newI < *oldI)) {
            HdPrimGather gather;

            SdfPathVector newPaths;
            gather.Subtree(paths, *newI, &newPaths);

            size_t numNewPaths = newPaths.size();
            for (size_t newPathNum = 0;
                        newPathNum < numNewPaths;
                      ++newPathNum) {
                const SdfPath &newPath = newPaths[newPathNum];

                if (col.HasRenderTag(index.GetRenderTag(newPath, repr))) {
                    _dirtyIds.push_back(newPath);
                    changeTracker.MarkRprimDirty(newPath,
                                                 HdChangeTracker::InitRepr);
                }
            }
            ++newI;
        } else if (oldI != oldEnd) { 
            // oldI < newI: Item removed in new list
            SdfPath const& oldPath = *oldI;
            _dirtyIds.erase(std::remove_if(_dirtyIds.begin(), _dirtyIds.end(), 
                  [&oldPath](SdfPath const& p){return p.HasPrefix(oldPath);}),
                  _dirtyIds.end());
            ++oldI;
        }
    }

    _collection = col;
    _collectionVersion
                    = changeTracker.GetCollectionVersion(_collection.GetName());


    // make sure the next GetDirtyRprims() picks up the updated list.
    _isEmpty = false;

    if (TfDebug::IsEnabled(HD_DIRTY_LIST)) {
        std::cout << "  New Collection: " << std::endl;
        for (auto const& i : _collection.GetRootPaths()) {
            std::cout << "    " << i << std::endl;
        }
        std::cout << "  New _dirtyIds: " << std::endl;
        for (auto const& i : _dirtyIds) {
            std::cout << "    " << i << std::endl;
        }
    }

    return true;
}
Пример #4
0
void
Hd_PrimTypeIndex<PrimType>::RemoveSubtree(const SdfPath &root,
                                          HdSceneDelegate* sceneDelegate,
                                          HdChangeTracker &tracker,
                                          HdRenderDelegate *renderDelegate)
{
    HD_TRACE_FUNCTION();
    HF_MALLOC_TAG_FUNCTION();

    struct _Range {
        size_t _start;
        size_t _end;

        _Range() = default;
        _Range(size_t start, size_t end)
         : _start(start)
         , _end(end)
        {
        }
    };


    size_t numTypes = _entries.size();
    for (size_t typeIdx = 0; typeIdx < numTypes; ++typeIdx) {
        _PrimTypeEntry &typeEntry = _entries[typeIdx];

        HdPrimGather gather;
        _Range totalRange;
        std::vector<_Range> rangesToRemove;

        const SdfPathVector &ids = typeEntry.primIds.GetIds();
        if (gather.SubtreeAsRange(ids,
                                   root,
                                   &totalRange._start,
                                   &totalRange._end)) {

            // end is inclusive!
            size_t currentRangeStart = totalRange._start;
            for (size_t primIdIdx  = totalRange._start;
                        primIdIdx <= totalRange._end;
                      ++primIdIdx) {
                const SdfPath &primId = ids[primIdIdx];

                typename _PrimMap::iterator primIt = typeEntry.primMap.find(primId);
                if (primIt == typeEntry.primMap.end()) {
                    TF_CODING_ERROR("Prim in id list not in info map: %s",
                                    primId.GetText());
                } else {
                    _PrimInfo &primInfo = primIt->second;

                    if (primInfo.sceneDelegate == sceneDelegate) {
                        _TrackerRemovePrim(tracker, primId);
                        _RenderDelegateDestroyPrim(renderDelegate, primInfo.prim);
                        primInfo.prim = nullptr;

                        typeEntry.primMap.erase(primIt);
                    } else {
                        if (currentRangeStart < primIdIdx) {
                            rangesToRemove.emplace_back(currentRangeStart,
                                                        primIdIdx - 1);
                        }

                        currentRangeStart = primIdIdx + 1;
                    }
                }
            }

            // Remove final range
            if (currentRangeStart <= totalRange._end) {
                rangesToRemove.emplace_back(currentRangeStart,
                                            totalRange._end);
            }

            // Remove ranges from id's in back to front order to not invalidate indices
            while (!rangesToRemove.empty()) {
                _Range &range = rangesToRemove.back();

                typeEntry.primIds.RemoveRange(range._start, range._end);
                rangesToRemove.pop_back();
            }
        }
    }
}