Exemplo n.º 1
0
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)
Exemplo n.º 2
0
    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)
Exemplo n.º 3
0
    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
Exemplo n.º 4
0
 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())