def testMuteLayerImpl(addLayerFunc): def checkMuted(layer, stage): # Make sure the layer is muted inside the stage. self.assertTrue(stage.IsLayerMuted(layer.identifier)) self.assertTrue(layer.identifier in stage.GetMutedLayers()) # Make sure the stage does not used the muted layer self.assertFalse(layer in stage.GetLayerStack(False)) self.assertFalse(layer in stage.GetUsedLayers(False)) def checkUnMuted(layer, stage): self.assertFalse(stage.IsLayerMuted(layer.identifier)) self.assertFalse(layer.identifier in stage.GetMutedLayers()) self.assertTrue(layer in stage.GetLayerStack(False)) self.assertTrue(layer in stage.GetUsedLayers(False)) shapePath, stage = getCleanMayaStage() rootLayer = stage.GetRootLayer() layer = addLayerFunc(rootLayer) checkUnMuted(layer, stage) # Mute the layer cmds.mayaUsdLayerEditor(layer.identifier, edit=True, muteLayer=(True, shapePath)) checkMuted(layer, stage) # undo mute cmds.undo() checkUnMuted(layer, stage) # redo mute cmds.redo() checkMuted(layer, stage)
def addFileBakedLayerByPath(parentLayer): tempFile = tempfile.NamedTemporaryFile(suffix=".usda", delete=False, mode="w") tempFile.write("#usda 1.0") tempFile.close() cmds.mayaUsdLayerEditor(parentLayer.identifier, edit=True, insertSubPath=[0, tempFile.name]) layer = Sdf.Layer.FindOrOpen(tempFile.name) self.assertTrue(layer) return layer
def testFileBackedLayers(self): mayaUtils.openTopLayerScene() shapePath, stage = getMayaStage() # Mute/Un-mute named layer -> dirties scene with DirtySceneCheck(self): stage.MuteLayer('Assembly_room_set.usda') with DirtySceneCheck(self): stage.UnmuteLayer('Assembly_room_set.usda') # Remove named layer -> dirties scene rootLayer = stage.GetRootLayer() with DirtySceneCheck(self): cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, removeSubPath=(0, shapePath))
def setAndRemoveEditTargetRecursive(layer, index, editLayer): cmds.mayaUsdEditTarget(shapePath, edit=True, editTarget=editLayer) cmds.mayaUsdLayerEditor(layer.identifier, edit=True, removeSubPath=[index, shapePath]) self.assertEqual(stage.GetEditTarget().GetLayer().identifier, rootLayerID) cmds.undo() self.assertEqual(stage.GetEditTarget().GetLayer().identifier, editLayer) subLayer = Sdf.Layer.FindRelativeToLayer(layer, editLayer) for subLayerOffset, subLayerId in enumerate( subLayer.subLayerPaths): setAndRemoveEditTargetRecursive(subLayer, subLayerOffset, subLayerId)
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) import mayaUsd_createStageWithNewLayer mayaUsd_createStageWithNewLayer.createStageWithNewLayer() proxyShapes = cmds.ls(type="mayaUsdProxyShapeBase", long=True) proxyShapePath = proxyShapes[0] proxyShapeItem = ufe.Hierarchy.createItem( ufe.PathString.path(proxyShapePath)) proxyShapeContextOps = ufe.ContextOps.contextOps(proxyShapeItem) stage = mayaUsd.lib.GetPrim(proxyShapePath).GetStage() # create a prim. This creates the primSpec in the root layer. proxyShapeContextOps.doOp(['Add New Prim', 'Capsule']) # create a USD prim capsulePath = ufe.PathString.path('|stage1|stageShape1,/Capsule1') capsuleItem = ufe.Hierarchy.createItem(capsulePath) capsulePrim = mayaUsd.ufe.ufePathToPrim( ufe.PathString.string(capsulePath)) # author a new radius value self.assertTrue(capsulePrim.HasAttribute('radius')) radiusAttrUsd = capsulePrim.GetAttribute('radius') # authoring new attribute edit is expected to be allowed. self.assertTrue(mayaUsdUfe.isAttributeEditAllowed(radiusAttrUsd)) radiusAttrUsd.Set(10) # author a new axis value self.assertTrue(capsulePrim.HasAttribute('axis')) axisAttrUsd = capsulePrim.GetAttribute('axis') # authoring new attribute edit is expected to be allowed. self.assertTrue(mayaUsdUfe.isAttributeEditAllowed(axisAttrUsd)) axisAttrUsd.Set('Y') # 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) # radiusAttrUsd is not allowed to change since there is an opinion in a stronger layer self.assertFalse(mayaUsdUfe.isAttributeEditAllowed(radiusAttrUsd)) # axisAttrUsd is not allowed to change since there is an opinion in a stronger layer self.assertFalse(mayaUsdUfe.isAttributeEditAllowed(axisAttrUsd))
def moveSubPath(parentLayer, subPath, newParentLayer, index, originalSubLayerPaths, newSubLayerPaths): cmds.mayaUsdLayerEditor( parentLayer.identifier, edit=True, moveSubPath=[subPath, newParentLayer.identifier, index]) self.assertEqual(newParentLayer.subLayerPaths, newSubLayerPaths) cmds.undo() self.assertEqual(newParentLayer.subLayerPaths, originalSubLayerPaths) cmds.redo() self.assertEqual(newParentLayer.subLayerPaths, newSubLayerPaths) cmds.undo() self.assertEqual(newParentLayer.subLayerPaths, originalSubLayerPaths)
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)
def testEditRouter(self): '''Test edit router functionality.''' cmds.file(new=True, force=True) import mayaUsd_createStageWithNewLayer # Create the following hierarchy: # # ps # |_ A # |_ B # # We A and duplicate it. psPathStr = mayaUsd_createStageWithNewLayer.createStageWithNewLayer() stage = mayaUsd.lib.GetPrim(psPathStr).GetStage() stage.DefinePrim('/A', 'Xform') stage.DefinePrim('/A/B', 'Xform') psPath = ufe.PathString.path(psPathStr) psPathSegment = psPath.segments[0] aPath = ufe.Path([psPathSegment, usdUtils.createUfePathSegment('/A')]) a = ufe.Hierarchy.createItem(aPath) bPath = aPath + ufe.PathComponent('B') b = ufe.Hierarchy.createItem(bPath) # Add a sub-layer, where the parent edit should write to. subLayerId = cmds.mayaUsdLayerEditor(stage.GetRootLayer().identifier, edit=True, addAnonymous="aSubLayer")[0] mayaUsd.lib.registerEditRouter('duplicate', firstSubLayer) sn = ufe.GlobalSelection.get() sn.clear() sn.append(a) cmds.duplicate() sublayer01 = Sdf.Find(subLayerId) self.assertIsNotNone(sublayer01) self.assertIsNotNone(sublayer01.GetPrimAtPath('/A1/B'))
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 testSubLayerEditing(self): """ test 'mayaUsdLayerEditor' command """ _shapePath, stage = getCleanMayaStage() rootLayer = stage.GetRootLayer() # -addAnonymous # add three layers. Note: these are always added at the top layer3Id = cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, addAnonymous="Layer1")[0] layer2Id = cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, addAnonymous="Layer2")[0] layer1Id = cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, addAnonymous="Layer3")[0] # check that they were added addedLayers = [layer1Id, layer2Id, layer3Id] self.assertEqual(rootLayer.subLayerPaths, addedLayers) # -removeSubPath # remove second sublayer cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, removeSubPath=1) afterDeletion = [layer1Id, layer3Id] self.assertEqual(rootLayer.subLayerPaths, afterDeletion) # remove second sublayer again to leave only one afterDeletion = [layer1Id, layer3Id] cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, removeSubPath=1) self.assertEqual(rootLayer.subLayerPaths, [layer1Id]) # remove second sublayer -- this time it's out of bounds with self.assertRaises(RuntimeError): cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, removeSubPath=1) # undo twice to get back to three layers cmds.undo() cmds.undo() self.assertEqual(rootLayer.subLayerPaths, addedLayers) # redo deletion of second layer cmds.redo() self.assertEqual(rootLayer.subLayerPaths, afterDeletion) cmds.undo() # put a sub layer and a sub-sub layer on the top layer. childLayerId = cmds.mayaUsdLayerEditor(layer1Id, edit=True, addAnonymous="ChildLayer")[0] grandChildLayerId = cmds.mayaUsdLayerEditor( childLayerId, edit=True, addAnonymous="GrandChild")[0] # delete the top layer. See if it comes back after redo. cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, removeSubPath=0) # check layer1 was deleted self.assertEqual(rootLayer.subLayerPaths, [layer2Id, layer3Id]) # bring it back cmds.undo() firstLayer = Sdf.Layer.Find(layer1Id) self.assertIsNotNone(firstLayer) # check the children were not deleted self.assertEqual(firstLayer.subLayerPaths[0], childLayerId) childLayer = Sdf.Layer.Find(childLayerId) self.assertEqual(childLayer.subLayerPaths[0], grandChildLayerId) # -insertSubPath # insert two layers rootLayer.subLayerPaths.clear() second = "second.usda" first = "first.usda" newName = "david.usda" cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, insertSubPath=[0, second]) cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, insertSubPath=[0, first]) # message for anyone looking at the test log: # It's normal for stage.cpp to print the error that it can't find second.usa and first.usda, they do not exist" self.assertEqual(rootLayer.subLayerPaths, [first, second]) # bad index with self.assertRaises(RuntimeError): cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, insertSubPath=[-2, "bogus"]) with self.assertRaises(RuntimeError): cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, insertSubPath=[2, "bogus"]) # -replaceSubPath cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, replaceSubPath=[first, newName]) self.assertEqual(rootLayer.subLayerPaths, [newName, second]) # bad replace path with self.assertRaises(RuntimeError): cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, replaceSubPath=["notfound", newName]) # -clear # -discardEdits testPasses = [CLEAR, DISCARD] for testPass in testPasses: if testPass == CLEAR: # get a clear stage rootLayer.subLayerPaths.clear() if testPass == DISCARD: # save and load a stage testUsdFile = tempfile.NamedTemporaryFile(suffix=".usda", prefix="dummy", delete=False, mode="w") testUsdFile.write(DUMMY_FILE_TEXT) testUsdFile.close() newStage = Usd.Stage.Open(testUsdFile.name) rootLayer = newStage.GetRootLayer() self.assertEqual(len(rootLayer.subLayerPaths), 0) childLayerId = cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, addAnonymous="Child")[0] grandChildLayerId = cmds.mayaUsdLayerEditor( childLayerId, edit=True, addAnonymous="GrandChild")[0] if testPass == CLEAR: cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, clear=True) if testPass == DISCARD: cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, discardEdits=True) # test everything is gone self.assertEqual(len(rootLayer.subLayerPaths), 0) cmds.undo() # layers are back self.assertEqual(len(rootLayer.subLayerPaths), 1) self.assertEqual(rootLayer.subLayerPaths[0], childLayerId) cmds.redo() # cleared/discarded again self.assertEqual(len(rootLayer.subLayerPaths), 0) cmds.undo() # layers are back self.assertEqual(rootLayer.subLayerPaths[0], childLayerId) childLayer = Sdf.Layer.Find(childLayerId) self.assertEqual(childLayer.subLayerPaths[0], grandChildLayerId)
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) import mayaUsd_createStageWithNewLayer mayaUsd_createStageWithNewLayer.createStageWithNewLayer() proxyShapes = cmds.ls(type="mayaUsdProxyShapeBase", long=True) proxyShapePath = proxyShapes[0] proxyShapeItem = ufe.Hierarchy.createItem( ufe.PathString.path(proxyShapePath)) proxyShapeContextOps = ufe.ContextOps.contextOps(proxyShapeItem) stage = mayaUsd.lib.GetPrim(proxyShapePath).GetStage() # 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 prim. This creates the primSpec in the SubLayerB. proxyShapeContextOps.doOp(['Add New Prim', 'Sphere']) spherePath = ufe.PathString.path('|stage1|stageShape1,/Sphere1') sphereItem = ufe.Hierarchy.createItem(spherePath) spherePrim = mayaUsd.ufe.ufePathToPrim( ufe.PathString.string(spherePath)) # create a transform3d sphereT3d = ufe.Transform3d.transform3d(sphereItem) # create a xformable sphereXformable = UsdGeom.Xformable(spherePrim) # writing to "transform op order" is expected to be allowed. self.assertTrue( mayaUsdUfe.isAttributeEditAllowed( sphereXformable.GetXformOpOrderAttr())) # do any transform editing. sphereT3d = ufe.Transform3d.transform3d(sphereItem) sphereT3d.scale(2.5, 2.5, 2.5) sphereT3d.translate(4.0, 2.0, 3.0) # check the "transform op order" stack. self.assertEqual(sphereXformable.GetXformOpOrderAttr().Get(), Vt.TokenArray(('xformOp:translate', 'xformOp:scale'))) # check if translate attribute is editable translateAttr = spherePrim.GetAttribute('xformOp:translate') self.assertIsNotNone(translateAttr) # authoring new transformation edit is expected to be allowed. self.assertTrue(mayaUsdUfe.isAttributeEditAllowed(translateAttr)) sphereT3d.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)) sphereT3d.rotate(0.0, 90.0, 0.0) # check the "transform op order" stack. self.assertEqual( sphereXformable.GetXformOpOrderAttr().Get(), Vt.TokenArray( ('xformOp:translate', 'xformOp:rotateXYZ', 'xformOp:scale')))
def testRemoveEditTarget(self): shapePath, stage = getCleanMayaStage() rootLayer = stage.GetRootLayer() rootLayerID = rootLayer.identifier def setAndRemoveEditTargetRecursive(layer, index, editLayer): cmds.mayaUsdEditTarget(shapePath, edit=True, editTarget=editLayer) cmds.mayaUsdLayerEditor(layer.identifier, edit=True, removeSubPath=[index, shapePath]) self.assertEqual(stage.GetEditTarget().GetLayer().identifier, rootLayerID) cmds.undo() self.assertEqual(stage.GetEditTarget().GetLayer().identifier, editLayer) subLayer = Sdf.Layer.FindRelativeToLayer(layer, editLayer) for subLayerOffset, subLayerId in enumerate( subLayer.subLayerPaths): setAndRemoveEditTargetRecursive(subLayer, subLayerOffset, subLayerId) # build a layer hierarchy layerColorId = cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, addAnonymous="Color")[0] myLayerId = cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, addAnonymous="MyLayer")[0] layerRedId = cmds.mayaUsdLayerEditor(layerColorId, edit=True, addAnonymous="Red")[0] layerGreen = cmds.mayaUsdLayerEditor(layerColorId, edit=True, addAnonymous="Green")[0] layerBlue = cmds.mayaUsdLayerEditor(layerColorId, edit=True, addAnonymous="Blue")[0] layerDarkRed = cmds.mayaUsdLayerEditor(layerRedId, edit=True, addAnonymous="DarkRed")[0] layerLightRed = cmds.mayaUsdLayerEditor(layerRedId, edit=True, addAnonymous="LightRed")[0] mySubLayerId = cmds.mayaUsdLayerEditor(myLayerId, edit=True, addAnonymous="MySubLayer")[0] # traverse the layer tree # for each layer, set it as the edit target and remove it. for subLayerOffset, subLayerPath in enumerate(rootLayer.subLayerPaths): setAndRemoveEditTargetRecursive(rootLayer, subLayerOffset, subLayerPath) # # Test when the editTarget's parent (direct/ indirect) layer is removed # cmds.mayaUsdEditTarget(shapePath, edit=True, editTarget=layerDarkRed) # remove the Red layer (direct parent of DarkRed layer) cmds.mayaUsdLayerEditor(layerColorId, edit=True, removeSubPath=[2, shapePath]) self.assertEqual(stage.GetEditTarget().GetLayer().identifier, rootLayerID) cmds.undo() self.assertEqual(stage.GetEditTarget().GetLayer().identifier, layerDarkRed) # remove the Color layer (indirect parent of DarkRed layer) cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, removeSubPath=[1, shapePath]) self.assertEqual(stage.GetEditTarget().GetLayer().identifier, rootLayerID) cmds.undo() self.assertEqual(stage.GetEditTarget().GetLayer().identifier, layerDarkRed) # # Test with a layer that is a sublayer multiple times. # sharedLayerFile = tempfile.NamedTemporaryFile(suffix=".usda", prefix="sharedLayer", delete=False, mode="w") sharedLayerFile.write("#usda 1.0") sharedLayerFile.close() sharedLayer = path.normcase(sharedLayerFile.name) cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, insertSubPath=[0, sharedLayer]) cmds.mayaUsdLayerEditor(mySubLayerId, edit=True, insertSubPath=[0, sharedLayer]) cmds.mayaUsdEditTarget(shapePath, edit=True, editTarget=sharedLayer) # remove the sharedLayer under the root layer. # the edit target should still be the shared layer cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, removeSubPath=[0, shapePath]) self.assertEqual( path.normcase(stage.GetEditTarget().GetLayer().identifier), sharedLayer) cmds.undo() self.assertEqual( path.normcase(stage.GetEditTarget().GetLayer().identifier), sharedLayer) # remove the sharedLayer under the MySubLayer. # the edit target should still be the shared layer cmds.mayaUsdLayerEditor(mySubLayerId, edit=True, removeSubPath=[0, shapePath]) self.assertEqual( path.normcase(stage.GetEditTarget().GetLayer().identifier), sharedLayer) cmds.undo() self.assertEqual( path.normcase(stage.GetEditTarget().GetLayer().identifier), sharedLayer) # remove MySubLayer (Direct parent of SharedLayer). # the edit target should still be the shared layer cmds.mayaUsdLayerEditor(myLayerId, edit=True, removeSubPath=[0, shapePath]) self.assertEqual( path.normcase(stage.GetEditTarget().GetLayer().identifier), sharedLayer) cmds.undo() self.assertEqual( path.normcase(stage.GetEditTarget().GetLayer().identifier), sharedLayer) # remove MyLayer (Indirect parent of SharedLayer). # the edit target should still be the shared layer cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, removeSubPath=[0, shapePath]) self.assertEqual( path.normcase(stage.GetEditTarget().GetLayer().identifier), sharedLayer) cmds.undo() self.assertEqual( path.normcase(stage.GetEditTarget().GetLayer().identifier), sharedLayer) # remove SharedLayer everywhere. # the edit target should become the root layer cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, removeSubPath=[0, shapePath]) cmds.mayaUsdLayerEditor(mySubLayerId, edit=True, removeSubPath=[0, shapePath]) self.assertEqual(stage.GetEditTarget().GetLayer().identifier, rootLayerID) cmds.undo() self.assertEqual( path.normcase(stage.GetEditTarget().GetLayer().identifier), sharedLayer)
def testAnonymousLayers(self): shapePath, stage = getCleanMayaStage() rootLayer = stage.GetRootLayer() # Add anonymous layer -> dirties scene with DirtySceneCheck(self): layer1Id = cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, addAnonymous="Layer1")[0] # Mute/un-mute anon layer -> dirties scene with DirtySceneCheck(self): cmds.mayaUsdLayerEditor(layer1Id, edit=True, muteLayer=(True, shapePath)) with DirtySceneCheck(self): cmds.mayaUsdLayerEditor(layer1Id, edit=True, muteLayer=(False, shapePath)) # Remove anon layer -> dirties scene with DirtySceneCheck(self): cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, removeSubPath=(0, shapePath)) # Reorder anon layer ->dirties scene cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, clear=True) layer1Id = cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, addAnonymous="Layer1")[0] layer2Id = cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, addAnonymous="Layer2")[0] layer3Id = cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, addAnonymous="Layer3")[0] self.assertIsNotNone(layer1Id) self.assertIsNotNone(layer2Id) self.assertIsNotNone(layer3Id) cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, removeSubPath=(2, shapePath)) with DirtySceneCheck(self): cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, insertSubPath=(1, layer1Id))
def testEditTarget(self): """ tests 'mayaUsdEditTarget' command, but also touches on adding anon layers """ shapePath, stage = getCleanMayaStage() # original target is the root anonymous layer originalTargetID = stage.GetEditTarget().GetLayer().identifier rootLayer = stage.GetRootLayer() self.assertEqual(originalTargetID, rootLayer.identifier) currentTargetID = cmds.mayaUsdEditTarget(shapePath, query=True, editTarget=True)[0] self.assertEqual(originalTargetID, currentTargetID) # add two sub layers redLayerId = cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, addAnonymous="redLayer")[0] greenLayerId = cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, addAnonymous="greenLayer")[0] self.assertEqual(len(rootLayer.subLayerPaths), 2) cmds.mayaUsdEditTarget(shapePath, edit=True, editTarget=greenLayerId) self.assertEqual(stage.GetEditTarget().GetLayer().identifier, greenLayerId) # do we return that new target? self.assertEqual( stage.GetEditTarget().GetLayer().identifier, cmds.mayaUsdEditTarget(shapePath, query=True, editTarget=True)[0]) undoStepTwo = greenLayerId cmds.mayaUsdEditTarget(shapePath, edit=True, editTarget=redLayerId) self.assertEqual(stage.GetEditTarget().GetLayer().identifier, redLayerId) undoStepOne = redLayerId # can we set the target back to the root? rootLayerID = rootLayer.identifier cmds.mayaUsdEditTarget(shapePath, edit=True, editTarget=rootLayerID) self.assertEqual(stage.GetEditTarget().GetLayer().identifier, rootLayerID) # undo cmds.undo() self.assertEqual(stage.GetEditTarget().GetLayer().identifier, undoStepOne) cmds.undo() self.assertEqual(stage.GetEditTarget().GetLayer().identifier, undoStepTwo) # test bad input with self.assertRaises(RuntimeError): cmds.mayaUsdEditTarget("bogusShape", query=True, editTarget=True) with self.assertRaises(RuntimeError): cmds.mayaUsdEditTarget("bogusShape", edit=True, editTarget=greenLayerId) with self.assertRaises(RuntimeError): cmds.mayaUsdEditTarget(shapePath, edit=True, editTarget="bogusLayer")
def testMoveSubPath(self): """ test 'mayaUsdLayerEditor' command 'moveSubPath' paramater """ def moveSubPath(parentLayer, subPath, newParentLayer, index, originalSubLayerPaths, newSubLayerPaths): cmds.mayaUsdLayerEditor( parentLayer.identifier, edit=True, moveSubPath=[subPath, newParentLayer.identifier, index]) self.assertEqual(newParentLayer.subLayerPaths, newSubLayerPaths) cmds.undo() self.assertEqual(newParentLayer.subLayerPaths, originalSubLayerPaths) cmds.redo() self.assertEqual(newParentLayer.subLayerPaths, newSubLayerPaths) cmds.undo() self.assertEqual(newParentLayer.subLayerPaths, originalSubLayerPaths) def moveElement(list, item, index): l = list[:] #copy the list l.remove(item) l.insert(index, item) return l shapePath, stage = getCleanMayaStage() rootLayer = stage.GetRootLayer() layerId1 = cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, addAnonymous="MyLayer1")[0] layerId2 = cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, addAnonymous="MyLayer2")[0] layerId3 = cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, addAnonymous="MyLayer3")[0] originalSubLayerPaths = [layerId3, layerId2, layerId1] self.assertEqual(rootLayer.subLayerPaths, originalSubLayerPaths) # Test moving each layers under the root layer to any valid index in the root layer # and test out-of-bound index for layer in originalSubLayerPaths: for i in range(len(originalSubLayerPaths)): expectedSubPath = moveElement(originalSubLayerPaths, layer, i) moveSubPath(rootLayer, layer, rootLayer, i, originalSubLayerPaths, expectedSubPath) with self.assertRaises(RuntimeError): cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, moveSubPath=[ layer, rootLayer.identifier, len(originalSubLayerPaths) ]) self.assertEqual(rootLayer.subLayerPaths, originalSubLayerPaths) # # Test moving sublayer (layer2 and layer3) inside a new parent layer (layer1) # layer1 = Sdf.Layer.Find(layerId1) self.assertTrue(len(layer1.subLayerPaths) == 0) # layer1 has no subLayer so index 1 is invalide with self.assertRaises(RuntimeError): cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, moveSubPath=[layerId3, layerId1, 1]) self.assertTrue(len(layer1.subLayerPaths) == 0) self.assertEqual(rootLayer.subLayerPaths, originalSubLayerPaths) # Move layer3 from the root layer inside layer1 at index 0 cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, moveSubPath=[layerId3, layerId1, 0]) self.assertEqual(rootLayer.subLayerPaths, [layerId2, layerId1]) self.assertEqual(layer1.subLayerPaths, [layerId3]) # Move layer2 from the root layer inside layer1 at index 0 cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, moveSubPath=[layerId2, layerId1, 0]) self.assertEqual(rootLayer.subLayerPaths, [layerId1]) self.assertEqual(layer1.subLayerPaths, [layerId2, layerId3]) cmds.undo() self.assertEqual(rootLayer.subLayerPaths, [layerId2, layerId1]) self.assertEqual(layer1.subLayerPaths, [layerId3]) # Move layer2 from the root layer inside layer1 at index 1 cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, moveSubPath=[layerId2, layerId1, 1]) self.assertEqual(rootLayer.subLayerPaths, [layerId1]) self.assertEqual(layer1.subLayerPaths, [layerId3, layerId2]) cmds.undo() self.assertEqual(rootLayer.subLayerPaths, [layerId2, layerId1]) self.assertEqual(layer1.subLayerPaths, [layerId3]) # Undo moving layer3 inside layer1 cmds.undo() self.assertEqual(rootLayer.subLayerPaths, [layerId3, layerId2, layerId1]) self.assertEqual(layer1.subLayerPaths, []) # Insert layer3 inside layer1 and try to move the layer3 from the root layer # inside layer1. This should fail. cmds.mayaUsdLayerEditor(layerId1, edit=True, insertSubPath=[0, layerId3]) self.assertEqual(layer1.subLayerPaths, [layerId3]) with self.assertRaises(RuntimeError): cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, moveSubPath=[layerId3, layerId1, 0]) self.assertEqual(rootLayer.subLayerPaths, originalSubLayerPaths) self.assertEqual(layer1.subLayerPaths, [layerId3])
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))
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))
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')))
def testMayaSelectMuteLayer(self): '''Stale selection items must be removed on mute layer.''' # Create new stage import mayaUsd_createStageWithNewLayer proxyShapePathStr = mayaUsd_createStageWithNewLayer.createStageWithNewLayer( ) proxyShapePath = ufe.PathString.path(proxyShapePathStr) proxyShapeItem = ufe.Hierarchy.createItem(proxyShapePath) proxyShapeContextOps = ufe.ContextOps.contextOps(proxyShapeItem) # Create a sub-layer. stage = mayaUsd.lib.GetPrim(proxyShapePathStr).GetStage() rootLayer = stage.GetRootLayer() subLayerId = cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, addAnonymous="Layer1")[0] # Set the edit target to new sub-layer. cmds.mayaUsdEditTarget(proxyShapePathStr, edit=True, editTarget=subLayerId) # Create a prim. This will create the primSpec in the new sub-layer. proxyShapeContextOps.doOp(['Add New Prim', 'Capsule']) capsulePathStr = '%s,/Capsule1' % proxyShapePathStr capsulePath = ufe.PathString.path(capsulePathStr) capsuleItem = ufe.Hierarchy.createItem(capsulePath) # Select the prim. This is the core of the test: on subtree invalidate, # the prim's UFE scene item should be removed from the selection. sn = ufe.GlobalSelection.get() sn.clear() sn.append(capsuleItem) self.assertTrue(sn.contains(capsulePath)) # Mute sub-layer cmds.mayaUsdLayerEditor(subLayerId, edit=True, muteLayer=[1, proxyShapePathStr]) # Should be nothing on the selection list. self.assertTrue(sn.empty()) # Undo: capsule should be back on the selection list. cmds.undo() self.assertTrue(sn.contains(capsulePath)) # Redo: selection list now empty. cmds.redo() self.assertTrue(sn.empty()) cmds.undo() # Change attribute on the capsule, using the item from the selection, # which must be valid. self.assertTrue(len(sn), 1) capsuleItem = sn.front() capsuleAttrs = ufe.Attributes.attributes(capsuleItem) self.assertIsNotNone(capsuleAttrs) capsuleRadius = capsuleAttrs.attribute('radius') capsuleRadius.set(2) self.assertEqual(capsuleRadius.get(), 2) # Now mute the layer outside a Maya command. Stale scene items must be # removed from the selection. self.assertTrue(len(sn), 1) self.assertTrue(sn.contains(capsulePath)) stage.MuteLayer(subLayerId) self.assertTrue(sn.empty())
def addAnonymousLayer(parentLayer): layerId = cmds.mayaUsdLayerEditor(parentLayer.identifier, edit=True, addAnonymous="MyLayer")[0] layer = Sdf.Layer.Find(layerId) return layer