def bdMain(): dagPath = om.MDagPath() mObj = om.MObject() selection = om.MSelectionList() status = om.MGlobal.getActiveSelectionList(selection) try: status = selection.getDependNode(0,mObj) except: sys.stderr.write('Nothing is selected, you need to select the IK handle') return if mObj.hasFn(om.MFn.kIkHandle): ikHandleFn = oma.MFnIkHandle(mObj) startJointPath = om.MDagPath() ikHandleFn.getStartJoint(startJointPath) startJointTransformNode = startJointPath.transform() startJointTransformFn = om.MFnTransform(startJointTransformNode) print startJointTransformFn.name() rotateOrientation = startJointTransformFn.rotateOrientation(om.MSpace.kTransform) rotateOrientationEuler = rotateOrientation .asEulerRotation() print 'Rotation axis', math.degrees(rotateOrientationEuler.x), math.degrees(rotateOrientationEuler.y), math.degrees(rotateOrientationEuler.z) matrix = om.MTransformationMatrix(startJointTransformFn.transformationMatrix()) rotOrderAxis = matrix.rotationOrder() print rotOrderAxis quatRotation = om.MQuaternion() startJointTransformFn.getRotation(quatRotation) eulerRotation = quatRotation.asEulerRotation() print 'Local Rotation ', math.degrees(eulerRotation.x), math.degrees(eulerRotation.y), math.degrees(eulerRotation.z) translation = matrix.getTranslation(om.MSpace.kWorld) print 'World transation', translation.x, translation.y, translation.z ikJoint = oma.MFnIkJoint(startJointTransformNode) jointOrient = om.MEulerRotation() quatJointOrient = om.MQuaternion() ikJoint.getRotation(quatJointOrient) ikJoint.getOrientation(jointOrient) print 'Joint orientation', math.degrees(jointOrient.x) , math.degrees(jointOrient.y), math.degrees(jointOrient.z) globalRot = om.MQuaternion() globalRot = rotateOrientation * quatRotation * quatJointOrient globalRotEuler = globalRot.asEulerRotation() print 'World orientation', math.degrees(globalRot.x) , math.degrees(globalRot.y), math.degrees(globalRot.z) print bdGetChainLength(ikJoint)
def doSimpleSolver(self): """ Solve single joint in the x-y plane - first it calculates the angle between the handle and the end-effector. - then it determines which way to rotate the joint. """ handle_group = self.handleGroup() handle = handle_group.handle(0) handlePath = OpenMaya.MDagPath.getAPathTo(handle) fnHandle = OpenMayaAnim.MFnIkHandle(handlePath) # Get the position of the end_effector end_effector = OpenMaya.MDagPath() fnHandle.getEffector(end_effector) tran = OpenMaya.MFnTransform(end_effector) effector_position = tran.rotatePivot(OpenMaya.MSpace.kWorld) # Get the position of the handle handle_position = fnHandle.rotatePivot(OpenMaya.MSpace.kWorld) # Get the start joint position start_joint = OpenMaya.MDagPath() fnHandle.getStartJoint(start_joint) start_transform = OpenMaya.MFnTransform(start_joint) start_position = start_transform.rotatePivot(OpenMaya.MSpace.kWorld) # Calculate the rotation angle v1 = start_position - effector_position v2 = start_position - handle_position angle = v1.angle(v2) # -------- Figure out which way to rotate -------- # # define two vectors U and V as follows # U = EndEffector(E) - StartJoint(S) # N = Normal to U passing through EndEffector # # Clip handle_position to half-plane U to determine the region it # lies in. Use the region to determine the rotation direction. # # U # ^ Region Rotation # | B # (E)---N A C-C-W # A | B C-W # | B # | # (S) # rot = 0.0 # Rotation about Z-axis # U and N define a half-plane to clip the handle against U = effector_position - start_position U.normalize() # Get a normal to U zAxis = OpenMaya.MVector(0.0, 0.0, 1.0) N = U ^ zAxis # Cross product N.normalize() # P is the handle position vector P = handle_position - effector_position # Determine the rotation direction PdotN = P[0] * N[0] + P[1] * N[1] if PdotN < 0: rot = angle # counter-clockwise else: rot = -1.0 * angle # clockwise # get and set the Joint Angles jointAngles = OpenMaya.MDoubleArray() try: self._getJointAngles(jointAngles) except: # getting angles failed, do nothing pass else: jointAngles.set(jointAngles[0] + rot, 0) self._setJointAngles(jointAngles)
def doSimpleSolver(self): ''' Solve single joint in the x-y plane - first it calculates the angle between the handle and the end-effector. - then it determines which way to rotate the joint. ''' handle_group = self.handleGroup() # return a MIkHandleGroup handle = handle_group.handle(0) # return a MObject handlePath = OpenMaya.MDagPath.getAPathTo( handle) # Determines the Path to the specified DAG Node fnHandle = OpenMayaAnim.MFnIkHandle( handlePath) # argument an Mobject, i supose we use an mdagpath, # for possible duplicated objects # get the position of the end_effector end_effector = OpenMaya.MDagPath() fnHandle.getEffector(end_effector) tran = OpenMaya.MFnTransform(end_effector) effector_position = tran.rotatePivot(OpenMaya.MSpace.kWorld) # get the position of the handle handle_positions = fnHandle.rotatePivot(OpenMaya.MSpace.kWorld) # get the start joint position start_joint = OpenMaya.MDagPath() fnHandle.getStartJoint( start_joint ) # start_joint is filled here with the getStartJoint method start_tramsform = OpenMaya.MFnTransform(start_joint) start_position = start_tramsform.rotatePivot(OpenMaya.MSpace.kWorld) # calculate the rotation angle v1 = start_position - effector_position v2 = start_position - handle_positions angle = v1.angle(v2) # -------- Figure out which way to rotate -------- # # define two vectors U and V as follows # U = EndEffector(E) - StartJoint(S) # N = Normal to U passing through EndEffector # # Clip handle_position to half-plane U to determine the region it # lies in. Use the region to determine the rotation direction. # # U # ^ Region Rotation # | B # (E)---N A C-C-W # A | B C-W # | B # | # (S) # rot = 0.0 # Rotation about z-axis # U and N define a half-plane to clip the handle against u = effector_position - start_position u.normalize() # Get a normal to U zAxis = OpenMaya.MVector(0.0, 0.0, 1.0) N = u ^ zAxis # cross product N.normalize() # P is the handle position vector P = handle_positions - effector_position # Determine the rotation direction PdotN = P[0] * N[0] + P[1] * N[1] if PdotN < 0: rot = angle # counter-clockwise else: rot = -1.0 * angle # clockwise # get and set the Joint Angles jointAngles = OpenMaya.MDoubleArray() try: self._getJointAngles(jointAngles) # here fill jointAngles except: # getting angles failed, do nothing pass else: jointAngles.set(jointAngles[0] + rot, 0) # set rotation in the array self._setJointAngles(jointAngles) # set joint rotation
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())