def redoIt(self): ''' Create and manipulate the nodes to form the joint chain. ''' # Perform the operations enqueued within our reference to MDagModifier. self.dagModifier.doIt() # ======================================= # JOINT MANIPULATION # ======================================= # We can now use the function sets on the newly created DAG objects. jointFn = OpenMayaAnim.MFnIkJoint() for i in range(1, len(self.jointObjects)): jointFn.setObject(self.jointObjects[i]) # We set the orientation for our joint to be 'jointOrientation' degrees, to form an arc. # We use MFnIkJoint.setOrientation() instead of MFnTransform.setRotation() to let the # inverse-kinematic handle maintain the curvature. global jointOrientation rotationAngle = OpenMaya.MAngle(jointOrientation, OpenMaya.MAngle.kDegrees) jointFn.setOrientation( OpenMaya.MEulerRotation(rotationAngle.asRadians(), 0, 0, OpenMaya.MEulerRotation.kXYZ)) # We translate the joint by 'jointDistance' units along its parent's y axis. global jointDistance translationVector = OpenMaya.MVector(0, jointDistance, 0) jointFn.setTranslation(translationVector, OpenMaya.MSpace.kTransform) # ======================================= # IK HANDLE MANIPULATION # ======================================= # We will use the MEL command 'ikHandle' to create the handle which will move our joint chain. This command # will be enqueued in our reference to the MDagModifier so that it can be undone in our call to MDagModifier.undoIt(). # Obtain the DAG path of the first joint. startJointDagPath = OpenMaya.MDagPath() jointFn.setObject(self.jointObjects[0]) jointFn.getPath(startJointDagPath) # Obtain the DAG path of the effector. effectorDagPath = OpenMaya.MDagPath() effectorFn = OpenMayaAnim.MFnIkEffector(self.effectorObj) effectorFn.getPath(effectorDagPath) # Enqueue the following MEL command with the DAG paths of the start joint and the end effector. self.dagModifier.commandToExecute('ikHandle -sj ' + startJointDagPath.fullPathName() + ' -ee ' + effectorDagPath.fullPathName()) # We call MDagModifier.doIt() to effectively execute the MEL command and create the ikHandle. self.dagModifier.doIt()
def splinePreSolve(self, solvernode): # '\n initiate all the members of the class.\n including :\n handleFn , handlePath , effectorFn , startJointFn ,\n startJointPrefAngle , .\n the reason why I put the initial codes here is fail to load the plugin ,\n when I put these codes in the __init__() function .\n ' solvernode.setRotatePlane(0) solvernode.setSingleChainOnly(1) solvernode.setPositionOnly(0) handleGroup = solvernode.handleGroup() handle = handleGroup.handle(0) self.handlePath = OpenMaya.MDagPath() self.handlePath.getAPathTo(handle, self.handlePath) self.handleFn = OpenMayaAnim.MFnIkHandle(self.handlePath) if not self.handleFn.hasAttribute('str'): fnAttr = OpenMaya.MFnNumericAttribute() attr = fnAttr.create('stretchRatio', 'str', OpenMaya.MFnNumericData.kDouble, self.stretchRatio) fnAttr.setKeyable(1) fnAttr.setWritable(1) fnAttr.setMin(0) fnAttr.setMax(1) fnAttr.setHidden(0) fnAttr.setStorable(1) fnAttr.setReadable(1) self.handleFn.addAttribute( attr, OpenMaya.MFnDependencyNode.kLocalDynamicAttr) else: strPlug = self.handleFn.findPlug('str') self.stretchRatio = strPlug.asDouble() effectorPath = OpenMaya.MDagPath() self.handleFn.getEffector(effectorPath) self.effectorFn = OpenMayaAnim.MFnIkEffector(effectorPath) startJointPath = OpenMaya.MDagPath() self.handleFn.getStartJoint(startJointPath) self.startJointFn = OpenMayaAnim.MFnIkJoint(startJointPath) self.joints = [] currJoint = '' inCurvePlug = self.handleFn.findPlug('inCurve') curveHandle = inCurvePlug.asMDataHandle() inputCurveObject = curveHandle.asNurbsCurveTransformed() self.curveFn = OpenMaya.MFnNurbsCurve(inputCurveObject) #get joints while True: effectorPath.pop() j = OpenMayaAnim.MFnIkJoint(effectorPath) self.joints.append(j) currJoint = effectorPath if currJoint == startJointPath: break self.joints = list(reversed(self.joints)) #get lengths for v, j in enumerate(self.joints): pBaseJoint = j.rotatePivot(OpenMaya.MSpace.kWorld) if v == len(self.joints) - 1: pEndJoint = self.effectorFn.rotatePivot(OpenMaya.MSpace.kWorld) else: #get position of next joint pEndJoint = self.joints[v + 1].rotatePivot( OpenMaya.MSpace.kWorld) jVec = OpenMaya.MVector(pBaseJoint[0] - pEndJoint[0], pBaseJoint[1] - pEndJoint[1], pBaseJoint[2] - pEndJoint[2]) self.jointsVectors.append(jVec) self.initLength.append(jVec.length())