Esempio n. 1
0
	def vectorDegreesToRadians(self, vector):
		""" Convert degree angles to radians. Returns MVector. 
			Parameters:
				vector (Tuple(x,y,z) or MVector)"""

		vector = om.MVector(vector)
		vector.x = om.MAngle(vector.x, unit = om.MAngle.kDegrees).asRadians()
		vector.y = om.MAngle(vector.y, unit = om.MAngle.kDegrees).asRadians()
		vector.z = om.MAngle(vector.z, unit = om.MAngle.kDegrees).asRadians()
		return om.MVector(vector)
Esempio n. 2
0
	def vectorRadiansToDegrees(self, vector):
		""" Convert radian angles to degrees. Returns MVector. 
			Parameters:
				vector (Tuple(x,y,z) or MVector)"""

		vector = om.MVector(vector)
		vector.x = om.MAngle(vector.x, unit = om.MAngle.kRadians).asDegrees()
		vector.y = om.MAngle(vector.y, unit = om.MAngle.kRadians).asDegrees()
		vector.z = om.MAngle(vector.z, unit = om.MAngle.kRadians).asDegrees()
		return om.MVector(vector)
Esempio n. 3
0
 def __init__(self, curve, idx):
     super(KeyFrame, self).__init__()
     self.curveobj = curve
     self.idx = idx
     self.timeobj = oma.MTime()
     self.time = 0.0
     self.value = 0.0
     self.inTanWT = (om.MAngle(0, om.MAngle.kRadians), 1.0)
     self.inTanXY = (1.0, 0.0)
     self.outTanWT = (om.MAngle(0, om.MAngle.kRadians), 1.0)
     self.outTanXY = (1.0, 0.0)
     self.load(idx)
Esempio n. 4
0
def getRotation(normal):
    vector = om.MVector(0, 1, 0)
    vNormal = om.MVector(normal[0], normal[1], normal[2])

    quat = om.MQuaternion(vector, vNormal)

    quat.normalizeIt()  # to normalize
    rot = quat.asEulerRotation()
    return [
        om.MAngle(rot.x).asDegrees(),
        om.MAngle(rot.y).asDegrees(),
        om.MAngle(rot.z).asDegrees()
    ]
Esempio n. 5
0
def addAttributesFromList(node, data):
    """Creates an attribute on the node given a list(dict) of attribute data

        :param data: The serialized form of the attribute
                    [{
                        "channelBox": true,
                        "default": 3,
                        "isDynamic": true,
                        "keyable": false,
                        "locked": false,
                        "max": 9999,
                        "min": 1,
                        "name": "jointCount",
                        "softMax": null,
                        "softMin": null,
                        "Type": 2,
                        "value": 3
                        "isArray": True
                    }]
        :type data: dict
        :return: A list of create MPlugs
        :rtype: list(om2.MPlug)
        """
    created = []
    for attrData in iter(data):
        Type = attrData["Type"]
        default = attrData["default"]
        value = attrData["value"]
        name = attrData["name"]
        if Type == attrtypes.kMFnDataString:
            default = om2.MFnStringData().create(default)
        elif Type == attrtypes.kMFnDataMatrix:
            default = om2.MFnMatrixData().create(om2.MMatrix(default))
        elif Type == attrtypes.kMFnUnitAttributeAngle:
            default = om2.MAngle(default, om2.MAngle.kDegrees)
            value = om2.MAngle(value, om2.MAngle.kDegrees)

        plug = om2.MPlug(node, addAttribute(node, name, name, Type, isArray=data.get("array", False), apply=True))
        plugs.setPlugDefault(plug, default)

        plug.isChannelBox = attrData["value"]
        plug.isKeyable = attrData["keyable"]
        plugs.setLockState(plug, attrData["locked"])
        plugs.setMin(plug, attrData["min"])
        plugs.setMax(plug, attrData["max"])
        plugs.setSoftMin(plug, attrData["softMin"])
        plugs.setSoftMax(plug, attrData["softMax"])
        if not plug.attribute().hasFn(om2.MFn.kMessageAttribute):
            plugs.setPlugValue(plug, value)
        created.append(plug)
    return created
Esempio n. 6
0
def get_attribute_default_value(plug):
    """ Get the default value for the given plug
    
    :param plug: Plug for the attribute
    :type plug: om.MPlug
    :return: Default value of the attribute found on the plug
    :rtype: float or None
    """
    attr = plug.attribute()
    api = attr.apiType()

    if api == om.MFn.kNumericAttribute:
        typeFn = om.MFnNumericAttribute(attr)
        return float(typeFn.default)

    if api in [om.MFn.kDoubleLinearAttribute, om.MFn.kFloatLinearAttribute]:
        typeFn = om.MFnUnitAttribute(attr)
        default = om.MDistance(typeFn.default)
        return default.value

    if api in [om.MFn.kDoubleAngleAttribute, om.MFn.kFloatAngleAttribute]:
        typeFn = om.MFnUnitAttribute(attr)
        default = om.MAngle(typeFn.default)
        return default.value

    return None
    def _get_angle(obj_path):
        node = obj_path.node()
        plug = om.MPlug(node, AngleConeHelperNode.angle)
        value = om.MAngle(0.0)
        if not plug.isNull:
            value = plug.asMAngle()

        return value
Esempio n. 8
0
def asEuler(rotation):
    """Converts tuple(float3) into a MEulerRotation

    :param rotation: a tuple of 3 elements in degrees which will be converted to redians for the eulerRotation
    :type rotation: tuple(float)
    :rtype: MEulerRotation
    """
    return om2.MEulerRotation(
        [om2.MAngle(i, om2.MAngle.kDegrees).asRadians() for i in rotation])
Esempio n. 9
0
    def compute(self, pPlug, pDataBlock):
                   
        ## Obtain the data handles for each attribute
        
        # Input Data Handles 
        J0DataHandle    = pDataBlock.inputValue( robotAccumRotation.J0Attr )
        JinDataHandle   = pDataBlock.inputValue( robotAccumRotation.JinAttr )
        JflipDataHandle = pDataBlock.inputValue( robotAccumRotation.JflipAttr )
        ikDataHandle    = pDataBlock.inputValue( robotAccumRotation.ikAttr )
        
        # Output Data Handles 
        JoutDataHandle = pDataBlock.outputValue( robotAccumRotation.JoutAttr )


        ## Extract the actual value associated to our input attribute
        J_0   = J0DataHandle.asAngle().asDegrees()
        J_in  = JinDataHandle.asAngle().asDegrees()
        Jflip = JflipDataHandle.asBool() 
        ik    = ikDataHandle.asBool()

        # Accumulate Rotation Solve Code 
        # If we're in IK mode, check to see if the current rotation value and 
        # the previous value differ by a large amount (e.g. 300 degrees)
        if ik:
            try:
                if abs(J_in - J_0) > 300: 
                    # If so, we assume that the inverse kinematic solver has
                    # flipped, so we manually flip the value back
                    # E.G. if J_0 = 179 and J_in = -179, we assume the output,
                    # J_out, should actually be +181
                    J_out = J_in - (abs(J_in)/J_in) * 360
                else:
                    J_out = J_in
            except:
                J_out = J_in
                
            # If the flipAxis boolean on the robot rig is set to True, we 
            # invert the output by +/- 360 degrees. So +235 becomes -125    
            if Jflip:
                try:
                    J_out = J_out - (abs(J_out)/J_out) * 360
                except:
                    pass
        # If ik is flase, we are in forward kinematic mode; in which case, we
        # pass the input straight through
        else:
            J_out = J_in
           
         
        # Set the Output Values
        Jout = JoutDataHandle.setMAngle( OpenMaya.MAngle( J_out , 2 ) )

            
        # Mark the output data handle as being clean; it need not be computed
        # given its input.
        JoutDataHandle.setClean()
Esempio n. 10
0
    def initialize(cls):
        unitFn = om.MFnUnitAttribute()
        AngleHelperNode.radius1 = unitFn.create("radius1", "r1",
                                                om.MFnUnitAttribute.kDistance)
        unitFn.channelBox = True
        unitFn.default = om.MDistance(0)
        unitFn.setMin(om.MDistance(0))
        om.MPxNode.addAttribute(AngleHelperNode.radius1)

        AngleHelperNode.radius2 = unitFn.create("radius2", "r2",
                                                om.MFnUnitAttribute.kDistance)
        unitFn.default = om.MDistance(1)
        unitFn.setMin(om.MDistance(0))
        unitFn.channelBox = True
        om.MPxNode.addAttribute(AngleHelperNode.radius2)

        AngleHelperNode.angle1 = unitFn.create("angle1", "a1",
                                               om.MFnUnitAttribute.kAngle)
        unitFn.default = om.MAngle(0)
        unitFn.channelBox = True
        om.MPxNode.addAttribute(AngleHelperNode.angle1)

        AngleHelperNode.angle2 = unitFn.create("angle2", "a2",
                                               om.MFnUnitAttribute.kAngle)
        unitFn.default = om.MAngle(0)
        unitFn.channelBox = True
        om.MPxNode.addAttribute(AngleHelperNode.angle2)

        numericFn = om.MFnNumericAttribute()
        AngleHelperNode.colorR = numericFn.create("colorR", "cr",
                                                  om.MFnNumericData.kFloat, 1)
        numericFn.channelBox = True
        om.MPxNode.addAttribute(AngleHelperNode.colorR)

        AngleHelperNode.colorG = numericFn.create("colorG", "cg",
                                                  om.MFnNumericData.kFloat, 0)
        numericFn.channelBox = True
        om.MPxNode.addAttribute(AngleHelperNode.colorG)

        AngleHelperNode.colorB = numericFn.create("colorB", "cb",
                                                  om.MFnNumericData.kFloat, 0)
        numericFn.channelBox = True
        om.MPxNode.addAttribute(AngleHelperNode.colorB)
Esempio n. 11
0
def pythonTypeToMayaType(dataType, value):
    if dataType == attrtypes.kMFnDataMatrixArray:
        return map(om2.MMatrix, value)
    elif attrtypes.kMFnDataVectorArray:
        return map(om2.MVector, value)
    elif dataType == attrtypes.kMFnUnitAttributeDistance:
        return om2.MDistance(value)
    elif dataType == attrtypes.kMFnUnitAttributeAngle:
        return om2.MAngle(value, om2.MAngle.kDegrees)
    elif dataType == attrtypes.kMFnUnitAttributeTime:
        return om2.MTime(value)
    return value
Esempio n. 12
0
    def fk_to_ik(node):
        """
        Calculates ik values corresponding to the current fk values and applies them.

        Args:
            node
        """
        # Get relevant data
        ik_pole_off = get_parent(node.ik_pole_conn)

        world_trans_ik_pole_off = get_world_trans(ik_pole_off)
        world_trans_fk_01 = get_world_trans(node.fk_01_conn)
        world_trans_fk_02 = get_world_trans(node.fk_02_conn)
        world_trans_fk_03 = get_world_trans(node.fk_03_conn)
        world_trans_ik_pole = get_world_trans(node.ik_pole_conn)

        world_rot_fk_03 = get_world_rot(node.fk_03_conn)

        # calculate ik pole position
        ik_pole_mid_point = (world_trans_fk_01 + world_trans_fk_03) / 2
        ik_pole_base = world_trans_fk_02 - ik_pole_mid_point

        # Handle the case when the leg is fully stretched
        if ik_pole_base.length() <= 0.0001:
            rot_fk_01 = get_rot_as_quat(node.fk_01_conn)
            rot_fk_02 = get_rot_as_quat(node.fk_02_conn)

            rot = rot_fk_01 * rot_fk_02

            ik_pole_base = oMa.MVector(2 * (rot.x * rot.z + rot.w * rot.y),
                                       2 * (rot.y * rot.z - rot.w * rot.x),
                                       1 - 2 * (rot.x * rot.x + rot.y * rot.y))

        ik_pole_len = (world_trans_ik_pole - world_trans_fk_02).length()

        pos_ik_pole = world_trans_fk_02 + ik_pole_base.normalize(
        ) * ik_pole_len - world_trans_ik_pole_off

        # Get the destination MPlugs
        ik_main_trans_plugs = get_trans_plugs(node.ik_main_conn)
        ik_main_rot_plugs = get_rot_plugs(node.ik_main_conn)
        ik_pole_trans_plugs = get_trans_plugs(node.ik_pole_conn)

        # Set the new values
        for i, plug in enumerate(ik_main_trans_plugs):
            plug.setFloat(world_trans_fk_03[i])

        for i, plug in enumerate(ik_main_rot_plugs):
            plug.setMAngle(oMa.MAngle(world_rot_fk_03[i], oMa.MAngle.kRadians))

        for i, plug in enumerate(ik_pole_trans_plugs):
            plug.setFloat(pos_ik_pole[i])
    def initialize(cls):
        unitFn = om.MFnUnitAttribute()

        AngleConeHelperNode.angle = unitFn.create("angle", "a",
                                                  om.MFnUnitAttribute.kAngle)
        unitFn.default = om.MAngle(0)
        unitFn.setMin(om.MAngle(0))
        unitFn.setMax(om.MAngle(math.pi))
        unitFn.channelBox = True
        om.MPxNode.addAttribute(AngleConeHelperNode.angle)

        numericFn = om.MFnNumericAttribute()

        AngleConeHelperNode.origin = numericFn.createPoint("origin", "o")
        numericFn.channelBox = True
        om.MPxNode.addAttribute(AngleConeHelperNode.origin)

        AngleConeHelperNode.target = numericFn.createPoint("target", "t")
        numericFn.channelBox = True
        om.MPxNode.addAttribute(AngleConeHelperNode.target)

        AngleConeHelperNode.colorR = numericFn.create("colorR", "cr",
                                                      om.MFnNumericData.kFloat,
                                                      1)
        numericFn.channelBox = True
        om.MPxNode.addAttribute(AngleConeHelperNode.colorR)

        AngleConeHelperNode.colorG = numericFn.create("colorG", "cg",
                                                      om.MFnNumericData.kFloat,
                                                      0)
        numericFn.channelBox = True
        om.MPxNode.addAttribute(AngleConeHelperNode.colorG)

        AngleConeHelperNode.colorB = numericFn.create("colorB", "cb",
                                                      om.MFnNumericData.kFloat,
                                                      0)
        numericFn.channelBox = True
        om.MPxNode.addAttribute(AngleConeHelperNode.colorB)
Esempio n. 14
0
    def compute(self, pPlug, pDataBlock):

        ## Obtain the data handles for each attribute

        # Input Data Handles
        JinDataHandle = pDataBlock.inputValue(robotLimitRotation.JinAttr)
        upperLimitDataHandle = pDataBlock.inputValue(
            robotLimitRotation.upperLimitAttr)
        lowerLimitDataHandle = pDataBlock.inputValue(
            robotLimitRotation.lowerLimitAttr)
        ikDataHandle = pDataBlock.inputValue(robotLimitRotation.ikAttr)

        # Output Data Handles
        JoutDataHandle = pDataBlock.outputValue(robotLimitRotation.JoutAttr)

        ## Extract the actual value associated to our input attribute
        J_in = JinDataHandle.asAngle().asDegrees()
        upperLimit = upperLimitDataHandle.asAngle().asDegrees()
        lowerLimit = lowerLimitDataHandle.asAngle().asDegrees()
        ik = ikDataHandle.asBool()

        #===================================#
        #     Limit Rotation Solve Code     #
        #===================================#
        # If the input is greater than the robot's upper rotation limit, or
        # less than the robot's lower rotation limit, we flip the axis rotation
        # by 360 degrees to achieve a value that fits within the robots limits
        if ik:
            if J_in > upperLimit:
                J_out = J_in - 360
                if J_out < lowerLimit and (abs(J_out - lowerLimit) >
                                           abs(J_in - upperLimit)):
                    J_out = J_out + 360
            elif J_in < lowerLimit:
                J_out = J_in + 360
                if J_out > upperLimit and (abs(J_out - upperLimit) >
                                           abs(J_in - lowerLimit)):
                    J_out = J_out - 360
            else:
                J_out = J_in

        else:
            J_out = J_in

        # Set the Output Values
        Jout = JoutDataHandle.setMAngle(OpenMaya.MAngle(J_out, 2))

        # Mark the output data handle as being clean; it need not be computed given its input.
        JoutDataHandle.setClean()
Esempio n. 15
0
    def setUnitAttr(plug, value, obj):
        apiType = obj.apiType()

        if apiType in [
                api2.MFn.kDoubleLinearAttribute, api2.MFn.kFloatLinearAttribute
        ]:
            unit = api2.MDistance.uiUnit()
            val = api2.MDistance(value, unit=unit)
            return plug.setMDistance(val)

        elif apiType in [
                api2.MFn.kDoubleAngleAttribute, api2.MFn.kFloatAngleAttribute
        ]:
            unit = api2.MAngle.uiUnit()
            val = api2.MAngle(value, unit=unit)
            return plug.setMAngle(val)

        elif apiType == api2.MFn.kTimeAttribute:
            unit = api2.MTime.uiUnit()
            val = api2.MTime(value, unit=unit)
            return plug.setMTime(val)

        return None
Esempio n. 16
0
def simplyfyAnimCurve(animationCurve, epsilon):
    """remove keys of the animation curve but preserving the overal shape

    Args:
        animationCurve (str): name of the animation curve
        epsilon (float): how much preserve the original keys
    """
    points = list()
    cacheAttrName = getCacheAttribute(animationCurve)
    points = cmds.getAttr(cacheAttrName)
    if not points:
        points = cacheCurvePoints(animationCurve)
    if not points:
        return
    animPoints = [a[:-1] for a in points]
    newPoints = rpd.simplify(animPoints, epsilon)
    fnAnimcurve = mUtils.getFn(animationCurve)
    #clear keys
    clearAnimCurve(fnAnimcurve)
    conversionValue = 1.0
    if fnAnimcurve.animCurveType == oma.MFnAnimCurve.kAnimCurveTA:
        conversionValue = om.MAngle(1.0).asDegrees()
    for time, value in newPoints:
        fnAnimcurve.addKey(om.MTime(time, TIMEUNIT), value/conversionValue)
Esempio n. 17
0
    def ik_to_fk(node):
        """
        Calculates fk values corresponding to the current ik values and applies them.

        Args:
            node
        """
        ik_main_off = get_parent(node.ik_main_conn)
        fk_01_off = get_parent(node.fk_01_conn)
        fk_02_off = get_parent(node.fk_02_conn)
        fk_03_off = get_parent(node.fk_03_conn)

        ik_main_world_trans = get_world_trans(node.ik_main_conn)
        fk_01_world_trans = get_world_trans(node.fk_01_conn)
        ik_main_off_world_trans = get_world_trans(ik_main_off)
        fk_01_off_world_trans = get_world_trans(fk_01_off)
        fk_02_off_world_trans = get_world_trans(fk_02_off)
        fk_03_off_world_trans = get_world_trans(fk_03_off)

        # calculate base information
        def_len = (ik_main_off_world_trans - fk_01_off_world_trans).length()

        # Calculate ik direction
        ik_dir_01 = ik_main_off_world_trans - fk_01_off_world_trans
        ik_dir_02 = ik_main_world_trans - fk_01_world_trans

        ik_dir_rot = ik_dir_01.rotateTo(ik_dir_02).asEulerRotation()

        # Apply ik direction -> important to calculate correct pole rotations
        fk_01_rot_plugs = get_rot_plugs(node.fk_01_conn)
        for i, plug in enumerate(fk_01_rot_plugs):
            plug.setMAngle(oMa.MAngle(ik_dir_rot[i], oMa.MAngle.kRadians))

        # Calculate ik pole rotations
        ik_pole_world_mat = get_world_matrix(node.ik_pole_conn, 0)
        fk_03_world_inv_mat = get_world_inv_matrix(node.fk_01_conn, 0)

        ik_pole_rot_mat = ik_pole_world_mat * fk_03_world_inv_mat

        ik_pole_vec = oMa.MTransformationMatrix(ik_pole_rot_mat).translation(
            oMa.MSpace.kWorld)
        ik_pole_vec.y = 0

        ik_pole_rot = oMa.MVector.kZaxisVector.rotateTo(
            ik_pole_vec).asEulerRotation()

        # Calculate ik rotations
        tri_a_len = (fk_02_off_world_trans - fk_01_off_world_trans).length()
        tri_b_len = (fk_03_off_world_trans - fk_02_off_world_trans).length()
        tri_c_len = (ik_main_world_trans - fk_01_world_trans).length()

        if tri_c_len >= def_len:
            fk_02_angle = 0
            fk_01_angle = 0
        else:
            fk_02_angle = math.pi - solve_triangle(tri_a_len, tri_b_len,
                                                   tri_c_len, "C")
            fk_01_angle = -solve_triangle(tri_a_len, tri_b_len, tri_c_len, "B")

        # Add rotations together
        fk_01_temp = oMa.MEulerRotation(fk_01_angle, ik_pole_rot.y, 0)

        ik_dir_mat = compose_mat(ik_dir_rot)
        fk_01_mat = compose_mat(fk_01_temp)
        rot_mat = fk_01_mat * ik_dir_mat

        # Apply everything
        fk_01_rot = get_rot_from_mat(rot_mat)
        fk_02_rot = (fk_02_angle, 0, 0)

        fk_01_rot_plugs = get_rot_plugs(node.fk_01_conn)
        for i, plug in enumerate(fk_01_rot_plugs):
            plug.setMAngle(oMa.MAngle(fk_01_rot[i], oMa.MAngle.kRadians))

        fk_02_rot_plugs = get_rot_plugs(node.fk_02_conn)
        for i, plug in enumerate(fk_02_rot_plugs):
            if not plug.isLocked:
                plug.setMAngle(oMa.MAngle(fk_02_rot[i], oMa.MAngle.kRadians))

        # Calculate ankle rotation
        fk_03_rot = rot_world_space_to_local_space(node.ik_main_conn,
                                                   get_parent(node.fk_03_conn))

        fk_03_rot_plugs = get_rot_plugs(node.fk_03_conn)
        for i, plug in enumerate(fk_03_rot_plugs):
            plug.setMAngle(oMa.MAngle(fk_03_rot[i], oMa.MAngle.kRadians))
Esempio n. 18
0
    def compute(self, plug, dataBlock):
        # get the incoming data
        inOverridingPoseIndex = dataBlock.inputValue(
            MatrixCombine.inOverridingPoseIndex).asInt()
        inOverridingWeight = dataBlock.inputValue(
            MatrixCombine.inOverridingWeight).asFloat()
        inOverridingIntensity = dataBlock.inputValue(
            MatrixCombine.inOverridingIntensity).asFloat()

        inInitialMatrix = dataBlock.inputValue(
            MatrixCombine.inInitialMatrix).asMatrix()
        inAllPoseInfoDataHandle = dataBlock.inputArrayValue(
            MatrixCombine.inAllPoseInfoList)
        inEditMode = dataBlock.inputValue(MatrixCombine.inEditMode).asFloat()
        inEditMatrix = dataBlock.inputValue(
            MatrixCombine.inEditMatrix).asMatrix()

        identityMatrix = om.MMatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0],
                                     [0, 0, 0, 1]])

        poseTranslation = om.MVector()
        poseQuaternion = om.MQuaternion()
        poseTransformMatrix = om.MTransformationMatrix(identityMatrix)

        if inOverridingIntensity > 0.0:
            # set the outgoing plug
            inAllPoseInfoDataHandle.jumpToPhysicalElement(
                inOverridingPoseIndex)
            currentPoseInfoDataHandle = inAllPoseInfoDataHandle.inputValue()
            inPoseMatrixDataHandle = currentPoseInfoDataHandle.child(
                MatrixCombine.inPoseMatrix)
            poseMatrixData = inPoseMatrixDataHandle.asMatrix()
            poseMatrix = om.MMatrix(poseMatrixData)

            poseTransformMatrix = om.MTransformationMatrix(poseMatrix)
            poseTranslation = poseTransformMatrix.translation(1)
            poseQuaternion = om.MQuaternion(
                poseTransformMatrix.rotationComponents(asQuaternion=True))

        else:
            poseMatrixList = []
            poseWeightsList = []

            for i in range(len(inAllPoseInfoDataHandle)):
                inAllPoseInfoDataHandle.jumpToPhysicalElement(i)

                currentPoseInfoDataHandle = inAllPoseInfoDataHandle.inputValue(
                )

                inPoseWeightDataHandle = currentPoseInfoDataHandle.child(
                    MatrixCombine.inPoseWeights)
                inPoseMatrixDataHandle = currentPoseInfoDataHandle.child(
                    MatrixCombine.inPoseMatrix)

                inPoseWeightArrayDataHandle = om.MArrayDataHandle(
                    inPoseWeightDataHandle)

                poseMatrixData = inPoseMatrixDataHandle.asMatrix()
                poseMatrix = om.MMatrix(poseMatrixData)
                poseMatrixList.append(poseMatrix)

                poseWeight = 0

                for w in range(len(inPoseWeightArrayDataHandle)):
                    inPoseWeightArrayDataHandle.jumpToPhysicalElement(w)
                    poseWeight += inPoseWeightArrayDataHandle.inputValue(
                    ).asFloat()

                if poseWeight > 1:
                    poseWeight = 1
                if poseWeight < 0:
                    poseWeight = 0

                poseWeightsList.append(poseWeight)

            # print 'poseWeightsList', poseWeightsList
            for i in range(len(poseMatrixList)):
                if poseWeightsList[i] > 0:
                    transMatrix = om.MTransformationMatrix(poseMatrixList[i])

                    translation = transMatrix.translation(1)
                    poseTranslation += translation * poseWeightsList[i]

                    quatTarget = om.MQuaternion(
                        transMatrix.rotationComponents(asQuaternion=True))
                    quatIdentity = om.MQuaternion()
                    quatBlend = om.MQuaternion.slerp(quatIdentity, quatTarget,
                                                     poseWeightsList[i])

                    poseQuaternion = poseQuaternion * quatBlend

        poseTransformMatrix.setRotationComponents(poseQuaternion,
                                                  asQuaternion=True)
        poseTransformMatrix.setTranslation(poseTranslation, 1)

        inInitialTransform = om.MTransformationMatrix(inInitialMatrix)

        inInitialQuat = om.MQuaternion(inInitialTransform.rotationComponents())
        inInitTranslation = om.MVector(inInitialTransform.translation(1))

        poseTransformMatrix.translateBy(inInitTranslation, 1)

        finalTranslation = poseTransformMatrix.translation(1)
        finalQuaternion = poseQuaternion * inInitialQuat

        finalEuler = finalQuaternion.asEulerRotation()

        # set the outgoing plug
        outTranslationX = finalTranslation[0]
        outTranslationY = finalTranslation[1]
        outTranslationZ = finalTranslation[2]

        outRotationX = om.MAngle(finalEuler[0], 1)
        outRotationY = om.MAngle(finalEuler[1], 1)
        outRotationZ = om.MAngle(finalEuler[2], 1)

        # set the outgoing plug
        dataHandle0 = dataBlock.outputValue(MatrixCombine.outTranslationX)
        dataHandle0.setFloat(outTranslationX)

        dataHandle1 = dataBlock.outputValue(MatrixCombine.outTranslationY)
        dataHandle1.setFloat(outTranslationY)

        dataHandle2 = dataBlock.outputValue(MatrixCombine.outTranslationZ)
        dataHandle2.setFloat(outTranslationZ)

        dataHandleRot0 = dataBlock.outputValue(MatrixCombine.outRotationX)
        dataHandleRot0.setMAngle(outRotationX)

        dataHandleRot1 = dataBlock.outputValue(MatrixCombine.outRotationY)
        dataHandleRot1.setMAngle(outRotationY)

        dataHandleRot2 = dataBlock.outputValue(MatrixCombine.outRotationZ)
        dataHandleRot2.setMAngle(outRotationZ)

        dataBlock.setClean(plug)
Esempio n. 19
0
                    # Time
                    input = mfnAnimCurve.input(keyIndex)
                    mTime = om.MTime(input)
                    currenttime = mTime.value
                    timeList.append(currenttime)

                    # Value
                    value = mfnAnimCurve.value(keyIndex)
                    valueList.append(value)

                    # InTangent
                    inTangentType = mfnAnimCurve.inTangentType(keyIndex)
                    inTangentTypeList.append(inTangentType)
                    inTangentAngleWeight = mfnAnimCurve.getTangentAngleWeight(
                        keyIndex, 1)
                    inTangetMAngle = om.MAngle(inTangentAngleWeight[0])
                    inTangentAngleValue = inTangetMAngle.value
                    inTangentAngleList.append(inTangentAngleValue)
                    inTangentWeightList.append(inTangentAngleWeight[1])

                    # OutTangent
                    outTangentType = mfnAnimCurve.outTangentType(keyIndex)
                    outTangentTypeList.append(outTangentType)
                    outTangentAngleWeight = mfnAnimCurve.getTangentAngleWeight(
                        keyIndex, 0)
                    outTangetMAngle = om.MAngle(outTangentAngleWeight[0])
                    outTangentAngleValue = outTangetMAngle.value
                    outTangentAngleList.append(outTangentAngleValue)
                    outTangentWeightList.append(outTangentAngleWeight[1])

                # Store the attribute vales to dictionary variable
Esempio n. 20
0
def addAttribute(node, longName, shortName, attrType=attrtypes.kMFnNumericDouble, isArray=False, apply=True):
    """This function uses the api to create attributes on the given node, currently WIP but currently works for
    string,int, float, bool, message, matrix. if the attribute exists a ValueError will be raised.

    :param node: MObject
    :param longName: str, the long name for the attribute
    :param shortName: str, the shortName for the attribute
    :param attrType: attribute Type, attrtypes constants
    :param apply: if False the attribute will be immediately created on the node else just return the attribute instance
    :rtype: om.MObject
    """
    if hasAttribute(node, longName):
        raise ValueError("Node -> '%s' already has attribute -> '%s'" % (nameFromMObject(node), longName))
    aobj = None
    attr = None
    if attrType == attrtypes.kMFnNumericDouble:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.kDouble)
    elif attrType == attrtypes.kMFnNumericFloat:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.kFloat)
    elif attrType == attrtypes.kMFnNumericBoolean:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.kBoolean)
    elif attrType == attrtypes.kMFnNumericInt:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.kInt)
    elif attrType == attrtypes.kMFnNumericShort:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.kShort)
    elif attrType == attrtypes.kMFnNumericLong:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.kLong)
    elif attrType == attrtypes.kMFnNumericByte:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.kByte)
    elif attrType == attrtypes.kMFnNumericChar:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.kChar)
    elif attrType == attrtypes.kMFnNumericAddr:
        attr = om2.MFnNumericAttribute()
        aobj = attr.createAddr(longName, shortName)
    elif attrType == attrtypes.kMFnkEnumAttribute:
        attr = om2.MFnEnumAttribute()
        aobj = attr.create(longName, shortName)
    elif attrType == attrtypes.kMFnCompoundAttribute:
        attr = om2.MFnCompoundAttribute()
        aobj = attr.create(longName, shortName)
    elif attrType == attrtypes.kMFnMessageAttribute:
        attr = om2.MFnMessageAttribute()
        aobj = attr.create(longName, shortName)
    elif attrType == attrtypes.kMFnDataString:
        attr = om2.MFnTypedAttribute()
        stringData = om2.MFnStringData().create("")
        aobj = attr.create(longName, shortName, om2.MFnData.kString, stringData)
    elif attrType == attrtypes.kMFnUnitAttributeDistance:
        attr = om2.MFnUnitAttribute()
        aobj = attr.create(longName, shortName, om2.MDistance())
    elif attrType == attrtypes.kMFnUnitAttributeAngle:
        attr = om2.MFnUnitAttribute()
        aobj = attr.create(longName, shortName, om2.MAngle())
    elif attrType == attrtypes.kMFnUnitAttributeTime:
        attr = om2.MFnUnitAttribute()
        aobj = attr.create(longName, shortName, om2.MTime())
    elif attrType == attrtypes.kMFnDataMatrix:
        attr = om2.MFnMatrixAttribute()
        aobj = attr.create(longName, shortName)
    elif attrType == attrtypes.kMFnDataFloatArray:
        attr = om2.MFnFloatArray()
        aobj = attr.create(longName, shortName)
    elif attrType == attrtypes.kMFnDataDoubleArray:
        data = om2.MFnDoubleArrayData().create(om2.MDoubleArray())
        attr = om2.MFnTypedAttribute()
        aobj = attr.create(longName, shortName, om2.MFnData.kDoubleArray, data)
    elif attrType == attrtypes.kMFnDataIntArray:
        data = om2.MFnIntArrayData().create(om2.MIntArray())
        attr = om2.MFnTypedAttribute()
        aobj = attr.create(longName, shortName, om2.MFnData.kIntArray, data)
    elif attrType == attrtypes.kMFnDataPointArray:
        data = om2.MFnPointArrayData().create(om2.MPointArray())
        attr = om2.MFnTypedAttribute()
        aobj = attr.create(longName, shortName, om2.MFnData.kPointArray, data)
    elif attrType == attrtypes.kMFnDataVectorArray:
        data = om2.MFnVectorArrayData().create(om2.MVectorArray())
        attr = om2.MFnTypedAttribute()
        aobj = attr.create(longName, shortName, om2.MFnData.kVectorArray, data)
    elif attrType == attrtypes.kMFnDataStringArray:
        data = om2.MFnStringArrayData().create(om2.MStringArray())
        attr = om2.MFnTypedAttribute()
        aobj = attr.create(longName, shortName, om2.MFnData.kStringArray, data)
    elif attrType == attrtypes.kMFnDataMatrixArray:
        data = om2.MFnMatrixArrayData().create(om2.MMatrixArray())
        attr = om2.MFnTypedAttribute()
        aobj = attr.create(longName, shortName, om2.MFnData.kMatrixArray, data)
    elif attrType == attrtypes.kMFnNumericInt64:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.kInt64)
    elif attrType == attrtypes.kMFnNumericLast:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.kLast)
    elif attrType == attrtypes.kMFnNumeric2Double:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.k2Double)
    elif attrType == attrtypes.kMFnNumeric2Float:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.k2Float)
    elif attrType == attrtypes.kMFnNumeric2Int:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.k2Int)
    elif attrType == attrtypes.kMFnNumeric2Long:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.k2Long)
    elif attrType == attrtypes.kMFnNumeric2Short:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.k2Short)
    elif attrType == attrtypes.kMFnNumeric3Double:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.k3Double)
    elif attrType == attrtypes.kMFnNumeric3Float:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.k3Float)
    elif attrType == attrtypes.kMFnNumeric3Int:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.k3Int)
    elif attrType == attrtypes.kMFnNumeric3Long:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.k3Long)
    elif attrType == attrtypes.kMFnNumeric3Short:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.k3Short)
    elif attrType == attrtypes.kMFnNumeric4Double:
        attr = om2.MFnNumericAttribute()
        aobj = attr.create(longName, shortName, om2.MFnNumericData.k4Double)

    if aobj is not None and apply:
        attr.array = isArray
        mod = om2.MDGModifier()
        mod.addAttribute(node, aobj)
        mod.doIt()
    return attr
Esempio n. 21
0
class robotLimitBlender(OpenMaya.MPxNode):
    # Static variables which will later be replaced by the node's attributes.
    # Inputs
    value_in_attr = OpenMaya.MAngle()
    upper_limit_attr = OpenMaya.MAngle()
    lower_limit_attr = OpenMaya.MAngle()

    shader_range_attr = OpenMaya.MObject()

    # Outputs
    blend_attr = OpenMaya.MAngle()

    def __init__(self):
        OpenMaya.MPxNode.__init__(self)

    ##################################################

    def compute(self, pPlug, pDataBlock):

        if pPlug == robotLimitBlender.blend_attr:
            ## Obtain the data handles for each attribute

            # Input Data Handles
            value_in_data_handle = pDataBlock.inputValue(
                robotLimitBlender.value_in_attr)
            upper_limit_data_handle = pDataBlock.inputValue(
                robotLimitBlender.upper_limit_attr)
            lower_limit_data_handle = pDataBlock.inputValue(
                robotLimitBlender.lower_limit_attr)
            shader_range_data_handle = pDataBlock.inputValue(
                robotLimitBlender.shader_range_attr)

            # Output Data Handles
            blend_data_handle = pDataBlock.outputValue(
                robotLimitBlender.blend_attr)

            ## Extract the actual value associated to our input attribute
            value_in = value_in_data_handle.asAngle().asDegrees()
            upper_limit = upper_limit_data_handle.asAngle().asDegrees()
            lower_limit = lower_limit_data_handle.asAngle().asDegrees()
            shader_range = shader_range_data_handle.asFloat()

            #==================================#
            #     Limit Blender Solve Code     #
            #==================================#
            upper_threshold = upper_limit - shader_range
            lower_threshold = lower_limit + shader_range

            if value_in >= upper_threshold:
                # If the value exceeds the upper limit,
                # clamp the value to the upper limit
                value = max(min(value_in, upper_limit), upper_threshold)

                # Remap the value between 0 and 1
                blend = (1.0 /
                         (upper_limit - upper_threshold)) * (value -
                                                             upper_threshold)

            elif value_in <= lower_threshold:
                # If the value exceeds the lower limit,
                # clamp the value to the lower limit
                value = min(max(value_in, lower_limit), lower_threshold)

                # Remap the value between 0 and 1
                blend = (1.0 /
                         (lower_limit - lower_threshold)) * (value -
                                                             lower_threshold)

            else:
                blend = 0

            # Set the Output Values
            blend_data_handle.setFloat(blend)

            # Mark the output data handle as being clean; it need not be computed given its input.
            blend_data_handle.setClean()
    curLen = i * size + moduloLenHalf
    param = curveFn.findParamFromLength(curLen)

    # Get the transformation values for the current object
    pos = curveFn.getPointAtParam(param, om2.MSpace.kWorld)
    tangent = curveFn.tangent(param, om2.MSpace.kWorld).normalize()
    upVector = om2.MVector(0.0, 1.0, 0.0)
    aim = tangent ^ upVector
    aim.normalize()
    normal = aim ^ tangent
    normal.normalize()
    qBasis = om2.MQuaternion()
    qAim = om2.MQuaternion(aimAxis, aim)
    qBasis *= qAim
    secAxis = upAxis.rotateBy(qAim)
    angle = secAxis.angle(normal)
    qNormal = om2.MQuaternion(angle, aim)
    if not normal.isEquivalent(secAxis.rotateBy(qNormal), 1.0e-5):
        angle = 2.0 * math.pi - angle
        qNormal = om2.MQuaternion(angle, aim)
    qBasis *= qNormal
    rot = qBasis.asEulerRotation()
    rot = [
        om2.MAngle(rot.x).asDegrees(),
        om2.MAngle(rot.y).asDegrees(),
        om2.MAngle(rot.z).asDegrees()
    ]

    # Create an instance of the original obj and apply the transformation
    instObj = cmds.instance(srcObj, n="%sInstance1" % srcObj, lf=True)[0]
    cmds.xform(instObj, t=(pos.x, pos.y, pos.z), ro=(rot[0], rot[1], rot[2]))
Esempio n. 23
0
def setRotation(node, rotation, space=om2.MSpace.kTransform):
    path = om2.MFnDagNode(node).getPath()
    trans = om2.MFnTransform(path)
    if isinstance(rotation, (list, tuple)):
        rotation = om2.MEulerRotation([om2.MAngle(i, om2.MAngle.kDegrees).asRadians() for i in rotation])
    trans.setRotation(rotation, space)
Esempio n. 24
0
def setPlugInfoFromDict(plug, **kwargs):
    """Sets the standard plug settings via a dict.


    :param plug: The Plug to change
    :type plug: om2.MPlug
    :param kwargs: currently includes, default, min, max, softMin, softMin, value, Type, channelBox, keyable, locked.
    :type kwargs: dict



    .. code-block:: python

        data = {
            "Type": 5, # attrtypes.kType
            "channelBox": true,
            "default": 1.0,
            "isDynamic": true,
            "keyable": true,
            "locked": false,
            "max": 99999,
            "min": 0.0,
            "name": "scale",
            "softMax": None,
            "softMin": None,
            "value": 1.0,
            "children": [{}] # in the same format as the parent info
          }
        somePLug = om2.MPlug()
        setPlugInfoFromDict(somePlug, **data)

    """
    children = kwargs.get("children", [])
    # just to ensure we dont crash we check to make sure the requested plug is a compound.
    if plug.isCompound:
        # cache the childCount
        childCount = plug.numChildren()
        if not children:
            #not a huge fan of doing a deepcopy just to deal with modifying the value/default further down
            children = [copy.deepcopy(kwargs) for i in xrange(childCount)]

            # now iterate the children data which contains a dict which is in the format
            for i, childInfo in enumerate(children):
                # it's possible that no data was passed for this child so skip
                if not childInfo:
                    continue
                # ensure the child index exists
                if i in range(childCount):
                    # modify the value and default value if we passed one in, this is done because the
                    # children would support a single value over and compound i.e kNumeric3Float
                    value = childInfo.get("value")
                    defaultValue = childInfo.get("default")
                    if value is not None and i in range(len(value)):
                        childInfo["value"] = value[i]
                    if defaultValue is not None and i in range(
                            len(defaultValue)):
                        childInfo["default"] = defaultValue[i]
                    setPlugInfoFromDict(plug.child(i), **childInfo)
        else:
            # now iterate the children data which contains a dict which is in the format
            for i, childInfo in enumerate(children):
                # it's possible that no data was passed for this child so skip
                if not childInfo:
                    continue
                # ensure the child index exists
                if i in range(childCount):
                    setPlugInfoFromDict(plug.child(i), **childInfo)

    default = kwargs.get("default")
    min = kwargs.get("min")
    max = kwargs.get("max")
    softMin = kwargs.get("softMin")
    softMax = kwargs.get("softMax")
    value = kwargs.get("value")
    Type = kwargs.get("Type")

    # certain data types require casting i.e MDistance
    if default is not None and Type is not None:
        if Type == attrtypes.kMFnDataString:
            default = om2.MFnStringData().create(default)
        elif Type == attrtypes.kMFnDataMatrix:
            default = om2.MMatrix(default)
            value = om2.MMatrix(value)
        elif Type == attrtypes.kMFnUnitAttributeAngle:
            default = om2.MAngle(default, om2.MAngle.kRadians)
            value = om2.MAngle(value, om2.MAngle.kRadians)
        elif Type == attrtypes.kMFnUnitAttributeDistance:
            default = om2.MDistance(default)
            value = om2.MDistance(value)
        elif Type == attrtypes.kMFnUnitAttributeTime:
            default = om2.MTime(default)
            value = om2.MTime(value)
        try:
            setPlugDefault(plug, default)
        except Exception:
            logger.error("Failed to set plug default values: {}".format(
                plug.name()),
                         exc_info=True,
                         extra={"data": default})
    if value is not None and not plug.attribute().hasFn(om2.MFn.kMessageAttribute) and not plug.isCompound and not \
            plug.isArray:
        setPlugValue(plug, value)
    if min is not None:
        setMin(plug, min)
    if max is not None:
        setMax(plug, max)
    if softMin is not None:
        setSoftMin(plug, softMin)
    if softMax is not None:
        setSoftMax(plug, softMax)
    plug.isChannelBox = kwargs.get("channelBox", False)
    plug.isKeyable = kwargs.get("keyable", False)
    plug.isLocked = kwargs.get("locked", False)
Esempio n. 25
0
def eulerToDegrees(euler):
    return [om2.MAngle(i, om2.MAngle.kRadians).asDegrees() for i in euler]
Esempio n. 26
0
    def compute(self, pPlug, pData):

        # only compute if output is in out array
        if not pPlug.isChild:
            return
        if (pPlug.parent() == generalIk.aOutArray):
            # descend into coordinated cycles
            # inputs

            solver = pData.inputValue(generalIk.aSolver).asInt()
            maxIter = pData.inputValue(generalIk.aMaxIter).asInt()
            tolerance = pData.inputValue(generalIk.aTolerance).asDouble()
            globalWeight = pData.inputValue(generalIk.aGlobalWeight).asDouble()
            cacheOn = pData.inputValue(generalIk.aCacheOn).asShort()

            # target
            targetMat = pData.inputValue(generalIk.aTargetMat).asMatrix()

            # end
            endMat = pData.inputValue(generalIk.aEndMat).asMatrix()

            # extract input world matrices from array then leave it alone
            inJntArrayDH = pData.inputArrayValue(generalIk.aJnts)
            inLength = inJntArrayDH.__len__()
            worldInputs = [None] * inLength
            orients = [None] * inLength
            ups = [None] * inLength
            jointData = [None] * inLength  # ARRAY OF STRUCTS REEEEEEEE
            for i in range(inLength):
                inJntArrayDH.jumpToPhysicalElement(i)
                childCompDH = inJntArrayDH.inputValue()
                worldInputs[i] = childCompDH.child(
                    generalIk.aJntMat).asMatrix()
                ups[i] = childCompDH.child(generalIk.aJntUpMat).asMatrix()

                orients[i] = om.MEulerRotation(
                    childCompDH.child(generalIk.aOrientRot).asDouble3())

                # extra data
                weight = childCompDH.child(generalIk.aJntWeight).asDouble()
                upDir = childCompDH.child(generalIk.aJntUpDir).asDouble3()
                jointData[i] = {
                    "weight": weight,
                    "upDir": upDir,
                }

            # from world inputs, reconstruct localised chain
            chainData = buildChains(worldInputs, orients, ups, length=inLength)
            localMatrices = chainData["localMatrices"]
            localUpMatrices = chainData["localUpMatrices"]
            ikSpaceMatrices = chainData["ikSpaceMatrices"]
            ikSpaceUpMatrices = chainData["ikSpaceUpMatrices"]
            # ikSpace and local matrices are correct

            # CACHE STUFF --------------------------------
            # extract cached matrices from previous graph evaluation
            cacheMatrices = pData.inputValue(generalIk.aCacheMatrices)
            cacheArray = om.MFnMatrixArrayData(cacheMatrices.data()).array()

            if len(cacheArray) != inLength:
                print("cache length different, rebuilding")
                cacheArray.clear()
                for n in localMatrices:
                    cacheArray.append(n)

            for i in range(inLength):
                if positionFromMatrix(localMatrices[i]) != \
                  positionFromMatrix(cacheArray[i]):
                    print("cache entry {} position has changed, substituting".
                          format(i))
                    cacheArray[i] = localMatrices[i]

            if cacheOn == 1 or cacheOn == 2:  # bind or bound
                # set local matrices to cached ------
                for i in range(inLength):
                    localMatrices[i] = cacheArray[i]
                if cacheOn == 1:
                    pData.inputValue(generalIk.aCacheOn).setShort(2)
            """ I don't think there is any point in treating the end
			matrix separately - it only adds a special case at every turn
			
			refactor to include it in normal local matrices
			
			"""

            # main loop ----------------
            n = 0
            tol = 100

            endIkSpace = endMat * worldInputs[0].inverse()
            # endIkSpace is correct

            targetMat = neutraliseRotations(targetMat)
            endLocalSpace = endMat * worldInputs[-1].inverse()
            """ localise target into ikSpace """
            targetIkSpace = targetMat * worldInputs[0].inverse()
            # targetIkSpace is correct

            while n < maxIter and tol > tolerance:
                debug()
                debug("n", n)
                data = iterateChainCCD(
                    worldMatrices=worldInputs,
                    ikSpaceMatrices=ikSpaceMatrices,
                    localMatrices=localMatrices,
                    length=inLength,
                    targetMat=targetIkSpace,
                    endMat=endIkSpace,
                    localEndMat=endLocalSpace,
                    upMatrices=ups,
                    jointData=jointData,
                    globalWeight=globalWeight,
                    ikSpaceUpMatrices=ikSpaceUpMatrices,
                    tolerance=tolerance,
                )
                localMatrices = data["results"]

                debug("results", localMatrices)

                tol = data["tolerance"]
                endIkSpace = data["end"]
                targetMat = data["target"]

                n += 1

                if tol < tolerance:
                    # process is complete
                    break

            results = localMatrices

            worldSpaceTarget = worldInputs[0] * targetMat

            ikSpaceOutputs = [
                multiplyMatrices(localMatrices[:i + 1])
                for i in range(inLength)
            ]
            endLocalSpace = endIkSpace * ikSpaceOutputs[-1].inverse()

            # save cached matrices for next evaluation
            # BEFORE reapplying world space to base
            cacheArray.clear()
            for i in localMatrices:
                cacheArray.append(i)

            # restore world space root position
            results[0] = results[0] * worldInputs[0]

            # outputs ---------------
            spaceConstant = 1

            outDebugDH = pData.outputValue(generalIk.aDebugTarget)
            outDebugDH.setMMatrix(worldSpaceTarget)
            outDebugOffsetDH = pData.outputValue(generalIk.aDebugOffset)
            outDebugOffsetDH.setDouble(tol)

            # end transform
            endTfMat = om.MTransformationMatrix(endLocalSpace)
            outEndTransDH = pData.outputValue(generalIk.aOutEndTrans)
            outEndTransDH.set3Double(*endTfMat.translation(spaceConstant))

            # convert jntArray of matrices to useful rotation values
            outArrayDH = pData.outputArrayValue(generalIk.aOutArray)

            for i in range(inLength):
                outArrayDH.jumpToPhysicalElement(i)
                outCompDH = outArrayDH.outputValue()

                outRotDH = outCompDH.child(generalIk.aOutRot)
                outRxDH = outRotDH.child(generalIk.aOutRx)
                outRyDH = outRotDH.child(generalIk.aOutRy)
                outRzDH = outRotDH.child(generalIk.aOutRz)

                # apply jointOrient -----
                outMat = om.MTransformationMatrix(results[i]).rotateBy(
                    orients[i].inverse(), spaceConstant)

                # set output rotations -------
                outRot = outMat.rotation()
                # unitConversions bring SHAME on family
                xAngle = om.MAngle(outRot[0])
                yAngle = om.MAngle(outRot[1])
                zAngle = om.MAngle(outRot[2])
                outRxDH.setMAngle(xAngle)
                outRyDH.setMAngle(yAngle)
                outRzDH.setMAngle(zAngle)

                outTranslate = (results[i][12], results[i][13], results[i][14])
                outTransDH = outCompDH.child(generalIk.aOutTrans)
                outTransDH.set3Double(*outTranslate)

            outArrayDH.setAllClean()

            pData.setClean(pPlug)
Esempio n. 27
0
class robotIKS(OpenMaya.MPxNode):
    """
    """
    # Define Node Input Attributes
    tcp_x_attr = OpenMaya.MObject()
    tcp_y_attr = OpenMaya.MObject()
    tcp_z_attr = OpenMaya.MObject()
    tcp_mat_attr = OpenMaya.MMatrix()
    lcs_x_attr = OpenMaya.MObject()
    lcs_y_attr = OpenMaya.MObject()
    lcs_z_attr = OpenMaya.MObject()
    lcs_mat_attr = OpenMaya.MMatrix()
    target_x_attr = OpenMaya.MObject()
    target_y_attr = OpenMaya.MObject()
    target_z_attr = OpenMaya.MObject()
    target_mat_attr = OpenMaya.MMatrix()
    
    a1_attr = OpenMaya.MObject()
    a2_attr = OpenMaya.MObject()
    b_attr = OpenMaya.MObject()
    c1_attr = OpenMaya.MObject()
    c2_attr = OpenMaya.MObject()
    c3_attr = OpenMaya.MObject()
    c4_attr = OpenMaya.MObject()
    
    axis1_offset_attr = OpenMaya.MObject()
    axis2_offset_attr = OpenMaya.MObject()
    axis3_offset_attr = OpenMaya.MObject()
    axis4_offset_attr = OpenMaya.MObject()
    axis5_offset_attr = OpenMaya.MObject()
    axis6_offset_attr = OpenMaya.MObject()
    
    flip_a1_attr = OpenMaya.MObject()
    flip_a2_attr = OpenMaya.MObject()
    flip_a3_attr = OpenMaya.MObject()
    flip_a4_attr = OpenMaya.MObject()
    flip_a5_attr = OpenMaya.MObject()
    flip_a6_attr = OpenMaya.MObject()
    
    sol_1_attr = OpenMaya.MObject()
    sol_2_attr = OpenMaya.MObject()
    sol_3_attr = OpenMaya.MObject()
    
    ik_attr = OpenMaya.MObject()

    a1_fk_attr = OpenMaya.MAngle()
    a2_fk_attr = OpenMaya.MAngle()
    a3_fk_attr = OpenMaya.MAngle()
    a4_fk_attr = OpenMaya.MAngle()
    a5_fk_attr = OpenMaya.MAngle()
    a6_fk_attr = OpenMaya.MAngle()

    solver_type_attr = OpenMaya.MObject()

    # Outputs 
    theta1_attr = OpenMaya.MAngle()
    theta2_attr = OpenMaya.MAngle()
    theta3_attr = OpenMaya.MAngle()
    theta4_attr = OpenMaya.MAngle()
    theta5_attr = OpenMaya.MAngle()
    theta6_attr = OpenMaya.MAngle()

    
    def __init__(self):
        OpenMaya.MPxNode.__init__(self)
    
    
    ##################################################
        
    def compute(self, pPlug, pDataBlock):
                   
        # Obtain the data handles for each attribute
        
        ## Input Data Handles ##
        tcp_x_data_handle = pDataBlock.inputValue(robotIKS.tcp_x_attr)
        tcp_y_data_handle = pDataBlock.inputValue(robotIKS.tcp_y_attr)
        tcp_z_data_handle = pDataBlock.inputValue(robotIKS.tcp_z_attr)
        tcp_mat_data_handle = pDataBlock.inputValue(robotIKS.tcp_mat_attr)
        lcs_x_data_handle = pDataBlock.inputValue(robotIKS.lcs_x_attr)  
        lcs_y_data_handle = pDataBlock.inputValue(robotIKS.lcs_y_attr)
        lcs_z_data_handle = pDataBlock.inputValue(robotIKS.lcs_z_attr)
        lcs_mat_data_handle = pDataBlock.inputValue(robotIKS.lcs_mat_attr)                      
        target_x_data_handle = pDataBlock.inputValue(robotIKS.target_x_attr)
        target_y_data_handle = pDataBlock.inputValue(robotIKS.target_y_attr)
        target_z_data_handle = pDataBlock.inputValue(robotIKS.target_z_attr)
        target_mat_data_handle = pDataBlock.inputValue(robotIKS.target_mat_attr)
        
        a1_data_handle = pDataBlock.inputValue(robotIKS.a1_attr)
        a2_data_handle = pDataBlock.inputValue(robotIKS.a2_attr)
        b_data_handle = pDataBlock.inputValue(robotIKS.b_attr)
        c1_data_handle = pDataBlock.inputValue(robotIKS.c1_attr)
        c2_data_handle = pDataBlock.inputValue(robotIKS.c2_attr)
        c3_data_handle = pDataBlock.inputValue(robotIKS.c3_attr)
        c4_data_handle = pDataBlock.inputValue(robotIKS.c4_attr)

        axis1_offset_data_handle = pDataBlock.inputValue(robotIKS.axis1_offset_attr)
        axis2_offset_data_handle = pDataBlock.inputValue(robotIKS.axis2_offset_attr)
        axis3_offset_data_handle = pDataBlock.inputValue(robotIKS.axis3_offset_attr)
        axis4_offset_data_handle = pDataBlock.inputValue(robotIKS.axis4_offset_attr)
        axis5_offset_data_handle = pDataBlock.inputValue(robotIKS.axis5_offset_attr)
        axis6_offset_data_handle = pDataBlock.inputValue(robotIKS.axis6_offset_attr)
        
        flip_a1_data_handle = pDataBlock.inputValue(robotIKS.flip_a1_attr)
        flip_a2_data_handle = pDataBlock.inputValue(robotIKS.flip_a2_attr)
        flip_a3_data_handle = pDataBlock.inputValue(robotIKS.flip_a3_attr)
        flip_a4_data_handle = pDataBlock.inputValue(robotIKS.flip_a4_attr)
        flip_a5_data_handle = pDataBlock.inputValue(robotIKS.flip_a5_attr)
        flip_a6_data_handle = pDataBlock.inputValue(robotIKS.flip_a6_attr)
        
        sol_1_data_handle = pDataBlock.inputValue(robotIKS.sol_1_attr)
        sol_2_data_handle = pDataBlock.inputValue(robotIKS.sol_2_attr)
        sol_3_data_handle = pDataBlock.inputValue(robotIKS.sol_3_attr)

        ik_data_handle = pDataBlock.inputValue(robotIKS.ik_attr)

        a1_fk_data_handle = pDataBlock.inputValue(robotIKS.a1_fk_attr)
        a2_fk_data_handle = pDataBlock.inputValue(robotIKS.a2_fk_attr)
        a3_fk_data_handle = pDataBlock.inputValue(robotIKS.a3_fk_attr)
        a4_fk_data_handle = pDataBlock.inputValue(robotIKS.a4_fk_attr)
        a5_fk_data_handle = pDataBlock.inputValue(robotIKS.a5_fk_attr)
        a6_fk_data_handle = pDataBlock.inputValue(robotIKS.a6_fk_attr)

        solver_type_data_handle = pDataBlock.inputValue(robotIKS.solver_type_attr)

        # Extract the actual value associated to our input attribute
        tcp = [tcp_x_data_handle.asFloat(),
               tcp_y_data_handle.asFloat(),
               tcp_z_data_handle.asFloat()]

        tcp_mat = tcp_mat_data_handle.asMatrix()

        lcs = [lcs_x_data_handle.asFloat(),
               lcs_y_data_handle.asFloat(),
               lcs_z_data_handle.asFloat()]

        lcs_mat = lcs_mat_data_handle.asMatrix()

        target = [target_x_data_handle.asFloat(),
                  target_y_data_handle.asFloat(),
                  target_z_data_handle.asFloat()]

        target_mat = target_mat_data_handle.asMatrix() 
        
        # Robot Definition
        robot_definition = [a1_data_handle.asFloat(),
                            a2_data_handle.asFloat(),
                            b_data_handle.asFloat(),
                            c1_data_handle.asFloat(),
                            c2_data_handle.asFloat(),
                            c3_data_handle.asFloat(),
                            c4_data_handle.asFloat()]

        # Axis Offset Values (robot's zero position in relation to IK solver zero position)
        axis1_offset = axis1_offset_data_handle.asFloat()
        axis2_offset = axis2_offset_data_handle.asFloat()
        axis3_offset = axis3_offset_data_handle.asFloat()
        axis4_offset = axis4_offset_data_handle.asFloat()
        axis5_offset = axis5_offset_data_handle.asFloat()
        axis6_offset = axis6_offset_data_handle.asFloat()
        
        angle_offsets = [axis1_offset,
                         axis2_offset,
                         axis3_offset,
                         axis4_offset,
                         axis5_offset,
                         axis6_offset]

        # Flip Axis Direction bools
        flip_a1 = flip_a1_data_handle.asBool()
        flip_a2 = flip_a2_data_handle.asBool()
        flip_a3 = flip_a3_data_handle.asBool()
        flip_a4 = flip_a4_data_handle.asBool()
        flip_a5 = flip_a5_data_handle.asBool()
        flip_a6 = flip_a6_data_handle.asBool()

        flip_rot_directions = [flip_a1, flip_a2, flip_a3, flip_a4, flip_a5, flip_a6]
        
        # Joint config solution bools
        sol = [sol_1_data_handle.asBool(),
               sol_2_data_handle.asBool(),
               sol_3_data_handle.asBool()]
        
        ik = ik_data_handle.asBool()

        # FK Handle inputs
        a1_fk = a1_fk_data_handle.asAngle().asDegrees()
        a2_fk = a2_fk_data_handle.asAngle().asDegrees()
        a3_fk = a3_fk_data_handle.asAngle().asDegrees()
        a4_fk = a4_fk_data_handle.asAngle().asDegrees()
        a5_fk = a5_fk_data_handle.asAngle().asDegrees()
        a6_fk = a6_fk_data_handle.asAngle().asDegrees()

        # Solver Type
        solver_type = solver_type_data_handle.asInt()
        
        ## Output Data Handles ##
        theta1_out_data_handle = pDataBlock.outputValue(robotIKS.theta1_attr)
        theta2_out_data_handle = pDataBlock.outputValue(robotIKS.theta2_attr)
        theta3_out_data_handle = pDataBlock.outputValue(robotIKS.theta3_attr)
        theta4_out_data_handle = pDataBlock.outputValue(robotIKS.theta4_attr)
        theta5_out_data_handle = pDataBlock.outputValue(robotIKS.theta5_attr)
        theta6_out_data_handle = pDataBlock.outputValue(robotIKS.theta6_attr)
        


        if ik:
            thetas = inverse_kinematics.solve(
                            tcp,
                            tcp_mat,
                            lcs,
                            lcs_mat,
                            target,
                            target_mat,
                            robot_definition,
                            solver_type,
                            sol)
           
            # Apply axis offsets
            thetas = inverse_kinematics.apply_offsets(thetas,
                                            angle_offsets,
                                            flip_rot_directions)
            
            # Convert to MAngle data type for output
            # (the "2" is for data type degrees. 1 = radians)
            a1 = OpenMaya.MAngle(thetas[0], 2)
            a2 = OpenMaya.MAngle(thetas[1], 2)
            a3 = OpenMaya.MAngle(thetas[2], 2)
            a4 = OpenMaya.MAngle(thetas[3], 2)
            a5 = OpenMaya.MAngle(thetas[4], 2)
            a6 = OpenMaya.MAngle(thetas[5], 2)
            
            # Set the Output Values
            theta1 = theta1_out_data_handle.setMAngle(a1)
            theta2 = theta2_out_data_handle.setMAngle(a2)
            theta3 = theta3_out_data_handle.setMAngle(a3)
            theta4 = theta4_out_data_handle.setMAngle(a4)
            theta5 = theta5_out_data_handle.setMAngle(a5)
            theta6 = theta6_out_data_handle.setMAngle(a6) 
            
                
            # Mark the output data handle as being clean; it need not be computed given its input.
            theta1_out_data_handle.setClean()
            theta2_out_data_handle.setClean()
            theta3_out_data_handle.setClean()
            theta4_out_data_handle.setClean()
            theta5_out_data_handle.setClean()
            theta6_out_data_handle.setClean()

        else:
            # Set the Output Values
            theta1 = theta1_out_data_handle.setMAngle(OpenMaya.MAngle(a1_fk, 2))
            theta2 = theta2_out_data_handle.setMAngle(OpenMaya.MAngle(a2_fk, 2))
            theta3 = theta3_out_data_handle.setMAngle(OpenMaya.MAngle(a3_fk, 2))
            theta4 = theta4_out_data_handle.setMAngle(OpenMaya.MAngle(a4_fk, 2))
            theta5 = theta5_out_data_handle.setMAngle(OpenMaya.MAngle(a5_fk, 2))
            theta6 = theta6_out_data_handle.setMAngle(OpenMaya.MAngle(a6_fk, 2)) 
            
                
            # Mark the output data handle as being clean; it need not be computed given its input.
            theta1_out_data_handle.setClean()
            theta2_out_data_handle.setClean()
            theta3_out_data_handle.setClean()
            theta4_out_data_handle.setClean()
            theta5_out_data_handle.setClean()
            theta6_out_data_handle.setClean()
Esempio n. 28
0
                    MFnAnimCurve.create(attributeMPlug, animCurveType)

                # set value
                MFnAnimCurve.setPreInfinityType(preInfinity)
                MFnAnimCurve.setPostInfinityType(postInfinity)

                MFnAnimCurve.setIsWeighted(weightedTangents)

                MTimeArray = om.MTimeArray()
                MDoubleValueList = om.MDoubleArray()

                for index in range(len(timeList)):
                    MTimeArray.append(om.MTime(timeList[index]), om.MTime.uiUnit())
                    MDoubleValueList.append(valueList[index])

                MFnAnimCurve.addKeys(MTimeArray, MDoubleValueList, 0, 0, 1)

                for index in range(len(timeList)):
                    MFnAnimCurve.setInTangentType(index, inTangentTypeList[index])
                    MFnAnimCurve.setOutTangentType(index, outTangentTypeList[index])

                    inTangentAngle = om.MAngle(inTangentAngleList[index])
                    outTangentAngle = om.MAngle(outTangentAngleList[index])

                    MFnAnimCurve.setAngle(index, inTangentAngle, 1)
                    MFnAnimCurve.setAngle(index, outTangentAngle, 0)

                    MFnAnimCurve.setWeight(index, inTangentAngleWeightList[index], 1)
                    MFnAnimCurve.setWeight(index, outTangentAngleWeightList[index], 0)
Esempio n. 29
0
def setPlugValue(plug, value):
    """
    Sets the given plug's value to the passed in value.

    :param plug: MPlug, The node plug.
    :param value: type, Any value of any data type.
    """

    if plug.isArray:
        count = plug.evaluateNumElements()
        if count != len(value):
            return
        for i in range(count):
            setPlugValue(plug.elementByPhysicalIndex(i), value[i])
        return
    elif plug.isCompound:
        count = plug.numChildren()
        if count != len(value):
            return
        for i in range(count):
            setPlugValue(plug.child(i), value[i])
        return
    obj = plug.attribute()
    if obj.hasFn(om2.MFn.kUnitAttribute):
        attr = om2.MFnUnitAttribute(obj)
        ut = attr.unitType()
        if ut == om2.MFnUnitAttribute.kDistance:
            plug.setMDistance(om2.MDistance(value))
        elif ut == om2.MFnUnitAttribute.kTime:
            plug.setMTime(om2.MTime(value))
        elif ut == om2.MFnUnitAttribute.kAngle:
            plug.setMAngle(om2.MAngle(value))
    elif obj.hasFn(om2.MFn.kNumericAttribute):
        attr = om2.MFnNumericAttribute(obj)
        at = attr.numericType()
        if at in (om2.MFnNumericData.k2Double, om2.MFnNumericData.k2Float,
                  om2.MFnNumericData.k2Int, om2.MFnNumericData.k2Long,
                  om2.MFnNumericData.k2Short, om2.MFnNumericData.k3Double,
                  om2.MFnNumericData.k3Float, om2.MFnNumericData.k3Int,
                  om2.MFnNumericData.k3Long, om2.MFnNumericData.k3Short,
                  om2.MFnNumericData.k4Double):
            data = om2.MFnNumericData().create(value)
            plug.setMObject(data.object())
        elif at == om2.MFnNumericData.kDouble:
            plug.setDouble(value)
        elif at == om2.MFnNumericData.kFloat:
            plug.setFloat(value)
        elif at == om2.MFnNumericData.kBoolean:
            plug.setBool(value)
        elif at == om2.MFnNumericData.kChar:
            plug.setChar(value)
        elif at in (om2.MFnNumericData.kInt, om2.MFnNumericData.kInt64,
                    om2.MFnNumericData.kLong, om2.MFnNumericData.kLast):
            plug.setInt(value)
        elif at == om2.MFnNumericData.kShort:
            plug.setInt(value)

    elif obj.hasFn(om2.MFn.kEnumAttribute):
        plug.setInt(value)

    elif obj.hasFn(om2.MFn.kTypedAttribute):
        attr = om2.MFnTypedAttribute(obj)
        at = attr.attrType()
        if at == om2.MFnData.kMatrix:
            mat = om2.MFnMatrixData().create(om2.MMatrix(value))
            plug.setMObject(mat)
        elif at == om2.MFnData.kString:
            plug.setString(value)

    elif obj.hasFn(om2.MFn.kMatrixAttribute):
        mat = om2.MFnMatrixData().create(om2.MMatrix(value))
        plug.setMObject(mat)
    elif obj.hasFn(om2.MFn.kMessageAttribute) and isinstance(value, om2.MPlug):
        # connect the message attribute
        connectPlugs(plug, value)
    else:
        raise ValueError(
            "Currently we don't support dataType ->{} contact the developers to get this implemented"
            .format(obj.apiTypeStr))
Esempio n. 30
0
def importAnimCurve(
    selectionList,
    animPath,
):

    animData = open(animPath, 'r')
    data = json.load(animData)
    animData.close()

    if data and selectionList:
        for eachObject in selectionList:
            for eachAnimCurveAttribute in data['animCurve'][eachObject]:

                # get value
                animCurveType = data['animCurve'][eachObject][
                    eachAnimCurveAttribute]['animCurveType']
                preInfinity = data['animCurve'][eachObject][
                    eachAnimCurveAttribute]['preInfinity']
                postInfinity = data['animCurve'][eachObject][
                    eachAnimCurveAttribute]['postInfinity']
                weightedTangents = data['animCurve'][eachObject][
                    eachAnimCurveAttribute]['weightedTangents']
                numKeys = data['animCurve'][eachObject][
                    eachAnimCurveAttribute]['numKeys']
                timeList = data['animCurve'][eachObject][
                    eachAnimCurveAttribute]['timeList']
                valueList = data['animCurve'][eachObject][
                    eachAnimCurveAttribute]['valueList']
                inTangentTypeList = data['animCurve'][eachObject][
                    eachAnimCurveAttribute]['inTangentTypeList']
                inTangentAngleList = data['animCurve'][eachObject][
                    eachAnimCurveAttribute]['inTangentAngleList']
                inTangentAngleWeightList = data['animCurve'][eachObject][
                    eachAnimCurveAttribute]['inTangentAngleWeightList']
                outTangentTypeList = data['animCurve'][eachObject][
                    eachAnimCurveAttribute]['outTangentTypeList']
                outTangentAngleList = data['animCurve'][eachObject][
                    eachAnimCurveAttribute]['outTangentAngleList']
                outTangentAngleWeightList = data['animCurve'][eachObject][
                    eachAnimCurveAttribute]['outTangentAngleWeightList']

                # convert current object and attribute to a new MPlug object
                mSelectionList = om.MSelectionList()
                mSelectionList.add('%s.%s' %
                                   (eachObject, eachAnimCurveAttribute))

                attributeMPlug = mSelectionList.getPlug(0)

                connectedList = attributeMPlug.connectedTo(1, 0)

                # whether to create a new curve or use the existed curve
                newAnimCurve = 1
                if connectedList:
                    connectedNode = connectedList[0].node()

                    if connectedNode.hasFn(om.MFn.kAnimCurve):

                        MFnAnimCurve = oma.MFnAnimCurve(connectedNode)
                        newAnimCurve = 0

                if newAnimCurve:
                    MFnAnimCurve = oma.MFnAnimCurve()

                    MFnAnimCurve.create(attributeMPlug, animCurveType)

                # set value
                MFnAnimCurve.setPreInfinityType(preInfinity)
                MFnAnimCurve.setPostInfinityType(postInfinity)

                MFnAnimCurve.setIsWeighted(weightedTangents)

                MTimeArray = om.MTimeArray()
                MDoubleValueList = om.MDoubleArray()

                for index in range(len(timeList)):
                    MTimeArray.append(
                        om.MTime(timeList[index], om.MTime.uiUnit()))
                    MDoubleValueList.append(valueList[index])

                MFnAnimCurve.addKeys(MTimeArray, MDoubleValueList, 0, 0, 1)

                for index in range(len(timeList)):
                    MFnAnimCurve.setInTangentType(index,
                                                  inTangentTypeList[index])
                    MFnAnimCurve.setOutTangentType(index,
                                                   outTangentTypeList[index])

                    inTangentAngle = om.MAngle(inTangentAngleList[index])
                    outTangentAngle = om.MAngle(outTangentAngleList[index])

                    MFnAnimCurve.setAngle(index, inTangentAngle, 1)
                    MFnAnimCurve.setAngle(index, outTangentAngle, 0)

                    MFnAnimCurve.setWeight(index,
                                           inTangentAngleWeightList[index], 1)
                    MFnAnimCurve.setWeight(index,
                                           outTangentAngleWeightList[index], 0)

    # read history
    historyData = data['history']
    historyList = [
        'Owner: %s' % historyData[0],
        'Created: %s' % historyData[1],
        'Maya version: %s' % historyData[2],
        'Module version: %s' % historyData[3]
    ]

    return historyList