From 041fe0cda9c4c237924f35c53400fa3332004ec6 Mon Sep 17 00:00:00 2001 From: ppt-adsk Date: Tue, 12 Nov 2024 09:50:39 -0500 Subject: [PATCH] Each stage should only respond to its own stage invalidation notices. (#199) --- .../mhMayaUsdProxyShapeSceneIndex.cpp | 12 +++++ .../mayaUsd/render/mayaToHydra/CMakeLists.txt | 1 + .../render/mayaToHydra/cpp/CMakeLists.txt | 1 + .../cpp/testUsdStageInvalidate.cpp | 46 +++++++++++++++++++ .../mayaToHydra/cpp/testUsdStageInvalidate.py | 43 +++++++++++++++++ 5 files changed, 103 insertions(+) create mode 100644 test/lib/mayaUsd/render/mayaToHydra/cpp/testUsdStageInvalidate.cpp create mode 100644 test/lib/mayaUsd/render/mayaToHydra/cpp/testUsdStageInvalidate.py diff --git a/lib/mayaHydra/hydraExtensions/sceneIndex/mhMayaUsdProxyShapeSceneIndex.cpp b/lib/mayaHydra/hydraExtensions/sceneIndex/mhMayaUsdProxyShapeSceneIndex.cpp index 170f7936d..c376ad8c2 100644 --- a/lib/mayaHydra/hydraExtensions/sceneIndex/mhMayaUsdProxyShapeSceneIndex.cpp +++ b/lib/mayaHydra/hydraExtensions/sceneIndex/mhMayaUsdProxyShapeSceneIndex.cpp @@ -103,6 +103,18 @@ void MayaUsdProxyShapeSceneIndex::_StageSet(const MAYAUSDAPI_NS::ProxyStageSetNo // In these cases we set the stage to null and start over. void MayaUsdProxyShapeSceneIndex::_StageInvalidate(const MAYAUSDAPI_NS::ProxyStageInvalidateNotice& notice) { + constexpr char const* INVALID_PROXY_SHAPE_MSG = + "Stage invalidate notification for invalid proxy shape node at path %s"; + + if (!TF_VERIFY(_dagNodeHandle.isValid(), INVALID_PROXY_SHAPE_MSG, notice.GetProxyShapePath().data())) { + return; + } + + // Is the notification for us? + if (notice.GetProxyShapeObj() != _dagNodeHandle.object()) { + return; + } + _usdImagingStageSceneIndex->SetStage(nullptr); _populated = false; // Simply mark populate as dirty and do not call diff --git a/test/lib/mayaUsd/render/mayaToHydra/CMakeLists.txt b/test/lib/mayaUsd/render/mayaToHydra/CMakeLists.txt index ffb908984..34ac5227d 100644 --- a/test/lib/mayaUsd/render/mayaToHydra/CMakeLists.txt +++ b/test/lib/mayaUsd/render/mayaToHydra/CMakeLists.txt @@ -80,6 +80,7 @@ set(INTERACTIVE_TEST_SCRIPT_FILES cpp/testGeomSubsetsPicking.py cpp/testSinglePicking.py cpp/testSceneIndexDirtying.py + cpp/testUsdStageInvalidate.py cpp/testGeomSubsetsWireframeHighlight.py ) diff --git a/test/lib/mayaUsd/render/mayaToHydra/cpp/CMakeLists.txt b/test/lib/mayaUsd/render/mayaToHydra/cpp/CMakeLists.txt index fd8022981..97a613d52 100644 --- a/test/lib/mayaUsd/render/mayaToHydra/cpp/CMakeLists.txt +++ b/test/lib/mayaUsd/render/mayaToHydra/cpp/CMakeLists.txt @@ -47,6 +47,7 @@ target_sources(${TARGET_NAME} testGeomSubsetsPicking.cpp testSinglePicking.cpp testSceneIndexDirtying.cpp + testUsdStageInvalidate.cpp testGeomSubsetsWireframeHighlight.cpp ) diff --git a/test/lib/mayaUsd/render/mayaToHydra/cpp/testUsdStageInvalidate.cpp b/test/lib/mayaUsd/render/mayaToHydra/cpp/testUsdStageInvalidate.cpp new file mode 100644 index 000000000..079471e78 --- /dev/null +++ b/test/lib/mayaUsd/render/mayaToHydra/cpp/testUsdStageInvalidate.cpp @@ -0,0 +1,46 @@ +// Copyright 2023 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 "testUtils.h" + +#include + +#include + +PXR_NAMESPACE_USING_DIRECTIVE + +TEST(TestUsdStageInvalidate, testAddStage) +{ + // Setup notifications accumulator for the first terminal scene index + const SceneIndicesVector& sceneIndices = GetTerminalSceneIndices(); + ASSERT_GT(sceneIndices.size(), 0u); + auto siRoot = sceneIndices.front(); + + // Start accumulating notifications. + SceneIndexNotificationsAccumulator notifsAccumulator(siRoot); + + // Add a stage with new layer. + MGlobal::executePythonCommand("import mayaUsd_createStageWithNewLayer; mayaUsd_createStageWithNewLayer.createStageWithNewLayer()"); + + // Confirm the new stage is in the Hydra scene. + auto prim = siRoot->GetPrim(SdfPath("/MayaUsdProxyShape_PluginNode/mayaUsdProxyShape1")); + ASSERT_TRUE(prim.dataSource); + + // There should not have been any prim removed notifications, only prim + // added and dirtied. + ASSERT_EQ(notifsAccumulator.GetRemovedPrimEntries().size(), 0u); + ASSERT_GT(notifsAccumulator.GetDirtiedPrimEntries().size(), 0u); + ASSERT_GT(notifsAccumulator.GetAddedPrimEntries().size(), 0u); +} diff --git a/test/lib/mayaUsd/render/mayaToHydra/cpp/testUsdStageInvalidate.py b/test/lib/mayaUsd/render/mayaToHydra/cpp/testUsdStageInvalidate.py new file mode 100644 index 000000000..9b6ce0a79 --- /dev/null +++ b/test/lib/mayaUsd/render/mayaToHydra/cpp/testUsdStageInvalidate.py @@ -0,0 +1,43 @@ +# 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. +# +import maya.cmds as cmds +import fixturesUtils +import mtohUtils +import usdUtils +import testUtils +from testUtils import PluginLoaded + +class TestUsdStageInvalidate(mtohUtils.MayaHydraBaseTestCase): + # MayaHydraBaseTestCase.setUpClass requirement. + _file = __file__ + + # Base class setUp() defines HdStorm as the renderer. + + def setupScene(self): + usdScenePath = testUtils.getTestScene('testUsdNativeInstances', 'instancedCubeHierarchies.usda') + usdUtils.createStageFromFile(usdScenePath) + # Clear the selection, otherwise we'll get selection highlighting + # geometry prim removals for the current stage when we create and + # switch the selection to the new stage in the C++ part of the test. + cmds.select(clear=True) + cmds.refresh() + + def test_addStage(self): + self.setupScene() + with PluginLoaded('mayaHydraCppTests'): + cmds.mayaHydraCppTest(f="TestUsdStageInvalidate.testAddStage") + +if __name__ == '__main__': + fixturesUtils.runTests(globals())