def testImportInverseXformOpsOnly(self): """ Tests that importing a USD cube mesh that has XformOps on it all tagged as inverse ops results in the correct transform when imported into Maya. """ usdFile = os.path.abspath('UsdImportXformsTest.usda') cmds.usdImport(file=usdFile, shadingMode='none') mayaTransform = self._GetMayaTransform('InverseOpsOnlyCube') transformationMatrix = mayaTransform.transformation() expectedTranslation = [-1.0, -2.0, -3.0] actualTranslation = list( transformationMatrix.translation(OM.MSpace.kTransform)) self.assertTrue( Gf.IsClose(expectedTranslation, actualTranslation, self.EPSILON)) expectedRotation = [0.0, 0.0, Gf.DegreesToRadians(-45.0)] actualRotation = list(transformationMatrix.rotation()) self.assertTrue( Gf.IsClose(expectedRotation, actualRotation, self.EPSILON)) expectedScale = [2.0, 2.0, 2.0] actualScale = list(transformationMatrix.scale(OM.MSpace.kTransform)) self.assertTrue( Gf.IsClose(expectedScale, actualScale, self.EPSILON))
def testPivot(self): """ Tests that pivotPosition attribute doesn't interfere with the matrix that we get in maya when importing a usd file. """ def _usdToMayaPath(usdPath): return str(usdPath).replace('/', '|') from maya import cmds usdFile = os.path.join(self.inputPath, "UsdImportXformsTest", "pivotTests.usda") from pxr import Usd, UsdGeom stage = Usd.Stage.Open(usdFile) xformCache = UsdGeom.XformCache() cmds.usdImport(file=os.path.abspath(usdFile), primPath='/World') usdPaths = [ '/World/anim/chars/SomeCharacter/Geom/Face/Eyes/LEye', '/World/anim/chars/SomeCharacter/Geom/Face/Eyes/LEye/Sclera_sbdv', '/World/anim/chars/SomeCharacter/Geom/Face/Eyes/REye/Sclera_sbdv', '/World/anim/chars/SomeCharacter/Geom/Hair/HairStandin/Hair/Hair_sbdv', '/World/anim/chars/SomeCharacter/Geom/Hair/HairStandin/Hair/HairFrontPiece_sbdv', ] for usdPath in usdPaths: usdMatrix = xformCache.GetLocalToWorldTransform(stage.GetPrimAtPath(usdPath)) mayaPath = _usdToMayaPath(usdPath) mayaMatrix = Gf.Matrix4d(*cmds.xform(mayaPath, query=True, matrix=True, worldSpace=True)) print('testing matrix at', usdPath) self.assertTrue(Gf.IsClose( usdMatrix.ExtractTranslation(), mayaMatrix.ExtractTranslation(), self.EPSILON))
def setUpClass(cls): inputPath = fixturesUtils.readOnlySetUpClass(__file__) cmds.file(new=True, force=True) # We need to use different input usd files depending on the version of USD. # We do this because USD introduced breaking changes on lights in USD 21.* # More precisely : # # - Before USD 21.* : lights attributes didn't have any prefix. Attributes # were named "intensity", "color", etc... # - In 21.02 : The attributes from light schemas were added a # namespace "inputs". But attributes from UsdLuxShapingAPI # (used for spot lights) or UsdLuxShadowsAPI (for shadows) # were still left without this namespace # - In 21.05 : Attributes from UsdLuxShadows and UsdLuxShapingAPI also # have a namespace "inputs" testFile = "LightsTest.usda" usdVersion = Usd.GetVersion() if usdVersion < (0, 21, 2): testFile = "LightsTest_2011.usda" elif usdVersion == (0, 21, 2): testFile = "LightsTest_2102.usda" # Import from USD. usdFilePath = os.path.join(inputPath, "UsdImportLightTest", testFile) cmds.usdImport(file=usdFilePath, readAnimData=True) cls._stage = Usd.Stage.Open(usdFilePath)
def _LoadUsd(self): # Import the USD file. usdFilePath = os.path.join(self.inputPath, "UsdImportXformAnimTest", "Mesh.usda") cmds.usdImport(file=usdFilePath, readAnimData=False) self.stage = Usd.Stage.Open(usdFilePath) self.assertTrue(self.stage)
def setUpClass(cls): standalone.initialize('usd') cmds.loadPlugin('pxrUsd') usdFile = os.path.abspath('UsdImportColorSetsTest.usda') cmds.usdImport(file=usdFile, shadingMode='none', excludePrimvar='ExcludeMe')
def testReexportScope(self): cmds.usdImport(file=self._usdFile, primPath='/') exportedUsdFile = os.path.abspath('Scopes.reexported.usda') cmds.usdExport(file=exportedUsdFile) stage = Usd.Stage.Open(exportedUsdFile) self.assertTrue(stage) self.assertTrue(stage.GetPrimAtPath('/A')) self.assertEqual(stage.GetPrimAtPath('/A').GetTypeName(), 'Xform') self.assertTrue(stage.GetPrimAtPath('/A/A_1')) self.assertEqual(stage.GetPrimAtPath('/A/A_1').GetTypeName(), 'Scope') self.assertTrue(stage.GetPrimAtPath('/A/A_1/A_1_I')) self.assertEqual( stage.GetPrimAtPath('/A/A_1/A_1_I').GetTypeName(), 'Mesh') self.assertTrue(stage.GetPrimAtPath('/A/A_1/A_1_II')) self.assertEqual( stage.GetPrimAtPath('/A/A_1/A_1_II').GetTypeName(), 'Camera') self.assertTrue(stage.GetPrimAtPath('/A/A_1/A_1_III')) self.assertEqual( stage.GetPrimAtPath('/A/A_1/A_1_III').GetTypeName(), 'Scope') self.assertTrue(stage.GetPrimAtPath('/A/A_2')) self.assertEqual(stage.GetPrimAtPath('/A/A_2').GetTypeName(), 'Scope') self.assertTrue(stage.GetPrimAtPath('/B')) self.assertEqual(stage.GetPrimAtPath('/B').GetTypeName(), 'Scope') self.assertTrue(stage.GetPrimAtPath('/B/B_1')) self.assertEqual(stage.GetPrimAtPath('/B/B_1').GetTypeName(), 'Xform')
def testImport_GeomModelAPI(self): """Tests importing UsdGeomModelAPI attributes.""" cmds.file(new=True, force=True) usdFile = os.path.abspath('UsdAttrs.usda') cmds.usdImport(file=usdFile, shadingMode='none', apiSchema=['GeomModelAPI']) worldProxy = UsdMaya.Adaptor('World') modelAPI = worldProxy.GetSchema(UsdGeom.ModelAPI) # model:cardGeometry self.assertTrue( cmds.attributeQuery('USD_ATTR_model_cardGeometry', node='World', exists=True)) self.assertEqual(cmds.getAttr('World.USD_ATTR_model_cardGeometry'), UsdGeom.Tokens.fromTexture) self.assertEqual( modelAPI.GetAttribute(UsdGeom.Tokens.modelCardGeometry).Get(), UsdGeom.Tokens.fromTexture) # model:cardTextureXPos self.assertTrue( cmds.attributeQuery('USD_ATTR_model_cardTextureXPos', node='World', exists=True)) self.assertEqual(cmds.getAttr('World.USD_ATTR_model_cardTextureXPos'), 'right.png') self.assertEqual( modelAPI.GetAttribute(UsdGeom.Tokens.modelCardTextureXPos).Get(), 'right.png')
def testImport_HiddenInstanceableKind(self): """ Tests that the adaptor mechanism can import hidden, instanceable, and kind metadata properly. """ cmds.file(new=True, force=True) usdFile = os.path.abspath('UsdAttrs.usda') cmds.usdImport(file=usdFile, shadingMode='none') # pCube1 and pCube2 have USD_kind. self.assertEqual(cmds.getAttr('pCube1.USD_kind'), 'potato') self.assertEqual(cmds.getAttr('pCube2.USD_kind'), 'bakedpotato') # pCube2, pCube4, and pCube5 have USD_hidden. pCube1 and pCube3 do not. self.assertTrue( cmds.attributeQuery('USD_hidden', node='pCube2', exists=True)) self.assertTrue( cmds.attributeQuery('USD_hidden', node='pCube4', exists=True)) self.assertTrue( cmds.attributeQuery('USD_hidden', node='pCube5', exists=True)) self.assertFalse( cmds.attributeQuery('USD_hidden', node='pCube1', exists=True)) self.assertFalse( cmds.attributeQuery('USD_hidden', node='pCube3', exists=True)) self.assertTrue(cmds.getAttr('pCube2.USD_hidden')) self.assertTrue(cmds.getAttr('pCube4.USD_hidden')) self.assertFalse(cmds.getAttr('pCube5.USD_hidden')) # pCube3 and pCube4 have USD_instanceable. self.assertTrue(cmds.getAttr('pCube3.USD_instanceable')) self.assertTrue(cmds.getAttr('pCube4.USD_instanceable'))
def test_SkelImport(self): cmds.file(new=True, force=True) path = os.path.join(self.inputPath, "UsdImportSkeleton", "skelCube.usda") cmds.usdImport(file=path, readAnimData=True, primPath="/Root", shadingMode=[ ["none", "default"], ]) stage = Usd.Stage.Open(path) skelCache = UsdSkel.Cache() bindingSitePrim = stage.GetPrimAtPath("/Root") self.assertTrue(bindingSitePrim.IsA(UsdSkel.Root)) if Usd.GetVersion() > (0, 20, 8): skelCache.Populate(UsdSkel.Root(bindingSitePrim), Usd.PrimDefaultPredicate) else: skelCache.Populate(UsdSkel.Root(bindingSitePrim)) skel = UsdSkel.Skeleton.Get(stage, "/Root/Skeleton") self.assertTrue(skel) skelQuery = skelCache.GetSkelQuery(skel) self.assertTrue(skelQuery) meshPrim = stage.GetPrimAtPath("/Root/Cube") self.assertTrue(meshPrim) skinningQuery = skelCache.GetSkinningQuery(meshPrim) self.assertTrue(skinningQuery) jointNames = [ name.split("/")[-1] for name in skelQuery.GetJointOrder() ] joints = [_GetDepNode(n) for n in jointNames] self.assertTrue(all(joints)) self._ValidateJointTransforms(skelQuery, joints) self._ValidateJointBindPoses(skelQuery, joints) self._ValidateBindPose("Skeleton_bindPose", skelQuery, joints) self._ValidateMeshTransform(meshPrim.GetName(), skinningQuery) self._ValidateSkinClusterRig(joints=joints, skinClusterName="skinCluster_{}".format( meshPrim.GetName()), groupPartsName="skinClusterGroupParts", groupIdName="skinClusterGroupId", bindPoseName="Skeleton_bindPose", meshName=meshPrim.GetName(), usdSkelQuery=skelQuery, usdSkinningQuery=skinningQuery)
def testImport_HiddenInstanceableKind(self): """ Tests that the adaptor mechanism can import hidden, instanceable, and kind metadata properly. """ cmds.file(new=True, force=True) cmds.usdImport(file=self.inputUsdFile, shadingMode='none') # pCube1 and pCube2 have USD_kind. self.assertEqual(cmds.getAttr('pCube1.USD_kind'), 'potato') self.assertEqual(cmds.getAttr('pCube2.USD_kind'), 'bakedpotato') # pCube2, pCube4, and pCube5 have USD_hidden. pCube1 and pCube3 do not. self.assertTrue( cmds.attributeQuery('USD_hidden', node='pCube2', exists=True)) self.assertTrue( cmds.attributeQuery('USD_hidden', node='pCube4', exists=True)) self.assertTrue( cmds.attributeQuery('USD_hidden', node='pCube5', exists=True)) self.assertFalse( cmds.attributeQuery('USD_hidden', node='pCube1', exists=True)) self.assertFalse( cmds.attributeQuery('USD_hidden', node='pCube3', exists=True)) self.assertTrue(cmds.getAttr('pCube2.USD_hidden')) self.assertTrue(cmds.getAttr('pCube4.USD_hidden')) self.assertFalse(cmds.getAttr('pCube5.USD_hidden')) # pCube3 and pCube4 have USD_instanceable. self.assertTrue(cmds.getAttr('pCube3.USD_instanceable')) self.assertTrue(cmds.getAttr('pCube4.USD_instanceable'))
def testReexport(self): cmds.usdImport(file=self.USD_FILE, primPath='/') cmds.usdExport(file=self.USD_FILE_OUT) stage = Usd.Stage.Open(self.USD_FILE_OUT) self.assertTrue(stage) self.assertTrue(stage.GetPrimAtPath('/A')) self.assertEqual(stage.GetPrimAtPath('/A').GetTypeName(), 'Xform') self.assertTrue(stage.GetPrimAtPath('/A/A_1')) self.assertEqual(stage.GetPrimAtPath('/A/A_1').GetTypeName(), '') self.assertTrue(stage.GetPrimAtPath('/A/A_1/A_1_I')) self.assertEqual(stage.GetPrimAtPath('/A/A_1/A_1_I').GetTypeName(), '') self.assertTrue(stage.GetPrimAtPath('/A/A_1/A_1_II')) self.assertEqual(stage.GetPrimAtPath('/A/A_1/A_1_II').GetTypeName(), '') # Originally Cube, but not on re-export! self.assertTrue(stage.GetPrimAtPath('/A/A_1/A_1_III')) self.assertEqual(stage.GetPrimAtPath('/A/A_1/A_1_III').GetTypeName(), 'Scope') self.assertTrue(stage.GetPrimAtPath('/A/A_2')) self.assertEqual(stage.GetPrimAtPath('/A/A_2').GetTypeName(), 'Scope') self.assertTrue(stage.GetPrimAtPath('/B')) self.assertEqual(stage.GetPrimAtPath('/B').GetTypeName(), '') self.assertTrue(stage.GetPrimAtPath('/B/B_1')) self.assertEqual(stage.GetPrimAtPath('/B/B_1').GetTypeName(), 'Xform')
def testImport_GeomModelAPI(self): """Tests importing UsdGeomModelAPI attributes.""" cmds.file(new=True, force=True) cmds.usdImport(file=self.inputUsdFile, shadingMode='none', apiSchema=['GeomModelAPI']) worldProxy = mayaUsdLib.Adaptor('World') modelAPI = worldProxy.GetSchema(UsdGeom.ModelAPI) # model:cardGeometry self.assertTrue( cmds.attributeQuery('USD_ATTR_model_cardGeometry', node='World', exists=True)) self.assertEqual(cmds.getAttr('World.USD_ATTR_model_cardGeometry'), UsdGeom.Tokens.fromTexture) self.assertEqual( modelAPI.GetAttribute(UsdGeom.Tokens.modelCardGeometry).Get(), UsdGeom.Tokens.fromTexture) # model:cardTextureXPos self.assertTrue( cmds.attributeQuery('USD_ATTR_model_cardTextureXPos', node='World', exists=True)) self.assertEqual(cmds.getAttr('World.USD_ATTR_model_cardTextureXPos'), 'right.png') self.assertEqual( modelAPI.GetAttribute(UsdGeom.Tokens.modelCardTextureXPos).Get(), 'right.png')
def setUpClass(cls): inputPath = fixturesUtils.readOnlySetUpClass(__file__) usdFile = os.path.join(inputPath, "UsdImportMeshTest", "Mesh.usda") cmds.usdImport(file=usdFile, shadingMode=[ ['none', 'default'], ])
def testImport_TypeName(self): """Tests import with metadata=typeName manually specified.""" cmds.file(new=True, force=True) cmds.usdImport(file=self.inputUsdFile, shadingMode=[ ["none", "default"], ], metadata=["typeName"]) # typeName metadata should come through. self.assertTrue( cmds.attributeQuery('USD_typeName', node='pCube1', exists=True)) self.assertEqual(cmds.getAttr('pCube1.USD_typeName'), 'Mesh') self.assertTrue( cmds.attributeQuery('USD_typeName', node='World', exists=True)) self.assertEqual(cmds.getAttr('World.USD_typeName'), 'Xform') # No USD_kind, hidden, or instanceable. self.assertFalse( cmds.attributeQuery('USD_kind', node='pCube1', exists=True)) self.assertFalse( cmds.attributeQuery('USD_hidden', node='pCube2', exists=True)) self.assertFalse( cmds.attributeQuery('USD_instanceable', node='pCube3', exists=True))
def testReexportScope(self): cmds.usdImport(file=self.USD_FILE, primPath='/') cmds.usdExport(file=self.USD_FILE_OUT) stage = Usd.Stage.Open(self.USD_FILE_OUT) self.assertTrue(stage) self.assertTrue(stage.GetPrimAtPath('/A')) self.assertEqual(stage.GetPrimAtPath('/A').GetTypeName(), 'Xform') self.assertTrue(stage.GetPrimAtPath('/A/A_1')) self.assertEqual(stage.GetPrimAtPath('/A/A_1').GetTypeName(), 'Scope') self.assertTrue(stage.GetPrimAtPath('/A/A_1/A_1_I')) self.assertEqual(stage.GetPrimAtPath('/A/A_1/A_1_I').GetTypeName(), 'Mesh') self.assertTrue(stage.GetPrimAtPath('/A/A_1/A_1_II')) self.assertEqual(stage.GetPrimAtPath('/A/A_1/A_1_II').GetTypeName(), 'Camera') self.assertTrue(stage.GetPrimAtPath('/A/A_1/A_1_III')) self.assertEqual(stage.GetPrimAtPath('/A/A_1/A_1_III').GetTypeName(), 'Scope') self.assertTrue(stage.GetPrimAtPath('/A/A_2')) self.assertEqual(stage.GetPrimAtPath('/A/A_2').GetTypeName(), 'Scope') self.assertTrue(stage.GetPrimAtPath('/B')) self.assertEqual(stage.GetPrimAtPath('/B').GetTypeName(), 'Scope') self.assertTrue(stage.GetPrimAtPath('/B/B_1')) self.assertEqual(stage.GetPrimAtPath('/B/B_1').GetTypeName(), 'Xform')
def testExport(self): """ Tests that the adaptor mechanism can export USD_hidden, USD_instanceable, and USD_kind attributes by setting the correct metadata in the output USD file. """ cmds.file(new=True, force=True) usdFile = os.path.abspath('UsdAttrs.usda') cmds.usdImport(file=usdFile, shadingMode='none') newUsdFilePath = os.path.abspath('UsdAttrsNew.usda') cmds.usdExport(file=newUsdFilePath, shadingMode='none') newUsdStage = Usd.Stage.Open(newUsdFilePath) # pCube1 and pCube2 have USD_kind. prim1 = newUsdStage.GetPrimAtPath('/World/pCube1') self.assertEqual(Usd.ModelAPI(prim1).GetKind(), 'potato') prim2 = newUsdStage.GetPrimAtPath('/World/pCube2') self.assertEqual(Usd.ModelAPI(prim2).GetKind(), 'bakedpotato') # pCube2, pCube4, and pCube5 have USD_hidden. pCube1 and pCube3 do not. self.assertTrue(newUsdStage.GetPrimAtPath('/World/pCube2').HasAuthoredHidden()) self.assertTrue(newUsdStage.GetPrimAtPath('/World/pCube4').HasAuthoredHidden()) self.assertTrue(newUsdStage.GetPrimAtPath('/World/pCube5').HasAuthoredHidden()) self.assertFalse(newUsdStage.GetPrimAtPath('/World/pCube1').HasAuthoredHidden()) self.assertFalse(newUsdStage.GetPrimAtPath('/World/pCube3').HasAuthoredHidden()) self.assertTrue(newUsdStage.GetPrimAtPath('/World/pCube2').IsHidden()) self.assertTrue(newUsdStage.GetPrimAtPath('/World/pCube4').IsHidden()) self.assertFalse(newUsdStage.GetPrimAtPath('/World/pCube5').IsHidden()) # pCube3 and pCube4 have USD_instanceable. self.assertTrue(newUsdStage.GetPrimAtPath('/World/pCube3').IsInstanceable()) self.assertTrue(newUsdStage.GetPrimAtPath('/World/pCube4').IsInstanceable())
def testImportInverseXformOpsOnly(self): """ Tests that importing a USD cube mesh that has XformOps on it all tagged as inverse ops results in the correct transform when imported into Maya. """ usdFile = os.path.join(self.inputPath, "UsdImportXformsTest", "UsdImportXformsTest.usda") cmds.usdImport(file=usdFile, shadingMode='none') mayaTransform = self._GetMayaTransform('InverseOpsOnlyCube') transformationMatrix = mayaTransform.transformation() expectedTranslation = [-1.0, -2.0, -3.0] actualTranslation = list( transformationMatrix.translation(OM.MSpace.kTransform)) self.assertTrue( Gf.IsClose(expectedTranslation, actualTranslation, self.EPSILON)) expectedRotation = [0.0, 0.0, Gf.DegreesToRadians(-45.0)] actualRotation = list(transformationMatrix.rotation()) self.assertTrue( Gf.IsClose(expectedRotation, actualRotation, self.EPSILON)) expectedScale = [2.0, 2.0, 2.0] actualScale = list(transformationMatrix.scale(OM.MSpace.kTransform)) self.assertTrue( Gf.IsClose(expectedScale, actualScale, self.EPSILON))
def testExport_GeomModelAPI_MotionAPI(self): """Tests export with both the GeomModelAPI and MotionAPI.""" cmds.file(new=True, force=True) cmds.usdImport(file=self.inputUsdFile, shadingMode=[ ["none", "default"], ], apiSchema=['GeomModelAPI', 'MotionAPI']) newUsdFilePath = os.path.abspath('UsdAttrsNew_TwoAPIs.usda') # usdExport used to export all API schemas found as dynamic attributes. We now # require the list to be explicit, mirroring the way usdImport works. cmds.usdExport(file=newUsdFilePath, shadingMode='none', apiSchema=['GeomModelAPI', 'MotionAPI']) newUsdStage = Usd.Stage.Open(newUsdFilePath) world = newUsdStage.GetPrimAtPath('/World') self.assertEqual(world.GetAppliedSchemas(), ['MotionAPI', 'GeomModelAPI']) geomModelAPI = UsdGeom.ModelAPI(world) self.assertEqual(geomModelAPI.GetModelCardTextureXPosAttr().Get(), 'right.png') motionAPI = UsdGeom.MotionAPI(world) self.assertAlmostEqual(motionAPI.GetVelocityScaleAttr().Get(), 4.2, places=6)
def testReexport(self): cmds.usdImport(file=self.USD_FILE, primPath='/') cmds.usdExport(file=self.USD_FILE_OUT) stage = Usd.Stage.Open(self.USD_FILE_OUT) self.assertTrue(stage) self.assertTrue(stage.GetPrimAtPath('/A')) self.assertEqual(stage.GetPrimAtPath('/A').GetTypeName(), 'Xform') self.assertTrue(stage.GetPrimAtPath('/A/A_1')) self.assertEqual(stage.GetPrimAtPath('/A/A_1').GetTypeName(), '') self.assertTrue(stage.GetPrimAtPath('/A/A_1/A_1_I')) self.assertEqual(stage.GetPrimAtPath('/A/A_1/A_1_I').GetTypeName(), '') self.assertTrue(stage.GetPrimAtPath('/A/A_1/A_1_II')) self.assertEqual( stage.GetPrimAtPath('/A/A_1/A_1_II').GetTypeName(), '') # Originally Cube, but not on re-export! self.assertTrue(stage.GetPrimAtPath('/A/A_1/A_1_III')) self.assertEqual( stage.GetPrimAtPath('/A/A_1/A_1_III').GetTypeName(), 'Scope') self.assertTrue(stage.GetPrimAtPath('/A/A_2')) self.assertEqual(stage.GetPrimAtPath('/A/A_2').GetTypeName(), 'Scope') self.assertTrue(stage.GetPrimAtPath('/B')) self.assertEqual(stage.GetPrimAtPath('/B').GetTypeName(), '') self.assertTrue(stage.GetPrimAtPath('/B/B_1')) self.assertEqual(stage.GetPrimAtPath('/B/B_1').GetTypeName(), 'Xform')
def testImport_HiddenInstanceable(self): """Tests import with only hidden, instanceable metadata and not kind.""" cmds.file(new=True, force=True) cmds.usdImport(file=self.inputUsdFile, shadingMode=[ ["none", "default"], ], metadata=['hidden', 'instanceable']) # pCube1 and pCube2 have USD_kind, but that shouldn't be imported. self.assertFalse( cmds.attributeQuery('USD_kind', node='pCube1', exists=True)) self.assertFalse( cmds.attributeQuery('USD_kind', node='pCube2', exists=True)) # hidden should be imported. self.assertTrue( cmds.attributeQuery('USD_hidden', node='pCube2', exists=True)) self.assertTrue(cmds.getAttr('pCube2.USD_hidden')) # instanceable should be imported. self.assertTrue( cmds.attributeQuery('USD_instanceable', node='pCube3', exists=True)) self.assertTrue(cmds.getAttr('pCube3.USD_instanceable'))
def testPivot(self): """ Tests that pivotPosition attribute doesn't interfere with the matrix that we get in maya when importing a usd file. """ def _usdToMayaPath(usdPath): return str(usdPath).replace('/', '|') from maya import cmds cmds.loadPlugin('pxrUsd') usdFile = './pivotTests.usda' from pxr import Usd, UsdGeom stage = Usd.Stage.Open(usdFile) xformCache = UsdGeom.XformCache() cmds.usdImport(file=os.path.abspath(usdFile), primPath='/World') usdPaths = [ '/World/anim/chars/SomeCharacter/Geom/Face/Eyes/LEye', '/World/anim/chars/SomeCharacter/Geom/Face/Eyes/LEye/Sclera_sbdv', '/World/anim/chars/SomeCharacter/Geom/Face/Eyes/REye/Sclera_sbdv', '/World/anim/chars/SomeCharacter/Geom/Hair/HairStandin/Hair/Hair_sbdv', '/World/anim/chars/SomeCharacter/Geom/Hair/HairStandin/Hair/HairFrontPiece_sbdv', ] for usdPath in usdPaths: usdMatrix = xformCache.GetLocalToWorldTransform(stage.GetPrimAtPath(usdPath)) mayaPath = _usdToMayaPath(usdPath) mayaMatrix = Gf.Matrix4d(*cmds.xform(mayaPath, query=True, matrix=True, worldSpace=True)) print 'testing matrix at', usdPath self.assertTrue(Gf.IsClose( usdMatrix.ExtractTranslation(), mayaMatrix.ExtractTranslation(), self.EPSILON))
def testReexportScope(self): cmds.usdImport(file=self.USD_FILE, primPath='/') cmds.usdExport(file=self.USD_FILE_OUT) stage = Usd.Stage.Open(self.USD_FILE_OUT) self.assertTrue(stage) self.assertTrue(stage.GetPrimAtPath('/A')) self.assertEqual(stage.GetPrimAtPath('/A').GetTypeName(), 'Xform') self.assertTrue(stage.GetPrimAtPath('/A/A_1')) self.assertEqual(stage.GetPrimAtPath('/A/A_1').GetTypeName(), 'Scope') self.assertTrue(stage.GetPrimAtPath('/A/A_1/A_1_I')) self.assertEqual( stage.GetPrimAtPath('/A/A_1/A_1_I').GetTypeName(), 'Mesh') self.assertTrue(stage.GetPrimAtPath('/A/A_1/A_1_II')) self.assertEqual( stage.GetPrimAtPath('/A/A_1/A_1_II').GetTypeName(), 'Camera') self.assertTrue(stage.GetPrimAtPath('/A/A_1/A_1_III')) self.assertEqual( stage.GetPrimAtPath('/A/A_1/A_1_III').GetTypeName(), 'Scope') self.assertTrue(stage.GetPrimAtPath('/A/A_2')) self.assertEqual(stage.GetPrimAtPath('/A/A_2').GetTypeName(), 'Scope') self.assertTrue(stage.GetPrimAtPath('/B')) self.assertEqual(stage.GetPrimAtPath('/B').GetTypeName(), 'Scope') self.assertTrue(stage.GetPrimAtPath('/B/B_1')) self.assertEqual(stage.GetPrimAtPath('/B/B_1').GetTypeName(), 'Xform')
def setUpClass(cls): inputPath = fixturesUtils.readOnlySetUpClass(__file__) usdFile = os.path.join(inputPath, "UsdImportColorSetsTest", "UsdImportColorSetsTest.usda") cmds.usdImport(file=usdFile, shadingMode='none', excludePrimvar='ExcludeMe')
def _ValidateRoundtrip(self): cmds.file(new=True, force=True) # Import from USD. cmds.usdImport(file=self._usdFilePath, readAnimData=True, primPath='/') self._ValidateMayaDistantLight() self._ValidateMayaSpotLight() self._ValidateMayaPointLight() self._ValidateMayaAreaLight()
def setUpClass(cls): cls.inputPath = fixturesUtils.setUpClass(__file__) usdFile = os.path.join(cls.inputPath, 'UsdMayaAdaptorGeomTest', 'UsdAttrs.usda') cmds.usdImport(file=usdFile, shadingMode=[ ["none", "default"], ])
def setUpClass(cls): inputPath = fixturesUtils.readOnlySetUpClass(__file__) cmds.file(new=True, force=True) # Import from USD. usdFilePath = os.path.join(inputPath, "UsdImportShadingModeDisplayColor", "RedCube.usda") cmds.usdImport(file=usdFilePath, shadingMode=[['displayColor', 'default'], ]) cls._stage = Usd.Stage.Open(usdFilePath)
def setUpClass(cls): cls.asFloat2 = mayaUsdLib.ReadUtil.ReadFloat2AsUV() cls.inputPath = fixturesUtils.readOnlySetUpClass(__file__) if cls.asFloat2: usdFile = os.path.join(cls.inputPath, "UsdImportUVSetsFloatTest", "UsdImportUVSetsTest_Float.usda") else: usdFile = os.path.join(cls.inputPath, "UsdImportUVSetsTest", "UsdImportUVSetsTest.usda") cmds.usdImport(file=usdFile, shadingMode='none')
def setUpClass(cls): standalone.initialize('usd') cmds.file(new=True, force=True) # Import the USD file. usdFilePath = os.path.abspath('UsdImportCameraTest.usda') cmds.loadPlugin('pxrUsd') cmds.usdImport(file=usdFilePath, readAnimData=True) cls._stage = Usd.Stage.Open(usdFilePath)
def setUpClass(cls): standalone.initialize('usd') cmds.loadPlugin('pxrUsd') usdFile = "" if UsdMaya.ReadUtil.ReadFloat2AsUV(): usdFile = os.path.abspath('UsdImportUVSetsTest_Float.usda') else: usdFile = os.path.abspath('UsdImportUVSetsTest.usda') cmds.usdImport(file=usdFile, shadingMode='none')
def setUpClass(cls): inputPath = fixturesUtils.readOnlySetUpClass(__file__) cmds.namespace(add='unique_namespace_1') usdFile = os.path.join(inputPath, "UsdImportMayaReferenceTest", "MayaReference.usda") cmds.usdImport(file=usdFile, shadingMode=[ ['none', 'default'], ])
def setUpClass(cls): standalone.initialize('usd') cmds.file(new=True, force=True) # Import from USD. usdFilePath = os.path.abspath('MarbleCube.usda') cmds.loadPlugin('pxrUsd') cmds.usdImport(file=usdFilePath, shadingMode='pxrRis') cls._stage = Usd.Stage.Open(usdFilePath)
def setUpClass(cls): inputPath = fixturesUtils.readOnlySetUpClass(__file__) cmds.file(new=True, force=True) # Import the USD file. usdFilePath = os.path.join(inputPath, "UsdImportCameraTest", "UsdImportCameraTest.usda") cmds.usdImport(file=usdFilePath, readAnimData=True) cls._stage = Usd.Stage.Open(usdFilePath)
def setUpClass(cls): inputPath = fixturesUtils.readOnlySetUpClass(__file__) cmds.file(new=True, force=True) # Import from USD. usdFilePath = os.path.join(inputPath, "UsdImportShadingModePxrRis", "MarbleCube.usda") cmds.usdImport(file=usdFilePath, shadingMode='pxrRis') cls._stage = Usd.Stage.Open(usdFilePath)
def setUpClass(cls): inputPath = fixturesUtils.readOnlySetUpClass(__file__) cmds.file(new=True, force=True) cmds.loadPlugin('RenderMan_for_Maya', quiet=True) # Import from USD. usdFilePath = os.path.join(inputPath, "UsdImportRfMLightTest", "RfMLightsTest.usda") cmds.usdImport(file=usdFilePath, shadingMode=[['pxrRis', 'default'], ], readAnimData=True) cls._stage = Usd.Stage.Open(usdFilePath)
def setUpClass(cls): standalone.initialize('usd') cmds.file(new=True, force=True) cmds.loadPlugin('RenderMan_for_Maya', quiet=True) # Import from USD. usdFilePath = os.path.abspath('RfMLightsTest.usda') cmds.loadPlugin('pxrUsd') cmds.usdImport(file=usdFilePath, shadingMode='pxrRis') cls._stage = Usd.Stage.Open(usdFilePath)
def _LoadUsdWithRange(self, start=None, end=None): # Import the USD file. usdFilePath = os.path.abspath('MovingCube.usda') cmds.loadPlugin('pxrUsd') if start is not None and end is not None: cmds.usdImport(file=usdFilePath, readAnimData=True, frameRange=(start, end)) else: cmds.usdImport(file=usdFilePath, readAnimData=True) self.stage = Usd.Stage.Open(usdFilePath) self.assertTrue(self.stage)
def _LoadUsdWithRange(self, start=None, end=None): # Import the USD file. usdFilePath = os.path.join(self.inputPath, "UsdImportFrameRangeTest", "MovingCube.usda") if start is not None and end is not None: cmds.usdImport(file=usdFilePath, readAnimData=True, frameRange=(start, end)) else: cmds.usdImport(file=usdFilePath, readAnimData=True) self.stage = Usd.Stage.Open(usdFilePath) self.assertTrue(self.stage)
def test_SkelImport(self): cmds.file(new=True, force=True) path = os.path.abspath("skelCube.usda") cmds.usdImport(file=path, readAnimData=True, primPath="/Root", assemblyRep="Import", shadingMode="none") stage = Usd.Stage.Open(path) skelCache = UsdSkel.Cache() bindingSitePrim = stage.GetPrimAtPath("/Root") self.assertTrue(bindingSitePrim.IsA(UsdSkel.Root)) skelCache.Populate(UsdSkel.Root(bindingSitePrim)) skel = UsdSkel.Skeleton.Get(stage, "/Root/Skeleton") self.assertTrue(skel) skelQuery = skelCache.GetSkelQuery(skel) self.assertTrue(skelQuery) meshPrim = stage.GetPrimAtPath("/Root/Cube") self.assertTrue(meshPrim) skinningQuery = skelCache.GetSkinningQuery(meshPrim) self.assertTrue(skinningQuery) jointNames = [name.split("/")[-1] for name in skelQuery.GetJointOrder()] joints = [_GetDepNode(n) for n in jointNames] self.assertTrue(all(joints)) self._ValidateJointTransforms(skelQuery, joints) self._ValidateJointBindPoses(skelQuery, joints) self._ValidateBindPose("Skeleton_bindPose", skelQuery, joints) self._ValidateMeshTransform(meshPrim.GetName(), skinningQuery) self._ValidateSkinClusterRig( joints=joints, skinClusterName="skinCluster_{}".format(meshPrim.GetName()), groupPartsName="skinClusterGroupParts", groupIdName="skinClusterGroupId", bindPoseName="Skeleton_bindPose", meshName=meshPrim.GetName(), usdSkelQuery=skelQuery, usdSkinningQuery=skinningQuery)
def testImportModifyAndExportCubeModel(self): """ Tests that re-exporting over a previously imported USD file works, and that changes are reflected in the new version of the file. """ self._ValidateUsdBeforeExport() cmds.usdImport(file=self.USD_FILE, shadingMode='none') self._ModifyMayaScene() cmds.usdExport(mergeTransformAndShape=True, file=self.USD_FILE, shadingMode='none') self._ValidateUsdAfterExport()
def testExport_GeomModelAPI(self): """Tests export with the GeomModelAPI.""" cmds.file(new=True, force=True) usdFile = os.path.abspath('UsdAttrs.usda') cmds.usdImport(file=usdFile, shadingMode='none', apiSchema=['GeomModelAPI']) newUsdFilePath = os.path.abspath('UsdAttrsNew_GeomModelAPI.usda') cmds.usdExport(file=newUsdFilePath, shadingMode='none') newUsdStage = Usd.Stage.Open(newUsdFilePath) world = newUsdStage.GetPrimAtPath('/World') self.assertEqual(world.GetAppliedSchemas(), ['GeomModelAPI']) geomModelAPI = UsdGeom.ModelAPI(world) self.assertEqual(geomModelAPI.GetModelCardTextureXPosAttr().Get(), 'right.png')
def testImport(self): cmds.usdImport(file=self.USD_FILE, primPath='/') dagObjects = cmds.ls(long=True, dag=True) self.assertIn('|A', dagObjects) self.assertEqual(cmds.nodeType('|A'), 'transform') self.assertFalse(cmds.getAttr('|A.tx', lock=True)) self.assertIn('|A|A_1', dagObjects) self.assertEqual(cmds.nodeType('|A|A_1'), 'transform') self.assertEqual(cmds.getAttr('|A|A_1.USD_typeName'), '') self.assertTrue(cmds.getAttr('|A|A_1.tx', lock=True)) self.assertIn('|A|A_1|A_1_I', dagObjects) self.assertEqual(cmds.nodeType('|A|A_1|A_1_I'), 'transform') self.assertEqual(cmds.getAttr('|A|A_1|A_1_I.USD_typeName'), '') self.assertTrue(cmds.getAttr('|A|A_1|A_1_I.tx', lock=True)) # This one is special: unknown types get a Maya "note" on import for # aid debugging import problems. (Note that we don't have a Cube # importer.) self.assertIn('|A|A_1|A_1_II', dagObjects) self.assertEqual(cmds.nodeType('|A|A_1|A_1_II'), 'transform') self.assertEqual(cmds.getAttr('|A|A_1|A_1_II.USD_typeName'), '') self.assertIn('Cube', cmds.getAttr('|A|A_1|A_1_II.notes')) self.assertTrue(cmds.getAttr('|A|A_1|A_1_II.tx', lock=True)) self.assertIn('|A|A_1|A_1_III', dagObjects) self.assertEqual(cmds.nodeType('|A|A_1|A_1_III'), 'transform') self.assertEqual(cmds.getAttr('|A|A_1|A_1_III.USD_typeName'), 'Scope') self.assertTrue(cmds.getAttr('|A|A_1|A_1_III.tx', lock=True)) self.assertIn('|A|A_2', dagObjects) self.assertEqual(cmds.nodeType('|A|A_2'), 'transform') self.assertEqual(cmds.getAttr('|A|A_2.USD_typeName'), 'Scope') self.assertTrue(cmds.getAttr('|A|A_2.tx', lock=True)) self.assertIn('|B', dagObjects) self.assertEqual(cmds.nodeType('|B'), 'transform') self.assertEqual(cmds.getAttr('|B.USD_typeName'), '') self.assertTrue(cmds.getAttr('|B.tx', lock=True)) self.assertIn('|B|B_1', dagObjects) self.assertEqual(cmds.nodeType('|B|B_1'), 'transform') self.assertFalse(cmds.getAttr('|B|B_1.tx', lock=True))
def testUsdImport(self): """ This tests that executing a usdImport with variants specified causes those variant selections to be made in a session layer and not affect other open stages. """ usdFile = os.path.abspath('Cubes.usda') # Open the asset USD file and make sure the default variant is what we # expect it to be. stage = Usd.Stage.Open(usdFile) self.assertTrue(stage) modelPrimPath = '/Cubes' modelPrim = stage.GetPrimAtPath(modelPrimPath) self.assertTrue(modelPrim) variantSet = modelPrim.GetVariantSet('modelingVariant') variantSelection = variantSet.GetVariantSelection() # This is the default variant. self.assertEqual(variantSelection, 'OneCube') # Now do a usdImport of a different variant in a clean Maya scene. cmds.file(new=True, force=True) cmds.loadPlugin('pxrUsd') variants = [('modelingVariant', 'ThreeCubes')] cmds.usdImport(file=usdFile, primPath=modelPrimPath, variant=variants) expectedMayaCubeNodesSet = set([ '|Cubes|Geom|CubeOne', '|Cubes|Geom|CubeTwo', '|Cubes|Geom|CubeThree']) mayaCubeNodesSet = set(cmds.ls('|Cubes|Geom|Cube*', long=True)) self.assertEqual(expectedMayaCubeNodesSet, mayaCubeNodesSet) # The import should have made the variant selections in a session layer, # so make sure the selection in our open USD stage was not changed. variantSet = modelPrim.GetVariantSet('modelingVariant') variantSelection = variantSet.GetVariantSelection() self.assertEqual(variantSelection, 'OneCube')
def testImportXformsRotateAxis(self): """ Tests that importing xforms that have a rotateAxis with rotate order other than just XYZ still imports correctly """ usdFile = os.path.abspath('UsdImportXformsTestRotateAxis.usda') cmds.usdImport(file=usdFile, shadingMode='none') expectedRotates = { 'X': (60, 0, 0), 'Y': (0, 60, 0), 'Z': (0, 0, 60), 'XYZ': (-120, 60, 0), 'YZX': (-106.1021138, 25.6589063, 56.3099325), 'ZXY': (120, -60, 0), 'XZY': (-120, -60, 0), 'YXZ': (106.1021138, 25.6589063, -56.3099325), 'ZYX': (-106.1021138, -25.6589063, -56.3099325), } expectedScale = (.5, .5, .5) expectedTranslation = (1.0, 2.0, 3.0) for rotOrderName, expectedRotation in expectedRotates.iteritems(): mayaTransform = self._GetMayaTransform(rotOrderName) transformationMatrix = mayaTransform.transformation() actualTranslation = list( transformationMatrix.translation(OM.MSpace.kTransform)) self.assertTrue( Gf.IsClose(expectedTranslation, actualTranslation, self.EPSILON)) expectedRotation = [Gf.DegreesToRadians(x) for x in expectedRotation] actualRotation = transformationMatrix.rotationOrientation().asEulerRotation() actualRotation = list(actualRotation) #print rotOrderName, actualRotation self.assertTrue( Gf.IsClose(expectedRotation, actualRotation, self.EPSILON)) actualScale = list(transformationMatrix.scale(OM.MSpace.kTransform)) self.assertTrue( Gf.IsClose(expectedScale, actualScale, self.EPSILON))
def testImport_TypeName(self): """Tests import with metadata=typeName manually specified.""" cmds.file(new=True, force=True) usdFile = os.path.abspath('UsdAttrs.usda') cmds.usdImport(file=usdFile, shadingMode='none', metadata=["typeName"]) # typeName metadata should come through. self.assertTrue( cmds.attributeQuery('USD_typeName', node='pCube1', exists=True)) self.assertEqual(cmds.getAttr('pCube1.USD_typeName'), 'Mesh') self.assertTrue( cmds.attributeQuery('USD_typeName', node='World', exists=True)) self.assertEqual(cmds.getAttr('World.USD_typeName'), 'Xform') # No USD_kind, hidden, or instanceable. self.assertFalse( cmds.attributeQuery('USD_kind', node='pCube1', exists=True)) self.assertFalse( cmds.attributeQuery('USD_hidden', node='pCube2', exists=True)) self.assertFalse( cmds.attributeQuery('USD_instanceable', node='pCube3', exists=True))
def testImportScope(self): cmds.usdImport(file=self.USD_FILE, primPath='/') dagObjects = cmds.ls(long=True, dag=True) self.assertIn('|A', dagObjects) self.assertEqual(cmds.nodeType('|A'), 'transform') self.assertFalse(cmds.getAttr('|A.tx', lock=True)) self.assertIn('|A|A_1', dagObjects) self.assertEqual(cmds.nodeType('|A|A_1'), 'transform') self.assertEqual(cmds.getAttr('|A|A_1.USD_typeName'), 'Scope') self.assertTrue(cmds.getAttr('|A|A_1.tx', lock=True)) self.assertIn('|A|A_1|A_1_I', dagObjects) self.assertEqual(cmds.nodeType('|A|A_1|A_1_I'), 'transform') self.assertFalse(cmds.getAttr('|A|A_1|A_1_I.tx', lock=True)) self.assertIn('|A|A_1|A_1_II', dagObjects) self.assertEqual(cmds.nodeType('|A|A_1|A_1_II'), 'transform') self.assertFalse(cmds.getAttr('|A|A_1|A_1_II.tx', lock=True)) self.assertIn('|A|A_1|A_1_III', dagObjects) self.assertEqual(cmds.nodeType('|A|A_1|A_1_III'), 'transform') self.assertEqual(cmds.getAttr('|A|A_1|A_1_III.USD_typeName'), 'Scope') self.assertTrue(cmds.getAttr('|A|A_1|A_1_III.tx', lock=True)) self.assertIn('|A|A_2', dagObjects) self.assertEqual(cmds.nodeType('|A|A_2'), 'transform') self.assertEqual(cmds.getAttr('|A|A_2.USD_typeName'), 'Scope') self.assertTrue(cmds.getAttr('|A|A_2.tx', lock=True)) self.assertIn('|B', dagObjects) self.assertEqual(cmds.nodeType('|B'), 'transform') self.assertEqual(cmds.getAttr('|B.USD_typeName'), 'Scope') self.assertTrue(cmds.getAttr('|B.tx', lock=True)) self.assertIn('|B|B_1', dagObjects) self.assertEqual(cmds.nodeType('|B|B_1'), 'transform') self.assertFalse(cmds.getAttr('|B|B_1.tx', lock=True))
def testImport_HiddenInstanceable(self): """Tests import with only hidden, instanceable metadata and not kind.""" cmds.file(new=True, force=True) usdFile = os.path.abspath('UsdAttrs.usda') cmds.usdImport(file=usdFile, shadingMode='none', metadata=['hidden', 'instanceable']) # pCube1 and pCube2 have USD_kind, but that shouldn't be imported. self.assertFalse( cmds.attributeQuery('USD_kind', node='pCube1', exists=True)) self.assertFalse( cmds.attributeQuery('USD_kind', node='pCube2', exists=True)) # hidden should be imported. self.assertTrue( cmds.attributeQuery('USD_hidden', node='pCube2', exists=True)) self.assertTrue(cmds.getAttr('pCube2.USD_hidden')) # instanceable should be imported. self.assertTrue( cmds.attributeQuery('USD_instanceable', node='pCube3', exists=True)) self.assertTrue(cmds.getAttr('pCube3.USD_instanceable'))
def _ImportPrimPathFromSet(primPath=None): usdFile = os.path.abspath(testUsdImportAsAssemblies.SET_USD_FILE) if primPath: cmds.usdImport(file=usdFile, primPath=primPath) else: cmds.usdImport(file=usdFile)
def setUpClass(cls): standalone.initialize('usd') cmds.loadPlugin('pxrUsd') usdFile = os.path.abspath('UsdAttrs.usda') cmds.usdImport(file=usdFile, shadingMode='none')
def _ImportPrimPathFromSet(*args, **kwargs): usdFile = os.path.abspath(testUsdImportAsAssemblies.SET_USD_FILE) cmds.usdImport(file=usdFile, **kwargs)
def testImportMayaXformVariations(self): """ Tests that all combinations of the various maya xform pieces will import correctly """ # create a bunch of transforms with varying transform attrs set from random import Random import itertools import os import pprint ATTRS = { 'translate': (.01, 5), # we do rotates separately, so we can see "rotateY" and "rotateXYZ" ops 'rotateX': (.01, 359.99), 'rotateY': (.01, 359.99), 'rotateZ': (.01, 359.99), 'scale': (1.01, 2.0), 'shear': (1.01, 2.0), 'rotateOrder': (1, 5), # it seems that internally rotateAxis is stored as a quaternion... # so to ensure proper roundtripping, keep values 0 < x < 90 'rotateAxis': (.01, 89.99), 'rotatePivot': (.01, 5), 'scalePivot': (.01, 5), 'rotatePivotTranslate': (.01, 5), 'scalePivotTranslate': (.01, 5), } rand = Random(3) cmds.file(new=1, f=1) allNodes = [] allExpected = {} topPrim = cmds.createNode('transform', name='topPrim') # Iterate through all combinations of whether each attr in ATTRS is set or not for i, enabledArray in enumerate(itertools.product((False, True), repeat=len(ATTRS))): # name will be like: mayaXform_000111010001 node = 'mayaXform_{}'.format(''.join(str(int(x)) for x in enabledArray)) node = cmds.createNode('transform', name=node, parent=topPrim) attrVals = {} allNodes.append(node) allExpected[node] = attrVals for enabled, (attr, (valMin, valMax)) in itertools.izip(enabledArray, ATTRS.iteritems()): if not enabled: if attr in ('rotateOrder', 'rotateX', 'rotateY', 'rotateZ'): attrVals[attr] = 0 elif attr == 'scale': attrVals[attr] = (1, 1, 1) else: attrVals[attr] = (0, 0, 0) else: if attr == 'rotateOrder': # 1 - 5 because 0 (xyz) would correspond to "not enabled" val = rand.randint(1, 5) elif attr in ('rotateX', 'rotateY', 'rotateZ'): val = rand.uniform(valMin, valMax) else: val = (rand.uniform(valMin, valMax), rand.uniform(valMin, valMax), rand.uniform(valMin, valMax)) attrVals[attr] = val #node.setAttr(attr, val) if isinstance(val, tuple): cmds.setAttr("{}.{}".format(node, attr), *val) else: cmds.setAttr("{}.{}".format(node, attr), val) # Now write out a usd file with all our xforms... cmds.select(allNodes) usdPath = os.path.abspath('UsdImportMayaXformVariationsTest.usdc') cmds.usdExport(selection=1, file=usdPath) # Now import, and make sure it round-trips as expected cmds.file(new=1, f=1) cmds.usdImport(file=usdPath) for node, attrVals in allExpected.iteritems(): # if only one (or less) of the three rotates is non-zero, then # the rotate order doesn't matter... nonZeroRotates = [attrVals['rotate' + dir] != 0 for dir in 'XYZ'] skipRotateOrder = sum(int(x) for x in nonZeroRotates) <= 1 for attr, expectedVal in attrVals.iteritems(): if attr == 'rotateOrder' and skipRotateOrder: continue attrName = "{}.{}".format(node, attr) actualVal = cmds.getAttr(attrName) if not isinstance(expectedVal, tuple): expectedVal = (expectedVal,) actualVal = (actualVal,) else: # cmds.getAttr('persp.scale') returns [(0, 0, 0)]... weird actualVal = actualVal[0] for expected, actual in zip(expectedVal, actualVal): try: self.assertAlmostEqual(expected, actual, msg="{} - expected {}, got {} (diff: {}".format( attrName, expected, actual, abs(expected - actual)), delta=1e-4) except Exception: print "full failed xform:" pprint.pprint(attrVals) raise