From 0254d92b52ae42d4dda149070c6c51b76dbad4e4 Mon Sep 17 00:00:00 2001 From: Pierre Tremblay Date: Wed, 18 Aug 2021 16:39:56 -0400 Subject: [PATCH] Improperly created scene item must not crash move tool. --- lib/mayaUsd/ufe/UsdTransform3dCommonAPI.cpp | 12 +++---- .../UsdTransform3dFallbackMayaXformStack.cpp | 6 ++-- lib/mayaUsd/ufe/UsdTransform3dMatrixOp.cpp | 10 ++++-- .../ufe/UsdTransform3dMayaXformStack.cpp | 6 ++-- .../ufe/UsdTransform3dPointInstance.cpp | 13 +++++--- test/lib/ufe/testMoveCmd.py | 32 +++++++++++++++++++ 6 files changed, 59 insertions(+), 20 deletions(-) diff --git a/lib/mayaUsd/ufe/UsdTransform3dCommonAPI.cpp b/lib/mayaUsd/ufe/UsdTransform3dCommonAPI.cpp index 0dd977a171..9e4ef6222d 100644 --- a/lib/mayaUsd/ufe/UsdTransform3dCommonAPI.cpp +++ b/lib/mayaUsd/ufe/UsdTransform3dCommonAPI.cpp @@ -278,9 +278,10 @@ Ufe::Transform3d::Ptr UsdTransform3dCommonAPIHandler::transform3d(const Ufe::SceneItem::Ptr& item) const { UsdSceneItem::Ptr usdItem = std::dynamic_pointer_cast(item); -#if !defined(NDEBUG) - assert(usdItem); -#endif + + if (!usdItem) { + return nullptr; + } // If the prim supports the common transform API, create a common API // interface for it, otherwise delegate to the next handler in the chain of @@ -294,11 +295,10 @@ Ufe::Transform3d::Ptr UsdTransform3dCommonAPIHandler::editTransform3d( const Ufe::SceneItem::Ptr& item UFE_V2(, const Ufe::EditTransform3dHint& hint)) const { UsdSceneItem::Ptr usdItem = std::dynamic_pointer_cast(item); -#if !defined(NDEBUG) + if (!usdItem) { - TF_FATAL_ERROR("Could not create common API Transform3d interface for null item."); + return nullptr; } -#endif // If the prim supports the common transform API, create a common API // interface for it, otherwise delegate to the next handler in the chain of diff --git a/lib/mayaUsd/ufe/UsdTransform3dFallbackMayaXformStack.cpp b/lib/mayaUsd/ufe/UsdTransform3dFallbackMayaXformStack.cpp index 279a6f6d19..9c653c4649 100644 --- a/lib/mayaUsd/ufe/UsdTransform3dFallbackMayaXformStack.cpp +++ b/lib/mayaUsd/ufe/UsdTransform3dFallbackMayaXformStack.cpp @@ -159,12 +159,10 @@ Ufe::Transform3d::Ptr createEditTransform3dImp( std::vector::const_iterator& firstFallbackOp) { UsdSceneItem::Ptr usdItem = std::dynamic_pointer_cast(item); -#if !defined(NDEBUG) + if (!usdItem) { - TF_FATAL_ERROR( - "Could not create fallback Maya transform stack Transform3d interface for null item."); + return nullptr; } -#endif // If the prim isn't transformable, can't create a Transform3d interface // for it. diff --git a/lib/mayaUsd/ufe/UsdTransform3dMatrixOp.cpp b/lib/mayaUsd/ufe/UsdTransform3dMatrixOp.cpp index ea279b663e..600b2ee8d2 100644 --- a/lib/mayaUsd/ufe/UsdTransform3dMatrixOp.cpp +++ b/lib/mayaUsd/ufe/UsdTransform3dMatrixOp.cpp @@ -360,7 +360,10 @@ UsdTransform3dMatrixOpHandler::transform3d(const Ufe::SceneItem::Ptr& item) cons // We must create a Transform3d interface to edit the whole object, // e.g. setting the local transformation matrix for the complete object. UsdSceneItem::Ptr usdItem = std::dynamic_pointer_cast(item); - TF_AXIOM(usdItem); + + if (!usdItem) { + return nullptr; + } UsdGeomXformable xformable(usdItem->prim()); bool unused; @@ -405,7 +408,10 @@ Ufe::Transform3d::Ptr UsdTransform3dMatrixOpHandler::editTransform3d( const Ufe::SceneItem::Ptr& item UFE_V2(, const Ufe::EditTransform3dHint& hint)) const { UsdSceneItem::Ptr usdItem = std::dynamic_pointer_cast(item); - TF_AXIOM(usdItem); + + if (!usdItem) { + return nullptr; + } // Beware: the default UsdGeomXformOp constructor // https://github.com/PixarAnimationStudios/USD/blob/71b4baace2044ea4400ba802e91667f9ebe342f0/pxr/usd/usdGeom/xformOp.h#L148 diff --git a/lib/mayaUsd/ufe/UsdTransform3dMayaXformStack.cpp b/lib/mayaUsd/ufe/UsdTransform3dMayaXformStack.cpp index b416c74169..a29df43697 100644 --- a/lib/mayaUsd/ufe/UsdTransform3dMayaXformStack.cpp +++ b/lib/mayaUsd/ufe/UsdTransform3dMayaXformStack.cpp @@ -138,12 +138,10 @@ Ufe::Transform3d::Ptr createTransform3d(const Ufe::SceneItem::Ptr& item, NextTransform3dFn nextTransform3dFn) { UsdSceneItem::Ptr usdItem = std::dynamic_pointer_cast(item); -#if !defined(NDEBUG) + if (!usdItem) { - TF_FATAL_ERROR( - "Could not create Maya transform stack Transform3d interface for null item."); + return nullptr; } -#endif // If the prim isn't transformable, can't create a Transform3d interface // for it. diff --git a/lib/mayaUsd/ufe/UsdTransform3dPointInstance.cpp b/lib/mayaUsd/ufe/UsdTransform3dPointInstance.cpp index 720c30d62b..1efa5a471a 100644 --- a/lib/mayaUsd/ufe/UsdTransform3dPointInstance.cpp +++ b/lib/mayaUsd/ufe/UsdTransform3dPointInstance.cpp @@ -158,7 +158,11 @@ UsdTransform3dPointInstanceHandler::transform3d(const Ufe::SceneItem::Ptr& item) { UsdSceneItem::Ptr usdItem = downcast(item); - if (!usdItem || !usdItem->isPointInstance()) { + if (!usdItem) { + return nullptr; + } + + if (!usdItem->isPointInstance()) { return _nextHandler->transform3d(item); } @@ -171,9 +175,10 @@ Ufe::Transform3d::Ptr UsdTransform3dPointInstanceHandler::editTransform3d( const Ufe::EditTransform3dHint& hint) const { UsdSceneItem::Ptr usdItem = downcast(item); -#if !defined(NDEBUG) - assert(usdItem); -#endif + + if (!usdItem) { + return nullptr; + } if (!usdItem->isPointInstance()) { return _nextHandler->editTransform3d(item, hint); diff --git a/test/lib/ufe/testMoveCmd.py b/test/lib/ufe/testMoveCmd.py index 325389045e..e165b7661b 100644 --- a/test/lib/ufe/testMoveCmd.py +++ b/test/lib/ufe/testMoveCmd.py @@ -394,5 +394,37 @@ def createCommonAPI(testCase, sphereXformable): self.runTestOpUndo(createCommonAPI, 'xformOp:translate') + def testBadSceneItem(self): + '''Improperly constructed scene item should not crash Maya.''' + + # MAYA-112601 / GitHub #1169: improperly constructed Python scene item + # should not cause a crash. + cmds.file(new=True, force=True) + + import mayaUsd_createStageWithNewLayer + proxyShape = mayaUsd_createStageWithNewLayer.createStageWithNewLayer() + + proxyShapePath = ufe.PathString.path(proxyShape) + proxyShapeItem = ufe.Hierarchy.createItem(proxyShapePath) + proxyShapeContextOps = ufe.ContextOps.contextOps(proxyShapeItem) + proxyShapeContextOps.doOp(['Add New Prim', 'Sphere']) + + spherePath = ufe.PathString.path('%s,/Sphere1' % proxyShape) + # The proper way to create a scene item is the following: + # + # sphereItem = ufe.Hierarchy.createItem(spherePath) + # + # A naive user can create a scene item as the following. The resulting + # scene item is not a USD scene item: it is a Python base class scene + # item, which has a path but nothing else. This should not a crash + # when using the move command. + sphereItem = ufe.SceneItem(spherePath) + + sn = ufe.GlobalSelection.get() + sn.clear() + sn.append(sphereItem) + + cmds.move(0, 10, 0, relative=True, os=True, wd=True) + if __name__ == '__main__': unittest.main(verbosity=2)