def UnapplySchema(self, dgModifier):
        if self.GetMayaObjectForSchema() is None:
            # Already unapplied?
            return False

        path = om.MDagPath.getAPathTo(self.mayaObject)
        if not path or not path.pop():
            return False

        BulletUtils.checkPluginLoaded()
        BulletUtils.removeBulletObjectsFromList([path.fullPathName()])

        return self.GetMayaObjectForSchema() is None
def _ApplyBulletSchema(mayaShape):
    """Creates a bullet simulation containing the "mayaShape", this is obviously demo
    code, so we will not even try to add the shape to an existing simluation."""
    if _GetBulletShape(mayaShape) is not None:
        return True

    path = om.MDagPath.getAPathTo(mayaShape)

    if not path or not path.pop():
        return False

    BulletUtils.checkPluginLoaded()
    RigidBody.CreateRigidBody.command(transformName=path.fullPathName(),
                                      bAttachSelected=False)

    return True
示例#3
0
# GenerateFractureLogs
# Script to generate fracture points in the Log scene

import maya.cmds as cmds
import random
import math
import maya.app.mayabullet.BulletUtils as BulletUtils
import maya.app.mayabullet.RigidBody as RigidBody
BulletUtils.checkPluginLoaded()

# Get object to be shattered
cmds.select(['log1','log2','log3'])
selected = cmds.ls(sl=True, transforms=True)
objCounter = 0
for obj in selected: 

    print(obj)
    
    # Get center point of collision (in our case center of the logs)
    com = cmds.objectCenter(obj, gl=True)
    numPoints = 30
    fractureRadius = 3
    thickness = 1 # Will get divided by 2
    height = cmds.getAttr(obj + '.translateY')
    transX = cmds.getAttr(obj + '.translateX')
    rotY = cmds.getAttr(obj + '.rotateY')
    voroX = []
    voroY = []
    voroZ = []
    #print(height)
    
    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)