Exemplo n.º 1
0
Arquivo: ikrig.py Projeto: rombick/cmt
def create(prefix=None):
    if prefix is None:
        prefix = ""
    node = cmds.createNode("ikRig")
    joints = ['Hips', 'Spine3', 'Neck', 'Head', 'Clavicle_L', 'UpperArm_L', 'Forearm_L', 'Hand_L', 'Thigh_L',
              'Knee_L', 'Foot_L', 'Clavicle_R', 'UpperArm_R', 'Forearm_R', 'Hand_R', 'Thigh_R', 'Knee_R', 'Foot_R']

    out_joints = ['pelvis', 'spine_03', 'neck_01', 'head', 'clavicle_l', 'upperarm_l', 'lowerarm_l', 'hand_l',
                  'thigh_l', 'calf_l', 'foot_l', 'clavicle_r', 'upperarm_r', 'lowerarm_r', 'hand_r', 'thigh_r',
                  'calf_r', 'foot_r']
    out_joints = ["{}{}".format(prefix, j) for j in out_joints]

    locs = []
    for i, j in enumerate(joints):
        cmds.connectAttr("{}.worldMatrix[0]".format(j), "{}.inMatrix[{}]".format(node, i))
        path = shortcuts.get_dag_path2(j)
        rest_matrix = list(path.inclusiveMatrix())
        cmds.setAttr("{}.inRestMatrix[{}]".format(node, i), *rest_matrix, type="matrix")

        path = shortcuts.get_dag_path2(out_joints[i])
        matrix = list(path.inclusiveMatrix())
        cmds.setAttr("{}.targetRestMatrix[{}]".format(node, i), *matrix, type="matrix")

        loc = cmds.spaceLocator(name="ikrig_{}".format(out_joints[i]))[0]
        cmds.connectAttr("{}.outputTranslate[{}]".format(node, i), "{}.t".format(loc))
        cmds.connectAttr("{}.outputRotate[{}]".format(node, i), "{}.r".format(loc))

        cmds.setAttr("{}Shape.localScale".format(loc), 5, 5, 5)
        locs.append(loc)

    for loc, joint in zip(locs, out_joints):
        cmds.parentConstraint(loc, joint)
    loc = cmds.spaceLocator(name="rootMotion")[0]
    cmds.connectAttr("{}.rootMotion".format(node), "{}.opm".format(loc))
    return node
Exemplo n.º 2
0
def mirror_curve(source, destination):
    """Mirrors the curve on source across the YZ plane to destination.

    The cvs will be mirrored in world space no matter the transform of destination.

    :param source: Source transform
    :param destination: Destination transform
    :return: The mirrored CurveShape object
    """
    source_curve = CurveShape(source)

    path_source = shortcuts.get_dag_path2(source)
    matrix = path_source.inclusiveMatrix()

    path_destination = shortcuts.get_dag_path2(destination)
    inverse_matrix = path_destination.inclusiveMatrixInverse()

    world_cvs = [OpenMaya.MPoint(*x) * matrix for x in source_curve.cvs]
    for cv in world_cvs:
        cv.x *= -1
    local_cvs = [p * inverse_matrix for p in world_cvs]
    source_curve.cvs = [(p.x, p.y, p.z) for p in local_cvs]
    is_controller = cmds.controller(source, q=True, isController=True)
    source_curve.transform = destination
    source_curve.create(destination, as_controller=is_controller)
    return source_curve
Exemplo n.º 3
0
def tpose_arm(shoulder,
              elbow,
              wrist,
              hand_aim=None,
              hand_up=None,
              length_scale=1.0):
    """Put the given shoulder, elbow, and wrist joints in a tpose.

    This function assumes the character is facing forward z.

    :param shoulder: Shoulder joint
    :param elbow: Elbow joint
    :param wrist: Wrist joint
    :param hand_aim: Local hand aim vector (Default [+-]1.0, 0.0, 0.0)
    :param hand_up: Local hand up vector (Default 0.0, 0.0, [+-]1.0)
    """
    a = OpenMaya.MVector(*cmds.xform(shoulder, q=True, ws=True, t=True))
    b = OpenMaya.MVector(*cmds.xform(elbow, q=True, ws=True, t=True))
    c = OpenMaya.MVector(*cmds.xform(wrist, q=True, ws=True, t=True))
    direction = 1.0 if b.x > a.x else -1.0

    t = OpenMaya.MVector(a)
    t.x += ((b - a).length() + (c - b).length()) * direction * length_scale
    pv = (a + t) * 0.5
    pv.z -= 100.0
    path_shoulder = shortcuts.get_dag_path2(shoulder)
    path_elbow = shortcuts.get_dag_path2(elbow)

    a_gr = OpenMaya.MTransformationMatrix(
        path_shoulder.inclusiveMatrix()).rotation(asQuaternion=True)
    b_gr = OpenMaya.MTransformationMatrix(
        path_elbow.inclusiveMatrix()).rotation(asQuaternion=True)
    ac = (c - a).normal()
    d = (b - (a + (ac * ((b - a) * ac)))).normal()

    a_gr, b_gr = two_bone_ik(a, b, c, d, t, pv, a_gr, b_gr)

    fn_shoulder = OpenMaya.MFnTransform(path_shoulder)
    fn_shoulder.setRotation(a_gr, OpenMaya.MSpace.kWorld)
    fn_elbow = OpenMaya.MFnTransform(path_elbow)
    fn_elbow.setRotation(b_gr, OpenMaya.MSpace.kWorld)

    if hand_aim is None:
        hand_aim = (1.0 * direction, 0.0, 0.0)
    if hand_up is None:
        hand_up = (0.0, 0.0, 1.0 * direction)
    aim_loc = cmds.spaceLocator()[0]
    t.x += direction
    cmds.xform(aim_loc, ws=True, t=(t.x, t.y, t.z))
    cmds.delete(
        cmds.aimConstraint(
            aim_loc,
            wrist,
            aimVector=hand_aim,
            upVector=hand_up,
            worldUpType="vector",
            worldUpVector=[0.0, 0.0, -1.0],
        ))
    cmds.delete(aim_loc)
Exemplo n.º 4
0
def attach_skeletons(source_joints, target_joints):
    """Create the ikRig node and constrain the target joints to locators driven by the ikRig node.

    :param source_joints: List of source joints in the order listed in Parts
    :param target_joints: List of target joints in the order listed in Parts
    :return: The created ikRig node
    """
    cmds.loadPlugin("cmt", qt=True)
    node = cmds.createNode("ikRig")
    locs = []
    for i, j in enumerate(source_joints):
        if j and not cmds.objExists(j):
            raise RuntimeError("Joint {} does not exist".format(j))
        if target_joints[i] and not cmds.objExists(target_joints[i]):
            raise RuntimeError("Joint {} does not exist".format(
                target_joints[i]))

        if j:
            cmds.connectAttr("{}.worldMatrix[0]".format(j),
                             "{}.inMatrix[{}]".format(node, i))
            path = shortcuts.get_dag_path2(j)
            rest_matrix = list(path.inclusiveMatrix())
            cmds.setAttr("{}.inRestMatrix[{}]".format(node, i),
                         *rest_matrix,
                         type="matrix")

        if target_joints[i]:
            path = shortcuts.get_dag_path2(target_joints[i])
            matrix = list(path.inclusiveMatrix())
            cmds.setAttr("{}.targetRestMatrix[{}]".format(node, i),
                         *matrix,
                         type="matrix")

            loc = cmds.spaceLocator(
                name="ikrig_{}".format(target_joints[i]))[0]
            cmds.connectAttr("{}.outputTranslate[{}]".format(node, i),
                             "{}.t".format(loc))
            cmds.connectAttr("{}.outputRotate[{}]".format(node, i),
                             "{}.r".format(loc))

            cmds.setAttr("{}Shape.localScale".format(loc), 5, 5, 5)
            locs.append(loc)
        else:
            locs.append(None)

    for loc, joint in zip(locs, target_joints):
        if loc and joint:
            cmds.parentConstraint(loc, joint)

    return node
Exemplo n.º 5
0
def _connect_driver_matrix_network(blend, node, driver, index,
                                   to_parent_local):
    # The multMatrix node will calculate the transformation to blend to when driven
    # by this driver transform
    mult = cmds.createNode("multMatrix",
                           name="spaceswitch_{}_to_{}".format(node, driver))

    offset = (shortcuts.get_dag_path2(node).exclusiveMatrix() *
              OpenMaya.MMatrix(
                  cmds.getAttr("{}.worldInverseMatrix[0]".format(driver))))
    cmds.setAttr("{}.matrixIn[0]".format(mult), list(offset), type="matrix")

    cmds.connectAttr("{}.worldMatrix[0]".format(driver),
                     "{}.matrixIn[1]".format(mult))

    if to_parent_local:
        cmds.connectAttr(to_parent_local, "{}.matrixIn[2]".format(mult))

    cmds.connectAttr("{}.matrixSum".format(mult),
                     "{}.target[{}].targetMatrix".format(blend, index))
Exemplo n.º 6
0
def get_points(mesh):
    path = shortcuts.get_dag_path2(shortcuts.get_shape(mesh))
    mesh_fn = OpenMaya.MFnMesh(path)
    return mesh_fn.getPoints()
Exemplo n.º 7
0
def set_points(mesh, points):
    path = shortcuts.get_dag_path2(shortcuts.get_shape(mesh))
    mesh_fn = OpenMaya.MFnMesh(path)
    mesh_fn.setPoints(points)
Exemplo n.º 8
0
    def create(self, global_scale_attr=None):
        self.spline_chain, original_chain = common.duplicate_chain(
            self.start_joint, self.end_joint, prefix="ikSpine_"
        )

        # Create the spline ik
        self.ik_handle, self.effector, self.curve = cmds.ikHandle(
            name="{}_ikh".format(self.name),
            solver="ikSplineSolver",
            startJoint=self.spline_chain[0],
            endEffector=self.spline_chain[-1],
            parentCurve=False,
            simplifyCurve=False,
        )
        self.effector = cmds.rename(self.effector, "{}_eff".format(self.name))
        self.curve = cmds.rename(self.curve, "{}_crv".format(self.name))

        # Create the joints to skin the curve
        curve_start_joint = cmds.duplicate(
            self.start_joint, parentOnly=True, name="{}CurveStart_jnt".format(self.name)
        )[0]
        start_parent = cmds.listRelatives(self.start_control, parent=True, path=True)
        if start_parent:
            cmds.parent(curve_start_joint, start_parent[0])
        cmds.pointConstraint(self.start_control, curve_start_joint)

        curve_end_joint = cmds.duplicate(
            self.end_joint, parentOnly=True, name="{}CurveEnd_jnt".format(self.name)
        )[0]
        cmds.parent(curve_end_joint, self.end_control)
        for node in [curve_start_joint, curve_end_joint]:
            cmds.setAttr("{}.v".format(node), 0)

        # Skin curve
        cmds.skinCluster(
            curve_start_joint,
            curve_end_joint,
            self.curve,
            name="{}_scl".format(self.name),
            tsb=True,
        )

        # Create stretch network
        curve_info = cmds.arclen(self.curve, constructionHistory=True)
        scale_mdn = cmds.createNode(
            "multiplyDivide", name="{}_global_scale_mdn".format(self.name)
        )
        cmds.connectAttr(
            "{}.arcLength".format(curve_info), "{}.input1X".format(scale_mdn)
        )
        if global_scale_attr:
            cmds.connectAttr(global_scale_attr, "{}.input2X".format(scale_mdn))
        else:
            cmds.setAttr("{}.input2X".format(scale_mdn), 1)
        cmds.setAttr("{}.operation".format(scale_mdn), 2)  # Divide

        mdn = cmds.createNode("multiplyDivide", name="{}Stretch_mdn".format(self.name))
        cmds.connectAttr("{}.outputX".format(scale_mdn), "{}.input1X".format(mdn))
        cmds.setAttr(
            "{}.input2X".format(mdn), cmds.getAttr("{}.arcLength".format(curve_info))
        )
        cmds.setAttr("{}.operation".format(mdn), 2)  # Divide

        # Connect to joints
        for joint in self.spline_chain[1:]:
            tx = cmds.getAttr("{}.translateX".format(joint))
            mdl = cmds.createNode(
                "multDoubleLinear", name="{}Stretch_mdl".format(joint)
            )
            cmds.setAttr("{}.input1".format(mdl), tx)
            cmds.connectAttr("{}.outputX".format(mdn), "{}.input2".format(mdl))
            cmds.connectAttr("{}.output".format(mdl), "{}.translateX".format(joint))

        joint_up = OpenMaya.MVector(0.0, 1.0, 0.0)
        start_joint_path = shortcuts.get_dag_path2(self.start_joint)
        start_control_path = shortcuts.get_dag_path2(self.start_control)
        up_vector_start = (
            joint_up
            * start_joint_path.inclusiveMatrix()
            * start_control_path.inclusiveMatrixInverse()
        )

        end_joint_path = shortcuts.get_dag_path2(self.end_joint)
        end_control_path = shortcuts.get_dag_path2(self.end_control)
        up_vector_end = (
            joint_up
            * end_joint_path.inclusiveMatrix()
            * end_control_path.inclusiveMatrixInverse()
        )

        # Setup advanced twist
        cmds.setAttr("{}.dTwistControlEnable".format(self.ik_handle), True)
        cmds.setAttr("{}.dWorldUpType".format(self.ik_handle), 4)  # Object up
        cmds.setAttr("{}.dWorldUpAxis".format(self.ik_handle), 0)  # Positive Y Up
        cmds.setAttr("{}.dWorldUpVectorX".format(self.ik_handle), up_vector_start.x)
        cmds.setAttr("{}.dWorldUpVectorY".format(self.ik_handle), up_vector_start.y)
        cmds.setAttr("{}.dWorldUpVectorZ".format(self.ik_handle), up_vector_start.z)
        cmds.setAttr("{}.dWorldUpVectorEndX".format(self.ik_handle), up_vector_end.x)
        cmds.setAttr("{}.dWorldUpVectorEndY".format(self.ik_handle), up_vector_end.y)
        cmds.setAttr("{}.dWorldUpVectorEndZ".format(self.ik_handle), up_vector_end.z)
        cmds.connectAttr(
            "{}.worldMatrix[0]".format(self.start_control),
            "{}.dWorldUpMatrix".format(self.ik_handle),
        )
        cmds.connectAttr(
            "{}.worldMatrix[0]".format(self.end_control),
            "{}.dWorldUpMatrixEnd".format(self.ik_handle),
        )

        # Constrain original chain back to spline chain
        for ik_joint, joint in zip(self.spline_chain, original_chain):
            if joint == self.end_joint:
                cmds.pointConstraint(ik_joint, joint, mo=True)
                cmds.orientConstraint(self.end_control, joint, mo=True)
            elif joint == self.start_joint:
                cmds.parentConstraint(self.start_control, joint, mo=True)
            else:
                cmds.parentConstraint(ik_joint, joint)
Exemplo n.º 9
0
def opm_constraint(
    driver,
    driven,
    maintain_offset=False,
    freeze=True,
    use_translate=True,
    use_rotate=True,
    use_scale=True,
    use_shear=True,
    segment_scale_compensate=True,
):
    """Create a parent constraint effect with offsetParentMatrix.

    :param driver: Target transforms
    :param driven: Transform to drive
    :param maintain_offset: True to maintain offset
    :param freeze: True to 0 out the local xforms
    :param use_translate: True to use the translation of the driver matrix
    :param use_rotate: True to use the rotation of the driver matrix
    :param use_scale: True to use the scale of the driver matrix
    :param use_shear: True to use the shear of the driver matrix
    :param segment_scale_compensate: True to remove the resulting scale and shear
    :return: The multMatrix node used in the network
    """
    mult = cmds.createNode(
        "multMatrix",
        name="{}_offset_parent_constraint_mult_matrix".format(driven))

    if maintain_offset:
        if freeze:
            offset = OpenMaya.MMatrix(
                cmds.getAttr("{}.worldMatrix[0]".format(driven)))
        else:
            offset = shortcuts.get_dag_path2(driven).exclusiveMatrix()
        offset *= OpenMaya.MMatrix(
            cmds.getAttr("{}.worldInverseMatrix[0]".format(driver)))
        cmds.setAttr("{}.matrixIn[0]".format(mult),
                     list(offset),
                     type="matrix")

    pick = cmds.createNode(
        "pickMatrix", name="{}_offset_parent_constraint_pick".format(driven))
    cmds.connectAttr("{}.worldMatrix[0]".format(driver),
                     "{}.inputMatrix".format(pick))
    cmds.setAttr("{}.useTranslate".format(pick), use_translate)
    cmds.setAttr("{}.useRotate".format(pick), use_rotate)
    cmds.setAttr("{}.useScale".format(pick), use_scale)
    cmds.setAttr("{}.useShear".format(pick), use_shear)

    cmds.connectAttr("{}.outputMatrix".format(pick),
                     "{}.matrixIn[1]".format(mult))
    parent = cmds.listRelatives(driven, parent=True, path=True)
    if parent:
        cmds.connectAttr("{}.worldInverseMatrix[0]".format(parent[0]),
                         "{}.matrixIn[2]".format(mult))
    if freeze:
        freeze_to_parent_offset(driven)

    if segment_scale_compensate:
        pick = cmds.createNode(
            "pickMatrix", name="{}_segment_scale_compensate".format(driven))
        cmds.setAttr("{}.useScale".format(pick), False)
        cmds.setAttr("{}.useShear".format(pick), False)
        cmds.connectAttr("{}.matrixSum".format(mult),
                         "{}.inputMatrix".format(pick))
        output = "{}.outputMatrix".format(pick)
    else:
        output = "{}.matrixSum".format(mult)

    cmds.connectAttr(output, "{}.offsetParentMatrix".format(driven))
    return mult