Exemplo n.º 1
0
    def testAttributeAliases(self):
        """Tests behavior with the purpose/USD_purpose alias."""
        cmds.file(new=True, force=True)
        cmds.group(name="group1", empty=True)

        cmds.addAttr("group1", longName="USD_purpose", dataType="string")
        cmds.setAttr("group1.USD_purpose", "proxy", type="string")
        self.assertEqual(
            mayaUsdLib.Adaptor("group1").GetSchema(UsdGeom.Xform).GetAttribute(
                UsdGeom.Tokens.purpose).Get(), UsdGeom.Tokens.proxy)

        cmds.addAttr("group1", longName="USD_ATTR_purpose", dataType="string")
        cmds.setAttr("group1.USD_ATTR_purpose", "render", type="string")
        self.assertEqual(
            mayaUsdLib.Adaptor("group1").GetSchema(UsdGeom.Xform).GetAttribute(
                UsdGeom.Tokens.purpose).Get(), UsdGeom.Tokens.render)

        cmds.deleteAttr("group1.USD_purpose")
        self.assertEqual(
            mayaUsdLib.Adaptor("group1").GetSchema(UsdGeom.Xform).GetAttribute(
                UsdGeom.Tokens.purpose).Get(), UsdGeom.Tokens.render)

        cmds.deleteAttr("group1.USD_ATTR_purpose")
        self.assertIsNone(
            mayaUsdLib.Adaptor("group1").GetSchema(UsdGeom.Xform).GetAttribute(
                UsdGeom.Tokens.purpose).Get())

        mayaUsdLib.Adaptor("group1")\
                    .GetSchema(UsdGeom.Xform)\
                    .CreateAttribute(UsdGeom.Tokens.purpose)
        self.assertTrue(
            cmds.attributeQuery("USD_ATTR_purpose", node="group1",
                                exists=True))
Exemplo n.º 2
0
    def testAttributes(self):
        """Tests creating and removing schema attributes."""
        cmds.file(new=True, force=True)
        cmds.group(name="group1", empty=True)

        modelAPI = mayaUsdLib.Adaptor('group1').ApplySchema(UsdGeom.ModelAPI)
        xform = mayaUsdLib.Adaptor('group1').GetSchema(UsdGeom.Xform)

        # Schema attributes list versus authored attributes list.
        self.assertIn(UsdGeom.Tokens.modelCardTextureXPos,
                      modelAPI.GetAttributeNames())
        self.assertNotIn(UsdGeom.Tokens.modelCardTextureXPos,
                         modelAPI.GetAuthoredAttributeNames())
        self.assertIn(UsdGeom.Tokens.purpose, xform.GetAttributeNames())
        self.assertNotIn(UsdGeom.Tokens.purpose,
                         xform.GetAuthoredAttributeNames())

        # Unauthored API attribute.
        self.assertFalse(
            modelAPI.GetAttribute(UsdGeom.Tokens.modelCardTextureXPos))

        # Unauthored schema attribute.
        self.assertFalse(xform.GetAttribute(UsdGeom.Tokens.purpose))

        # Non-existent attribute.
        with self.assertRaises(Tf.ErrorException):
            modelAPI.GetAttribute("fakeAttr")

        # Create and set an API attribute.
        attr = modelAPI.CreateAttribute(UsdGeom.Tokens.modelCardTextureXPos)
        self.assertTrue(attr)
        self.assertTrue(attr.Set(Sdf.AssetPath("example.png")))

        attr = modelAPI.GetAttribute(UsdGeom.Tokens.modelCardTextureXPos)
        self.assertTrue(attr)
        self.assertEqual(attr.Get(), Sdf.AssetPath("example.png"))

        self.assertEqual(attr.GetAttributeDefinition().name,
                         "model:cardTextureXPos")
        self.assertEqual(modelAPI.GetAuthoredAttributeNames(),
                         [UsdGeom.Tokens.modelCardTextureXPos])

        # Existing attrs become invalid when the plug is removed.
        modelAPI.RemoveAttribute(UsdGeom.Tokens.modelCardTextureXPos)
        self.assertFalse(attr)

        # Should return None on invalid attr access.
        self.assertIsNone(attr.Get())

        # Create a typed schema attribute. It should be set to the fallback
        # initially.
        self.assertEqual(
            xform.CreateAttribute(UsdGeom.Tokens.purpose).Get(),
            UsdGeom.Tokens.default_)
Exemplo n.º 3
0
    def testUnapplySchema(self):
        """Tests unapplying schemas and effect on existing proxy objects."""
        cmds.file(new=True, force=True)
        cmds.group(name="group1", empty=True)

        proxy = mayaUsdLib.Adaptor('group1')
        self.assertEqual(proxy.GetAppliedSchemas(), [])

        proxy.ApplySchema(UsdGeom.ModelAPI)
        proxy.ApplySchema(UsdGeom.MotionAPI)
        self.assertEqual(proxy.GetAppliedSchemas(),
                         ["GeomModelAPI", "MotionAPI"])

        proxy.UnapplySchema(UsdGeom.ModelAPI)
        self.assertEqual(proxy.GetAppliedSchemas(), ["MotionAPI"])

        # Note that schema objects still remain alive after being
        # unapplied.
        modelAPI = proxy.GetSchema(UsdGeom.ModelAPI)
        self.assertTrue(modelAPI)

        # But they expire once the underlying Maya node is removed.
        cmds.delete("group1")
        self.assertFalse(modelAPI)
        self.assertFalse(proxy)
Exemplo n.º 4
0
    def testApplySchema(self):
        """Tests schema application."""
        cmds.file(new=True, force=True)
        cmds.group(name="group1", empty=True)

        proxy = mayaUsdLib.Adaptor('group1')
        self.assertTrue(proxy)
        self.assertEqual(proxy.GetAppliedSchemas(), [])

        modelAPI = proxy.ApplySchema(UsdGeom.ModelAPI)
        self.assertTrue(modelAPI)
        self.assertEqual(proxy.GetAppliedSchemas(), ["GeomModelAPI"])
        self.assertEqual(modelAPI.GetAuthoredAttributeNames(), [])

        motionAPI = proxy.ApplySchema(UsdGeom.MotionAPI)
        self.assertTrue(motionAPI)
        self.assertEqual(proxy.GetAppliedSchemas(),
                         ["GeomModelAPI", "MotionAPI"])
        self.assertEqual(motionAPI.GetAuthoredAttributeNames(), [])

        # No support currently for typed schemas.
        with self.assertRaises(Tf.ErrorException):
            proxy.ApplySchema(UsdGeom.Xformable)

        with self.assertRaises(Tf.ErrorException):
            proxy.ApplySchema(UsdGeom.Mesh)

        self.assertEqual(proxy.GetAppliedSchemas(),
                         ["GeomModelAPI", "MotionAPI"])
Exemplo n.º 5
0
    def testMetadata(self):
        """Tests setting and clearing metadata."""
        cmds.file(new=True, force=True)
        cmds.group(name="group1", empty=True)

        proxy = mayaUsdLib.Adaptor('group1')
        self.assertEqual(proxy.GetAllAuthoredMetadata(), {})
        self.assertIsNone(proxy.GetMetadata("instanceable"))

        proxy.SetMetadata("instanceable", True)
        self.assertEqual(proxy.GetMetadata("instanceable"), True)

        proxy.SetMetadata("kind", "awesomeKind")
        self.assertEqual(proxy.GetAllAuthoredMetadata(), {
            "instanceable": True,
            "kind": "awesomeKind"
        })

        # Unregistered key.
        with self.assertRaises(Tf.ErrorException):
            proxy.SetMetadata("fakeMetadata", True)

        with self.assertRaises(Tf.ErrorException):
            proxy.GetMetadata("otherFakeMetadata")

        proxy.ApplySchema(UsdGeom.ModelAPI)
        apiSchemas = proxy.GetMetadata("apiSchemas")
        self.assertEqual(apiSchemas.prependedItems, ["GeomModelAPI"])

        # Clear metadata.
        proxy.ClearMetadata("kind")
        self.assertIsNone(proxy.GetMetadata("kind"))
Exemplo n.º 6
0
    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')
Exemplo n.º 7
0
    def testUndoRedo(self):
        """Tests that adaptors work with undo/redo."""
        cmds.file(new=True, force=True)
        cmds.group(name="group1", empty=True)
        adaptor = mayaUsdLib.Adaptor("group1")
        self.assertEqual(adaptor.GetAppliedSchemas(), [])

        # Do a single operation, then undo, then redo.
        adaptor.ApplySchema(UsdGeom.ModelAPI)
        self.assertEqual(adaptor.GetAppliedSchemas(), ["GeomModelAPI"])
        cmds.undo()
        self.assertEqual(adaptor.GetAppliedSchemas(), [])
        cmds.redo()
        self.assertEqual(adaptor.GetAppliedSchemas(), ["GeomModelAPI"])

        # Do a compound operation, then undo, then redo.
        cmds.undoInfo(openChunk=True)
        adaptor.ApplySchema(UsdGeom.MotionAPI).CreateAttribute(
                UsdGeom.Tokens.motionVelocityScale).Set(0.42)
        self.assertEqual(adaptor.GetAppliedSchemas(),
                ["GeomModelAPI", "MotionAPI"])
        self.assertAlmostEqual(adaptor.GetSchema(UsdGeom.MotionAPI).GetAttribute(
                UsdGeom.Tokens.motionVelocityScale).Get(), 0.42)
        cmds.undoInfo(closeChunk=True)
        cmds.undo()
        self.assertEqual(adaptor.GetAppliedSchemas(), ["GeomModelAPI"])
        self.assertFalse(adaptor.GetSchema(UsdGeom.MotionAPI).GetAttribute(
                UsdGeom.Tokens.motionVelocityScale))
        self.assertIsNone(adaptor.GetSchema(UsdGeom.MotionAPI).GetAttribute(
                UsdGeom.Tokens.motionVelocityScale).Get())
        cmds.redo()
        self.assertEqual(adaptor.GetAppliedSchemas(),
                ["GeomModelAPI", "MotionAPI"])
        self.assertAlmostEqual(adaptor.GetSchema(UsdGeom.MotionAPI).GetAttribute(
                UsdGeom.Tokens.motionVelocityScale).Get(), 0.42)
Exemplo n.º 8
0
    def testMinimalAdaptation(self):
        """Test that we can adapt ShadowAPI to an existing light shape. This exercises the most
        basic callbacks exposed by a SchemaAPI adaptor:"""

        mayaUsdLib.SchemaApiAdaptor.Register(shadowApiAdaptorShape, "light",
                                             "ShadowAPI")

        lightShape1 = cmds.pointLight()
        cmds.setAttr(lightShape1 + ".shadowColor", 0.5, 0.25, 0)
        lightShape2 = cmds.pointLight()
        cubeXform, cubeShape = cmds.polyCube()

        # Wrong type: not adapted
        adaptor = mayaUsdLib.Adaptor(cubeShape)
        self.assertEqual(adaptor.GetAppliedSchemas(), [])

        # Wrong name: not adapted
        adaptor = mayaUsdLib.Adaptor(lightShape2)
        self.assertEqual(adaptor.GetAppliedSchemas(), [])

        # Adapted:
        adaptor = mayaUsdLib.Adaptor(lightShape1)
        self.assertEqual(adaptor.GetAppliedSchemas(), ["ShadowAPI"])

        schema = adaptor.GetSchemaByName("ShadowAPI")
        self.assertTrue(schema)

        self.assertEqual(set(schema.GetAuthoredAttributeNames()),
                         set(["inputs:shadow:color", "inputs:shadow:enable"]))
        colorAttr = schema.GetAttribute("inputs:shadow:color")
        self.assertTrue(colorAttr)
        linearizedValue = (0.21763764, 0.047366142, 0)
        colorAttrValue = colorAttr.Get()
        self.assertAlmostEqual(linearizedValue[0], colorAttrValue[0])
        self.assertAlmostEqual(linearizedValue[1], colorAttrValue[1])
        self.assertEqual(linearizedValue[2], colorAttrValue[2])

        colorAttr.Set((1, 0, 1))
        self.assertEqual(cmds.getAttr(lightShape1 + ".shadowColor"),
                         [(1.0, 0.0, 1.0)])
Exemplo n.º 9
0
 def testAdaptorRegistration(self):
     """Tests Registration Python functions."""
     mayaUsdLib.Adaptor.RegisterTypedSchemaConversion(
         "polySphere", UsdGeom.Sphere)
     mayaUsdLib.Adaptor.RegisterAttributeAlias(
         UsdGeom.Tokens.faceVaryingLinearInterpolation, "USD_RegTest")
     cmds.file(new=True, force=True)
     cmds.createNode("polySphere", name="TestSphere")
     self.assertTrue(
         mayaUsdLib.Adaptor("TestSphere").GetSchema(UsdGeom.Sphere))
     self.assertEqual(
         mayaUsdLib.Adaptor.GetAttributeAliases(
             "faceVaryingLinearInterpolation"), [
                 "USD_ATTR_faceVaryingLinearInterpolation", "USD_RegTest",
                 "USD_faceVaryingLinearInterpolation"
             ])
Exemplo n.º 10
0
    def testGetSchema(self):
        """Tests getting schemas from the proxy."""
        cmds.file(new=True, force=True)
        cmds.group(name="group1", empty=True)

        proxy = mayaUsdLib.Adaptor('group1')
        self.assertTrue(proxy.GetSchema(UsdGeom.ModelAPI))
        self.assertTrue(proxy.GetSchema(UsdGeom.Xform))

        # Wrong schemas should be invalid. Currently, exact schema match is
        # required (i.e. if Xform is compatible, Xformable isn't).
        self.assertFalse(proxy.GetSchema(UsdGeom.Mesh))

        # We can't currently get prim definitions from the schema registry for
        # typed non-concrete schemas, so we can't expect them to work with
        # GetSchema/GetSchemaByName.
        self.assertFalse(proxy.GetSchema(UsdGeom.Xformable))
Exemplo n.º 11
0
    def testConcreteSchemaRegistrations(self):
        """Tests some of the PXRUSDMAYA_REGISTER_ADAPTOR_SCHEMA macros."""
        cmds.file(new=True, force=True)
        cmds.createNode("joint", name="TestJoint")
        self.assertTrue(
            mayaUsdLib.Adaptor("TestJoint").GetSchema(UsdSkel.Skeleton))
        self.assertFalse(
            mayaUsdLib.Adaptor("TestJoint").GetSchema(UsdGeom.Mesh))

        cmds.createNode("camera", name="TestCamera")
        self.assertTrue(
            mayaUsdLib.Adaptor("TestCamera").GetSchema(UsdGeom.Camera))

        cmds.createNode("mesh", name="TestMesh")
        self.assertTrue(mayaUsdLib.Adaptor("TestMesh").GetSchema(UsdGeom.Mesh))

        cmds.createNode("instancer", name="TestInstancer")
        self.assertTrue(
            mayaUsdLib.Adaptor("TestInstancer").GetSchema(
                UsdGeom.PointInstancer))

        cmds.createNode("nurbsSurface", name="TestNurbsSurface")
        self.assertTrue(
            mayaUsdLib.Adaptor("TestNurbsSurface").GetSchema(
                UsdGeom.NurbsPatch))

        cmds.createNode("nurbsCurve", name="TestNurbsCurve")
        self.assertTrue(
            mayaUsdLib.Adaptor("TestNurbsCurve").GetSchema(
                UsdGeom.NurbsCurves))

        cmds.createNode("locator", name="TestLocator")
        self.assertTrue(
            mayaUsdLib.Adaptor("TestLocator").GetSchema(UsdGeom.Xform))

        cmds.createNode("nParticle", name="TestParticles")
        self.assertTrue(
            mayaUsdLib.Adaptor("TestParticles").GetSchema(UsdGeom.Points))
Exemplo n.º 12
0
    def verifySubdivCommonAttributes(self, mesh):
        self.assertTrue(cmds.objExists(mesh))

        schema = mayaUsdLib.Adaptor(mesh).GetSchema(UsdGeom.Mesh)
        subdivisionScheme = \
                schema.GetAttribute(UsdGeom.Tokens.subdivisionScheme).Get()
        self.assertIsNone(subdivisionScheme)

        faceVaryingLinearInterpolation = schema.GetAttribute(
                UsdGeom.Tokens.faceVaryingLinearInterpolation).Get()
        self.assertEqual(faceVaryingLinearInterpolation, UsdGeom.Tokens.all)

        interpolateBoundary = schema.GetAttribute(
                UsdGeom.Tokens.interpolateBoundary).Get()
        self.assertEqual(interpolateBoundary, UsdGeom.Tokens.edgeOnly)

        self.assertFalse(
                cmds.attributeQuery("USD_EmitNormals", node=mesh, exists=True))
Exemplo n.º 13
0
    def testImportPoly(self):
        mesh = 'PolyMeshShape'
        self.assertTrue(cmds.objExists(mesh))

        schema = mayaUsdLib.Adaptor(mesh).GetSchema(UsdGeom.Mesh)
        subdivisionScheme = schema.GetAttribute(
            UsdGeom.Tokens.subdivisionScheme).Get()
        self.assertEqual(subdivisionScheme, UsdGeom.Tokens.none)

        faceVaryingLinearInterpolation = schema.GetAttribute(
            UsdGeom.Tokens.faceVaryingLinearInterpolation).Get()
        self.assertIsNone(faceVaryingLinearInterpolation)  # not authored

        interpolateBoundary = schema.GetAttribute(
            UsdGeom.Tokens.interpolateBoundary).Get()
        self.assertEqual(interpolateBoundary, UsdGeom.Tokens.none)

        self.assertTrue(
            cmds.attributeQuery("USD_EmitNormals", node=mesh, exists=True))
Exemplo n.º 14
0
    def testComplexAdaptation(self):
        """Test that we can adapt a bullet simulation"""

        mayaUsdLib.SchemaApiAdaptor.Register(TestBulletMassShemaAdaptor,
                                             "shape", "PhysicsMassAPI")
        mayaUsdLib.SchemaApiAdaptor.Register(TestBulletRigidBodyShemaAdaptor,
                                             "shape", "PhysicsRigidBodyAPI")

        # Build a scene (and exercise the adaptor in a freeform context)
        cmds.file(f=True, new=True)

        s1T = cmds.polySphere()[0]
        cmds.loadPlugin("bullet")
        if not BulletUtils.checkPluginLoaded():
            return

        rbT, rbShape = RigidBody.CreateRigidBody().command(
            autoFit=True,
            colliderShapeType=RigidBody.eShapeType.kColliderSphere,
            meshes=[s1T],
            radius=1.0,
            mass=5.0,
            centerOfMass=(0.9, 0.8, 0.7))

        # See if the plugin adaptor can read the bullet shape under the mesh:
        sl = om.MSelectionList()
        sl.add(s1T)
        dagPath = sl.getDagPath(0)
        dagPath.extendToShape()

        adaptor = mayaUsdLib.Adaptor(dagPath.fullPathName())
        self.assertEqual(adaptor.GetUsdType(),
                         Tf.Type.FindByName('UsdGeomMesh'))
        # NOTICE: PhysicsRigidBodyAPI is not in the list because that API is
        # supported only on export!!!
        self.assertEqual(adaptor.GetAppliedSchemas(), ['PhysicsMassAPI'])
        physicsMass = adaptor.GetSchemaByName("PhysicsMassAPI")
        self.assertEqual(physicsMass.GetName(), "PhysicsMassAPI")
        massAttributes = set([
            'physics:centerOfMass', 'physics:density',
            'physics:diagonalInertia', 'physics:mass', 'physics:principalAxes'
        ])
        self.assertEqual(set(physicsMass.GetAttributeNames()), massAttributes)
        bulletAttributes = set(['physics:centerOfMass', 'physics:mass'])
        self.assertEqual(set(physicsMass.GetAuthoredAttributeNames()),
                         bulletAttributes)
        bulletMass = physicsMass.GetAttribute('physics:mass')
        self.assertAlmostEqual(bulletMass.Get(), 5.0)
        bulletMass.Set(12.0)

        bulletCenter = physicsMass.GetAttribute('physics:centerOfMass')
        bulletCenter.Set(Gf.Vec3f(3, 4, 5))

        sl = om.MSelectionList()
        sl.add(s1T)
        bulletPath = sl.getDagPath(0)
        bulletPath.extendToShape(1)
        massDepFn = om.MFnDependencyNode(bulletPath.node())
        plug = om.MPlug(bulletPath.node(), massDepFn.attribute("mass"))
        self.assertAlmostEqual(plug.asFloat(), 12.0)

        # Create an untranslated attribute:
        usdDensity = physicsMass.CreateAttribute('physics:density')
        usdDensity.Set(33.0)
        self.assertAlmostEqual(usdDensity.Get(), 33.0)

        # This will result in a dynamic attribute on the bulletShape:
        plug = massDepFn.findPlug("USD_ATTR_physics_density", True)
        self.assertAlmostEqual(plug.asFloat(), 33.0)
        bulletAttributes.add('physics:density')
        self.assertEqual(set(physicsMass.GetAuthoredAttributeNames()),
                         bulletAttributes)

        physicsMass.RemoveAttribute('physics:density')
        bulletAttributes.remove('physics:density')
        self.assertEqual(set(physicsMass.GetAuthoredAttributeNames()),
                         bulletAttributes)

        # Add some animation:
        cmds.setKeyframe(bulletPath, at="mass", t=0, v=3.0)
        cmds.setKeyframe(bulletPath, at="mass", t=10, v=30.0)

        # Modify the velocity so it can be exported to the RBD Physics schema.
        cmds.setKeyframe(bulletPath, at="initialVelocityX", t=0, v=5.0)
        cmds.setKeyframe(bulletPath, at="initialVelocityX", t=10, v=50.0)
        cmds.setKeyframe(bulletPath, at="initialVelocityY", t=0, v=6.0)
        cmds.setKeyframe(bulletPath, at="initialVelocityY", t=10, v=60.0)
        cmds.setKeyframe(bulletPath, at="initialVelocityZ", t=0, v=7.0)
        cmds.setKeyframe(bulletPath, at="initialVelocityZ", t=10, v=70.0)

        # Try applying the schema on a new sphere:
        s2T = cmds.polySphere()[0]
        sl.add(s2T)
        dagPath = sl.getDagPath(1)
        dagPath.extendToShape()
        adaptor = UsdMaya.Adaptor(dagPath.fullPathName())
        physicsMass = adaptor.ApplySchemaByName("PhysicsMassAPI")
        self.assertEqual(physicsMass.GetName(), "PhysicsMassAPI")
        self.assertEqual(adaptor.GetUsdType(),
                         Tf.Type.FindByName('UsdGeomMesh'))
        self.assertEqual(adaptor.GetAppliedSchemas(), ['PhysicsMassAPI'])

        usdDensity = physicsMass.CreateAttribute('physics:density')
        usdDensity.Set(33.0)

        # Export, but without enabling Bullet:
        usdFilePath = os.path.abspath('UsdExportSchemaApiTest_NoBullet.usda')
        cmds.mayaUSDExport(mergeTransformAndShape=True, file=usdFilePath)

        # Check that there are no Physics API schemas exported:
        stage = Usd.Stage.Open(usdFilePath)
        for i in (1, 2):
            spherePrim = stage.GetPrimAtPath(
                '/pSphere{0}/pSphereShape{0}'.format(i))
            self.assertFalse(
                "PhysicsMassAPI" in spherePrim.GetAppliedSchemas())

        schemasToExport = ["PhysicsMassAPI", "PhysicsRigidBodyAPI"]
        # Export, with Bullet:
        usdFilePath = os.path.abspath('UsdExportSchemaApiTest_WithBullet.usda')
        cmds.mayaUSDExport(mergeTransformAndShape=True,
                           file=usdFilePath,
                           apiSchema=schemasToExport,
                           frameRange=(1, 10))

        # Check that Physics API schemas did get exported:
        stage = Usd.Stage.Open(usdFilePath)
        values = [
            ("physics:centerOfMass", (Gf.Vec3f(3, 4, 5), Gf.Vec3f(0, 0, 0))),
            ("physics:mass", (3.0, 1.0)),
            ("physics:density", (None, 33.0)),
        ]
        for i in (1, 2):
            spherePrim = stage.GetPrimAtPath(
                '/pSphere{0}/pSphereShape{0}'.format(i))
            self.assertTrue("PhysicsMassAPI" in spherePrim.GetAppliedSchemas())
            for n, v in values:
                if v[i - 1]:
                    a = spherePrim.GetAttribute(n)
                    self.assertEqual(a.Get(), v[i - 1])
            if i == 1:
                # Is mass animated?
                a = spherePrim.GetAttribute("physics:mass")
                self.assertEqual(a.Get(10), 30)
            # This got exported even though invisible in interactive:
            self.assertTrue(
                "PhysicsRigidBodyAPI" in spherePrim.GetAppliedSchemas())
            a = spherePrim.GetAttribute("physics:velocity")
            if i == 1:
                self.assertEqual(a.Get(0), (5, 6, 7))
                self.assertEqual(a.Get(10), (50, 60, 70))
                numberOfExportedKeys = len(a.GetTimeSamples())

        # Try unapplying the schema:
        adaptor.UnapplySchemaByName("PhysicsMassAPI")
        self.assertEqual(adaptor.GetAppliedSchemas(), [])

        # Test import of USDPhysics without job context:
        cmds.file(new=True, force=True)
        cmds.mayaUSDImport(f=usdFilePath)

        sl = om.MSelectionList()
        # pSphereShape1 is a transform, since the bullet shape prevented merging the mesh and the
        # transform. The shape will be pSphereShape1Shape...
        sl.add("pSphereShape1")
        bulletPath = sl.getDagPath(0)
        # No bullet shape since we did not put Bullet as jobContext
        self.assertEqual(bulletPath.numberOfShapesDirectlyBelow(), 1)

        cmds.file(new=True, force=True)
        cmds.mayaUSDImport(f=usdFilePath,
                           apiSchema=schemasToExport,
                           readAnimData=True)

        sl = om.MSelectionList()
        sl.add("pSphereShape1")
        bulletPath = sl.getDagPath(0)
        # Finds bullet shape since we did put Bullet as jobContext

        self.assertEqual(bulletPath.numberOfShapesDirectlyBelow(), 2)

        # The bullet shape has animated mass and initial velocity since we read the animation.
        bulletPath.extendToShape(1)
        massDepFn = om.MFnDependencyNode(bulletPath.node())
        for attrName in ("mass", "initialVelocityX", "initialVelocityY",
                         "initialVelocityZ"):
            plug = om.MPlug(bulletPath.node(), massDepFn.attribute(attrName))
            self.assertTrue(plug.isConnected)
            fcurve = oma.MFnAnimCurve(plug.source().node())
            self.assertEqual(fcurve.numKeys, numberOfExportedKeys)