From e03935a07b07959cf692f91eae85f506a40debed Mon Sep 17 00:00:00 2001 From: Pierre Baillargeon Date: Mon, 17 Apr 2023 11:17:53 -0400 Subject: [PATCH 1/3] MAYA-128513 implement code wrapper handler Implement a code wrapper handler to support edit routing for composite commands: - Make the batch-ops handler derive from the correct class depending on which feature is supported in UFE. - Implement a code wrapper handler derived from the batch ops handler. - This code wrapper handler creates edit-routing wrappers for composite commands. Implement a code wrapper that does the edit routing: - The code wrapper cache the stage and layer used when first executing a composite command. - This allows using the same values when undoing. - This is necessary because the original prim that was used when executing the command might not exist anymore once the command executed. - In particular, this is true for the group command, the original prim no longer exists. Make the group command work with edit routing. Note that the Maya group command is implemented in term of the insert-child UFE command. That is why we are modifying the insert-child command. - Use the generic undo/redo support to record the changes, undo and redo them. - Don't assume that the current edit target is where the source prim has opinion. - Instead, apply the child-insertion to the layer that have opinion about the moving prim. - The command restrictions already ensure that we only affect prims that have a single opinion. - (But with these changes, the code will be ready if we support multi-layers command later on.) - The problem was that the command restrictions were correctly looking at where the prim was authored, but the command execution was assuming that the source opinion was on the target layer. - When routing commands, that can obviously be false: the target might not be where the original opinions were. - We do the right thing using similar code as when affecting the session layer, except the target layer is the layer where the command was routed. - By default, when no routing is registered, that is the current edit target. - Fix load rules duplication: the Load rules are not part of the USD data that gets restore by automatic USD undo block, so we need to duplicate them explicitly. Also, the UFE reparent notification need to be triggered during undo and redo. Fix unit tests: - The unit tests were tied to some subtle behavior of the implementation. Now that we use "perfect" undo/redo, the order of items is also preserved, so the testGroupCmd assertions had to be fixed. Similarly, the parent command was assuming the parent prim was passed to the edit router. It was also creating the parent prims, which is not necessary. (The problem was fixed before, but the fix was hidden due to the exact timing of the edit routing call.) - Also made the parent unit test for edit routing properly unregister the router even when the test fails. Otherwise, the subsequent test crashes due to the invalid edit router being left behind. - Added a unit test for the Maya group composite command. - Made sure the code wrapper unit test is not run when the API is not available. - Made text filtering ignore all white spaces at the start and end of lines to avoid to have to write the exact indentations. --- cmake/modules/FindUFE.cmake | 5 + lib/mayaUsd/ufe/CMakeLists.txt | 19 +++ lib/mayaUsd/ufe/Global.cpp | 45 ++++++- lib/mayaUsd/ufe/UsdBatchOpsHandler.cpp | 5 +- lib/mayaUsd/ufe/UsdBatchOpsHandler.h | 8 ++ lib/mayaUsd/ufe/UsdCodeWrapperHandler.cpp | 97 +++++++++++++ lib/mayaUsd/ufe/UsdCodeWrapperHandler.h | 39 ++++++ lib/usdUfe/ufe/UsdUndoInsertChildCommand.cpp | 135 ++++++++++++------- lib/usdUfe/ufe/UsdUndoInsertChildCommand.h | 9 +- lib/usdUfe/utils/editRouterContext.cpp | 26 ++++ lib/usdUfe/utils/editRouterContext.h | 22 ++- test/lib/ufe/CMakeLists.txt | 6 + test/lib/ufe/testEditRouting.py | 74 ++++++++-- test/lib/ufe/testGroupCmd.py | 10 +- test/lib/ufe/testParentCmd.py | 61 ++++----- 15 files changed, 456 insertions(+), 105 deletions(-) create mode 100644 lib/mayaUsd/ufe/UsdCodeWrapperHandler.cpp create mode 100644 lib/mayaUsd/ufe/UsdCodeWrapperHandler.h diff --git a/cmake/modules/FindUFE.cmake b/cmake/modules/FindUFE.cmake index 828e6af9e7..e1d6cb563a 100644 --- a/cmake/modules/FindUFE.cmake +++ b/cmake/modules/FindUFE.cmake @@ -99,6 +99,11 @@ if (UFE_INCLUDE_DIR AND EXISTS "${UFE_INCLUDE_DIR}/ufe/batchOpsHandler.h") list(APPEND UFE_PREVIEW_FEATURES v4_BatchOps) endif() +if(UFE_INCLUDE_DIR AND EXISTS "${UFE_INCLUDE_DIR}/ufe/codeWrapperHandler.h") + list(APPEND UFE_PREVIEW_FEATURES CodeWrapperHandler) + message(STATUS "Maya has UFE code wrapper API") +endif() + # Handle the QUIETLY and REQUIRED arguments and set UFE_FOUND to TRUE if # all listed variables are TRUE. include(FindPackageHandleStandardArgs) diff --git a/lib/mayaUsd/ufe/CMakeLists.txt b/lib/mayaUsd/ufe/CMakeLists.txt index 6f66b5c409..65d47e0770 100644 --- a/lib/mayaUsd/ufe/CMakeLists.txt +++ b/lib/mayaUsd/ufe/CMakeLists.txt @@ -142,6 +142,19 @@ if (v4_BatchOps IN_LIST UFE_PREVIEW_FEATURES) ) endif() +if(CodeWrapperHandler IN_LIST UFE_PREVIEW_FEATURES) + message(STATUS "UFE_PREVIEW has composite command handler support") + target_sources(${PROJECT_NAME} + PRIVATE + UsdCodeWrapperHandler.cpp + ) + + target_compile_definitions(${PROJECT_NAME} + PRIVATE + UFE_PREVIEW_CODE_WRAPPER_HANDLER_SUPPORT=1 + ) +endif() + if(CMAKE_UFE_V4_FEATURES_AVAILABLE) target_sources(${PROJECT_NAME} PRIVATE @@ -269,6 +282,12 @@ if (v4_BatchOps IN_LIST UFE_PREVIEW_FEATURES) ) endif() +if(CodeWrapperHandler IN_LIST UFE_PREVIEW_FEATURES) + list(APPEND HEADERS + UsdCodeWrapperHandler.h + ) +endif() + if(CMAKE_UFE_V4_FEATURES_AVAILABLE) list(APPEND HEADERS UsdShaderNodeDef.h diff --git a/lib/mayaUsd/ufe/Global.cpp b/lib/mayaUsd/ufe/Global.cpp index 845bd12f0b..dc7c017ff5 100644 --- a/lib/mayaUsd/ufe/Global.cpp +++ b/lib/mayaUsd/ufe/Global.cpp @@ -23,6 +23,7 @@ #include #include #include + #ifdef UFE_V2_FEATURES_AVAILABLE #include #include @@ -37,6 +38,7 @@ #include #include #endif + #ifdef UFE_V3_FEATURES_AVAILABLE #define HAVE_PATH_MAPPING #include @@ -44,22 +46,39 @@ #include #include #endif + #if UFE_LIGHTS_SUPPORT #include #endif + #if UFE_MATERIALS_SUPPORT #include #endif + #ifdef UFE_V4_FEATURES_AVAILABLE #include #include #include + #if UFE_PREVIEW_BATCHOPS_SUPPORT #include #endif + +#if UFE_PREVIEW_CODE_WRAPPER_HANDLER_SUPPORT +#include +#endif + +#if (UFE_PREVIEW_VERSION_NUM >= 4001) +#include +#endif + +#endif + +#if defined(UFE_V4_FEATURES_AVAILABLE) && (UFE_PREVIEW_VERSION_NUM >= 4013) #include #include #endif + #if UFE_SCENE_SEGMENT_SUPPORT #include #endif @@ -72,6 +91,7 @@ #include #include #include + #ifdef UFE_V2_FEATURES_AVAILABLE #include #endif @@ -187,21 +207,31 @@ MStatus initialize() handlers.contextOpsHandler = UsdContextOpsHandler::create(); handlers.uiInfoHandler = UsdUIInfoHandler::create(); handlers.cameraHandler = UsdCameraHandler::create(); + #ifdef UFE_V4_FEATURES_AVAILABLE + #if UFE_LIGHTS_SUPPORT handlers.lightHandler = UsdLightHandler::create(); #endif + #if UFE_MATERIALS_SUPPORT handlers.materialHandler = UsdMaterialHandler::create(); #endif handlers.connectionHandler = UsdConnectionHandler::create(); handlers.uiNodeGraphNodeHandler = UsdUINodeGraphNodeHandler::create(); -#if UFE_PREVIEW_BATCHOPS_SUPPORT + +#if UFE_PREVIEW_CODE_WRAPPER_HANDLER_SUPPORT + handlers.batchOpsHandler = UsdCodeWrapperHandler::create(); +#elif UFE_PREVIEW_BATCHOPS_SUPPORT handlers.batchOpsHandler = UsdBatchOpsHandler::create(); #endif + +#if (UFE_PREVIEW_VERSION_NUM >= 4001) handlers.nodeDefHandler = UsdShaderNodeDefHandler::create(); #endif +#endif /* UFE_V4_FEATURES_AVAILABLE */ + #if UFE_SCENE_SEGMENT_SUPPORT // set up the SceneSegmentHandler g_MayaSceneSegmentHandler = runTimeMgr.sceneSegmentHandler(g_MayaRtid); @@ -209,6 +239,7 @@ MStatus initialize() = ProxyShapeSceneSegmentHandler::create(g_MayaSceneSegmentHandler); runTimeMgr.setSceneSegmentHandler(g_MayaRtid, proxyShapeSceneSegmentHandler); #endif + #ifdef UFE_V4_FEATURES_AVAILABLE // set up the ProxyShapeCameraHandler g_MayaCameraHandler = runTimeMgr.cameraHandler(g_MayaRtid); @@ -281,13 +312,15 @@ MStatus initialize() MayaUsd::ufe::UsdUIUfeObserver::create(); #ifndef UFE_V4_FEATURES_AVAILABLE + #if UFE_LIGHTS_SUPPORT runTimeMgr.setLightHandler(usdRtid, UsdLightHandler::create()); #endif #if UFE_MATERIALS_SUPPORT runTimeMgr.setMaterialHandler(usdRtid, UsdMaterialHandler::create()); #endif -#endif + +#endif /* UFE_V4_FEATURES_AVAILABLE */ #ifdef HAVE_PATH_MAPPING g_MayaPathMappingHandler = runTimeMgr.pathMappingHandler(g_MayaRtid); @@ -300,7 +333,13 @@ MStatus initialize() runTimeMgr.setUIInfoHandler(g_MayaRtid, uiInfoHandler); #endif -#endif +#else /* UFE_V2_FEATURES_AVAILABLE */ + auto usdHierHandler = UsdHierarchyHandler::create(); + auto usdTrans3dHandler = UsdTransform3dHandler::create(); + auto usdSceneItemOpsHandler = UsdSceneItemOpsHandler::create(); + g_USDRtid = runTimeMgr.register_( + kUSDRunTimeName, usdHierHandler, usdTrans3dHandler, usdSceneItemOpsHandler); +#endif /* UFE_V2_FEATURES_AVAILABLE */ #if !defined(NDEBUG) assert(usdRtid != 0); diff --git a/lib/mayaUsd/ufe/UsdBatchOpsHandler.cpp b/lib/mayaUsd/ufe/UsdBatchOpsHandler.cpp index 5ca710107d..4334b7499d 100644 --- a/lib/mayaUsd/ufe/UsdBatchOpsHandler.cpp +++ b/lib/mayaUsd/ufe/UsdBatchOpsHandler.cpp @@ -20,10 +20,7 @@ namespace MAYAUSD_NS_DEF { namespace ufe { -UsdBatchOpsHandler::UsdBatchOpsHandler() - : Ufe::BatchOpsHandler() -{ -} +UsdBatchOpsHandler::UsdBatchOpsHandler() { } UsdBatchOpsHandler::~UsdBatchOpsHandler() { } diff --git a/lib/mayaUsd/ufe/UsdBatchOpsHandler.h b/lib/mayaUsd/ufe/UsdBatchOpsHandler.h index 1c2800a86b..59abd37112 100644 --- a/lib/mayaUsd/ufe/UsdBatchOpsHandler.h +++ b/lib/mayaUsd/ufe/UsdBatchOpsHandler.h @@ -23,13 +23,21 @@ #include #include +#if UFE_PREVIEW_CODE_WRAPPER_HANDLER_SUPPORT +#include +#else #include +#endif namespace MAYAUSD_NS_DEF { namespace ufe { //! \brief Interface to create a UsdBatchOpsHandler interface object. +#if UFE_PREVIEW_CODE_WRAPPER_HANDLER_SUPPORT +class MAYAUSD_CORE_PUBLIC UsdBatchOpsHandler : public Ufe::CodeWrapperHandler +#else class MAYAUSD_CORE_PUBLIC UsdBatchOpsHandler : public Ufe::BatchOpsHandler +#endif { public: typedef std::shared_ptr Ptr; diff --git a/lib/mayaUsd/ufe/UsdCodeWrapperHandler.cpp b/lib/mayaUsd/ufe/UsdCodeWrapperHandler.cpp new file mode 100644 index 0000000000..57325ffecc --- /dev/null +++ b/lib/mayaUsd/ufe/UsdCodeWrapperHandler.cpp @@ -0,0 +1,97 @@ +// +// 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 "UsdCodeWrapperHandler.h" + +#include +#include + +#include +#include + +namespace MAYAUSD_NS_DEF { +namespace ufe { + +namespace { + +// A code wrapper that does edit routing for a command name by its operation. +// The edit routing decision is cached after the first sub-operation and is +// reused in subsequent sub-operations. This ensures the same edit routing is +// used during a command execution and during undo and redo. +// +// Note: the code wrapper is the same for the command execute, undo and redo, +// so we don't need the sub-operation name. +class UsdEditRoutingCodeWrapper : public Ufe::CodeWrapper +{ +public: + UsdEditRoutingCodeWrapper(const Ufe::Selection& selection, const std::string& operationName) + : _prim(findPrimInSelection(selection)) + , _operationName(PXR_NS::TfToken(operationName)) + { + } + + void prelude(const std::string& /* subOperation */) override + { + if (_alreadyRouted) { + _editRouterContext = std::make_unique(_stage, _layer); + } else { + _editRouterContext + = std::make_unique(_operationName, _prim); + _stage = _editRouterContext->getStage(); + _layer = _editRouterContext->getLayer(); + _alreadyRouted = true; + } + } + + void cleanup(const std::string& /* subOperation */) override { _editRouterContext.reset(); } + +private: + static PXR_NS::UsdPrim findPrimInSelection(const Ufe::Selection& selection) + { + for (const Ufe::SceneItem::Ptr& item : selection) { + const auto usdItem = std::dynamic_pointer_cast(item); + if (!usdItem) + continue; + return usdItem->prim(); + } + + return {}; + } + + PXR_NS::UsdPrim _prim; + PXR_NS::TfToken _operationName; + bool _alreadyRouted = false; + PXR_NS::UsdStagePtr _stage; + PXR_NS::SdfLayerHandle _layer; + std::unique_ptr _editRouterContext; +}; + +} // namespace + +/*static*/ +std::shared_ptr UsdCodeWrapperHandler::create() +{ + return std::make_shared(); +} + +Ufe::CodeWrapper::Ptr UsdCodeWrapperHandler::createCodeWrapper( + const Ufe::Selection& selection, + const std::string& operationName) +{ + return std::make_unique(selection, operationName); +} + +} // namespace ufe +} // namespace MAYAUSD_NS_DEF diff --git a/lib/mayaUsd/ufe/UsdCodeWrapperHandler.h b/lib/mayaUsd/ufe/UsdCodeWrapperHandler.h new file mode 100644 index 0000000000..82af81d1d0 --- /dev/null +++ b/lib/mayaUsd/ufe/UsdCodeWrapperHandler.h @@ -0,0 +1,39 @@ +// +// 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. +// +#pragma once + +#include + +#include + +namespace MAYAUSD_NS_DEF { +namespace ufe { + +//! \brief Interface to create a UsdCodeWrapperHandler interface object. +class MAYAUSD_CORE_PUBLIC UsdCodeWrapperHandler : public UsdBatchOpsHandler +{ +public: + //! Create a UsdCodeWrapperHandler. + static std::shared_ptr create(); + +protected: + // Ufe::CodeWrapperHandler overrides. + Ufe::CodeWrapper::Ptr + createCodeWrapper(const Ufe::Selection& selection, const std::string& operationName) override; +}; // UsdCodeWrapperHandler + +} // namespace ufe +} // namespace MAYAUSD_NS_DEF diff --git a/lib/usdUfe/ufe/UsdUndoInsertChildCommand.cpp b/lib/usdUfe/ufe/UsdUndoInsertChildCommand.cpp index 067b3b7510..bd1b7322e5 100644 --- a/lib/usdUfe/ufe/UsdUndoInsertChildCommand.cpp +++ b/lib/usdUfe/ufe/UsdUndoInsertChildCommand.cpp @@ -18,8 +18,11 @@ #include "private/UfeNotifGuard.h" +#include + #include #include +#include #include #include #include @@ -130,8 +133,6 @@ UsdUndoInsertChildCommand::UsdUndoInsertChildCommand( // Apply restriction rules UsdUfe::applyCommandRestriction(childPrim, "reparent"); UsdUfe::applyCommandRestriction(parentPrim, "reparent"); - - _childLayer = childPrim.GetStage()->GetEditTarget().GetLayer(); } UsdUndoInsertChildCommand::~UsdUndoInsertChildCommand() { } @@ -180,41 +181,52 @@ static void doUsdInsertion( } } -static UsdSceneItem::Ptr doInsertion( - const SdfLayerHandle& srcLayer, - const SdfPath& srcUsdPath, - const Ufe::Path& srcUfePath, - const SdfLayerHandle& dstLayer, - const SdfPath& dstUsdPath, - const Ufe::Path& dstUfePath) +static void doInsertion( + const SdfPath& srcUsdPath, + const Ufe::Path& srcUfePath, + const SdfPath& dstUsdPath, + const Ufe::Path& dstUfePath) { // We must retrieve the item every time we are called since it could be stale. // We need to get the USD prim from the UFE path. const UsdPrim srcPrim = ufePathToPrim(srcUfePath); const UsdStagePtr stage = srcPrim.GetStage(); - enforceMutedLayer(srcPrim, "reparent"); + // Enforce the edit routing for the insert-child command in order to find + // the target layer. The edit router context sets the edit target of the + // stage of the given prim, if it gets routed. + OperationEditRouterContext ctx(UsdUfe::EditRoutingTokens->RouteParent, srcPrim); + const SdfLayerHandle& dstLayer = srcPrim.GetStage()->GetEditTarget().GetLayer(); - // Make sure the load state of the reparented prim will be preserved. - // We copy all rules that applied to it specifically and remove the rules - // that applied to it specifically. - duplicateLoadRules(*stage, srcUsdPath, dstUsdPath); - removeRulesForPath(*stage, srcUsdPath); + enforceMutedLayer(srcPrim, "reparent"); - // Do the insertion fro, the soufce layer to the target layer. - doUsdInsertion(stage, srcLayer, srcUsdPath, dstLayer, dstUsdPath); + // Do the insertion from the source layer to the target layer. + { + PrimLayerFunc insertionFunc + = [stage, srcUsdPath, dstLayer, dstUsdPath]( + const UsdPrim& prim, const PXR_NS::SdfLayerRefPtr& layer) { + doUsdInsertion(stage, layer, srcUsdPath, dstLayer, dstUsdPath); + }; + + const bool includeTopLayer = true; + const auto rootLayers = getAllSublayerRefs(stage->GetRootLayer(), includeTopLayer); + applyToSomeLayersWithOpinions(srcPrim, rootLayers, insertionFunc); + } // Do the insertion in all other applicable layers, which, due to the command // restrictions that have been verified when the command was created, should // only be session layers. - PrimLayerFunc insertionFunc = - [stage, srcUsdPath, dstUsdPath](const UsdPrim& prim, const PXR_NS::SdfLayerRefPtr& layer) { - doUsdInsertion(stage, layer, srcUsdPath, layer, dstUsdPath); - }; - - const bool includeTopLayer = true; - const auto sessionLayers = getAllSublayerRefs(stage->GetSessionLayer(), includeTopLayer); - applyToSomeLayersWithOpinions(srcPrim, sessionLayers, insertionFunc); + { + PrimLayerFunc insertionFunc + = [stage, srcUsdPath, dstUsdPath]( + const UsdPrim& prim, const PXR_NS::SdfLayerRefPtr& layer) { + doUsdInsertion(stage, layer, srcUsdPath, layer, dstUsdPath); + }; + + const bool includeTopLayer = true; + const auto sessionLayers = getAllSublayerRefs(stage->GetSessionLayer(), includeTopLayer); + applyToSomeLayersWithOpinions(srcPrim, sessionLayers, insertionFunc); + } // Remove all scene descriptions for the source path and its subtree in the source layer. // Note: is the layer targeting really needed? We are removing the prim entirely. @@ -232,23 +244,39 @@ static UsdSceneItem::Ptr doInsertion( }; applyToAllLayersWithOpinions(srcPrim, removeFunc); +} - UsdSceneItem::Ptr dstItem = UsdSceneItem::create(dstUfePath, ufePathToPrim(dstUfePath)); - sendNotification(dstItem, srcUfePath); - return dstItem; +static void +preserveLoadRules(const Ufe::Path& srcUfePath, const SdfPath& srcUsdPath, const SdfPath& dstUsdPath) +{ + UsdPrim srcPrim = ufePathToPrim(srcUfePath); + const UsdStagePtr stage = srcPrim.GetStage(); + + // Make sure the load state of the reparented prim will be preserved. + // We copy all rules that applied to it specifically and remove the rules + // that applied to it specifically. + duplicateLoadRules(*stage, srcUsdPath, dstUsdPath); + removeRulesForPath(*stage, srcUsdPath); } -void UsdUndoInsertChildCommand::insertChildRedo() +static const UsdSceneItem::Ptr +sendReparentNotification(const Ufe::Path& srcUfePath, const Ufe::Path& dstUfePath) { + UsdPrim dstPrim = ufePathToPrim(dstUfePath); + const UsdSceneItem::Ptr ufeDstItem = UsdSceneItem::create(dstUfePath, dstPrim); + + sendNotification(ufeDstItem, srcUfePath); + + return ufeDstItem; +} + +void UsdUndoInsertChildCommand::execute() +{ + InPathChange pc; + if (_usdDstPath.IsEmpty()) { const auto& parentPrim = ufePathToPrim(_ufeParentPath); - // Enforce the edit routing for the insert-child command in order to find - // the target layer. The edit router context sets the edit target of the - // stage of the given prim, if it gets routed. - OperationEditRouterContext ctx(UsdUfe::EditRoutingTokens->RouteParent, parentPrim); - _parentLayer = parentPrim.GetStage()->GetEditTarget().GetLayer(); - // First, check if we need to rename the child. const auto childName = uniqueChildName(parentPrim, _ufeSrcPath.back().string()); @@ -265,29 +293,46 @@ void UsdUndoInsertChildCommand::insertChildRedo() _usdDstPath = parentPrim.GetPath().AppendChild(TfToken(childName)); } + // Load rules must be duplicated before the prim is moved to be able + // to access the existing rules. + preserveLoadRules(_ufeSrcPath, _usdSrcPath, _usdDstPath); + // We need to keep the generated item to be able to return it to the caller // via the insertedChild() member function. - _ufeDstItem = doInsertion( - _childLayer, _usdSrcPath, _ufeSrcPath, _parentLayer, _usdDstPath, _ufeDstPath); -} + { + UsdUndoBlock undoBlock(&_undoableItem); + doInsertion(_usdSrcPath, _ufeSrcPath, _usdDstPath, _ufeDstPath); + } -void UsdUndoInsertChildCommand::insertChildUndo() -{ - // Note: we don't need to keep the source item, we only need it to validate - // that the operation worked. - doInsertion(_parentLayer, _usdDstPath, _ufeDstPath, _childLayer, _usdSrcPath, _ufeSrcPath); + _ufeDstItem = sendReparentNotification(_ufeSrcPath, _ufeDstPath); } void UsdUndoInsertChildCommand::undo() { InPathChange pc; - insertChildUndo(); + + // Load rules must be duplicated before the prim is moved to be able + // to access the existing rules. + // Note: the arguments passed are the opposite of those in execute and redo(). + preserveLoadRules(_ufeDstPath, _usdDstPath, _usdSrcPath); + + _undoableItem.undo(); + + // Note: the arguments passed are the opposite of those in execute and redo(). + sendReparentNotification(_ufeDstPath, _ufeSrcPath); } void UsdUndoInsertChildCommand::redo() { InPathChange pc; - insertChildRedo(); + + // Load rules must be duplicated before the prim is moved to be able + // to access the existing rules. + preserveLoadRules(_ufeSrcPath, _usdSrcPath, _usdDstPath); + + _undoableItem.redo(); + + _ufeDstItem = sendReparentNotification(_ufeSrcPath, _ufeDstPath); } } // namespace USDUFE_NS_DEF diff --git a/lib/usdUfe/ufe/UsdUndoInsertChildCommand.h b/lib/usdUfe/ufe/UsdUndoInsertChildCommand.h index d1470b8841..b786977431 100644 --- a/lib/usdUfe/ufe/UsdUndoInsertChildCommand.h +++ b/lib/usdUfe/ufe/UsdUndoInsertChildCommand.h @@ -18,6 +18,7 @@ #include #include #include +#include #include @@ -59,12 +60,10 @@ class USDUFE_PUBLIC UsdUndoInsertChildCommand : public Ufe::InsertChildCommand const UsdSceneItem::Ptr& pos); private: + void execute() override; void undo() override; void redo() override; - void insertChildRedo(); - void insertChildUndo(); - UsdSceneItem::Ptr _ufeDstItem; Ufe::Path _ufeSrcPath; @@ -74,9 +73,7 @@ class USDUFE_PUBLIC UsdUndoInsertChildCommand : public Ufe::InsertChildCommand PXR_NS::SdfPath _usdSrcPath; PXR_NS::SdfPath _usdDstPath; - PXR_NS::SdfLayerHandle _childLayer; - PXR_NS::SdfLayerHandle _parentLayer; - + UsdUndoableItem _undoableItem; }; // UsdUndoInsertChildCommand } // namespace USDUFE_NS_DEF diff --git a/lib/usdUfe/utils/editRouterContext.cpp b/lib/usdUfe/utils/editRouterContext.cpp index 11463ceeac..69a8ede456 100644 --- a/lib/usdUfe/utils/editRouterContext.cpp +++ b/lib/usdUfe/utils/editRouterContext.cpp @@ -59,6 +59,18 @@ const PXR_NS::SdfLayerHandle& StackedEditRouterContext::getLayer() const return empty; } +const PXR_NS::UsdStagePtr& StackedEditRouterContext::getStage() const +{ + if (_stage) + return _stage; + + if (const StackedEditRouterContext* ctx = GetStackPrevious()) + return ctx->getStage(); + + static const PXR_NS::UsdStagePtr empty; + return empty; +} + bool StackedEditRouterContext::isTargetAlreadySet() const { // Use the edit target of a edit router context higher-up in the call @@ -88,6 +100,13 @@ OperationEditRouterContext::OperationEditRouterContext( { } +OperationEditRouterContext::OperationEditRouterContext( + const PXR_NS::UsdStagePtr& stage, + const PXR_NS::SdfLayerHandle& layer) + : StackedEditRouterContext(stage, layer) +{ +} + PXR_NS::SdfLayerHandle AttributeEditRouterContext::getAttributeLayer( const PXR_NS::UsdPrim& prim, const PXR_NS::TfToken& attributeName) @@ -105,4 +124,11 @@ AttributeEditRouterContext::AttributeEditRouterContext( { } +AttributeEditRouterContext::AttributeEditRouterContext( + const PXR_NS::UsdStagePtr& stage, + const PXR_NS::SdfLayerHandle& layer) + : StackedEditRouterContext(stage, layer) +{ +} + } // namespace USDUFE_NS_DEF diff --git a/lib/usdUfe/utils/editRouterContext.h b/lib/usdUfe/utils/editRouterContext.h index 525ad086b5..1aeb08c016 100644 --- a/lib/usdUfe/utils/editRouterContext.h +++ b/lib/usdUfe/utils/editRouterContext.h @@ -33,12 +33,18 @@ namespace USDUFE_NS_DEF { class USDUFE_PUBLIC StackedEditRouterContext : public PXR_NS::TfStacked { -protected: +public: /*! \brief Retrieve the current targeted layer. * \return The targeted layer. Null if the edit target was not changed. */ const PXR_NS::SdfLayerHandle& getLayer() const; + /*! \brief Retrieve the routed stage. + * \return The stage that is being routed. Null if the edit target was not changed. + */ + const PXR_NS::UsdStagePtr& getStage() const; + +protected: /*! \brief Check if an edit context higher-up in the call-stack of this * thread already routed the edits to a specific layer. */ @@ -76,6 +82,13 @@ class USDUFE_PUBLIC OperationEditRouterContext : public StackedEditRouterContext */ OperationEditRouterContext(const PXR_NS::TfToken& operationName, const PXR_NS::UsdPrim& prim); + /*! \brief Route to the given stage and layer. + * Should be used in undo to ensure the same target is used as in the initial execution. + */ + OperationEditRouterContext( + const PXR_NS::UsdStagePtr& stage, + const PXR_NS::SdfLayerHandle& layer); + private: PXR_NS::SdfLayerHandle getOperationLayer(const PXR_NS::TfToken& operationName, const PXR_NS::UsdPrim& prim); @@ -100,6 +113,13 @@ class USDUFE_PUBLIC AttributeEditRouterContext : public StackedEditRouterContext */ AttributeEditRouterContext(const PXR_NS::UsdPrim& prim, const PXR_NS::TfToken& attributeName); + /*! \brief Route to the given stage and layer. + * Should be used in undo to ensure the same target is used as in the initial execution. + */ + AttributeEditRouterContext( + const PXR_NS::UsdStagePtr& stage, + const PXR_NS::SdfLayerHandle& layer); + private: PXR_NS::SdfLayerHandle getAttributeLayer(const PXR_NS::UsdPrim& prim, const PXR_NS::TfToken& attributeName); diff --git a/test/lib/ufe/CMakeLists.txt b/test/lib/ufe/CMakeLists.txt index af1d2d87ac..05bc14fc11 100644 --- a/test/lib/ufe/CMakeLists.txt +++ b/test/lib/ufe/CMakeLists.txt @@ -121,6 +121,11 @@ if (MAYA_HAS_DISPLAY_LAYER_API) ) endif() +if(CodeWrapperHandler IN_LIST UFE_PREVIEW_FEATURES) + set(UFE_HAS_CODE_WRAPPER "1") +else() + set(UFE_HAS_CODE_WRAPPER "0") +endif() foreach(script ${TEST_SCRIPT_FILES}) mayaUsd_get_unittest_target(target ${script}) @@ -131,6 +136,7 @@ foreach(script ${TEST_SCRIPT_FILES}) "MAYA_PLUG_IN_PATH=${CMAKE_CURRENT_SOURCE_DIR}/ufeTestPlugins" "UFE_PREVIEW_VERSION_NUM=${UFE_PREVIEW_VERSION_NUM}" "LD_LIBRARY_PATH=${ADDITIONAL_LD_LIBRARY_PATH}" + "UFE_HAS_CODE_WRAPPER=${UFE_HAS_CODE_WRAPPER}" "USD_HAS_COLOR4_SDR_SUPPORT=${USD_HAS_COLOR4_SDR_SUPPORT}" "USD_HAS_MX_METADATA_SUPPORT=${USD_HAS_MX_METADATA_SUPPORT}" "UFE_ATTRIBUTES_GET_ENUMS=${UFE_ATTRIBUTES_GET_ENUMS}" diff --git a/test/lib/ufe/testEditRouting.py b/test/lib/ufe/testEditRouting.py index 927fe57f23..c1ee5db6c2 100644 --- a/test/lib/ufe/testEditRouting.py +++ b/test/lib/ufe/testEditRouting.py @@ -7,6 +7,7 @@ import mayaUtils import ufeUtils import ufe +import os import unittest import usdUtils from pxr import UsdGeom @@ -17,7 +18,7 @@ def filterUsdStr(usdSceneStr): '''Remove empty lines and lines starting with pound character.''' - nonBlankLines = filter(None, [l.rstrip() for l in usdSceneStr.splitlines()]) + nonBlankLines = filter(None, [l.strip() for l in usdSceneStr.splitlines()]) finalLines = [l for l in nonBlankLines if not l.startswith('#')] return '\n'.join(finalLines) @@ -206,7 +207,7 @@ def verifyVisibility(sessionLayer): # Check that correct visibility changes were written to the session layer self.assertEqual(filterUsdStr(sessionLayer.ExportToString()), - 'over "B"\n{\n token visibility = "invisible"\n}') + filterUsdStr('over "B"\n{\n token visibility = "invisible"\n}')) self._verifyEditRouterForCmd('visibility', setVisibility, verifyVisibility) @@ -225,7 +226,7 @@ def verifyDuplicate(sessionLayer): # Check that correct duplicated prim was written to the session layer self.assertEqual(filterUsdStr(sessionLayer.ExportToString()), - 'def Xform "B1"\n{\n}') + filterUsdStr('def Xform "B1"\n{\n}')) self._verifyEditRouterForCmd('duplicate', duplicate, verifyDuplicate) @@ -240,7 +241,7 @@ def group(): def verifyGroup(sessionLayer): # Check that correct grouped prim was written to the session layer self.assertEqual(filterUsdStr(sessionLayer.ExportToString()), - 'over "group1"\n{\n def Xform "B"\n {\n }\n}') + filterUsdStr('over "group1"\n{\n def Xform "B"\n {\n }\n}')) # Check that the grouped prim was created in the session layer self.assertIsNotNone(sessionLayer.GetPrimAtPath('/group1')) @@ -280,7 +281,7 @@ def testEditRouterForSetVisibility(self): # Check that correct visibility changes were written to the session layer self.assertEqual(filterUsdStr(sessionLayer.ExportToString()), - 'over "B"\n{\n token visibility = "invisible"\n}') + filterUsdStr('over "B"\n{\n token visibility = "invisible"\n}')) def testEditRouterForAttributeVisibility(self): ''' @@ -313,7 +314,7 @@ def testEditRouterForAttributeVisibility(self): # Check that correct visibility changes were written to the session layer self.assertEqual(filterUsdStr(sessionLayer.ExportToString()), - 'over "B"\n{\n token visibility = "invisible"\n}') + filterUsdStr('over "B"\n{\n token visibility = "invisible"\n}')) # Check we are still allowed to set the attribute without # explicitly changing the edit target. @@ -416,7 +417,7 @@ def testRoutingCompositeCmd(self): # Check to root layer only contains bare A and B xforms. rootLayer = stage.GetRootLayer() self.assertEqual(filterUsdStr(rootLayer.ExportToString()), - 'def Xform "A"\n{\n}\ndef Xform "B"\n{\n}') + filterUsdStr('def Xform "A"\n{\n}\ndef Xform "B"\n{\n}')) # Route the visibility command to the session layer. # Route the custom composite command to the root layer. @@ -442,7 +443,7 @@ def testRoutingCompositeCmd(self): # Check that visibility was written to the root layer rootLayer = stage.GetRootLayer() self.assertEqual(filterUsdStr(rootLayer.ExportToString()), - 'def Xform "A"\n{\n}\ndef Xform "B"\n{\n token visibility = "invisible"\n}') + filterUsdStr('def Xform "A"\n{\n}\ndef Xform "B"\n{\n token visibility = "invisible"\n}')) @unittest.skipUnless(ufeUtils.ufeFeatureSetVersion() >= 4, 'UFE composite commands only available in Python from UFE v4.') def testNotRoutingCompositeCmd(self): @@ -460,7 +461,7 @@ def testNotRoutingCompositeCmd(self): # Check to root layer only contains bare A and B xforms. rootLayer = stage.GetRootLayer() self.assertEqual(filterUsdStr(rootLayer.ExportToString()), - 'def Xform "A"\n{\n}\ndef Xform "B"\n{\n}') + filterUsdStr('def Xform "A"\n{\n}\ndef Xform "B"\n{\n}')) # Select /B sn = ufe.GlobalSelection.get() @@ -480,8 +481,61 @@ def testNotRoutingCompositeCmd(self): # Check that visibility was written to the root layer rootLayer = stage.GetRootLayer() self.assertEqual(filterUsdStr(rootLayer.ExportToString()), - 'def Xform "A"\n{\n}\ndef Xform "B"\n{\n token visibility = "invisible"\n}') + filterUsdStr('def Xform "A"\n{\n}\ndef Xform "B"\n{\n token visibility = "invisible"\n}')) + @unittest.skipIf(os.getenv('UFE_HAS_CODE_WRAPPER', '0') < '1', 'Test requires code wrapper handler only available in UFE 0.5.5 and later') + def testRoutingCompositeGroupCmd(self): + ''' + Test that an edit router for the group composite command routes all sub-commands. + ''' + # Get the session layer + prim = mayaUsd.ufe.ufePathToPrim("|stage1|stageShape1,/A") + stage = prim.GetStage() + sessionLayer = stage.GetSessionLayer() + + # Check that the session layer is empty + self.assertTrue(sessionLayer.empty) + + # Check to root layer only contains bare A and B xforms. + rootLayer = stage.GetRootLayer() + self.assertEqual(filterUsdStr(rootLayer.ExportToString()), + filterUsdStr('def Xform "A"\n{\n}\ndef Xform "B"\n{\n}')) + + # Route the group command to the session layer. + mayaUsd.lib.registerEditRouter('group', routeCmdToSessionLayer) + + # Select /B + sn = ufe.GlobalSelection.get() + sn.clear() + sn.append(self.b) + + # Group + cmds.group() + + # Check that everything was written to the session layer + self.assertIsNotNone(sessionLayer) + expectedContents = ''' + def Xform "group1" ( + kind = "group" + ) + { + float3 xformOp:translate:rotatePivot = (0, 0, 0) + float3 xformOp:translate:rotatePivotTranslate = (0, 0, 0) + float3 xformOp:translate:scalePivot = (0, 0, 0) + float3 xformOp:translate:scalePivotTranslate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate:rotatePivotTranslate", "xformOp:translate:rotatePivot", "!invert!xformOp:translate:rotatePivot", "xformOp:translate:scalePivotTranslate", "xformOp:translate:scalePivot", "!invert!xformOp:translate:scalePivot"] + def Xform "B" + { + float3 xformOp:rotateXYZ = (0, -0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:rotateXYZ", "xformOp:scale"] + } + } + ''' + self.maxDiff = None + self.assertEqual(filterUsdStr(sessionLayer.ExportToString()), filterUsdStr(expectedContents)) + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/test/lib/ufe/testGroupCmd.py b/test/lib/ufe/testGroupCmd.py index 6e33243247..a564fcd970 100644 --- a/test/lib/ufe/testGroupCmd.py +++ b/test/lib/ufe/testGroupCmd.py @@ -521,9 +521,9 @@ def testGroupUndoRedo(self): cmds.undo() self.assertEqual([item for item in stage.Traverse()], - [stage.GetPrimAtPath("/Sphere3"), + [stage.GetPrimAtPath("/Sphere1"), stage.GetPrimAtPath("/Sphere2"), - stage.GetPrimAtPath("/Sphere1")]) + stage.GetPrimAtPath("/Sphere3")]) cmds.redo() @@ -610,9 +610,9 @@ def verifyRadius(item, radius): cmds.undo() self.assertEqual([item for item in stage.Traverse()], - [stage.GetPrimAtPath("/Sphere3"), + [stage.GetPrimAtPath("/Sphere1"), stage.GetPrimAtPath("/Sphere2"), - stage.GetPrimAtPath("/Sphere1")]) + stage.GetPrimAtPath("/Sphere3")]) verifyRadius(getItem(oldSphere1Name), radius) @@ -667,6 +667,8 @@ def testGroupPreserveLoadRules(self): groupHierarchy = ufe.Hierarchy.hierarchy(groupItem) self.assertEqual(len(groupHierarchy.children()), 3) + print(stage.GetLoadRules()) + self.assertEqual(loadRules.NoneRule, stage.GetLoadRules().GetEffectiveRuleForPath('/group1/Sphere1')) self.assertEqual(loadRules.AllRule, stage.GetLoadRules().GetEffectiveRuleForPath('/group1/Sphere2')) diff --git a/test/lib/ufe/testParentCmd.py b/test/lib/ufe/testParentCmd.py index d003d0be47..64e03d8671 100644 --- a/test/lib/ufe/testParentCmd.py +++ b/test/lib/ufe/testParentCmd.py @@ -1359,43 +1359,40 @@ def firstSubLayer(context, routingData): self.assertFalse(len(prim.GetStage().GetRootLayer().subLayerPaths)==0) layerId = prim.GetStage().GetRootLayer().subLayerPaths[0] layer = Sdf.Layer.Find(layerId) - # Make sure the destination exists in the target layer, otherwise - # SdfCopySpec will error. - Sdf.JustCreatePrimInLayer(layer, prim.GetPath()) routingData['layer'] = layerId # Register our edit router which directs the parent edit to # higher-priority layer B, which is not the edit target. mayaUsd.lib.registerEditRouter('parent', firstSubLayer) - - # Check that layer B is empty. - bSubLayer = Sdf.Layer.Find(bSubLayerId) - self.assertEqual(filterUsdStr(bSubLayer.ExportToString()), '') - - # We select B and C, in order, and parent. This parents B to C. - sn = ufe.GlobalSelection.get() - sn.clear() - b = ufe.Hierarchy.createItem(ufe.PathString.path(psPathStr+',/A/B')) - c = ufe.Hierarchy.createItem(ufe.PathString.path(psPathStr+',/C')) - sn.append(b) - sn.append(c) - - a = ufe.Hierarchy.createItem(ufe.PathString.path(psPathStr+',/A')) - self.assertEqual(ufe.Hierarchy.hierarchy(b).parent(), a) - - cmds.parent() - - # Check that prim B is now a child of prim C. Re-create its scene - # item, as its path has changed. - b = ufe.Hierarchy.createItem(ufe.PathString.path(psPathStr+',/C/B')) - self.assertEqual(ufe.Hierarchy.hierarchy(b).parent(), c) - - # Check that layer B now has the parent overs. - self.assertEqual(filterUsdStr(bSubLayer.ExportToString()), - 'over "C"\n{\n def Xform "B"\n {\n }\n}') - - # Restore default edit router. - mayaUsd.lib.restoreDefaultEditRouter('parent') + try: + # Check that layer B is empty. + bSubLayer = Sdf.Layer.Find(bSubLayerId) + self.assertEqual(filterUsdStr(bSubLayer.ExportToString()), '') + + # We select B and C, in order, and parent. This parents B to C. + sn = ufe.GlobalSelection.get() + sn.clear() + b = ufe.Hierarchy.createItem(ufe.PathString.path(psPathStr+',/A/B')) + c = ufe.Hierarchy.createItem(ufe.PathString.path(psPathStr+',/C')) + sn.append(b) + sn.append(c) + + a = ufe.Hierarchy.createItem(ufe.PathString.path(psPathStr+',/A')) + self.assertEqual(ufe.Hierarchy.hierarchy(b).parent(), a) + + cmds.parent() + + # Check that prim B is now a child of prim C. Re-create its scene + # item, as its path has changed. + b = ufe.Hierarchy.createItem(ufe.PathString.path(psPathStr+',/C/B')) + self.assertEqual(ufe.Hierarchy.hierarchy(b).parent(), c) + + # Check that layer B now has the parent overs. + self.assertEqual(filterUsdStr(bSubLayer.ExportToString()), + 'over "C"\n{\n def Xform "B"\n {\n }\n}') + finally: + # Restore default edit router. + mayaUsd.lib.restoreDefaultEditRouter('parent') @unittest.skipUnless(mayaUtils.ufeSupportFixLevel() >= 7, 'Require parent command fix from Maya') def testParentAbsoluteUnderScope(self): From 7e9af764cf70090b1369a4ccd2983c98e0ae1da3 Mon Sep 17 00:00:00 2001 From: Pierre Baillargeon Date: Tue, 30 May 2023 12:07:28 -0400 Subject: [PATCH 2/3] MAYA-128513 fix merge resolution errors and minor issues. - Fix some incorrect ifdef in Global.cpp. They were currently harmless because all UFE V4 if were always satisfied simultaneously, but the code was still not theoretically correct. - Fix some useUfe vs mayaUSD include issues. - Move an anonymous namespace. - Remove a debug print in a test. --- lib/mayaUsd/ufe/Global.cpp | 23 +++++--------------- lib/mayaUsd/ufe/UsdBatchOpsHandler.h | 4 ++-- lib/mayaUsd/ufe/UsdCodeWrapperHandler.cpp | 7 +++--- lib/usdUfe/ufe/UsdUndoInsertChildCommand.cpp | 2 -- test/lib/ufe/testGroupCmd.py | 2 -- 5 files changed, 10 insertions(+), 28 deletions(-) diff --git a/lib/mayaUsd/ufe/Global.cpp b/lib/mayaUsd/ufe/Global.cpp index dc7c017ff5..331b90c3f7 100644 --- a/lib/mayaUsd/ufe/Global.cpp +++ b/lib/mayaUsd/ufe/Global.cpp @@ -56,7 +56,9 @@ #endif #ifdef UFE_V4_FEATURES_AVAILABLE +#include #include +#include #include #include @@ -64,19 +66,10 @@ #include #endif -#if UFE_PREVIEW_CODE_WRAPPER_HANDLER_SUPPORT -#include -#endif - -#if (UFE_PREVIEW_VERSION_NUM >= 4001) -#include -#endif - #endif -#if defined(UFE_V4_FEATURES_AVAILABLE) && (UFE_PREVIEW_VERSION_NUM >= 4013) -#include -#include +#ifdef UFE_PREVIEW_CODE_WRAPPER_HANDLER_SUPPORT +#include #endif #if UFE_SCENE_SEGMENT_SUPPORT @@ -220,7 +213,7 @@ MStatus initialize() handlers.connectionHandler = UsdConnectionHandler::create(); handlers.uiNodeGraphNodeHandler = UsdUINodeGraphNodeHandler::create(); -#if UFE_PREVIEW_CODE_WRAPPER_HANDLER_SUPPORT +#ifdef UFE_PREVIEW_CODE_WRAPPER_HANDLER_SUPPORT handlers.batchOpsHandler = UsdCodeWrapperHandler::create(); #elif UFE_PREVIEW_BATCHOPS_SUPPORT handlers.batchOpsHandler = UsdBatchOpsHandler::create(); @@ -333,12 +326,6 @@ MStatus initialize() runTimeMgr.setUIInfoHandler(g_MayaRtid, uiInfoHandler); #endif -#else /* UFE_V2_FEATURES_AVAILABLE */ - auto usdHierHandler = UsdHierarchyHandler::create(); - auto usdTrans3dHandler = UsdTransform3dHandler::create(); - auto usdSceneItemOpsHandler = UsdSceneItemOpsHandler::create(); - g_USDRtid = runTimeMgr.register_( - kUSDRunTimeName, usdHierHandler, usdTrans3dHandler, usdSceneItemOpsHandler); #endif /* UFE_V2_FEATURES_AVAILABLE */ #if !defined(NDEBUG) diff --git a/lib/mayaUsd/ufe/UsdBatchOpsHandler.h b/lib/mayaUsd/ufe/UsdBatchOpsHandler.h index 59abd37112..2f4e9ae9a5 100644 --- a/lib/mayaUsd/ufe/UsdBatchOpsHandler.h +++ b/lib/mayaUsd/ufe/UsdBatchOpsHandler.h @@ -23,7 +23,7 @@ #include #include -#if UFE_PREVIEW_CODE_WRAPPER_HANDLER_SUPPORT +#ifdef UFE_PREVIEW_CODE_WRAPPER_HANDLER_SUPPORT #include #else #include @@ -33,7 +33,7 @@ namespace MAYAUSD_NS_DEF { namespace ufe { //! \brief Interface to create a UsdBatchOpsHandler interface object. -#if UFE_PREVIEW_CODE_WRAPPER_HANDLER_SUPPORT +#ifdef UFE_PREVIEW_CODE_WRAPPER_HANDLER_SUPPORT class MAYAUSD_CORE_PUBLIC UsdBatchOpsHandler : public Ufe::CodeWrapperHandler #else class MAYAUSD_CORE_PUBLIC UsdBatchOpsHandler : public Ufe::BatchOpsHandler diff --git a/lib/mayaUsd/ufe/UsdCodeWrapperHandler.cpp b/lib/mayaUsd/ufe/UsdCodeWrapperHandler.cpp index 57325ffecc..5f532df0bf 100644 --- a/lib/mayaUsd/ufe/UsdCodeWrapperHandler.cpp +++ b/lib/mayaUsd/ufe/UsdCodeWrapperHandler.cpp @@ -18,12 +18,8 @@ #include #include -#include #include -namespace MAYAUSD_NS_DEF { -namespace ufe { - namespace { // A code wrapper that does edit routing for a command name by its operation. @@ -80,6 +76,9 @@ class UsdEditRoutingCodeWrapper : public Ufe::CodeWrapper } // namespace +namespace MAYAUSD_NS_DEF { +namespace ufe { + /*static*/ std::shared_ptr UsdCodeWrapperHandler::create() { diff --git a/lib/usdUfe/ufe/UsdUndoInsertChildCommand.cpp b/lib/usdUfe/ufe/UsdUndoInsertChildCommand.cpp index bd1b7322e5..cf748d20e4 100644 --- a/lib/usdUfe/ufe/UsdUndoInsertChildCommand.cpp +++ b/lib/usdUfe/ufe/UsdUndoInsertChildCommand.cpp @@ -18,8 +18,6 @@ #include "private/UfeNotifGuard.h" -#include - #include #include #include diff --git a/test/lib/ufe/testGroupCmd.py b/test/lib/ufe/testGroupCmd.py index a564fcd970..a8b2665587 100644 --- a/test/lib/ufe/testGroupCmd.py +++ b/test/lib/ufe/testGroupCmd.py @@ -667,8 +667,6 @@ def testGroupPreserveLoadRules(self): groupHierarchy = ufe.Hierarchy.hierarchy(groupItem) self.assertEqual(len(groupHierarchy.children()), 3) - print(stage.GetLoadRules()) - self.assertEqual(loadRules.NoneRule, stage.GetLoadRules().GetEffectiveRuleForPath('/group1/Sphere1')) self.assertEqual(loadRules.AllRule, stage.GetLoadRules().GetEffectiveRuleForPath('/group1/Sphere2')) From 6795467d653cfd82f65b0a6fd060a61c6c057059 Mon Sep 17 00:00:00 2001 From: Pierre Baillargeon Date: Tue, 30 May 2023 16:14:23 -0400 Subject: [PATCH 3/3] MAYA-128513 simplify code and fix UFE version issues - Return the stage pointer by value. - Remove old UFE version check. --- lib/mayaUsd/ufe/Global.cpp | 2 -- lib/mayaUsd/ufe/UsdCodeWrapperHandler.h | 5 ++++- lib/usdUfe/utils/editRouterContext.cpp | 5 ++--- lib/usdUfe/utils/editRouterContext.h | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/mayaUsd/ufe/Global.cpp b/lib/mayaUsd/ufe/Global.cpp index 331b90c3f7..f02557e83b 100644 --- a/lib/mayaUsd/ufe/Global.cpp +++ b/lib/mayaUsd/ufe/Global.cpp @@ -219,9 +219,7 @@ MStatus initialize() handlers.batchOpsHandler = UsdBatchOpsHandler::create(); #endif -#if (UFE_PREVIEW_VERSION_NUM >= 4001) handlers.nodeDefHandler = UsdShaderNodeDefHandler::create(); -#endif #endif /* UFE_V4_FEATURES_AVAILABLE */ diff --git a/lib/mayaUsd/ufe/UsdCodeWrapperHandler.h b/lib/mayaUsd/ufe/UsdCodeWrapperHandler.h index 82af81d1d0..51204193e2 100644 --- a/lib/mayaUsd/ufe/UsdCodeWrapperHandler.h +++ b/lib/mayaUsd/ufe/UsdCodeWrapperHandler.h @@ -13,7 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. // -#pragma once +#ifndef MAYA_USD_CODE_WRAPPER_HANDLER_H +#define MAYA_USD_CODE_WRAPPER_HANDLER_H #include @@ -37,3 +38,5 @@ class MAYAUSD_CORE_PUBLIC UsdCodeWrapperHandler : public UsdBatchOpsHandler } // namespace ufe } // namespace MAYAUSD_NS_DEF + +#endif /* MAYA_USD_CODE_WRAPPER_HANDLER_H */ diff --git a/lib/usdUfe/utils/editRouterContext.cpp b/lib/usdUfe/utils/editRouterContext.cpp index 69a8ede456..9b33bfd7a3 100644 --- a/lib/usdUfe/utils/editRouterContext.cpp +++ b/lib/usdUfe/utils/editRouterContext.cpp @@ -59,7 +59,7 @@ const PXR_NS::SdfLayerHandle& StackedEditRouterContext::getLayer() const return empty; } -const PXR_NS::UsdStagePtr& StackedEditRouterContext::getStage() const +PXR_NS::UsdStagePtr StackedEditRouterContext::getStage() const { if (_stage) return _stage; @@ -67,8 +67,7 @@ const PXR_NS::UsdStagePtr& StackedEditRouterContext::getStage() const if (const StackedEditRouterContext* ctx = GetStackPrevious()) return ctx->getStage(); - static const PXR_NS::UsdStagePtr empty; - return empty; + return {}; } bool StackedEditRouterContext::isTargetAlreadySet() const diff --git a/lib/usdUfe/utils/editRouterContext.h b/lib/usdUfe/utils/editRouterContext.h index 1aeb08c016..815d319306 100644 --- a/lib/usdUfe/utils/editRouterContext.h +++ b/lib/usdUfe/utils/editRouterContext.h @@ -42,7 +42,7 @@ class USDUFE_PUBLIC StackedEditRouterContext : public PXR_NS::TfStacked