From 18e304bf679591451e903ce82eac0c402a36afa6 Mon Sep 17 00:00:00 2001 From: debloip-adsk <145056365+debloip-adsk@users.noreply.github.com> Date: Thu, 9 Jan 2025 11:27:27 -0500 Subject: [PATCH] HYDRA-1098 : Viewport filters for Hydra data (#189) --- lib/flowViewport/sceneIndex/CMakeLists.txt | 2 + .../sceneIndex/fvpPruningSceneIndex.cpp | 349 ++++++++++++++++++ .../sceneIndex/fvpPruningSceneIndex.h | 143 +++++++ lib/mayaHydra/mayaPlugin/renderOverride.cpp | 31 +- lib/mayaHydra/mayaPlugin/renderOverride.h | 2 + .../cameras_USD_excluded.png | Bin 0 -> 1563 bytes .../cameras_USD_included.png | Bin 0 -> 6372 bytes .../lights_USD_excluded.png | Bin 0 -> 1563 bytes .../lights_USD_included.png | Bin 0 -> 3889 bytes .../nurbsCurves_USD_excluded.png | Bin 0 -> 1563 bytes .../nurbsCurves_USD_included.png | Bin 0 -> 5176 bytes .../nurbsPatches_USD_excluded.png | Bin 0 -> 1563 bytes .../nurbsPatches_USD_included.png | Bin 0 -> 20117 bytes .../polygons_DataProducer_excluded.png | Bin 0 -> 1563 bytes .../polygons_DataProducer_included.png | Bin 0 -> 19037 bytes .../polygons_USD_excluded.png | Bin 0 -> 1563 bytes .../polygons_USD_included.png | Bin 0 -> 15188 bytes .../render/mayaToHydra/testViewportFilters.py | 92 ++++- test/testUtils/fixturesUtils.py | 2 +- 19 files changed, 618 insertions(+), 3 deletions(-) create mode 100644 lib/flowViewport/sceneIndex/fvpPruningSceneIndex.cpp create mode 100644 lib/flowViewport/sceneIndex/fvpPruningSceneIndex.h create mode 100644 test/lib/mayaUsd/render/mayaToHydra/ViewportFiltersTest/cameras_USD_excluded.png create mode 100644 test/lib/mayaUsd/render/mayaToHydra/ViewportFiltersTest/cameras_USD_included.png create mode 100644 test/lib/mayaUsd/render/mayaToHydra/ViewportFiltersTest/lights_USD_excluded.png create mode 100644 test/lib/mayaUsd/render/mayaToHydra/ViewportFiltersTest/lights_USD_included.png create mode 100644 test/lib/mayaUsd/render/mayaToHydra/ViewportFiltersTest/nurbsCurves_USD_excluded.png create mode 100644 test/lib/mayaUsd/render/mayaToHydra/ViewportFiltersTest/nurbsCurves_USD_included.png create mode 100644 test/lib/mayaUsd/render/mayaToHydra/ViewportFiltersTest/nurbsPatches_USD_excluded.png create mode 100644 test/lib/mayaUsd/render/mayaToHydra/ViewportFiltersTest/nurbsPatches_USD_included.png create mode 100644 test/lib/mayaUsd/render/mayaToHydra/ViewportFiltersTest/polygons_DataProducer_excluded.png create mode 100644 test/lib/mayaUsd/render/mayaToHydra/ViewportFiltersTest/polygons_DataProducer_included.png create mode 100644 test/lib/mayaUsd/render/mayaToHydra/ViewportFiltersTest/polygons_USD_excluded.png create mode 100644 test/lib/mayaUsd/render/mayaToHydra/ViewportFiltersTest/polygons_USD_included.png diff --git a/lib/flowViewport/sceneIndex/CMakeLists.txt b/lib/flowViewport/sceneIndex/CMakeLists.txt index a6e8beff27..1af5ae65bb 100644 --- a/lib/flowViewport/sceneIndex/CMakeLists.txt +++ b/lib/flowViewport/sceneIndex/CMakeLists.txt @@ -13,6 +13,7 @@ target_sources(${TARGET_NAME} fvpWireframeSelectionHighlightSceneIndex.cpp fvpDisplayStyleOverrideSceneIndex.cpp fvpPruneTexturesSceneIndex.cpp + fvpPruningSceneIndex.cpp fvpBBoxSceneIndex.cpp fvpReprSelectorSceneIndex.cpp fvpBlockPrimRemovalPropagationSceneIndex.cpp @@ -32,6 +33,7 @@ set(HEADERS fvpWireframeSelectionHighlightSceneIndex.h fvpDisplayStyleOverrideSceneIndex.h fvpPruneTexturesSceneIndex.h + fvpPruningSceneIndex.h fvpBBoxSceneIndex.h fvpReprSelectorSceneIndex.h fvpBlockPrimRemovalPropagationSceneIndex.h diff --git a/lib/flowViewport/sceneIndex/fvpPruningSceneIndex.cpp b/lib/flowViewport/sceneIndex/fvpPruningSceneIndex.cpp new file mode 100644 index 0000000000..783e8fdf31 --- /dev/null +++ b/lib/flowViewport/sceneIndex/fvpPruningSceneIndex.cpp @@ -0,0 +1,349 @@ +// Copyright 2024 Autodesk +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#include "fvpPruningSceneIndex.h" + +#include +#include +#include +#include + +PXR_NAMESPACE_OPEN_SCOPE + +TF_DEFINE_PUBLIC_TOKENS(FvpPruningTokens, FVP_PRUNING_TOKENS); + +PXR_NAMESPACE_CLOSE_SCOPE + +PXR_NAMESPACE_USING_DIRECTIVE + +namespace { + +template +bool _HasAncestorInclusiveInContainer(const SdfPath& path, const Container& pathsContainer) { + SdfPath currPath = path; + while (!currPath.IsEmpty() && !currPath.IsAbsoluteRootPath()) { + if (pathsContainer.find(currPath) != pathsContainer.end()) { + return true; + } else { + currPath = currPath.GetParentPath(); + } + } + return false; +} + +bool _MeshesFilterHandler(const HdSceneIndexBaseRefPtr& sceneIndex, const SdfPath& primPath, const HdSceneIndexPrim& prim) +{ + // Currently we just flat out remove any prim with a mesh type. If we were to add extra checks to make sure this is not + // a mesh prim that serves another purpose, we would add them here. + return prim.primType == HdPrimTypeTokens->mesh; +} + +bool _CapsulesFilterHandler(const HdSceneIndexBaseRefPtr& sceneIndex, const SdfPath& primPath, const HdSceneIndexPrim& prim) +{ + return prim.primType == HdPrimTypeTokens->capsule; +} + +bool _ConesFilterHandler(const HdSceneIndexBaseRefPtr& sceneIndex, const SdfPath& primPath, const HdSceneIndexPrim& prim) +{ + return prim.primType == HdPrimTypeTokens->cone; +} + +bool _CubesFilterHandler(const HdSceneIndexBaseRefPtr& sceneIndex, const SdfPath& primPath, const HdSceneIndexPrim& prim) +{ + return prim.primType == HdPrimTypeTokens->cube; +} + +bool _CylindersFilterHandler(const HdSceneIndexBaseRefPtr& sceneIndex, const SdfPath& primPath, const HdSceneIndexPrim& prim) +{ + return prim.primType == HdPrimTypeTokens->cylinder; +} + +bool _SpheresFilterHandler(const HdSceneIndexBaseRefPtr& sceneIndex, const SdfPath& primPath, const HdSceneIndexPrim& prim) +{ + return prim.primType == HdPrimTypeTokens->sphere; +} + +bool _NurbsCurvesFilterHandler(const HdSceneIndexBaseRefPtr& sceneIndex, const SdfPath& primPath, const HdSceneIndexPrim& prim) +{ + return prim.primType == HdPrimTypeTokens->nurbsCurves; +} + +bool _NurbsPatchesFilterHandler(const HdSceneIndexBaseRefPtr& sceneIndex, const SdfPath& primPath, const HdSceneIndexPrim& prim) +{ + return prim.primType == HdPrimTypeTokens->nurbsPatch; +} + +} // namespace + +namespace FVP_NS_DEF { + +PruningSceneIndexRefPtr PruningSceneIndex::New(const HdSceneIndexBaseRefPtr &inputSceneIndex) +{ + return TfCreateRefPtr(new PruningSceneIndex(inputSceneIndex)); +} + +PruningSceneIndex::PruningSceneIndex(HdSceneIndexBaseRefPtr const &inputSceneIndex) : + HdSingleInputFilteringSceneIndexBase(inputSceneIndex), + InputSceneIndexUtils(inputSceneIndex) +{ +} + +void PruningSceneIndex::AddExcludedSceneRoot(const PXR_NS::SdfPath& sceneRoot) +{ + _excludedSceneRoots.emplace(sceneRoot); +} + +bool PruningSceneIndex::_IsExcluded(const PXR_NS::SdfPath& primPath) const +{ + return _HasAncestorInclusiveInContainer(primPath, _excludedSceneRoots); +} + +bool PruningSceneIndex::_PrunePrim(const SdfPath& primPath, const HdSceneIndexPrim& prim, const TfToken& pruningToken) const +{ + if (_IsExcluded(primPath)) { + return false; + } + using FilterHandler = std::function; + static std::map filterHandlers = { + { FvpPruningTokens->meshes, _MeshesFilterHandler }, + { FvpPruningTokens->capsules, _CapsulesFilterHandler }, + { FvpPruningTokens->cones, _ConesFilterHandler }, + { FvpPruningTokens->cubes, _CubesFilterHandler }, + { FvpPruningTokens->cylinders, _CylindersFilterHandler }, + { FvpPruningTokens->spheres, _SpheresFilterHandler }, + { FvpPruningTokens->nurbsCurves, _NurbsCurvesFilterHandler }, + { FvpPruningTokens->nurbsPatches, _NurbsPatchesFilterHandler } + }; + return filterHandlers[pruningToken](GetInputSceneIndex(), primPath, prim); +} + +bool PruningSceneIndex::_IsAncestorPrunedInclusive(const SdfPath& primPath) const +{ + return _HasAncestorInclusiveInContainer(primPath, _filtersByPrunedPath); +} + +HdSceneIndexPrim PruningSceneIndex::GetPrim(const SdfPath& primPath) const +{ + if (_filtersByPrunedPath.find(primPath) != _filtersByPrunedPath.end()) { + // Path is pruned out; return nothing. Note that we could also use + // _IsAncestorPrunedInclusive, but child paths of a pruned out prim + // should not be reachable in the first place due to GetChildPrimPaths + // pruning them out as well. + return {}; + } + return GetInputSceneIndex()->GetPrim(primPath); +} + +SdfPathVector PruningSceneIndex::GetChildPrimPaths(const SdfPath& primPath) const +{ + SdfPathVector baseChildPaths = GetInputSceneIndex()->GetChildPrimPaths(primPath); + SdfPathVector editedChildPaths; + for (const auto& baseChildPath : baseChildPaths) { + // Only keep child paths which are not pruned out. + if (_filtersByPrunedPath.find(baseChildPath) == _filtersByPrunedPath.end()) { + editedChildPaths.emplace_back(baseChildPath); + } + } + return editedChildPaths; +} + +void PruningSceneIndex::SetFilterStatus(const TfToken& pruningToken, bool enabled) +{ + if (enabled) { + _EnableFilter(pruningToken); + } else { + _DisableFilter(pruningToken); + } +} + +void PruningSceneIndex::_EnableFilter(const TfToken& pruningToken) +{ + if (_prunedPathsByFilter.find(pruningToken) != _prunedPathsByFilter.end()) { + // Filter already enabled, no change needed. + return; + } + + // Enable the filter + _prunedPathsByFilter[pruningToken] = SdfPathSet(); + + HdSceneIndexObserver::RemovedPrimEntries prunedPrims; + + for (const SdfPath& primPath : HdSceneIndexPrimView(GetInputSceneIndex())) { + if (_PrunePrim(primPath, GetInputSceneIndex()->GetPrim(primPath), pruningToken)) { + // Only send notification if it was not already pruned out, either directly or indirectly + if (!_IsAncestorPrunedInclusive(primPath)) { + prunedPrims.emplace_back(primPath); + } + + _InsertEntry(primPath, pruningToken); + } + } + + if (!prunedPrims.empty()) { + _SendPrimsRemoved(prunedPrims); + } +} + +void PruningSceneIndex::_DisableFilter(const TfToken& pruningToken) +{ + if (_prunedPathsByFilter.find(pruningToken) == _prunedPathsByFilter.end()) { + // Filter already disabled, no change needed. + return; + } + + HdSceneIndexObserver::AddedPrimEntries unprunedPrims; + + SdfPathSet prunedPaths = _prunedPathsByFilter[pruningToken]; + for (const auto& primPath : prunedPaths) { + _RemoveEntry(primPath, pruningToken); + + // Only send notification if it was pruned and no longer is + if (!_IsAncestorPrunedInclusive(primPath)) { + unprunedPrims.emplace_back(primPath, GetInputSceneIndex()->GetPrim(primPath).primType); + } + } + + // Disable the filter + _prunedPathsByFilter.erase(pruningToken); + + if (!unprunedPrims.empty()) { + _SendPrimsAdded(unprunedPrims); + } +} + +std::set PruningSceneIndex::GetActiveFilters() +{ + std::set pruningTokens; + for (const auto& filterEntry : _prunedPathsByFilter) { + pruningTokens.emplace(filterEntry.first); + } + return pruningTokens; +} + +void PruningSceneIndex::_InsertEntry(const PXR_NS::SdfPath& primPath, const PXR_NS::TfToken& pruningToken) +{ + _prunedPathsByFilter[pruningToken].emplace(primPath); + _filtersByPrunedPath[primPath].emplace(pruningToken); +} + +void PruningSceneIndex::_RemoveEntry(const PXR_NS::SdfPath& primPath, const PXR_NS::TfToken& pruningToken) +{ + if (_prunedPathsByFilter.find(pruningToken) != _prunedPathsByFilter.end()) { + _prunedPathsByFilter[pruningToken].erase(primPath); + } + + if (_filtersByPrunedPath.find(primPath) != _filtersByPrunedPath.end()) { + _filtersByPrunedPath[primPath].erase(pruningToken); + if (_filtersByPrunedPath[primPath].empty()) { + _filtersByPrunedPath.erase(primPath); + } + } +} + +void PruningSceneIndex::_PrimsAdded( + const PXR_NS::HdSceneIndexBase &sender, + const PXR_NS::HdSceneIndexObserver::AddedPrimEntries &entries) +{ + HdSceneIndexObserver::AddedPrimEntries editedEntries; + + for (const auto& addedEntry : entries) { + for (const auto& pruningToken : GetActiveFilters()) { + if (_PrunePrim(addedEntry.primPath, GetInputSceneIndex()->GetPrim(addedEntry.primPath), pruningToken)) { + _InsertEntry(addedEntry.primPath, pruningToken); + } + } + + // Only send notification if not pruned + if (!_IsAncestorPrunedInclusive(addedEntry.primPath)) { + editedEntries.emplace_back(addedEntry); + } + } + + if (!editedEntries.empty()) { + _SendPrimsAdded(editedEntries); + } +} + +void PruningSceneIndex::_PrimsRemoved( + const PXR_NS::HdSceneIndexBase &sender, + const PXR_NS::HdSceneIndexObserver::RemovedPrimEntries &entries) +{ + HdSceneIndexObserver::RemovedPrimEntries editedEntries; + + for (const auto& removedEntry : entries) { + if (!_IsAncestorPrunedInclusive(removedEntry.primPath)) { + // Prim was not pruned; forward the notification + editedEntries.emplace_back(removedEntry); + } else { + // Prim was pruned; we have either already sent a PrimsRemoved + // notification from EnableFilter() or have prevented the original + // PrimsAdded notification from being forwarded in the first place. + // No need to send a PrimsRemoved notification for a prim that + // doesn't exist, just remove the pruning entry. + for (const auto& pruningToken : GetActiveFilters()) { + _RemoveEntry(removedEntry.primPath, pruningToken); + } + } + } + + if (!editedEntries.empty()) { + _SendPrimsRemoved(editedEntries); + } +} + +void PruningSceneIndex::_PrimsDirtied( + const PXR_NS::HdSceneIndexBase &sender, + const PXR_NS::HdSceneIndexObserver::DirtiedPrimEntries &entries) +{ + HdSceneIndexObserver::RemovedPrimEntries removedEntries; + HdSceneIndexObserver::AddedPrimEntries addedEntries; + HdSceneIndexObserver::DirtiedPrimEntries editedEntries; + + for (const auto& dirtiedEntry : entries) { + bool wasInitiallyPruned = _IsAncestorPrunedInclusive(dirtiedEntry.primPath); + + HdSceneIndexPrim dirtiedPrim = GetInputSceneIndex()->GetPrim(dirtiedEntry.primPath); + + for (const auto& pruningToken : GetActiveFilters()) { + if (_PrunePrim(dirtiedEntry.primPath, dirtiedPrim, pruningToken)) { + _InsertEntry(dirtiedEntry.primPath, pruningToken); + } else { + _RemoveEntry(dirtiedEntry.primPath, pruningToken); + } + } + + bool isNowPruned = _IsAncestorPrunedInclusive(dirtiedEntry.primPath); + + if (!wasInitiallyPruned && isNowPruned) { + removedEntries.emplace_back(dirtiedEntry.primPath); + } else if (wasInitiallyPruned && !isNowPruned) { + addedEntries.emplace_back(dirtiedEntry.primPath, dirtiedPrim.primType); + } else { + editedEntries.emplace_back(dirtiedEntry); + } + } + + if (!removedEntries.empty()) { + _SendPrimsRemoved(removedEntries); + } + if (!addedEntries.empty()) { + _SendPrimsAdded(addedEntries); + } + if (!editedEntries.empty()) { + _SendPrimsDirtied(editedEntries); + } +} + +} // namespace FVP_NS_DEF diff --git a/lib/flowViewport/sceneIndex/fvpPruningSceneIndex.h b/lib/flowViewport/sceneIndex/fvpPruningSceneIndex.h new file mode 100644 index 0000000000..3549959cb2 --- /dev/null +++ b/lib/flowViewport/sceneIndex/fvpPruningSceneIndex.h @@ -0,0 +1,143 @@ +// Copyright 2024 Autodesk +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef FVP_PRUNING_SCENE_INDEX_H +#define FVP_PRUNING_SCENE_INDEX_H + +#include "flowViewport/api.h" +#include "flowViewport/sceneIndex/fvpSceneIndexUtils.h" +#include "flowViewport/sceneIndex/fvpPathInterface.h" + +#include +#include +#include + +#include +#include + +PXR_NAMESPACE_OPEN_SCOPE + +// clang-format off +#define FVP_PRUNING_TOKENS \ + (meshes) \ + (capsules) \ + (cones) \ + (cubes) \ + (cylinders) \ + (spheres) \ + (nurbsCurves) \ + (nurbsPatches) \ +// clang-format on + +TF_DECLARE_PUBLIC_TOKENS(FvpPruningTokens, FVP_API, FVP_PRUNING_TOKENS); + +PXR_NAMESPACE_CLOSE_SCOPE + +namespace FVP_NS_DEF { + +class PruningSceneIndex; +typedef PXR_NS::TfRefPtr PruningSceneIndexRefPtr; +typedef PXR_NS::TfRefPtr PruningSceneIndexConstRefPtr; + +class PruningSceneIndex : + public PXR_NS::HdSingleInputFilteringSceneIndexBase + , public InputSceneIndexUtils + , public PathInterface // As a workaround until we move to exclusively using PathMappers +{ +public: + using PXR_NS::HdSingleInputFilteringSceneIndexBase::_GetInputSceneIndex; + + FVP_API + static PruningSceneIndexRefPtr New(const PXR_NS::HdSceneIndexBaseRefPtr &inputScene); + + FVP_API + ~PruningSceneIndex() override = default; + + FVP_API + PXR_NS::HdSceneIndexPrim GetPrim(const PXR_NS::SdfPath& primPath) const override; + + FVP_API + PXR_NS::SdfPathVector GetChildPrimPaths(const PXR_NS::SdfPath& primPath) const override; + + // Add a path for which it and all prims under it will not be considered for filtering. + FVP_API + void AddExcludedSceneRoot(const PXR_NS::SdfPath& sceneRoot); + + // Enable or disable a filter and send corresponding prim notifications + FVP_API + void SetFilterStatus(const PXR_NS::TfToken& pruningToken, bool enabled); + + // Returns the tokens corresponding to the currently enabled filters. + FVP_API + std::set GetActiveFilters(); + + // As a workaround until we move to exclusively using PathMappers + FVP_API + PrimSelections UfePathToPrimSelections(const Ufe::Path& appPath) const override { + PXR_NAMESPACE_USING_DIRECTIVE; + const PathInterface* pathInterface = dynamic_cast(&*GetInputSceneIndex()); + TF_AXIOM(pathInterface); + return pathInterface->UfePathToPrimSelections(appPath); + } + +protected: + FVP_API + PruningSceneIndex(PXR_NS::HdSceneIndexBaseRefPtr const &inputSceneIndex); + + FVP_API + void _PrimsAdded( + const PXR_NS::HdSceneIndexBase &sender, + const PXR_NS::HdSceneIndexObserver::AddedPrimEntries &entries) override; + + FVP_API + void _PrimsRemoved( + const PXR_NS::HdSceneIndexBase &sender, + const PXR_NS::HdSceneIndexObserver::RemovedPrimEntries &entries) override; + + FVP_API + void _PrimsDirtied( + const PXR_NS::HdSceneIndexBase &sender, + const PXR_NS::HdSceneIndexObserver::DirtiedPrimEntries &entries) override; + + FVP_API + void _EnableFilter(const PXR_NS::TfToken& pruningToken); + + FVP_API + void _DisableFilter(const PXR_NS::TfToken& pruningToken); + + FVP_API + void _InsertEntry(const PXR_NS::SdfPath& primPath, const PXR_NS::TfToken& pruningToken); + + FVP_API + void _RemoveEntry(const PXR_NS::SdfPath& primPath, const PXR_NS::TfToken& pruningToken); + + FVP_API + bool _IsExcluded(const PXR_NS::SdfPath& primPath) const; + + FVP_API + bool _PrunePrim(const PXR_NS::SdfPath& primPath, const PXR_NS::HdSceneIndexPrim& prim, const PXR_NS::TfToken& pruningToken) const; + + FVP_API + bool _IsAncestorPrunedInclusive(const PXR_NS::SdfPath& primPath) const; + + std::set _excludedSceneRoots; + + // Maps a pruning token to the set of prim paths that have been pruned out by this token + std::map _prunedPathsByFilter; + std::map> _filtersByPrunedPath; +}; + +} // namespace FVP_NS_DEF + +#endif // FVP_PRUNING_SCENE_INDEX_H diff --git a/lib/mayaHydra/mayaPlugin/renderOverride.cpp b/lib/mayaHydra/mayaPlugin/renderOverride.cpp index c06ae99b0b..f87a2c0f73 100644 --- a/lib/mayaHydra/mayaPlugin/renderOverride.cpp +++ b/lib/mayaHydra/mayaPlugin/renderOverride.cpp @@ -103,6 +103,7 @@ #include #include #include +#include #include #include #include @@ -114,6 +115,7 @@ #include #include #include +#include #include #include @@ -816,6 +818,31 @@ MStatus MtohRenderOverride::Render( _displayStyleSceneIndex->SetRefineLevel({true, delegateParams.refineLevel}); } + // Update "Show" menu filters + { + auto objectExclusions = framecontext->objectTypeExclusions(); + + static const TfTokenVector polygonFilters = { + FvpPruningTokens->meshes, + FvpPruningTokens->capsules, + FvpPruningTokens->cones, + FvpPruningTokens->cubes, + FvpPruningTokens->cylinders, + FvpPruningTokens->spheres + }; + static const std::map mayaFiltersToFvpPruningTokens = { + { MHWRender::MFrameContext::kExcludeMeshes, polygonFilters }, + { MHWRender::MFrameContext::kExcludeNurbsCurves, {FvpPruningTokens->nurbsCurves} }, + { MHWRender::MFrameContext::kExcludeNurbsSurfaces, {FvpPruningTokens->nurbsPatches} } + }; + + for (auto [mayaFilter, fvpPruningTokens] : mayaFiltersToFvpPruningTokens) { + for (const auto& fvpPruningToken : fvpPruningTokens) { + _pruningSceneIndex->SetFilterStatus(fvpPruningToken, objectExclusions & mayaFilter); + } + } + } + // Toggle textures in the material network const unsigned int currentDisplayMode = drawContext.getDisplayStyle(); bool isTextured = currentDisplayMode & MHWRender::MFrameContext::kTextured; @@ -1111,8 +1138,10 @@ void MtohRenderOverride::_InitHydraResources(const MHWRender::MDrawContext& draw //Put BlockPrimRemovalPropagationSceneIndex first as it can block/unblock the prim removal propagation on the whole scene indices chain _blockPrimRemovalPropagationSceneIndex = Fvp::BlockPrimRemovalPropagationSceneIndex::New(_inputSceneIndexOfFilteringSceneIndicesChain); + _pruningSceneIndex = Fvp::PruningSceneIndex::New(_blockPrimRemovalPropagationSceneIndex); + _pruningSceneIndex->AddExcludedSceneRoot(MAYA_NATIVE_ROOT); // Maya filtering is handled by VP2/OGS. _selection = std::make_shared(); - _selectionSceneIndex = Fvp::SelectionSceneIndex::New(_blockPrimRemovalPropagationSceneIndex, _selection); + _selectionSceneIndex = Fvp::SelectionSceneIndex::New(_pruningSceneIndex, _selection); _selectionSceneIndex->SetDisplayName("Flow Viewport Selection Scene Index"); _inputSceneIndexOfFilteringSceneIndicesChain = _selectionSceneIndex; diff --git a/lib/mayaHydra/mayaPlugin/renderOverride.h b/lib/mayaHydra/mayaPlugin/renderOverride.h index 79a7140ade..6ff97cc9f6 100644 --- a/lib/mayaHydra/mayaPlugin/renderOverride.h +++ b/lib/mayaHydra/mayaPlugin/renderOverride.h @@ -53,6 +53,7 @@ #include #include #include +#include #include #include @@ -281,6 +282,7 @@ class MtohRenderOverride : public MHWRender::MRenderOverride, Fvp::SelectionPtr _selection; Fvp::WireframeSelectionHighlightSceneIndexRefPtr _wireframeSelectionHighlightSceneIndex; Fvp::BlockPrimRemovalPropagationSceneIndexRefPtr _blockPrimRemovalPropagationSceneIndex; + Fvp::PruningSceneIndexRefPtr _pruningSceneIndex; Fvp::LightsManagementSceneIndexRefPtr _lightsManagementSceneIndex; // Naming this identifier _ufeSelection clashes with UFE's selection.h diff --git a/test/lib/mayaUsd/render/mayaToHydra/ViewportFiltersTest/cameras_USD_excluded.png b/test/lib/mayaUsd/render/mayaToHydra/ViewportFiltersTest/cameras_USD_excluded.png new file mode 100644 index 0000000000000000000000000000000000000000..dbedef32fd8f3b0a32f32b3420710101c9e1097e GIT binary patch literal 1563 zcmeAS@N?(olHy`uVBq!ia0y~yV4MKL9Be?5hW%z|fD~V9glC$sFM}44%>l$9a4C2) zkmSsFb1Me(LBuVsZRZ#mSZ8{=IEGZrd3)87mqAhBz=6jl>*{4Q7RWmpEncvH-OQg1 z53bZ(Gc=e>axio@GE9&drAC8bG!=|ygwe8q#>HXI_W%}?wyzd{fMqrAGM&NG)z4*} HQ$iB}d4q$r literal 0 HcmV?d00001 diff --git a/test/lib/mayaUsd/render/mayaToHydra/ViewportFiltersTest/cameras_USD_included.png b/test/lib/mayaUsd/render/mayaToHydra/ViewportFiltersTest/cameras_USD_included.png new file mode 100644 index 0000000000000000000000000000000000000000..85139cc31368d52c156fe8d7c12473cf4c6fa895 GIT binary patch literal 6372 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 literal 0 HcmV?d00001 diff --git a/test/lib/mayaUsd/render/mayaToHydra/ViewportFiltersTest/lights_USD_excluded.png b/test/lib/mayaUsd/render/mayaToHydra/ViewportFiltersTest/lights_USD_excluded.png new file mode 100644 index 0000000000000000000000000000000000000000..dbedef32fd8f3b0a32f32b3420710101c9e1097e GIT binary patch literal 1563 zcmeAS@N?(olHy`uVBq!ia0y~yV4MKL9Be?5hW%z|fD~V9glC$sFM}44%>l$9a4C2) zkmSsFb1Me(LBuVsZRZ#mSZ8{=IEGZrd3)87mqAhBz=6jl>*{4Q7RWmpEncvH-OQg1 z53bZ(Gc=e>axio@GE9&drAC8bG!=|ygwe8q#>HXI_W%}?wyzd{fMqrAGM&NG)z4*} HQ$iB}d4q$r literal 0 HcmV?d00001 diff --git a/test/lib/mayaUsd/render/mayaToHydra/ViewportFiltersTest/lights_USD_included.png b/test/lib/mayaUsd/render/mayaToHydra/ViewportFiltersTest/lights_USD_included.png new file mode 100644 index 0000000000000000000000000000000000000000..0455435c717eea9167bc031c272af08e58adfa45 GIT binary patch literal 3889 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 btdp!6uUcjl$9a4C2) zkmSsFb1Me(LBuVsZRZ#mSZ8{=IEGZrd3)87mqAhBz=6jl>*{4Q7RWmpEncvH-OQg1 z53bZ(Gc=e>axio@GE9&drAC8bG!=|ygwe8q#>HXI_W%}?wyzd{fMqrAGM&NG)z4*} HQ$iB}d4q$r literal 0 HcmV?d00001 diff --git a/test/lib/mayaUsd/render/mayaToHydra/ViewportFiltersTest/nurbsCurves_USD_included.png b/test/lib/mayaUsd/render/mayaToHydra/ViewportFiltersTest/nurbsCurves_USD_included.png new file mode 100644 index 0000000000000000000000000000000000000000..ddd8f44330797b25ee941c92554051223826331b GIT binary patch literal 5176 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 literal 0 HcmV?d00001 diff --git a/test/lib/mayaUsd/render/mayaToHydra/ViewportFiltersTest/nurbsPatches_USD_excluded.png b/test/lib/mayaUsd/render/mayaToHydra/ViewportFiltersTest/nurbsPatches_USD_excluded.png new file mode 100644 index 0000000000000000000000000000000000000000..dbedef32fd8f3b0a32f32b3420710101c9e1097e GIT binary patch literal 1563 zcmeAS@N?(olHy`uVBq!ia0y~yV4MKL9Be?5hW%z|fD~V9glC$sFM}44%>l$9a4C2) zkmSsFb1Me(LBuVsZRZ#mSZ8{=IEGZrd3)87mqAhBz=6jl>*{4Q7RWmpEncvH-OQg1 z53bZ(Gc=e>axio@GE9&drAC8bG!=|ygwe8q#>HXI_W%}?wyzd{fMqrAGM&NG)z4*} HQ$iB}d4q$r literal 0 HcmV?d00001 diff --git a/test/lib/mayaUsd/render/mayaToHydra/ViewportFiltersTest/nurbsPatches_USD_included.png b/test/lib/mayaUsd/render/mayaToHydra/ViewportFiltersTest/nurbsPatches_USD_included.png new file mode 100644 index 0000000000000000000000000000000000000000..6c42ebcf78abd4df79bcb3fecc85c187be93b258 GIT binary patch literal 20117 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