Beispiel #1
0
    def setUp(self):
        ''' Called initially to set up the maya test environment '''
        # Load plugins
        self.assertTrue(self.pluginsLoaded)

        # Open usdCylinder.ma scene in testSamples
        mayaUtils.openCylinderScene()
Beispiel #2
0
    def testTranslateLockedLayer(self):
        # create new stage
        cmds.file(new=True, force=True)

        # Open usdCylinder.ma scene in testSamples
        mayaUtils.openCylinderScene()

        # get the stage
        proxyShapes = cmds.ls(type="mayaUsdProxyShapeBase", long=True)
        proxyShapePath = proxyShapes[0]
        stage = mayaUsd.lib.GetPrim(proxyShapePath).GetStage()

        # cylinder prim
        cylinderPrim = stage.GetPrimAtPath('/pCylinder1')
        self.assertIsNotNone(cylinderPrim)

        # create a sub-layer.
        rootLayer = stage.GetRootLayer()
        subLayerA = cmds.mayaUsdLayerEditor(rootLayer.identifier,
                                            edit=True,
                                            addAnonymous="LayerA")[0]

        # check to see the if the sublayers was added
        addedLayers = [subLayerA]
        self.assertEqual(rootLayer.subLayerPaths, addedLayers)

        # set the edit target to LayerA.
        cmds.mayaUsdEditTarget(proxyShapePath, edit=True, editTarget=subLayerA)

        # set permission to edit to false
        layerA = Sdf.Find(subLayerA)
        layerA.SetPermissionToEdit(False)

        # Check that our helper function is returning the right thing
        self.assertFalse(mayaUsdUfe.isEditTargetLayerModifiable(stage))

        # Get translate attribute and make sure its empty
        translateAttr = cylinderPrim.GetAttribute('xformOp:translate')
        self.assertIsNotNone(translateAttr)

        tranlateBeforeEdit = translateAttr.Get()

        # create a transform3d and translate
        cylinderPath = ufe.Path([
            mayaUtils.createUfePathSegment("|mayaUsdTransform|shape"),
            usdUtils.createUfePathSegment("/pCylinder1")
        ])
        cylinderItem = ufe.Hierarchy.createItem(cylinderPath)

        cylinderT3d = ufe.Transform3d.transform3d(cylinderItem)
        if cylinderT3d is not None:
            cylinderT3d.translate(5.0, 6.0, 7.0)

        # check that the translate operation didn't change anything
        tranlateAfterEdit = translateAttr.Get()
        self.assertEqual(tranlateBeforeEdit, tranlateAfterEdit)
Beispiel #3
0
    def testRenameNotifications(self):
        '''Rename a USD node and test for the UFE notifications.'''

        # open usdCylinder.ma scene in testSamples
        mayaUtils.openCylinderScene()

        # clear selection to start off
        cmds.select(clear=True)

        # select a USD object.
        mayaPathSegment = mayaUtils.createUfePathSegment(
            '|mayaUsdTransform|shape')
        usdPathSegment = usdUtils.createUfePathSegment('/pCylinder1')
        cylinderPath = ufe.Path([mayaPathSegment, usdPathSegment])
        cylinderItem = ufe.Hierarchy.createItem(cylinderPath)

        ufe.GlobalSelection.get().append(cylinderItem)

        # get the USD stage
        stage = mayaUsd.ufe.getStage(str(mayaPathSegment))

        # set the edit target to the root layer
        stage.SetEditTarget(stage.GetRootLayer())
        self.assertEqual(stage.GetEditTarget().GetLayer(),
                         stage.GetRootLayer())

        # Create our UFE notification observer
        ufeObs = TestObserver()

        if (os.getenv('UFE_PREVIEW_VERSION_NUM', '0000') < '2021'):
            # We start off with no observers
            self.assertFalse(ufe.Scene.hasObjectAddObserver(ufeObs))
            self.assertFalse(ufe.Scene.hasObjectDeleteObserver(ufeObs))
            self.assertFalse(ufe.Scene.hasObjectPathChangeObserver(ufeObs))

            # Add the UFE observers we want to test
            ufe.Scene.addObjectAddObserver(ufeObs)
            ufe.Scene.addObjectDeleteObserver(ufeObs)
            ufe.Scene.addObjectPathChangeObserver(ufeObs)
        else:
            # We start off with no observers
            self.assertFalse(ufe.Scene.hasObserver(ufeObs))

            # Add the UFE observer we want to test
            ufe.Scene.addObserver(ufeObs)

        # rename
        newName = 'pCylinder1_Renamed'
        cmds.rename(newName)

        # After the rename we should have 1 rename notif and no unexepected notifs.
        self.assertEqual(ufeObs.notifications(), 1)
        self.assertFalse(ufeObs.receivedUnexpectedNotif())
Beispiel #4
0
    def testShareStage(self):
        '''
        Verify share/unshare stage workflow works properly
        '''
        # create new stage
        cmds.file(new=True, force=True)

        # Open usdCylinder.ma scene in testSamples
        mayaUtils.openCylinderScene()

        # get the stage
        proxyShapes = cmds.ls(type="mayaUsdProxyShapeBase", long=True)
        proxyShapePath = proxyShapes[0]
        stage = mayaUsd.lib.GetPrim(proxyShapePath).GetStage()
        rootIdentifier = stage.GetRootLayer().identifier

        # check that the stage is shared and the root is the right one
        self.assertTrue(
            cmds.getAttr('{}.{}'.format(proxyShapePath, "shareStage")))
        self.assertEqual(stage.GetRootLayer().GetDisplayName(),
                         "cylinder.usda")

        # unshare the stage
        cmds.setAttr('{}.{}'.format(proxyShapePath, "shareStage"), False)
        stage = mayaUsd.lib.GetPrim(proxyShapePath).GetStage()
        rootLayer = stage.GetRootLayer()

        # check that the stage is now unshared and the root is the anon layer
        # and the old root is now sublayered under that
        self.assertFalse(
            cmds.getAttr('{}.{}'.format(proxyShapePath, "shareStage")))
        self.assertEqual(rootLayer.GetDisplayName(), "unshareableLayer")
        self.assertEqual(rootLayer.subLayerPaths, [rootIdentifier])

        # re-share the stage
        cmds.setAttr('{}.{}'.format(proxyShapePath, "shareStage"), True)
        stage = mayaUsd.lib.GetPrim(proxyShapePath).GetStage()

        # check that the stage is now shared again and the layer is the same
        self.assertTrue(
            cmds.getAttr('{}.{}'.format(proxyShapePath, "shareStage")))
        self.assertEqual(stage.GetRootLayer().GetDisplayName(),
                         "cylinder.usda")
Beispiel #5
0
    def testSingleAttributeBlocking(self):
        ''' Authoring attribute(s) in weaker layer(s) are not permitted if there exist opinion(s) in stronger layer(s).'''

        # create new stage
        cmds.file(new=True, force=True)

        # Open usdCylinder.ma scene in testSamples
        mayaUtils.openCylinderScene()

        # get the stage
        proxyShapes = cmds.ls(type="mayaUsdProxyShapeBase", long=True)
        proxyShapePath = proxyShapes[0]
        stage = mayaUsd.lib.GetPrim(proxyShapePath).GetStage()

        # cylinder prim
        cylinderPrim = stage.GetPrimAtPath('/pCylinder1')
        self.assertIsNotNone(cylinderPrim)

        # author a new radius value
        self.assertTrue(cylinderPrim.HasAttribute('doubleSided'))
        doubleSidedAttr = cylinderPrim.GetAttribute('doubleSided')

        # authoring new attribute edit is expected to be allowed.
        self.assertTrue(mayaUsdUfe.isAttributeEditAllowed(doubleSidedAttr))
        doubleSidedAttr.Set(0)

        # create a sub-layer.
        rootLayer = stage.GetRootLayer()
        subLayerA = cmds.mayaUsdLayerEditor(rootLayer.identifier,
                                            edit=True,
                                            addAnonymous="LayerA")[0]

        # check to see the if the sublayers was added
        addedLayers = [subLayerA]
        self.assertEqual(rootLayer.subLayerPaths, addedLayers)

        # set the edit target to LayerA.
        cmds.mayaUsdEditTarget(proxyShapePath, edit=True, editTarget=subLayerA)

        # doubleSidedAttr is not allowed to change since there is an opinion in a stronger layer
        self.assertFalse(mayaUsdUfe.isAttributeEditAllowed(doubleSidedAttr))
    def testRenameUndo(self):
        '''Rename USD node.'''

        # open usdCylinder.ma scene in testSamples
        mayaUtils.openCylinderScene()

        # clear selection to start off
        cmds.select(clear=True)

        # select a USD object.
        mayaPathSegment = mayaUtils.createUfePathSegment(
            '|mayaUsdTransform|shape')
        usdPathSegment = usdUtils.createUfePathSegment('/pCylinder1')
        cylinderPath = ufe.Path([mayaPathSegment, usdPathSegment])
        cylinderItem = ufe.Hierarchy.createItem(cylinderPath)
        cylinderHierarchy = ufe.Hierarchy.hierarchy(cylinderItem)
        propsItem = cylinderHierarchy.parent()

        propsHierarchy = ufe.Hierarchy.hierarchy(propsItem)
        propsChildrenPre = propsHierarchy.children()

        ufe.GlobalSelection.get().append(cylinderItem)

        # get the USD stage
        stage = mayaUsd.ufe.getStage(str(mayaPathSegment))

        # check GetLayerStack behavior
        self.assertEqual(stage.GetLayerStack()[0], stage.GetSessionLayer())
        self.assertEqual(stage.GetEditTarget().GetLayer(),
                         stage.GetRootLayer())

        # by default edit target is set to the Rootlayer.
        self.assertEqual(stage.GetEditTarget().GetLayer(),
                         stage.GetRootLayer())

        # rename
        cylinderItemType = cylinderItem.nodeType()
        newName = 'pCylinder1_Renamed'
        cmds.rename(newName)

        # The renamed item is in the selection.
        snIter = iter(ufe.GlobalSelection.get())
        pCylinder1Item = next(snIter)
        pCylinder1RenName = str(pCylinder1Item.path().back())

        self.assertEqual(pCylinder1RenName, newName)

        propsChildren = propsHierarchy.children()

        self.assertEqual(len(propsChildren), len(propsChildrenPre))
        self.assertIn(pCylinder1Item, propsChildren)

        cmds.undo()
        self.assertEqual(cylinderItemType,
                         ufe.GlobalSelection.get().back().nodeType())

        def childrenNames(children):
            return [str(child.path().back()) for child in children]

        propsHierarchy = ufe.Hierarchy.hierarchy(propsItem)
        propsChildren = propsHierarchy.children()
        propsChildrenNames = childrenNames(propsChildren)

        self.assertNotIn(pCylinder1RenName, propsChildrenNames)
        self.assertIn('pCylinder1', propsChildrenNames)
        self.assertEqual(len(propsChildren), len(propsChildrenPre))

        cmds.redo()
        self.assertEqual(cylinderItemType,
                         ufe.GlobalSelection.get().back().nodeType())

        propsHierarchy = ufe.Hierarchy.hierarchy(propsItem)
        propsChildren = propsHierarchy.children()
        propsChildrenNames = childrenNames(propsChildren)

        self.assertIn(pCylinder1RenName, propsChildrenNames)
        self.assertNotIn('pCylinder1', propsChildrenNames)
        self.assertEqual(len(propsChildren), len(propsChildrenPre))
Beispiel #7
0
    def testShareStageSourceChange(self):
        '''
        Verify the stage source change maintains the position in the hierarchy
        '''
        # create new stage
        cmds.file(new=True, force=True)

        # Open usdCylinder.ma scene in testSamples
        mayaUtils.openCylinderScene()

        # get the proxy shape path
        proxyShapes = cmds.ls(type="mayaUsdProxyShapeBase", long=True)
        proxyShapeA = proxyShapes[0]

        # create another proxyshape (B)
        import mayaUsd_createStageWithNewLayer
        proxyShapeB = mayaUsd_createStageWithNewLayer.createStageWithNewLayer()
        proxyShapeB = proxyShapeB.split("|")[-1]

        # Connect them using stage data
        cmds.connectAttr('{}.outStageData'.format(proxyShapeA),
                         '{}.inStageData'.format(proxyShapeB))

        # get the stage
        stageB = mayaUsd.lib.GetPrim(proxyShapeB).GetStage()
        originalRootIdentifierB = stageB.GetRootLayer().identifier

        # check that the stage is shared and the root is the right one
        self.assertTrue(cmds.getAttr('{}.{}'.format(proxyShapeB,
                                                    "shareStage")))
        self.assertEqual(stageB.GetRootLayer().GetDisplayName(),
                         "cylinder.usda")

        # unshare the stage
        cmds.setAttr('{}.{}'.format(proxyShapeB, "shareStage"), False)
        stageB = mayaUsd.lib.GetPrim(proxyShapeB).GetStage()
        rootLayerB = stageB.GetRootLayer()

        # check that the stage is now unshared and the root is the anon layer
        # and the old root is now sublayered under that
        self.assertFalse(
            cmds.getAttr('{}.{}'.format(proxyShapeB, "shareStage")))
        self.assertEqual(rootLayerB.GetDisplayName(), "unshareableLayer")
        self.assertEqual(rootLayerB.subLayerPaths, [originalRootIdentifierB])

        # Add complex hierarchy
        middleLayerB = Sdf.Layer.CreateAnonymous("middleLayer")
        middleLayerB.subLayerPaths = [originalRootIdentifierB]
        rootLayerB.subLayerPaths = [middleLayerB.identifier]

        # unshare the stage from the first proxy
        cmds.setAttr('{}.{}'.format(proxyShapeA, "shareStage"), False)
        stageA = mayaUsd.lib.GetPrim(proxyShapeA).GetStage()
        rootLayerA = stageA.GetRootLayer()
        stageB = mayaUsd.lib.GetPrim(proxyShapeB).GetStage()
        rootLayerB = stageB.GetRootLayer()

        # check that the stage is now unshared and the entire hierachy is good (A)
        self.assertFalse(
            cmds.getAttr('{}.{}'.format(proxyShapeA, "shareStage")))
        self.assertEqual(rootLayerA.GetDisplayName(), "unshareableLayer")
        self.assertEqual(len(rootLayerA.subLayerPaths), 1)
        self.assertEqual(rootLayerA.subLayerPaths[0], originalRootIdentifierB)

        # Make sure the hierachy is good (B)
        self.assertFalse(
            cmds.getAttr('{}.{}'.format(proxyShapeB, "shareStage")))
        self.assertEqual(rootLayerB.GetDisplayName(), "unshareableLayer")
        self.assertEqual(len(rootLayerB.subLayerPaths), 1)
        middleLayer = Sdf.Layer.Find(rootLayerB.subLayerPaths[0])
        self.assertEqual(middleLayer.GetDisplayName(), "middleLayer")
        self.assertEqual(len(middleLayer.subLayerPaths), 1)
        unshareableLayerFromA = Sdf.Layer.Find(middleLayer.subLayerPaths[0])
        self.assertEqual(unshareableLayerFromA.GetDisplayName(),
                         "unshareableLayer")
        self.assertEqual(len(unshareableLayerFromA.subLayerPaths), 1)
        self.assertEqual(unshareableLayerFromA.subLayerPaths[0],
                         originalRootIdentifierB)
Beispiel #8
0
    def testShareStageComplexHierarchyToggle(self):
        '''
        Verify share/unshare stage toggle works with complex heirharchies
        '''
        # create new stage
        cmds.file(new=True, force=True)

        # Open usdCylinder.ma scene in testSamples
        mayaUtils.openCylinderScene()

        # get the stage
        proxyShapes = cmds.ls(type="mayaUsdProxyShapeBase", long=True)
        proxyShapePath = proxyShapes[0]
        stage = mayaUsd.lib.GetPrim(proxyShapePath).GetStage()
        originalRootIdentifier = stage.GetRootLayer().identifier

        # check that the stage is shared and the root is the right one
        self.assertTrue(
            cmds.getAttr('{}.{}'.format(proxyShapePath, "shareStage")))
        self.assertEqual(stage.GetRootLayer().GetDisplayName(),
                         "cylinder.usda")

        # unshare the stage
        cmds.setAttr('{}.{}'.format(proxyShapePath, "shareStage"), False)
        stage = mayaUsd.lib.GetPrim(proxyShapePath).GetStage()
        rootLayer = stage.GetRootLayer()

        # check that the stage is now unshared and the root is the anon layer
        # and the old root is now sublayered under that
        self.assertFalse(
            cmds.getAttr('{}.{}'.format(proxyShapePath, "shareStage")))
        self.assertEqual(rootLayer.GetDisplayName(), "unshareableLayer")
        self.assertEqual(rootLayer.subLayerPaths, [originalRootIdentifier])

        middleLayer = Sdf.Layer.CreateAnonymous("middleLayer")
        middleLayer.subLayerPaths = [originalRootIdentifier]
        rootLayer.subLayerPaths = [middleLayer.identifier]

        # Save and re-open
        testDir = tempfile.mkdtemp(prefix='ProxyShapeBase')
        tempMayaFile = os.path.join(testDir,
                                    'ShareStageComplexHierarchyToggle.ma')
        cmds.file(rename=tempMayaFile)
        # make the USD layer absolute otherwise it won't be found
        cmds.setAttr('{}.{}'.format(proxyShapePath, "filePath"),
                     originalRootIdentifier,
                     type='string')
        cmds.file(save=True, force=True)
        cmds.file(new=True, force=True)
        cmds.file(tempMayaFile, open=True)

        # get the stage again (since we opened a new file)
        proxyShapes = cmds.ls(type="mayaUsdProxyShapeBase", long=True)
        proxyShapePath = proxyShapes[0]
        stage = mayaUsd.lib.GetPrim(proxyShapePath).GetStage()
        rootLayer = stage.GetRootLayer()

        # make sure the middle layer is back (only one)
        self.assertEqual(len(rootLayer.subLayerPaths), 1)
        middleLayer = Sdf.Layer.Find(rootLayer.subLayerPaths[0])
        self.assertEqual(middleLayer.GetDisplayName(), "middleLayer")

        # re-share the stage
        cmds.setAttr('{}.{}'.format(proxyShapePath, "shareStage"), True)
        stage = mayaUsd.lib.GetPrim(proxyShapePath).GetStage()

        # check that the stage is now shared again and the identifier is correct
        self.assertTrue(
            cmds.getAttr('{}.{}'.format(proxyShapePath, "shareStage")))
        self.assertEqual(stage.GetRootLayer().identifier,
                         originalRootIdentifier)

        # unshare the stage
        cmds.setAttr('{}.{}'.format(proxyShapePath, "shareStage"), False)
        stage = mayaUsd.lib.GetPrim(proxyShapePath).GetStage()
        rootLayer = stage.GetRootLayer()

        # check that the stage is now shared and the root is the anon layer
        # and the old root is now sublayered under that
        self.assertFalse(
            cmds.getAttr('{}.{}'.format(proxyShapePath, "shareStage")))
        self.assertEqual(rootLayer.GetDisplayName(), "unshareableLayer")
        self.assertEqual(rootLayer.subLayerPaths, [middleLayer.identifier])
Beispiel #9
0
    def testAttributeBlocking3dMatrixOps(self):
        '''
        Verify authoring transformation attribute(s) in weaker layer(s) are not permitted if there exist opinion(s) 
        in stronger layer(s) when using UsdTransform3dMatrixOp.
        '''

        # create new stage
        cmds.file(new=True, force=True)

        # Open usdCylinder.ma scene in testSamples
        mayaUtils.openCylinderScene()

        # get the stage
        proxyShapes = cmds.ls(type="mayaUsdProxyShapeBase", long=True)
        proxyShapePath = proxyShapes[0]
        stage = mayaUsd.lib.GetPrim(proxyShapePath).GetStage()

        # cylinder prim
        cylinderPrim = stage.GetPrimAtPath('/pCylinder1')
        self.assertIsNotNone(cylinderPrim)

        # create 3 sub-layers ( LayerA, LayerB, LayerC ) and set the edit target to LayerB.
        rootLayer = stage.GetRootLayer()
        subLayerC = cmds.mayaUsdLayerEditor(rootLayer.identifier,
                                            edit=True,
                                            addAnonymous="SubLayerC")[0]
        subLayerB = cmds.mayaUsdLayerEditor(rootLayer.identifier,
                                            edit=True,
                                            addAnonymous="SubLayerB")[0]
        subLayerA = cmds.mayaUsdLayerEditor(rootLayer.identifier,
                                            edit=True,
                                            addAnonymous="SubLayerA")[0]

        # check to see the sublayers added
        addedLayers = [subLayerA, subLayerB, subLayerC]
        self.assertEqual(rootLayer.subLayerPaths, addedLayers)

        # set the edit target to LayerB
        cmds.mayaUsdEditTarget(proxyShapePath, edit=True, editTarget=subLayerB)

        # create a xformable and give it a matrix4d xformOp:transform
        # This will match the UsdTransform3dMatrixOp, but not the Maya API.
        cylinderXformable = UsdGeom.Xformable(cylinderPrim)
        transformOp = cylinderXformable.AddTransformOp()
        xform = Gf.Matrix4d(1.0).SetTranslate(Gf.Vec3d(10, 20, 30))
        transformOp.Set(xform)
        self.assertTrue(
            cylinderPrim.GetPrim().HasAttribute("xformOp:transform"))

        # Now that we have set up the transform stack to be 3dMatrixOp compatible,
        # create the Transform3d interface.
        cylinderPath = ufe.Path([
            mayaUtils.createUfePathSegment("|mayaUsdTransform|shape"),
            usdUtils.createUfePathSegment("/pCylinder1")
        ])
        cylinderItem = ufe.Hierarchy.createItem(cylinderPath)

        cylinderT3d = ufe.Transform3d.transform3d(cylinderItem)

        # select the cylinderItem
        sn = ufe.GlobalSelection.get()
        sn.clear()
        sn.append(cylinderItem)

        # move
        cmds.move(65, 20, 10)
        self.assertEqual(cylinderXformable.GetXformOpOrderAttr().Get(),
                         Vt.TokenArray(('xformOp:transform', )))

        # validate the Matrix4d entires
        actual = cylinderXformable.GetLocalTransformation()
        expected = Gf.Matrix4d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 65, 20, 10,
                               1)

        self.assertTrue(Gf.IsClose(actual, expected, 1e-5))

        # set the edit target to a weaker layer (LayerC)
        cmds.mayaUsdEditTarget(proxyShapePath, edit=True, editTarget=subLayerC)

        # check if transform attribute is editable
        transformAttr = cylinderPrim.GetAttribute('xformOp:transform')
        self.assertIsNotNone(transformAttr)

        # authoring new transformation edit is not allowed.
        self.assertFalse(mayaUsdUfe.isAttributeEditAllowed(transformAttr))

        # set the edit target to a stronger layer (LayerA)
        cmds.mayaUsdEditTarget(proxyShapePath, edit=True, editTarget=subLayerA)

        # authoring new transformation edit is allowed.
        self.assertTrue(mayaUsdUfe.isAttributeEditAllowed(transformAttr))
Beispiel #10
0
    def testAttributeBlocking3dCommonApi(self):
        '''
        Verify authoring transformation attribute(s) in weaker layer(s) are not permitted if there exist opinion(s) 
        in stronger layer(s) when using UsdGeomXformCommonAPI.
        '''

        # create new stage
        cmds.file(new=True, force=True)

        # Open usdCylinder.ma scene in testSamples
        mayaUtils.openCylinderScene()

        # get the stage
        proxyShapes = cmds.ls(type="mayaUsdProxyShapeBase", long=True)
        proxyShapePath = proxyShapes[0]
        stage = mayaUsd.lib.GetPrim(proxyShapePath).GetStage()

        # cylinder prim
        cylinderPrim = stage.GetPrimAtPath('/pCylinder1')
        self.assertIsNotNone(cylinderPrim)

        # create 3 sub-layers ( LayerA, LayerB, LayerC ) and set the edit target to LayerB.
        rootLayer = stage.GetRootLayer()
        subLayerC = cmds.mayaUsdLayerEditor(rootLayer.identifier,
                                            edit=True,
                                            addAnonymous="SubLayerC")[0]
        subLayerB = cmds.mayaUsdLayerEditor(rootLayer.identifier,
                                            edit=True,
                                            addAnonymous="SubLayerB")[0]
        subLayerA = cmds.mayaUsdLayerEditor(rootLayer.identifier,
                                            edit=True,
                                            addAnonymous="SubLayerA")[0]

        # check to see the sublayers added
        addedLayers = [subLayerA, subLayerB, subLayerC]
        self.assertEqual(rootLayer.subLayerPaths, addedLayers)

        # set the edit target to LayerB
        cmds.mayaUsdEditTarget(proxyShapePath, edit=True, editTarget=subLayerB)

        # create a xformable and give it a common API single "pivot".
        # This will match the common API, but not the Maya API.
        cylinderXformable = UsdGeom.Xformable(cylinderPrim)

        cylinderXformable.AddTranslateOp(UsdGeom.XformOp.PrecisionFloat,
                                         "pivot")
        cylinderXformable.AddTranslateOp(UsdGeom.XformOp.PrecisionFloat,
                                         "pivot", True)

        self.assertEqual(
            cylinderXformable.GetXformOpOrderAttr().Get(),
            Vt.TokenArray(("xformOp:translate:pivot",
                           "!invert!xformOp:translate:pivot")))
        self.assertTrue(UsdGeom.XformCommonAPI(cylinderXformable))

        # Now that we have set up the transform stack to be common API-compatible,
        # create the Transform3d interface.
        cylinderPath = ufe.Path([
            mayaUtils.createUfePathSegment("|mayaUsdTransform|shape"),
            usdUtils.createUfePathSegment("/pCylinder1")
        ])
        cylinderItem = ufe.Hierarchy.createItem(cylinderPath)

        cylinderT3d = ufe.Transform3d.transform3d(cylinderItem)

        # select the cylinderItem
        sn = ufe.GlobalSelection.get()
        sn.clear()
        sn.append(cylinderItem)

        # rotate the cylinder
        cmds.rotate(0,
                    90,
                    0,
                    relative=True,
                    objectSpace=True,
                    forceOrderXYZ=True)

        self.assertEqual(
            cylinderXformable.GetXformOpOrderAttr().Get(),
            Vt.TokenArray(("xformOp:translate:pivot", "xformOp:rotateXYZ",
                           "!invert!xformOp:translate:pivot")))
        self.assertTrue(UsdGeom.XformCommonAPI(cylinderXformable))

        # set the edit target to a weaker layer (LayerC)
        cmds.mayaUsdEditTarget(proxyShapePath, edit=True, editTarget=subLayerC)

        # check if rotate attribute is editable
        rotateAttr = cylinderPrim.GetAttribute('xformOp:rotateXYZ')
        self.assertIsNotNone(rotateAttr)

        # authoring new transformation edit is not allowed.
        self.assertFalse(mayaUsdUfe.isAttributeEditAllowed(rotateAttr))

        # set the edit target to a stronger layer (LayerA)
        cmds.mayaUsdEditTarget(proxyShapePath, edit=True, editTarget=subLayerA)

        # authoring new transformation edit is allowed.
        self.assertTrue(mayaUsdUfe.isAttributeEditAllowed(rotateAttr))
Beispiel #11
0
    def testTransformationAttributeBlocking(self):
        '''Authoring transformation attribute(s) in weaker layer(s) are not permitted if there exist opinion(s) in stronger layer(s).'''

        # create new stage
        cmds.file(new=True, force=True)

        # Open usdCylinder.ma scene in testSamples
        mayaUtils.openCylinderScene()

        # get the stage
        proxyShapes = cmds.ls(type="mayaUsdProxyShapeBase", long=True)
        proxyShapePath = proxyShapes[0]
        stage = mayaUsd.lib.GetPrim(proxyShapePath).GetStage()

        # cylinder prim
        cylinderPrim = stage.GetPrimAtPath('/pCylinder1')
        self.assertIsNotNone(cylinderPrim)

        # create 3 sub-layers ( LayerA, LayerB, LayerC ) and set the edit target to LayerB.
        rootLayer = stage.GetRootLayer()
        subLayerC = cmds.mayaUsdLayerEditor(rootLayer.identifier,
                                            edit=True,
                                            addAnonymous="SubLayerC")[0]
        subLayerB = cmds.mayaUsdLayerEditor(rootLayer.identifier,
                                            edit=True,
                                            addAnonymous="SubLayerB")[0]
        subLayerA = cmds.mayaUsdLayerEditor(rootLayer.identifier,
                                            edit=True,
                                            addAnonymous="SubLayerA")[0]

        # check to see the sublayers added
        addedLayers = [subLayerA, subLayerB, subLayerC]
        self.assertEqual(rootLayer.subLayerPaths, addedLayers)

        # set the edit target to LayerB
        cmds.mayaUsdEditTarget(proxyShapePath, edit=True, editTarget=subLayerB)

        # create a transform3d
        cylinderPath = ufe.Path([
            mayaUtils.createUfePathSegment("|mayaUsdTransform|shape"),
            usdUtils.createUfePathSegment("/pCylinder1")
        ])
        cylinderItem = ufe.Hierarchy.createItem(cylinderPath)

        cylinderT3d = ufe.Transform3d.transform3d(cylinderItem)

        # create a xformable
        cylinderXformable = UsdGeom.Xformable(cylinderPrim)

        # writing to "transform op order" is expected to be allowed.
        self.assertTrue(
            mayaUsdUfe.isAttributeEditAllowed(
                cylinderXformable.GetXformOpOrderAttr()))

        # do any transform editing.
        cylinderT3d = ufe.Transform3d.transform3d(cylinderItem)
        cylinderT3d.scale(2.5, 2.5, 2.5)
        cylinderT3d.translate(4.0, 2.0, 3.0)

        # check the "transform op order" stack.
        self.assertEqual(cylinderXformable.GetXformOpOrderAttr().Get(),
                         Vt.TokenArray(('xformOp:translate', 'xformOp:scale')))

        # check if translate attribute is editable
        translateAttr = cylinderPrim.GetAttribute('xformOp:translate')
        self.assertIsNotNone(translateAttr)

        # authoring new transformation edit is expected to be allowed.
        self.assertTrue(mayaUsdUfe.isAttributeEditAllowed(translateAttr))
        cylinderT3d.translate(5.0, 6.0, 7.0)
        self.assertEqual(translateAttr.Get(), Gf.Vec3d(5.0, 6.0, 7.0))

        # set the edit target to a weaker layer (LayerC)
        cmds.mayaUsdEditTarget(proxyShapePath, edit=True, editTarget=subLayerC)

        # authoring new transformation edit is not allowed.
        self.assertFalse(mayaUsdUfe.isAttributeEditAllowed(translateAttr))

        # set the edit target to a stronger layer (LayerA)
        cmds.mayaUsdEditTarget(proxyShapePath, edit=True, editTarget=subLayerA)

        # authoring new transformation edit is allowed.
        self.assertTrue(mayaUsdUfe.isAttributeEditAllowed(translateAttr))
        cylinderT3d.rotate(0.0, 90.0, 0.0)

        # check the "transform op order" stack.
        self.assertEqual(
            cylinderXformable.GetXformOpOrderAttr().Get(),
            Vt.TokenArray(
                ('xformOp:translate', 'xformOp:rotateXYZ', 'xformOp:scale')))