From 097a8040d91b8b24a10d3ef0c5312242e9a643e1 Mon Sep 17 00:00:00 2001 From: debloip Date: Wed, 22 Nov 2023 14:08:01 -0500 Subject: [PATCH 1/2] HYDRA-456 : Add test for USD stage layer muting --- .../mayaUsd/render/mayaToHydra/CMakeLists.txt | 1 + .../render/mayaToHydra/cpp/CMakeLists.txt | 1 + .../cpp/testUsdStageLayerMuting.cpp | 78 +++++++++++++++++++ .../cpp/testUsdStageLayerMuting.py | 73 +++++++++++++++++ .../render/mayaToHydra/cpp/testUtils.h | 21 +++++ 5 files changed, 174 insertions(+) create mode 100644 test/lib/mayaUsd/render/mayaToHydra/cpp/testUsdStageLayerMuting.cpp create mode 100644 test/lib/mayaUsd/render/mayaToHydra/cpp/testUsdStageLayerMuting.py diff --git a/test/lib/mayaUsd/render/mayaToHydra/CMakeLists.txt b/test/lib/mayaUsd/render/mayaToHydra/CMakeLists.txt index e614f5a072..a687913f70 100644 --- a/test/lib/mayaUsd/render/mayaToHydra/CMakeLists.txt +++ b/test/lib/mayaUsd/render/mayaToHydra/CMakeLists.txt @@ -21,6 +21,7 @@ set(TEST_SCRIPT_FILES cpp/testSelectionSceneIndex.py cpp/testWireframeSelectionHighlightSceneIndex.py cpp/testFlowViewportAPIViewportInformation.py + cpp/testUsdStageLayerMuting.py ) # Test use of mesh adapter code for mesh support, using environment variable. diff --git a/test/lib/mayaUsd/render/mayaToHydra/cpp/CMakeLists.txt b/test/lib/mayaUsd/render/mayaToHydra/cpp/CMakeLists.txt index f59cd60821..d8019d6985 100644 --- a/test/lib/mayaUsd/render/mayaToHydra/cpp/CMakeLists.txt +++ b/test/lib/mayaUsd/render/mayaToHydra/cpp/CMakeLists.txt @@ -22,6 +22,7 @@ target_sources(${TARGET_NAME} testWireframeSelectionHighlightSceneIndex.cpp testFvpViewportInformationMultipleViewports.cpp testFvpViewportInformationRendererSwitching.cpp + testUsdStageLayerMuting.cpp ) # ----------------------------------------------------------------------------- diff --git a/test/lib/mayaUsd/render/mayaToHydra/cpp/testUsdStageLayerMuting.cpp b/test/lib/mayaUsd/render/mayaToHydra/cpp/testUsdStageLayerMuting.cpp new file mode 100644 index 0000000000..c7e0fd3794 --- /dev/null +++ b/test/lib/mayaUsd/render/mayaToHydra/cpp/testUsdStageLayerMuting.cpp @@ -0,0 +1,78 @@ +// 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 + +namespace { + +constexpr float kUnmutedExtent = 4.0f; + +FindPrimPredicate findCubePredicate = PrimNamePredicate("USDCube"); + +HdDataSourceLocator extentMinLocator = HdDataSourceLocator(TfToken("extent"), TfToken("min")); +HdDataSourceLocator extentMaxLocator = HdDataSourceLocator(TfToken("extent"), TfToken("max")); + +} // namespace + +TEST(UsdStageLayerMuting, testSubLayerUnmuted) +{ + // Get the terminal scene index + const auto& sceneIndices = GetTerminalSceneIndices(); + ASSERT_GT(sceneIndices.size(), 0u); + SceneIndexInspector inspector(sceneIndices.front()); + + // Find the cube prim + PrimEntriesVector cubePrims = inspector.FindPrims(findCubePredicate); + ASSERT_EQ(cubePrims.size(), 1u); + HdSceneIndexPrim cubePrim = cubePrims.front().prim; + + // Retrieve the extent/min and extent/max data sources + auto extentMinDataSource = HdTypedSampledDataSource::Cast( + HdContainerDataSource::Get(cubePrim.dataSource, extentMinLocator)); + ASSERT_TRUE(extentMinDataSource); + auto extentMaxDataSource = HdTypedSampledDataSource::Cast( + HdContainerDataSource::Get(cubePrim.dataSource, extentMaxLocator)); + ASSERT_TRUE(extentMaxDataSource); + + // Ensure the extents have the correct values + EXPECT_TRUE(GfIsClose( + extentMinDataSource->GetTypedValue(0), -GfVec3d(kUnmutedExtent), DEFAULT_TOLERANCE)); + EXPECT_TRUE(GfIsClose( + extentMaxDataSource->GetTypedValue(0), GfVec3d(kUnmutedExtent), DEFAULT_TOLERANCE)); +} + +TEST(UsdStageLayerMuting, testSubLayerMuted) +{ + // Get the terminal scene index + const auto& sceneIndices = GetTerminalSceneIndices(); + ASSERT_GT(sceneIndices.size(), 0u); + SceneIndexInspector inspector(sceneIndices.front()); + + // Find the cube prim + PrimEntriesVector cubePrims = inspector.FindPrims(findCubePredicate); + ASSERT_EQ(cubePrims.size(), 1u); + HdSceneIndexPrim cubePrim = cubePrims.front().prim; + + // Ensure there is no "extent" data source with the sublayer muted, + // since the root layer did not define any special extents. + auto extentDataSource = cubePrim.dataSource->Get(TfToken("extent")); + EXPECT_FALSE(extentDataSource); +} diff --git a/test/lib/mayaUsd/render/mayaToHydra/cpp/testUsdStageLayerMuting.py b/test/lib/mayaUsd/render/mayaToHydra/cpp/testUsdStageLayerMuting.py new file mode 100644 index 0000000000..a4cf44fa50 --- /dev/null +++ b/test/lib/mayaUsd/render/mayaToHydra/cpp/testUsdStageLayerMuting.py @@ -0,0 +1,73 @@ +# 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. +# +import maya.cmds as cmds + +import fixturesUtils +import mtohUtils +import unittest + +from testUtils import PluginLoaded + +class TestUsdStageLayerMuting(mtohUtils.MayaHydraBaseTestCase): + # MayaHydraBaseTestCase.setUpClass requirement. + _file = __file__ + + CUBE_PRIM_PATH = "/USDCube" + SUB_LAYER_CUBE_SIZE = 8.0 + + def setSubLayerMuted(self, isMuted: bool): + import maya.cmds as cmds + cmds.mayaUsdLayerEditor(self.subLayer.identifier, edit=True, muteLayer=(isMuted, self.usdProxyShapeUfePathString)) + + def setupUsdStage(self): + import maya.cmds as cmds + import mayaUsd + import mayaUsd_createStageWithNewLayer + from pxr import UsdGeom, Sdf + + self.setHdStormRenderer() + cmds.refresh() + + # Create a USD stage + self.usdProxyShapeUfePathString = mayaUsd_createStageWithNewLayer.createStageWithNewLayer() + stage = mayaUsd.lib.GetPrim(self.usdProxyShapeUfePathString).GetStage() + + # Define a cube prim in the stage (implicit surface) + UsdGeom.Cube.Define(stage, self.CUBE_PRIM_PATH) + + # Add a sublayer to the stage + rootLayer = stage.GetRootLayer() + subLayerId = cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, addAnonymous="testSubLayer")[0] + self.subLayer = Sdf.Layer.Find(subLayerId) + + # Author an opinion on the sublayer + stage.SetEditTarget(self.subLayer) + cubePrim = stage.GetPrimAtPath(self.CUBE_PRIM_PATH) + cubePrim.GetAttribute('size').Set(self.SUB_LAYER_CUBE_SIZE) + + cmds.refresh() + + @unittest.skipUnless(mtohUtils.checkForMayaUsdPlugin(), "Requires Maya USD Plugin.") + def test_UsdStageLayerMuting(self): + self.setupUsdStage() + with PluginLoaded('mayaHydraCppTests'): + cmds.mayaHydraCppTest(f="UsdStageLayerMuting.testSubLayerUnmuted") + self.setSubLayerMuted(True) + cmds.mayaHydraCppTest(f="UsdStageLayerMuting.testSubLayerMuted") + self.setSubLayerMuted(False) + cmds.mayaHydraCppTest(f="UsdStageLayerMuting.testSubLayerUnmuted") + +if __name__ == '__main__': + fixturesUtils.runTests(globals()) diff --git a/test/lib/mayaUsd/render/mayaToHydra/cpp/testUtils.h b/test/lib/mayaUsd/render/mayaToHydra/cpp/testUtils.h index 69b9f8bbb5..5eee765536 100644 --- a/test/lib/mayaUsd/render/mayaToHydra/cpp/testUtils.h +++ b/test/lib/mayaUsd/render/mayaToHydra/cpp/testUtils.h @@ -144,6 +144,27 @@ class SceneIndexInspector HdSceneIndexBasePtr _sceneIndex; }; +class PrimNamePredicate +{ +public: + PrimNamePredicate(const std::string& primName) : _primName(primName) {} + + /** + * @brief Predicate to match a prim name. + * + * @param[in] sceneIndex The scene index in which the prim path to test is contained. + * @param[in] primPath The prim path to test. + * + * @return True if the argument prim path's name matches the predicate's prim name, false otherwise. + */ + bool operator()(const HdSceneIndexBasePtr& sceneIndex, const SdfPath& primPath) { + return primPath.GetName() == _primName; + } + +private: + const std::string _primName; +}; + class SceneIndexDisplayNamePred { const std::string _name; public: From 93ec02020b1d1e954e707bd7b8a5a6123b4afd42 Mon Sep 17 00:00:00 2001 From: debloip Date: Thu, 23 Nov 2023 11:21:46 -0500 Subject: [PATCH 2/2] HYDRA-456 : Address code review feedback --- .../render/mayaToHydra/cpp/testUsdStageLayerMuting.py | 2 -- test/lib/mayaUsd/render/mayaToHydra/cpp/testUtils.h | 7 ++++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/test/lib/mayaUsd/render/mayaToHydra/cpp/testUsdStageLayerMuting.py b/test/lib/mayaUsd/render/mayaToHydra/cpp/testUsdStageLayerMuting.py index a4cf44fa50..3c12162c3a 100644 --- a/test/lib/mayaUsd/render/mayaToHydra/cpp/testUsdStageLayerMuting.py +++ b/test/lib/mayaUsd/render/mayaToHydra/cpp/testUsdStageLayerMuting.py @@ -28,11 +28,9 @@ class TestUsdStageLayerMuting(mtohUtils.MayaHydraBaseTestCase): SUB_LAYER_CUBE_SIZE = 8.0 def setSubLayerMuted(self, isMuted: bool): - import maya.cmds as cmds cmds.mayaUsdLayerEditor(self.subLayer.identifier, edit=True, muteLayer=(isMuted, self.usdProxyShapeUfePathString)) def setupUsdStage(self): - import maya.cmds as cmds import mayaUsd import mayaUsd_createStageWithNewLayer from pxr import UsdGeom, Sdf diff --git a/test/lib/mayaUsd/render/mayaToHydra/cpp/testUtils.h b/test/lib/mayaUsd/render/mayaToHydra/cpp/testUtils.h index 5eee765536..7668faedb3 100644 --- a/test/lib/mayaUsd/render/mayaToHydra/cpp/testUtils.h +++ b/test/lib/mayaUsd/render/mayaToHydra/cpp/testUtils.h @@ -150,14 +150,15 @@ class PrimNamePredicate PrimNamePredicate(const std::string& primName) : _primName(primName) {} /** - * @brief Predicate to match a prim name. + * @brief Predicate to match a prim name. This class is to be used as a FindPrimPredicate. * - * @param[in] sceneIndex The scene index in which the prim path to test is contained. + * @param[in] _ Unused scene index parameter. Is only present to conform to the + * FindPrimPredicate signature. * @param[in] primPath The prim path to test. * * @return True if the argument prim path's name matches the predicate's prim name, false otherwise. */ - bool operator()(const HdSceneIndexBasePtr& sceneIndex, const SdfPath& primPath) { + bool operator()(const HdSceneIndexBasePtr& _, const SdfPath& primPath) { return primPath.GetName() == _primName; }