def command_shape(**kwargs): returnedTransforms = [] shapes = kwargs['shapes'] # Make sure the list doesn't contain any bullet objects. shapes = BulletUtils.verifySelectionNotBullet(shapes, False) for s in shapes: shapeT = _firstParent(s) # Verify collision shape type is valid. if (maya.cmds.nodeType(s) != 'mesh'): if (kwargs.has_key('colliderShapeType')): shapeType = kwargs['colliderShapeType'] if (shapeType == eShapeType.kColliderHull) or (shapeType == eShapeType.kColliderMesh): kwargs['colliderShapeType'] = eShapeType.kColliderBox kwargs['centerOfMass'] = centerOfMass(shapeT) # Create rigidbody kwargs['bAttachSelected']=False kwargs['transformName']=shapeT rbTs = CreateRigidBody.doCommand(**kwargs) rbShape = _longName(rbTs[1]) if kwargs.has_key('autoFit') and kwargs['autoFit']: (radius, length, ex, ey, ez, cx, cy, cz) = refitCollisionShape(rbShape, s) kwargs['radius'] = radius kwargs['length'] = length kwargs['extents'] = [ex, ey, ez] kwargs['centerOfMass'] = [cx, cy, cz] returnedTransforms.append(rbTs[0]) returnedTransforms.append(rbTs[1]) # Connects if (maya.cmds.nodeType(s) == 'mesh'): _connectAttr( _attr(s,"outMesh"), _attr(rbShape, "inMesh")) return returnedTransforms
def command( meshes=None, name='bulletSoftBodyShape#', # Attrs generateBendConstraints=None, selfCollision=None, bendResistance=None, linearStiffness=None, friction=None, damping=None, pressure=None, collisionMargin=None, positionIterations=None, #poseMatching=None, #enablePoseMatching=None, preserveSourceMesh=None, singleTransform=None, **kwargs): '''Create a bulletSoftBody from specified mesh. ''' # Explicitly list the names of settable attributes iterated over below settableAttrs = [ 'generateBendConstraints', 'selfCollision', 'bendResistance', 'linearStiffness', 'friction', 'damping', 'pressure', 'collisionMargin', 'positionIterations', #'poseMatching', #'enablePoseMatching', ] # Make a boolean value that is easier to read in code singleTransform = singleTransform != False # Get list of meshes from selection if not passed in if (meshes == None): maya.cmds.select(maya.cmds.listRelatives(shapes=True, fullPath=True), add=True) meshes = maya.cmds.ls(sl=True, type='mesh', long=True) # Make sure the selection doesn't contain any bullet objects. BulletUtils.verifySelectionNotBullet(meshes) returnedNodes = [] # Sanity Checking if len(meshes) == 0: maya.OpenMaya.MGlobal.displayError( maya.stringTable['y_SoftBody.kSelectMesh']) return returnedNodes # Loop over meshes and create soft bodies for mesh in meshes: meshT = maya.cmds.listRelatives([mesh], parent=True, fullPath=True)[0] # Duplicate mesh and connect in history # Alternate: use a stub func like polyReduce -replaceOriginal 0 -percentage 100 -nodeState 1 -name "stubPolyMod"; meshCopyT = maya.cmds.polyDuplicateAndConnect(mesh)[0] meshCopyShape = maya.cmds.listRelatives(meshCopyT, s=True, fullPath=True)[0] if not singleTransform: maya.cmds.setAttr((meshCopyT + ".t"), 0, 0, 0) # zero out the transform since get values from WorldSpace maya.cmds.setAttr((meshCopyT + ".r"), 0, 0, 0) # zero out the transform since get values from WorldSpace maya.cmds.setAttr((meshCopyT + ".s"), 1, 1, 1) # zero out the transform since get values from WorldSpace maya.cmds.setAttr((meshCopyT + ".inheritsTransform"), 0) # Create softbody shape # NOTE: If plugin not loaded, then sbShape will return unknown nodetype # and listRelatives will not work as expected sbShape = maya.cmds.createNode('bulletSoftBodyShape', name=name) sbT = maya.cmds.listRelatives([sbShape], parent=True, fullPath=True)[0] # Reparent body shape under it maya.cmds.parent(sbShape, meshT, r=True, s=True) maya.cmds.delete(sbT) sbT = meshT # Create Solver (proto) sol = BulletUtils.getSolver() # Connect maya.cmds.connectAttr((mesh + ".worldMesh"), (sbShape + ".inWorldMesh")) maya.cmds.connectAttr((sol + ".outSolverInitialized"), (sbShape + ".solverInitialized")) maya.cmds.connectAttr((sbShape + ".outSoftBodyData"), (sol + ".softBodies"), na=True) maya.cmds.connectAttr((sol + ".outSolverUpdated"), (sbShape + ".solverUpdated")) maya.cmds.connectAttr((sbShape + ".outSolvedMesh"), (meshCopyShape + ".inMesh"), f=True) # REVISIT: Consider alternatives like a single initSystem bool attr instead of startTime and currentTime. # Might be able to get around needing it at all maya.cmds.connectAttr((sol + ".startTime"), (sbShape + ".startTime")) maya.cmds.connectAttr((sol + ".currentTime"), (sbShape + ".currentTime")) # Set Attrs (optional, set if value != None) # Use the settableAttrs list above to qualify kwargs passed into the function for k, v in locals().iteritems(): if k in settableAttrs and v != None: if isinstance(v, list): maya.cmds.setAttr('%s.%s' % (sbShape, k), *v) # covers float3 cases else: maya.cmds.setAttr('%s.%s' % (sbShape, k), v) # Additional Actions if (preserveSourceMesh == False): maya.cmds.setAttr((mesh + '.intermediateObject'), True) # Alternate: Explicit method #if generateBendConstraints != None: # maya.cmds.setAttr((sbShape+'.generateBendConstraints'), generateBendConstraints) #if selfCollision != None: # maya.cmds.setAttr((sbShape+'.selfCollision'), selfCollision) #... if singleTransform: # Move the solved mesh under the same transform as the original mesh maya.cmds.parent(meshCopyShape, meshT, relative=True, shape=True) maya.cmds.reorder(sbShape, back=True) maya.cmds.delete(meshCopyT) maya.cmds.setAttr(sbShape + '.localSpaceOutput', True) else: # We will keep the solved mesh under the new transform # Rename new transform maya.cmds.rename(meshCopyT, meshT + "_Solved") # Update list of returned nodes returnedNodes.append(sbT) returnedNodes.append(sbShape) # If command echoing is off, echo this short line. if (not maya.cmds.commandEcho(query=True, state=True)): print("SoftBody.CreateSoftBody.executeCommandCB()") print "// Result: %s //" % string.join(returnedNodes, " ") # Select and return maya.cmds.select(returnedNodes, add=True) return returnedNodes