Beispiel #1
0
def assignBindAttributes(joints=None):
    """
    Assigns the bind matrix attribute to the given joints.

    Args:
        joints (list): Joints to assign bind matrix attribute to. If None given, will use selected or all joints.
    """
    joints = myu.validateSelect(joints, find='joint')

    for joint in joints:

        if not joint.hasAttr(pcfg.length_attribute):
            joint.addAttr(pcfg.length_attribute,
                          s=True,
                          w=True,
                          r=True,
                          dv=0.001,
                          min=0.001)

        joint_parent = joint.getParent()
        if joint_parent and isinstance(joint_parent, pm.nodetypes.Joint):
            distance_name = joint.name() + '_to_' + joint_parent.name(
            ) + pcfg.distance_suffix

            if pm.objExists(distance_name):
                pm.delete(distance_name)

            distance = pm.createNode('distanceBetween', n=distance_name)
            joint.worldMatrix >> distance.inMatrix1
            joint_parent.worldMatrix >> distance.inMatrix2
            distance.distance >> joint.attr(pcfg.length_attribute)

    pm.displayInfo('Finished assigning Piper joint attributes to ' +
                   str(len(joints)) + ' joints.')
Beispiel #2
0
def parent(transforms, world=False):
    """
    Parents transforms to the last given transform and gets rid of joint orient values if transform is a joint.

    Args:
        transforms (list or pm.nodetypes.DependNode): Transforms to parent. Last transform is the parent of the rest.
        Minimum of two objects.

        world (boolean): If True, will parent all the given transforms to world
    """
    transforms = myu.validateSelect(transforms, minimum=1)

    if world:
        for transform in transforms:

            if isinstance(transform, pm.nodetypes.Joint):
                matrix = transform.worldMatrix.get()
                pm.parent(transform, w=True)
                transform.jointOrient.set(0, 0, 0)
                pm.xform(transform, ws=True, m=matrix)
            else:
                pm.parent(transform, w=True)
    else:
        for transform in transforms[:-1]:

            if isinstance(transform, pm.nodetypes.Joint):
                matrix = transform.worldMatrix.get()
                pm.parent(transform, transforms[-1])
                transform.jointOrient.set(0, 0, 0)
                pm.xform(transform, ws=True, m=matrix)
            else:
                pm.parent(transform, transforms[-1])
Beispiel #3
0
def assignLabels(joints=None):
    """
    Assigns labels and sides to the given joints based on their names.

    Args:
        joints (list): Joints to assign labels to.
    """
    joints = myu.validateSelect(joints, find='joint')

    for joint in joints:
        joint_name = joint.nodeName()

        if joint_name.endswith(pcfg.left_suffix):
            joint.side.set(1)
            joint_name = pcu.removeSuffixes(joint_name, pcfg.left_suffix)
        elif joint_name.endswith(pcfg.right_suffix):
            joint.side.set(2)
            joint_name = pcu.removeSuffixes(joint_name, pcfg.right_suffix)

        # have to do string "type" because type is a built-in python function
        if joint_name in convert.JOINT_LABELS:
            label = convert.jointNameToLabel(joint_name)
            joint.attr('type').set(label)
        else:
            label = convert.jointNameToLabel('other')
            joint.attr('type').set(label)
            joint.otherType.set(joint_name)
Beispiel #4
0
    def unbind(self, meshes=None, bind_pose=True):
        """
        Unbinds the skin clusters from the given meshes (will use selection or all meshes in scene if None).
        Stores skin cluster weights in a temp file to be rebound with the rebind method.

        Args:
            meshes (list): Meshes to unbind.

            bind_pose (boolean): If True will move joints back to the bind pose before unbinding.

        Returns:
            (dictionary): All the info gathered  from unbinding joints.
        """
        # reset info
        self.info = {}
        scene_path = pm.sceneName()
        scene_name = os.path.splitext(
            scene_path.name)[0] + '_' if scene_path else ''
        meshes = myu.validateSelect(meshes, find='mesh', parent=True)
        pcu.validateDirectory(self.directory)

        for mesh in meshes:
            # get the skin of the mesh, if it doesnt exist then we don't need to store skin weights
            mesh_name = mesh.nodeName()
            skin = mesh.listHistory(type='skinCluster')

            if not skin:
                continue

            # get the info we need to rebind the mesh: skin name, max influences, and joints influencing mesh
            # stored as string in case object gets deleted and renamed after unbinding
            skin = skin[0].nodeName()
            max_influences = pm.skinCluster(mesh, q=True, mi=True)
            joints = [
                joint.nodeName()
                for joint in pm.skinCluster(skin, q=True, influence=True)
            ]

            if bind_pose:
                returnToBindPose(joints)

            # select mesh, export skin weights, and detach skin using MEL because pm.bindSkin(delete=True) has errors.
            pm.select(mesh)
            deformer_name = scene_name + mesh_name + '.xml'
            path = pm.deformerWeights(deformer_name,
                                      export=True,
                                      deformer=skin,
                                      path=self.directory)
            pm.mel.eval('doDetachSkin "2" { "1","1" }')

            self.info[mesh_name] = {
                'skin': skin,
                'max_influences': max_influences,
                'joints': joints,
                'path': path
            }

        pm.select(meshes)
        return self.info
Beispiel #5
0
def createAtPivot(selected=None):
    """
    Creates a joint at the current manipulator pivot point.
    """
    joints = []
    shift_held = myu.isShiftHeld()
    ctrl_held = myu.isCtrlHeld()
    alt_held = myu.isAltHeld()
    selected = myu.validateSelect(selected, minimum=1)

    if shift_held:
        for transform in selected:
            name = transform.nodeName() if alt_held else ''
            if isinstance(transform, pm.nodetypes.Transform):
                joint, position, _ = _createAtPivot(transform,
                                                    name,
                                                    joints=joints)
                xform.orientToTransform(transform, joint, ctrl_held)

            elif isinstance(transform, pm.general.MeshVertex):
                for i in transform.indices():
                    joint, position, vertex = _createAtPivot(
                        transform, name, i, 'vtx', joints)
                    xform.orientToVertex(joint, vertex, position, ctrl_held)

            elif isinstance(transform, pm.general.MeshEdge):
                for i in transform.indices():
                    joint, position, edge = _createAtPivot(
                        transform, name, i, 'e', joints)
                    xform.orientToEdge(joint, edge, position, ctrl_held)

            elif isinstance(transform, pm.general.MeshFace):
                for i in transform.indices():
                    joint, position, face = _createAtPivot(
                        transform, name, i, 'f', joints)
                    xform.orientToFace(joint, face, position, ctrl_held)

    else:
        transform = selected[-1]
        name = transform.nodeName() if alt_held else ''
        joint, position, _ = _createAtPivot(transform, name, joints=joints)

        if len(selected) == 1 and ctrl_held:

            if isinstance(transform, pm.nodetypes.Transform):
                xform.orientToTransform(transform, joint)

            elif isinstance(transform, pm.general.MeshVertex):
                xform.orientToVertex(joint, transform, position)

            elif isinstance(transform, pm.general.MeshEdge):
                xform.orientToEdge(joint, transform, position)

            elif isinstance(transform, pm.general.MeshFace):
                xform.orientToFace(joint, transform, position)

    return joints
Beispiel #6
0
def mirrorTranslate(transforms=None,
                    axis=pcfg.default_mirror_axis,
                    swap=None,
                    duplicate=True):
    """
    Mirrors the given transforms across the given axis set up to be used as a mirror translate transform.

    Args:
        transforms (list): Transforms to mirror across given axis.

        axis (string): Name of axis to mirror across.

        swap (list): Text to swap with each other for duplicates name.

        duplicate (boolean): If True will duplicate transforms before mirroring. Else will mirror the given transforms.

    Returns:
        (list): Transforms mirrored.
    """
    transforms = myu.validateSelect(transforms)
    axis_vector = convert.axisToVector(axis, absolute=True)
    mirrored_axis = [value * -1 for value in axis_vector]
    mirrored_axis.append(1)
    to_mirror = []

    if swap is None:
        swap = [pcfg.left_suffix, pcfg.right_suffix]

    if duplicate:
        for transform in transforms:
            name = transform.nodeName()
            new_name = pcu.swapText(name, *swap)
            new_transform = pm.duplicate(transform,
                                         ic=False,
                                         un=False,
                                         n=new_name)[0]
            to_mirror.append(new_transform)
    else:
        to_mirror = transforms

    for transform in to_mirror:
        matrix = transform.worldMatrix.get()
        identity = [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]
        mirrored_matrix = [
            m * a if m != 0 and a != 0 else m for row in identity
            for m, a in zip(row, mirrored_axis)
        ]
        mirrored_matrix = matrix * pm.dt.Matrix(mirrored_matrix)
        pm.xform(transform, ws=True, m=mirrored_matrix)
        [
            transform.attr('s' + axis).set(
                abs(transform.attr('s' + axis).get()))
            for axis in ['x', 'y', 'z']
        ]

    return to_mirror
Beispiel #7
0
def mirrorRotate(transforms=None, axis=pcfg.default_mirror_axis, swap=None):
    """
    Mirrors the given transforms across the given axis set up to be used as a mirror rotate transform.

    Args:
        transforms (list): Transforms to mirror across given axis.

        axis (string): Name of axis to mirror across.

        swap (list): Words to search and replace. Will search for first index, and replace with second index.

    Returns:
        (list): Joints that were mirrored. Note that all their children get mirrored as well.
    """
    mirrored_transforms = []
    transforms = myu.validateSelect(transforms)
    options = {
        'mxy': False,
        'myz': False,
        'mxz': False,
        'mb': True,
        'sr': swap
    }

    if axis == 'x':
        options['myz'] = True
    elif axis == 'y':
        options['mxz'] = True
    elif axis == 'z':
        options['mxy'] = True
    else:
        pm.error('No valid axis given. Pick "x", "y", or "z".')

    for transform in transforms:
        name = transform.nodeName()

        if not swap:
            if name.endswith(pcfg.left_suffix):
                options['sr'] = [pcfg.left_suffix, pcfg.right_suffix]
            elif name.endswith(pcfg.right_suffix):
                options['sr'] = [pcfg.right_suffix, pcfg.left_suffix]
            else:
                options['sr'] = ['', '']

        mirrored_joint = pm.mirrorJoint(transform, **options)[0]
        mirrored_joint = pm.PyNode(mirrored_joint)
        mirrored_transforms.append(mirrored_joint)
        joint_parent = mirrored_joint.getParent()

        if joint_parent:
            pm.parent(mirrored_joint, w=True)
            parent([mirrored_joint, joint_parent])

    return mirrored_transforms
Beispiel #8
0
def createTensionDisplay(transforms=None,
                         shape_display=pm.warning,
                         skin_display=pm.warning):
    """
    Creates tension nodes and hooks them up to mesh by intercepting the skin cluster.

    Args:
        transforms (list): Transforms with mesh shapes that will get tension nodes hooked up.

        shape_display (method): Error to display if there are not two shapes.

        skin_display (method): Error to display if no skin clusters found.

    Returns:
        (list): Tension nodes created.
    """
    tension_nodes = []
    transforms = myu.validateSelect(transforms, find='mesh', parent=True)

    for transform in transforms:
        original_shape = None
        deformed_shape = None
        skin_cluster = None
        shapes = transform.getShapes()

        if len(shapes) != 2:
            shape_display(
                'Need two shapes! A deformed shape and an original one.')
            continue

        # get skin cluster and figure out which shape is the original and which is the deformed
        for i, shape in enumerate(shapes):
            skin_cluster = shape.listHistory(type='skinCluster')
            if skin_cluster:
                skin_cluster = skin_cluster[0]
                deformed_shape = shape
                original_shape = shapes[0] if i == 1 else shapes[1]
                break

        if not skin_cluster:
            skin_display('No skin cluster found.')
            continue

        # create tension node and hook it up with necessary data
        tension = pm.createNode('tensionNode',
                                name=transform.nodeName() + '_tension')
        skin_cluster.outputGeometry[0] >> tension.deformedShape
        original_shape.worldMesh >> tension.origShape
        deformed_shape.inMesh.disconnect()
        tension.out >> deformed_shape.inMesh
        tension_nodes.append(tension)

    return tension_nodes
Beispiel #9
0
def addDelete(transforms=None):
    """
    Adds a "delete" attribute to the given transforms that marks them to be delete on export.

    Args:
        transforms (list): List of pm.nodetypes.transform to add "delete" attribute to.
    """
    transforms = myu.validateSelect(transforms, display=pm.warning)

    for transform in transforms:
        addSeparator(transform)
        transform.addAttr(pcfg.delete_node_attribute,
                          at='bool',
                          k=True,
                          dv=1,
                          max=1,
                          min=1)
        nonKeyable(transform.delete)
Beispiel #10
0
def returnToBindPose(joints=None):
    """
    Returns the associated bindPoses of the given joints to the pose when they were originally bound.

    Args:
        joints (list): Joints to find bind poses of.
        Note, these are NOT necessarily all the joints that will be restored since joints can share bindPose nodes.

    Returns:
        (set): Bind poses restored.
    """
    # Get joints, find all the bind poses all the joints are using, restore the bind poses for each pose found.
    joints = myu.validateSelect(joints, find='joint')
    poses = {
        pose
        for joint in joints for pose in pm.dagPose(joint, bp=True, q=True)
    }
    [pm.dagPose(pose, g=True, restore=True) for pose in poses]
    return poses
Beispiel #11
0
def assignBindAttributes(joints=None):
    """
    Assigns the bind matrix attribute to the given joints.

    Args:
        joints (list): Joints to assign bind matrix attribute to. If None given, will use selected or all joints.
    """
    joints = myu.validateSelect(joints, find='joint')

    for joint in joints:

        if not joint.hasAttr(pcfg.length_attribute):
            joint.addAttr(pcfg.length_attribute, s=True, w=True, r=True, dv=0.001, min=0.001)

        joint_parent = joint.getParent()
        if joint_parent and isinstance(joint_parent, pm.nodetypes.Joint):
            length = pipermath.getDistance(joint_parent, joint)
            joint.bindLength.set(length)

    pm.displayInfo('Finished assigning Piper joint attributes to ' + str(len(joints)) + ' joints.')