Example #1
0
    def testMergeToUsdToNonRootTargetInSessionLayer(self):
        '''Merge edits on a USD transform back to USD targeting a non-root destination path that
           does not exists in the destination layer.'''

        # To merge back to USD, we must edit as Maya first.
        (ps, aXlateOp, _, aUsdUfePathStr, aUsdUfePath, aUsdItem,
         bXlateOp, _, bUsdUfePathStr, bUsdUfePath, bUsdItem) = \
            createSimpleXformScene()

        with mayaUsd.lib.OpUndoItemList():
            self.assertTrue(
                mayaUsd.lib.PrimUpdaterManager.editAsMaya(bUsdUfePathStr))

        bMayaItem = ufe.GlobalSelection.get().front()
        (bMayaPath, bMayaPathStr, _, bMayaMatrix) = \
            setMayaTranslation(bMayaItem, om.MVector(10, 11, 12))

        psHier = ufe.Hierarchy.hierarchy(ps)

        # Merge edits back to USD.
        with mayaUsd.lib.OpUndoItemList():
            stage = mayaUsd.ufe.getStage(bUsdUfePathStr)
            stage.SetEditTarget(stage.GetSessionLayer())
            self.assertTrue(
                mayaUsd.lib.PrimUpdaterManager.mergeToUsd(bMayaPathStr))

        # Check that edits have been preserved in USD.
        bUsdMatrix = bXlateOp.GetOpTransform(
            mayaUsd.ufe.getTime(bUsdUfePathStr))
        mayaValues = [v for v in bMayaMatrix]
        usdValues = [v for row in bUsdMatrix for v in row]

        assertVectorAlmostEqual(self, mayaValues, usdValues)
Example #2
0
    def testDuplicateAsMaya(self):
        '''Duplicate a USD transform hierarchy to Maya.'''

        (_, _, aXlation, aUsdUfePathStr, aUsdUfePath, _, _, 
               bXlation, bUsdUfePathStr, bUsdUfePath, _) = \
            createSimpleXformScene()

        # Duplicate USD data as Maya data, placing it under the root.
        with mayaUsd.lib.OpUndoItemList():
            self.assertTrue(mayaUsd.lib.PrimUpdaterManager.duplicate(
                aUsdUfePathStr, '|world'))

        # Should now have two transform nodes in the Maya scene: the path
        # components in the second segment of the aUsdItem and bUsdItem will
        # now be under the Maya world.
        aMayaPathStr = str(aUsdUfePath.segments[1]).replace('/', '|')
        bMayaPathStr = str(bUsdUfePath.segments[1]).replace('/', '|')
        self.assertEqual(cmds.ls(aMayaPathStr, long=True)[0], aMayaPathStr)
        self.assertEqual(cmds.ls(bMayaPathStr, long=True)[0], bMayaPathStr)

        # Translation should have been copied over to the Maya data model.
        self.assertEqual(cmds.getAttr(aMayaPathStr + '.translate')[0],
                         aXlation)
        self.assertEqual(cmds.getAttr(bMayaPathStr + '.translate')[0],
                         bXlation)
Example #3
0
    def testSimplePrimUpdater(self):
        mayaUsdLib.PrimUpdater.Register(
            primUpdaterTest, "UsdGeomXform", "transform",
            primUpdaterTest.Supports.All.value
        )  # primUpdaterTest.Supports.Push.value + primUpdaterTest.Supports.Clear.value + primUpdaterTest.Supports.AutoPull.value)

        # Edit as Maya first time.
        (ps, xlateOp, usdXlation, aUsdUfePathStr, aUsdUfePath, aUsdItem, _, _,
         _, _, _) = createSimpleXformScene()
        with mayaUsdLib.OpUndoItemList():
            self.assertTrue(
                mayaUsdLib.PrimUpdaterManager.editAsMaya(aUsdUfePathStr))

        aMayaItem = ufe.GlobalSelection.get().front()
        (aMayaPath, aMayaPathStr, _,
         aMayaMatrix) = setMayaTranslation(aMayaItem, om.MVector(4, 5, 6))

        # Discard Maya edits.
        with mayaUsdLib.OpUndoItemList():
            self.assertTrue(
                mayaUsdLib.PrimUpdaterManager.discardEdits(aMayaPathStr))

        cmds.file(new=True, force=True)

        # Edit as Maya second time.
        (ps, xlateOp, usdXlation, aUsdUfePathStr, aUsdUfePath, aUsdItem, _, _,
         _, _, _) = createSimpleXformScene()
        with mayaUsdLib.OpUndoItemList():
            self.assertTrue(
                mayaUsdLib.PrimUpdaterManager.editAsMaya(aUsdUfePathStr))

        aMayaItem = ufe.GlobalSelection.get().front()
        (aMayaPath, aMayaPathStr, _,
         aMayaMatrix) = setMayaTranslation(aMayaItem, om.MVector(4, 5, 6))

        # Merge edits back to USD.
        with mayaUsdLib.OpUndoItemList():
            self.assertTrue(
                mayaUsdLib.PrimUpdaterManager.mergeToUsd(aMayaPathStr))

        self.assertTrue(primUpdaterTest.editAsMayaCalled)
        self.assertTrue(primUpdaterTest.discardEditsCalled)
        self.assertTrue(primUpdaterTest.pushCopySpecsCalled)
        self.assertTrue(primUpdaterTest.pushEndCalled)
Example #4
0
    def testTransformEditAsMaya(self):
        '''Edit a USD transform as a Maya object.'''

        (ps, xlateOp, xlation, aUsdUfePathStr, aUsdUfePath, aUsdItem, _, _, _,
         _, _) = createSimpleXformScene()

        # Edit aPrim as Maya data.
        with mayaUsd.lib.OpUndoItemList():
            self.assertTrue(
                mayaUsd.lib.PrimUpdaterManager.canEditAsMaya(aUsdUfePathStr))
            self.assertTrue(
                mayaUsd.lib.PrimUpdaterManager.editAsMaya(aUsdUfePathStr))

        # Test the path mapping services.
        #
        # Unfortunately, toHost is unimplemented as of 20-Sep-2021.  Use the
        # selection to retrieve the Maya object.
        #
        # usdToMaya = ufe.PathMappingHandler.pathMappingHandler(aUsdItem)
        # aMayaUfePath = usdToMaya.toHost(aUsdUfePath)
        # self.assertEqual(aMayaUfePath.nbSegments(), 1)

        aMayaItem = ufe.GlobalSelection.get().front()
        aMayaPath = aMayaItem.path()
        self.assertEqual(aMayaPath.nbSegments(), 1)
        mayaToUsd = ufe.PathMappingHandler.pathMappingHandler(aMayaItem)
        self.assertEqual(mayaToUsd.fromHost(aMayaPath), aUsdUfePath)

        # Confirm the hierarchy is preserved through the Hierarchy interface:
        # one child, the parent of the pulled item is the proxy shape, and
        # the proxy shape has the pulled item as a child, not the original USD
        # scene item.
        aMayaHier = ufe.Hierarchy.hierarchy(aMayaItem)
        self.assertEqual(len(aMayaHier.children()), 1)
        self.assertEqual(ps, aMayaHier.parent())
        psHier = ufe.Hierarchy.hierarchy(ps)
        self.assertIn(aMayaItem, psHier.children())
        self.assertNotIn(aUsdItem, psHier.children())

        # Confirm the translation has been transferred, and that the local
        # transformation is only a translation.
        aDagPath = om.MSelectionList().add(
            ufe.PathString.string(aMayaPath)).getDagPath(0)
        aFn = om.MFnTransform(aDagPath)
        self.assertEqual(aFn.translation(om.MSpace.kObject),
                         om.MVector(*xlation))
        mayaMatrix = aFn.transformation().asMatrix()
        usdMatrix = xlateOp.GetOpTransform(mayaUsd.ufe.getTime(aUsdUfePathStr))
        mayaValues = [v for v in mayaMatrix]
        usdValues = [v for row in usdMatrix for v in row]

        assertVectorAlmostEqual(self, mayaValues, usdValues)
Example #5
0
    def testDiscardEditsUndoRedo(self):
        '''Discard edits on a USD transform then undo and redo.'''

        # Edit as Maya first.
        (ps, xlateOp, usdXlation, aUsdUfePathStr, aUsdUfePath, aUsdItem, _, _,
         _, _, _) = createSimpleXformScene()

        cmds.mayaUsdEditAsMaya(aUsdUfePathStr)

        # Modify the scene.
        aMayaItem = ufe.GlobalSelection.get().front()
        mayaXlation = om.MVector(4, 5, 6)
        (aMayaPath, aMayaPathStr, aFn, mayaMatrix) = \
            setMayaTranslation(aMayaItem, mayaXlation)

        # Verify the scene modifications.
        def verifyScenesModifications():
            self.assertEqual(aFn.translation(om.MSpace.kObject), mayaXlation)
            mayaToUsd = ufe.PathMappingHandler.pathMappingHandler(aMayaItem)
            self.assertEqual(
                ufe.PathString.string(mayaToUsd.fromHost(aMayaPath)),
                ufe.PathString.string(aUsdUfePath))

        verifyScenesModifications()

        # Discard Maya edits.
        cmds.mayaUsdDiscardEdits(aMayaPathStr)

        def verifyDiscard():
            # Original USD translation values are preserved.
            usdMatrix = xlateOp.GetOpTransform(
                mayaUsd.ufe.getTime(aUsdUfePathStr))
            self.assertEqual(usdMatrix.ExtractTranslation(), usdXlation)

            # Maya node is removed.
            with self.assertRaises(RuntimeError):
                om.MSelectionList().add(aMayaPathStr)

        verifyDiscard()

        # undo
        cmds.undo()

        verifyScenesModifications()

        # redo
        cmds.redo()

        verifyDiscard()
Example #6
0
    def testDiscardEdits(self):
        '''Discard edits on a USD transform.'''

        # Edit as Maya first.
        (ps, xlateOp, usdXlation, aUsdUfePathStr, aUsdUfePath, aUsdItem, _, _,
         _, _, _) = createSimpleXformScene()

        with mayaUsd.lib.OpUndoItemList():
            self.assertTrue(
                mayaUsd.lib.PrimUpdaterManager.editAsMaya(aUsdUfePathStr))

        aMayaItem = ufe.GlobalSelection.get().front()
        mayaXlation = om.MVector(4, 5, 6)
        (aMayaPath, aMayaPathStr, aFn, mayaMatrix) = \
            setMayaTranslation(aMayaItem, mayaXlation)

        self.assertEqual(aFn.translation(om.MSpace.kObject), mayaXlation)

        mayaToUsd = ufe.PathMappingHandler.pathMappingHandler(aMayaItem)
        self.assertEqual(mayaToUsd.fromHost(aMayaPath), aUsdUfePath)

        psHier = ufe.Hierarchy.hierarchy(ps)
        self.assertNotIn(aUsdItem, psHier.children())
        self.assertIn(aMayaItem, psHier.children())

        # Discard Maya edits.
        with mayaUsd.lib.OpUndoItemList():
            self.assertTrue(
                mayaUsd.lib.PrimUpdaterManager.discardEdits(aMayaPathStr))

        # Original USD translation values are preserved.
        usdMatrix = xlateOp.GetOpTransform(mayaUsd.ufe.getTime(aUsdUfePathStr))
        self.assertEqual(usdMatrix.ExtractTranslation(), usdXlation)

        # There no longer is a path mapping from the Maya path to the USD path.
        self.assertEqual(len(mayaToUsd.fromHost(aMayaPath)), 0)

        # Hierarchy is restored: USD item is child of proxy shape, Maya item is
        # not.  Be careful to use the Maya path rather than the Maya item, which
        # should no longer exist.
        self.assertIn(aUsdItem, psHier.children())
        self.assertNotIn(aMayaPath,
                         [child.path() for child in psHier.children()])

        # Maya node is removed.
        with self.assertRaises(RuntimeError):
            om.MSelectionList().add(aMayaPathStr)
Example #7
0
    def testDuplicateAsMayaUndoRedo(self):
        '''Duplicate a USD transform hierarchy to Maya and then undo and redo the command.'''

        (_, _, aXlation, aUsdUfePathStr, aUsdUfePath, _, _, 
               bXlation, bUsdUfePathStr, bUsdUfePath, _) = \
            createSimpleXformScene()

        # Duplicate USD data as Maya data, placing it under the root.
        cmds.mayaUsdDuplicate(aUsdUfePathStr, '|world')

        def verifyDuplicate():
            # Should now have two transform nodes in the Maya scene: the path
            # components in the second segment of the aUsdItem and bUsdItem will
            # now be under the Maya world.
            aMayaPathStr = str(aUsdUfePath.segments[1]).replace('/', '|')
            bMayaPathStr = str(bUsdUfePath.segments[1]).replace('/', '|')
            self.assertEqual(cmds.ls(aMayaPathStr, long=True)[0], aMayaPathStr)
            self.assertEqual(cmds.ls(bMayaPathStr, long=True)[0], bMayaPathStr)

            # Translation should have been copied over to the Maya data model.
            self.assertEqual(cmds.getAttr(aMayaPathStr + '.translate')[0],
                            aXlation)
            self.assertEqual(cmds.getAttr(bMayaPathStr + '.translate')[0],
                            bXlation)

        verifyDuplicate()

        cmds.undo()

        def verifyDuplicateIsGone():
            bMayaPathStr = str(bUsdUfePath.segments[1]).replace('/', '|')
            self.assertListEqual(cmds.ls(bMayaPathStr, long=True), [])

        verifyDuplicateIsGone()

        cmds.redo()

        verifyDuplicate()
Example #8
0
    def testEditAsMayaUndoRedo(self):
        '''Edit a USD transform as a Maya object and apply undo and redo.'''

        (ps, xlateOp, xlation, aUsdUfePathStr, aUsdUfePath, aUsdItem, _, _, _,
         _, _) = createSimpleXformScene()

        # Edit aPrim as Maya data.
        self.assertTrue(
            mayaUsd.lib.PrimUpdaterManager.canEditAsMaya(aUsdUfePathStr))

        cmds.mayaUsdEditAsMaya(aUsdUfePathStr)

        def getMayaPathStr():
            aMayaItem = ufe.GlobalSelection.get().front()
            aMayaPath = aMayaItem.path()
            aMayaPathStr = ufe.PathString.string(aMayaPath)
            return aMayaPathStr

        aMayaPathStr = getMayaPathStr()

        def verifyEditedScene():
            aMayaItem = ufe.GlobalSelection.get().front()
            aMayaPath = aMayaItem.path()
            aMayaPathStr = ufe.PathString.string(aMayaPath)

            # Confirm the hierarchy is preserved through the Hierarchy interface:
            # one child, the parent of the pulled item is the proxy shape, and
            # the proxy shape has the pulled item as a child, not the original USD
            # scene item.
            aMayaHier = ufe.Hierarchy.hierarchy(aMayaItem)
            self.assertEqual(len(aMayaHier.children()), 1)
            self.assertEqual(ps, aMayaHier.parent())
            psHier = ufe.Hierarchy.hierarchy(ps)
            self.assertIn(aMayaItem, psHier.children())
            self.assertNotIn(aUsdItem, psHier.children())

            # Confirm the translation has been transferred, and that the local
            # transformation is only a translation.
            aDagPath = om.MSelectionList().add(
                ufe.PathString.string(aMayaPath)).getDagPath(0)
            aFn = om.MFnTransform(aDagPath)
            self.assertEqual(aFn.translation(om.MSpace.kObject),
                             om.MVector(*xlation))
            mayaMatrix = aFn.transformation().asMatrix()
            usdMatrix = xlateOp.GetOpTransform(
                mayaUsd.ufe.getTime(aUsdUfePathStr))
            mayaValues = [v for v in mayaMatrix]
            usdValues = [v for row in usdMatrix for v in row]

            assertVectorAlmostEqual(self, mayaValues, usdValues)

        verifyEditedScene()

        # Undo
        cmds.undo()

        def verifyNoLongerEdited():
            # Maya node is removed.
            with self.assertRaises(RuntimeError):
                om.MSelectionList().add(aMayaPathStr)

        verifyNoLongerEdited()

        # Redo
        cmds.redo()

        verifyEditedScene()
Example #9
0
    def testTransformMergeToUsd(self):
        '''Merge edits on a USD transform back to USD.'''

        # To merge back to USD, we must edit as Maya first.
        (ps, aXlateOp, _, aUsdUfePathStr, aUsdUfePath, aUsdItem,
         bXlateOp, _, bUsdUfePathStr, bUsdUfePath, bUsdItem) = \
            createSimpleXformScene()
        with mayaUsd.lib.OpUndoItemList():
            self.assertTrue(
                mayaUsd.lib.PrimUpdaterManager.editAsMaya(aUsdUfePathStr))

        aMayaItem = ufe.GlobalSelection.get().front()
        (aMayaPath, aMayaPathStr, _, aMayaMatrix) = \
            setMayaTranslation(aMayaItem, om.MVector(4, 5, 6))

        bMayaPathStr = aMayaPathStr + '|B'
        bMayaPath = ufe.PathString.path(bMayaPathStr)
        bMayaItem = ufe.Hierarchy.createItem(bMayaPath)
        (_, _, _, bMayaMatrix) = \
            setMayaTranslation(bMayaItem, om.MVector(10, 11, 12))

        # There should be a path mapping for the edit as Maya hierarchy.
        for (mayaItem, mayaPath, usdUfePath) in \
            zip([aMayaItem, bMayaItem], [aMayaPath, bMayaPath],
                [aUsdUfePath, bUsdUfePath]):
            mayaToUsd = ufe.PathMappingHandler.pathMappingHandler(mayaItem)
            self.assertEqual(mayaToUsd.fromHost(mayaPath), usdUfePath)

        psHier = ufe.Hierarchy.hierarchy(ps)

        # Merge edits back to USD.
        with mayaUsd.lib.OpUndoItemList():
            self.assertTrue(
                mayaUsd.lib.PrimUpdaterManager.mergeToUsd(aMayaPathStr))

        # Edit will re-allocate anything that was under pulled prim due to deactivation
        # Grab new references for /A/B prim
        bUsdPrim = mayaUsd.ufe.ufePathToPrim(bUsdUfePathStr)
        bXlateOp = UsdGeom.Xformable(bUsdPrim).GetOrderedXformOps()[0]

        # Check that edits have been preserved in USD.
        for (usdUfePathStr, mayaMatrix, xlateOp) in \
            zip([aUsdUfePathStr, bUsdUfePathStr], [aMayaMatrix, bMayaMatrix],
                [aXlateOp, bXlateOp]):
            usdMatrix = xlateOp.GetOpTransform(
                mayaUsd.ufe.getTime(usdUfePathStr))
            mayaValues = [v for v in mayaMatrix]
            usdValues = [v for row in usdMatrix for v in row]

            assertVectorAlmostEqual(self, mayaValues, usdValues)

        # There no longer are any Maya to USD path mappings.
        for mayaPath in [aMayaPath, bMayaPath]:
            self.assertEqual(len(mayaToUsd.fromHost(mayaPath)), 0)

        # Hierarchy is restored: USD item is child of proxy shape, Maya item is
        # not.  Be careful to use the Maya path rather than the Maya item, which
        # should no longer exist.
        self.assertIn(aUsdItem, psHier.children())
        self.assertNotIn(aMayaPath,
                         [child.path() for child in psHier.children()])

        # Maya nodes are removed.
        for mayaPathStr in [aMayaPathStr, bMayaPathStr]:
            with self.assertRaises(RuntimeError):
                om.MSelectionList().add(mayaPathStr)