Пример #1
0
def setSoftBodyPerParticleBendResistance(newValue=None):
    # Store off original selection
    origSel = maya.cmds.ls(sl=True)

    #Get softBody for verts
    maya.cmds.select(maya.cmds.listConnections('.worldMesh',
                                               d=1,
                                               sh=1,
                                               type='bulletSoftBodyShape'),
                     add=True)
    maya.cmds.select(maya.cmds.listConnections(".inMesh",
                                               s=1,
                                               sh=1,
                                               type='bulletSoftBodyShape'),
                     add=True)
    softBodies = maya.cmds.ls(sl=True, dag=True, type='bulletSoftBodyShape')
    if len(softBodies) != 1:
        maya.cmds.select(origSel, r=True)
        maya.OpenMaya.MGlobal.displayError(
            _loadUIString('kSelectVertsAttached'))
        return

    # If $newValue is -1, then bring up the prompt
    if (newValue == None):
        okBut = _loadUIString('kOk')
        cancelBut = _loadUIString('kCancel')
        result = maya.cmds.promptDialog(
            title=_loadUIString('kBulletSoftbodyPerParticleSet'),
            message=maya.
            stringTable['y_SoftBody.kEnterPerParticleBendResistance'],
            button=[okBut, cancelBut],
            defaultButton=okBut,
            cancelButton=cancelBut,
            dismissString=cancelBut)
        if result != okBut:
            maya.cmds.select(origSel, r=True)
            return
        newValue = float(maya.cmds.promptDialog(query=True, text=True))

    if newValue < 0.0:
        maya.cmds.select(origSel, r=True)
        maya.OpenMaya.MGlobal.displayError(maya.stringTable[
            'y_SoftBody.kCannotHaveANegativeValueForBendResistance'])
        return

    softBody = softBodies[0]

    # Get ids
    ids = BulletUtils.extractVertexIds(
        maya.cmds.ls(sl=True, flatten=True, type='float3'))

    # Set particleBendResistance
    if len(ids) > 0:
        # get the current array of values
        attr = softBody + ".particleBendResistance"
        vals = maya.cmds.getAttr(attr)
        # create the array if it doesn't exist
        if (vals == None):
            mesh = maya.cmds.listConnections(softBody + '.inWorldMesh',
                                             d=1,
                                             sh=1)
            maya.cmds.select(mesh, r=True)
            selList = maya.OpenMaya.MSelectionList()
            maya.OpenMaya.MGlobal.getActiveSelectionList(selList)
            path = maya.OpenMaya.MDagPath()
            comp = maya.OpenMaya.MObject()
            selList.getDagPath(0, path, comp)
            path.extendToShape()
            meshFn = maya.OpenMaya.MFnMesh(path)
            count = meshFn.numVertices()
            vals = [1] * count
        # override value for selected ids
        for id in ids:
            vals[id] = newValue
        # set the array of values
        maya.cmds.setAttr(attr, vals, type='doubleArray')
    else:
        maya.OpenMaya.MGlobal.displayError(
            _loadUIString('kSelectVertsAttached'))

    # Set back original selection
    maya.cmds.select(origSel, r=True)
Пример #2
0
def createSoftBodyAnchorConstraint(selectedVerts=None):
    '''Create a bulletSoftConstraint to anchor selected SoftBody vertices to a
    RigidBody. If no RigidBody is specified, then one will be created and
    centered on the first selected vertex.
    '''

    # Get list of selected verts
    if selectedVerts == None:
        selectedVerts = maya.cmds.ls(sl=True, flatten=True,
                                     type='float3')  # flattened list
    if len(selectedVerts) == 0:
        maya.OpenMaya.MGlobal.displayError(maya.stringTable[
            'y_SoftBodyConstraint.kPleaseSelectASetOfMeshVertsForTheAnchorConstraint']
                                           )
        return

    # extract out the vertex number
    anchoredVertexIds = BulletUtils.extractVertexIds(selectedVerts)

    # Get center of selected vertices
    origTranslate = centroid(selectedVerts)

    # Get meshshape
    objs = maya.cmds.listRelatives(selectedVerts[0], parent=True, type='mesh')
    if objs == None or len(objs) == 0:
        maya.OpenMaya.MGlobal.displayError(maya.stringTable[
            'y_SoftBodyConstraint.kPleaseSelectMeshVertsForTheAnchorConstraint']
                                           )
        return

    mesh = objs[0]
    # Get $softbody attached to mesh
    # First check if output mesh vert selected, so look for incoming connection
    softbody = ""
    cons = maya.cmds.listConnections(".inMesh",
                                     s=1,
                                     sh=1,
                                     type='bulletSoftBodyShape')
    if cons != None and len(cons) == 1:
        softbody = cons[0]
    else:
        # Otherwise, check input mesh to be connected to a softbody
        cons = maya.cmds.listConnections(".worldMesh[0]",
                                         d=1,
                                         sh=1,
                                         type='bulletSoftBodyShape')
        if cons != None and len(cons) == 1:
            softbody = cons[0]
    if softbody == "":
        maya.OpenMaya.MGlobal.displayError(
            maya.stringTable['y_SoftBodyConstraint.kCouldNotDetermineSBShape'])
        return

    # Get anchor object
    anchorCandidates = maya.cmds.ls(
        sl=True, dag=True, shapes=True)  # list all selected shape nodes
    numCandidates = len(anchorCandidates)
    if numCandidates == 0:
        maya.OpenMaya.MGlobal.displayError(maya.stringTable[
            'y_SoftBodyConstraint.kPleaseSelectOneBulletRigidBodyForAnchorConstraint']
                                           )
        return

    # use first object found or first rigid body found
    anchorConstrError1 = maya.stringTable[
        'y_SoftBodyConstraint.kPleaseSelectOnlyOneObjectForAnchorConstraint1']
    anchorConstrError2 = maya.stringTable[
        'y_SoftBodyConstraint.kPleaseSelectOnlyOneObjectForAnchorConstraint2']
    anchor = None
    shape = None
    rigidbody = None
    for candidate in anchorCandidates:
        if maya.cmds.objectType(candidate, isType='bulletRigidBodyShape'):
            if rigidbody is not None:
                maya.OpenMaya.MGlobal.displayError(anchorConstrError1)
                return
            anchor = candidate
            rigidbody = candidate
        else:
            if shape is not None:
                maya.OpenMaya.MGlobal.displayError(anchorConstrError2)
                return
            anchor = candidate
            shape = candidate

    # allow a geometry shape and rigid body shape to be selected as long as the rigid body
    # shape is connected to the geometry shape and therefore the same 'object'.
    if shape and rigidbody:
        rigidbodies = maya.cmds.listConnections(shape,
                                                sh=True,
                                                type='bulletRigidBodyShape')
        if rigidbodies is None or rigidbodies[0] != rigidbody:
            maya.OpenMaya.MGlobal.displayError(anchorConstrError2)
            return

    # Create SoftConstraint
    shape = maya.cmds.createNode("bulletSoftConstraintShape")
    shapeT = maya.cmds.listRelatives(shape, parent=True)[0]
    # Create Solver
    sol = BulletUtils.getSolver()

    maya.cmds.setAttr((shapeT + ".translate"), *origTranslate)

    # The logical place for the anchors to be stored is on the constraint node,
    # but in order to remap the indices when the topology changes we have to
    # put it on the soft body node and connect it to the constraint node.  This
    # is an array (multi) attribute, one per constraint; each constraint is
    # itself an int32 array.

    # Find the new index for the anchor.
    anchorListAttr = softbody + ".anchors"
    anchorIndices = maya.cmds.getAttr(anchorListAttr, multiIndices=True)
    if anchorIndices:
        anchorNewIndex = anchorIndices[-1] + 1
    else:
        anchorNewIndex = 0
    anchorName = "%s[%d]" % (anchorListAttr, anchorNewIndex)

    # getAttr allocates the new index, then setAttr stores the data,
    # then connectAttr moves the data to where it's used.
    maya.cmds.getAttr(anchorName)
    maya.cmds.setAttr(anchorName, anchoredVertexIds, type='Int32Array')
    maya.cmds.connectAttr(anchorName, shape + ".indexList")

    # Connect the simple attributes.
    maya.cmds.connectAttr((sol + ".startTime"), (shape + ".startTime"))
    maya.cmds.connectAttr((sol + ".currentTime"), (shape + ".currentTime"))
    maya.cmds.connectAttr((softbody + ".outSoftBodyData"),
                          (shape + ".softBody"))

    if (rigidbody):
        maya.cmds.connectAttr((rigidbody + ".outRigidBodyData"),
                              (shape + ".rigidBody"))
    else:
        maya.cmds.connectAttr((anchor + ".worldMatrix"),
                              (shape + ".inWorldMatrix"))

    maya.cmds.connectAttr((shape + ".outConstraintData"),
                          (sol + ".softConstraints"),
                          na=True)
    # Return
    maya.cmds.select(shape)
    ret = [shape]

    # If command echoing is off, echo this short line.
    if (not maya.cmds.commandEcho(query=True, state=True)):
        print("SoftBodyConstraint.createSoftBodyAnchorConstraint()")
        print "// Result: %s //" % shape

    return ret