def transfer_uvs_to_skinned_geometry(source_mesh=None,
                                     target_mesh=None,
                                     use_intermediate_shape=False,
                                     **kwargs):

    out_dict = {'success': False, 'result': None}

    selection = dcc.selected_nodes_of_type('transform')
    source_transform = source_mesh or (
        selection[0] if python.index_exists_in_list(selection, 0) else None)
    target_transform = target_mesh or (
        selection[1] if python.index_exists_in_list(selection, 1) else None)
    if not source_transform or not target_transform:
        out_dict[
            'msg'] = 'Select source mesh and target mesh before executing Transfers UVs to skinned geometry.'
        return out_dict

    try:
        result = skin_utils.transfer_uvs_to_skinned_geometry(
            source_mesh=source_mesh,
            target_mesh=target_mesh,
            use_intermediate_shape=use_intermediate_shape,
            **kwargs)
        out_dict['result'] = result
    except Exception as exc:
        out_dict[
            'msg'] = 'Was not possible to transfers UVs to skinned geometry: {}'.format(
                exc)
        return out_dict

    out_dict['success'] = True

    return out_dict
Exemple #2
0
def check_joint_labels(joints=None):

    out_dict = {'success': False, 'result': False}

    valid_joints = list()
    joints = joints or dcc.selected_nodes_of_type(node_type='joint')
    joints = python.force_list(joints)
    for joint in joints:
        if not dcc.object_type(joint) == 'joint':
            continue
        valid_joints.append(joint)
    if not valid_joints:
        out_dict['msg'] = 'No joints to check found.'
        return out_dict

    try:
        result = joint_utils.check_joint_labels(valid_joints)
        out_dict['result'] = result
    except Exception as exc:
        out_dict['msg'] = 'Was not possible to check joints label: {}'.format(
            exc)
        return out_dict

    out_dict['success'] = True

    return out_dict
def restore_to_bind_pose(skinned_mesh=None):

    out_dict = {'success': False, 'result': None}

    skinned_meshes = skinned_mesh or dcc.selected_nodes_of_type('transform')
    skinned_meshes = python.force_list(skinned_meshes)
    if not skinned_meshes:
        skinned_meshes = list()
        meshes = dcc.list_nodes(node_type='mesh')
        for mesh in meshes:
            skinned_meshes.append(
                maya.cmds.listRelatives(mesh, parent=True)[0])
    if not skinned_meshes:
        out_dict['msg'] = 'No skinned meshes to restore bind poses of found.'
        return out_dict

    try:
        result = skin_utils.restore_to_bind_pose(skinned_mesh)
        out_dict['result'] = result
    except Exception as exc:
        out_dict[
            'msg'] = 'Was not possible to restore skinned mesh to bind pose: {}'.format(
                exc)
        return out_dict

    out_dict['success'] = True

    return out_dict
Exemple #4
0
def unlock_visibility(transforms=None):
    """
    Locks visibility channel of the given transforms nodes
    """

    out_dict = {'success': False, 'result': list()}

    transforms = python.force_list(
        transforms or dcc.selected_nodes_of_type(node_type='transform')
        or list())
    if not transforms:
        out_dict[
            'msg'] = 'No transforms to unlock all scale channels of. Select at least one.'
        return out_dict

    percentage = 100.0 / len(transforms)

    for i, node in enumerate(transforms):
        library.Command.progressCommand.emit(
            percentage * (i + 1), 'Unlocking scale channels: {}'.format(node))
        try:
            dcc.unlock_visibility_attribute(node)
            out_dict['result'].append(node)
        except Exception as exc:
            out_dict[
                'msg'] = 'Was not possible to unlock visibility channel in node: "{}" : {}'.format(
                    node, exc)
            return out_dict

    out_dict['success'] = True

    return out_dict
def detach_bind_skin(geo=None, show_options=False):

    out_dict = {'success': False, 'result': list()}

    geo_nodes = geo or dcc.selected_nodes_of_type(node_type='transform')
    geo_nodes = python.force_list(geo_nodes)
    valid_geo_nodes = list()
    for geo_node in geo_nodes:
        if not mesh_utils.is_a_mesh(geo_node):
            continue
        valid_geo_nodes.append(geo_node)
    if not valid_geo_nodes:
        out_dict['msg'] = 'No meshes to apply rigid bind skin into found.'
        return out_dict

    try:
        result = skin_utils.detach_bind_skin(geo=valid_geo_nodes,
                                             show_options=show_options)
        out_dict['result'].append(result)
    except Exception as exc:
        out_dict[
            'msg'] = 'Was not possible to apply smooth bind skin: {}'.format(
                exc)
        return out_dict

    out_dict['success'] = True

    return out_dict
Exemple #6
0
def insert_joints(joints=None, num_joints=1):
    """
    Inserts new joints between selected joint and its direct child
    :param joints: int
    :param num_joints: int
    """

    out_dict = {'success': False, 'result': None}

    joints = joints or dcc.selected_nodes_of_type(node_type='joint')
    joints = python.force_list(joints)
    if not joints:
        out_dict['msg'] = 'No joints to insert joints into found.'
        return out_dict

    try:

        result = joint_utils.insert_joints(joints=joints,
                                           joint_count=num_joints)
        out_dict['result'] = result
    except Exception as exc:
        out_dict['msg'] = 'Was not possible to insert joints: {}'.format(exc)
        return out_dict

    out_dict['success'] = True

    return out_dict
Exemple #7
0
def create_joints_on_curve(curve=None, num_joints=1):

    out_dict = {'success': False, 'result': list()}

    valid_curves = list()
    curves = curve or dcc.selected_nodes_of_type(node_type='transform')
    curves = python.force_list(curves)
    for curve in curves:
        if not curve_utils.is_a_curve(curve):
            continue
        valid_curves.append(curve)
    if not valid_curves:
        out_dict['msg'] = 'No curves to create joints on found.'
        return out_dict

    try:
        for curve in valid_curves:
            new_joint = joint_utils.create_oriented_joints_along_curve(
                curve, num_joints)
            out_dict['result'].append(new_joint)
    except Exception as exc:
        out_dict[
            'msg'] = 'Was not possible to create joints on curve: {}'.format(
                exc)
        return out_dict

    out_dict['success'] = True

    return out_dict
Exemple #8
0
def freeze_transforms(transforms=None):
    """
    Freeze selected transforms
    """

    out_dict = {'success': False, 'result': list()}

    transforms = python.force_list(
        transforms or dcc.selected_nodes_of_type(node_type='transform')
        or list())
    if not transforms:
        out_dict[
            'msg'] = 'No transforms to freeze transforms of. Select at least one.'
        return out_dict

    percentage = 100.0 / len(transforms)

    for i, node in enumerate(transforms):
        library.Command.progressCommand.emit(
            percentage * (i + 1), 'Freezing transforms: {}'.format(node))
        try:
            dcc.freeze_transforms(node)
            out_dict['result'].append(node)
        except Exception as exc:
            out_dict[
                'msg'] = 'Was not possible to freeze transforms in node: "{}" : {}'.format(
                    node, exc)
            return out_dict

    out_dict['success'] = True

    return out_dict
Exemple #9
0
def match_rotation(source_transform=None, target_transform=None):
    """
    Matches rotation of the source node to the rotation of the given target node(s)
    """

    out_dict = {'success': False, 'result': list()}

    selection = dcc.selected_nodes_of_type(node_type='transform')
    source_transform = source_transform or selection[
        0] if python.index_exists_in_list(selection, 0) else None
    if not source_transform:
        out_dict[
            'msg'] = 'No source transform given to match against target rotation.'
        return out_dict
    target_transform = target_transform or selection[1:] if len(
        selection) > 1 else None
    if not source_transform:
        out_dict[
            'msg'] = 'No target transform(s) given to match source rotation against.'
        return out_dict
    source_transform = python.force_list(source_transform)
    target_transform = python.force_list(target_transform)

    percentage = 100.0 / len(source_transform)

    for i, source in enumerate(source_transform):
        library.Command.progressCommand.emit(
            percentage * (i + 1), 'Matching rotation: {}'.format(source))
        try:
            maya.cmds.delete(
                maya.cmds.orientConstraint(target_transform,
                                           source,
                                           maintainOffset=False))

            # For joints, we store now rotation data in jointOrient attribute
            if dcc.node_type(source) == 'joint':
                for axis in 'XYZ':
                    joint_orient_attr = 'jointOrient{}'.format(axis)
                    joint_rotation_attr = 'rotate{}'.format(axis)
                    dcc.set_attribute_value(source, joint_orient_attr, 0.0)
                    joint_rotation = dcc.get_attribute_value(
                        source, joint_rotation_attr)
                    dcc.set_attribute_value(source, joint_orient_attr,
                                            joint_rotation)
                    dcc.set_attribute_value(source, joint_rotation_attr, 0.0)

            out_dict['result'].append(source)
        except Exception as exc:
            out_dict[
                'msg'] = 'Was not possible to match node "{}" rotation to "{}" : {}'.format(
                    source_transform, target_transform, exc)
            return out_dict

    matched_nodes = out_dict.get('result', None)
    if matched_nodes:
        dcc.select_node(matched_nodes)

    out_dict['success'] = True

    return out_dict
Exemple #10
0
def separate_meshes(meshes=None, new_mesh_name=None):
    """
    Separates given meshes into one transform
    """

    out_dict = {'success': False, 'result': None}

    meshes = meshes or dcc.selected_nodes_of_type(node_type='transform')
    meshes = python.force_list(meshes)
    if not meshes:
        out_dict['msg'] = 'No meshes to separate selected.'
        return out_dict
    new_mesh_name = new_mesh_name or dcc.node_short_name(meshes[0])

    try:
        result_meshes = list()
        separated_meshes = dcc.separate_meshes(construction_history=False)
        if not separated_meshes:
            out_dict[
                'msg'] = 'Separate operation was done but not separated mesh was generated'
            return out_dict
        for separated_mesh in separated_meshes:
            separated_mesh = dcc.rename_node(separated_mesh, new_mesh_name)
            result_meshes.append(separated_mesh)

        out_dict['result'] = result_meshes
    except Exception as exc:
        out_dict[
            'msg'] = 'Was not possible to separate meshes "{}" : {}'.format(
                meshes, exc)
        return out_dict

    out_dict['success'] = True

    return out_dict
def copy_skin_weights(source_mesh=None,
                      target_mesh=None,
                      show_options=False,
                      **kwargs):

    out_dict = {'success': False, 'result': None}

    selection = dcc.selected_nodes_of_type('transform')
    source_transform = source_mesh or (
        selection[0] if python.index_exists_in_list(selection, 1) else None)
    target_transform = target_mesh or (
        selection[1] if python.index_exists_in_list(selection, 1) else None)
    if not source_transform or not target_transform:
        out_dict[
            'msg'] = 'Select source mesh and target mesh before executing Copy Skin Weights.'
        return out_dict

    try:
        result = skin_utils.copy_skin_weights(source_mesh=source_mesh,
                                              target_mesh=target_mesh,
                                              show_options=show_options,
                                              **kwargs)
        out_dict['result'] = result
    except Exception as exc:
        out_dict['msg'] = 'Was not possible to copy skin weights: {}'.format(
            exc)
        return out_dict

    out_dict['success'] = True

    return out_dict
Exemple #12
0
def move_pivot_to_zero(transforms=None):
    """
    Moves selected nodes pivots to zero (0, 0, 0 in the world)
    """

    out_dict = {'success': False, 'result': list()}

    transforms = python.force_list(
        transforms or dcc.selected_nodes_of_type(node_type='transform')
        or list())
    if not transforms:
        out_dict[
            'msg'] = 'No transforms to move pivot to zero of. Select at least one.'
        return out_dict

    percentage = 100.0 / len(transforms)

    for i, node in enumerate(transforms):
        library.Command.progressCommand.emit(
            percentage * (i + 1), 'Moving pivot to zero: {}'.format(node))
        try:
            dcc.move_pivot_to_zero(node)
            out_dict['result'].append(node)
        except Exception as exc:
            out_dict[
                'msg'] = 'Was not possible move pivot to zero for node: "{}" : {}'.format(
                    node, exc)
            return out_dict

    out_dict['success'] = True

    return out_dict
def freeze_skinned_mesh(skinned_mesh, **kwargs):

    out_dict = {'success': False, 'result': list()}

    meshes = skinned_mesh or dcc.selected_nodes_of_type('transform')
    meshes = python.force_list(meshes)
    if not meshes:
        return False

    if kwargs.pop('auto_assign_labels', False):
        joint_utils.auto_assign_labels_to_mesh_influences(
            meshes,
            input_left=kwargs.pop('left_side_label', None),
            input_right=kwargs.pop('right_side_label', None),
            check_labels=True)

    percentage = 100.0 / len(meshes)

    for i, mesh in enumerate(meshes):
        library.Command.progressCommand.emit(
            percentage * (i + 1), 'Cleaning Skinned Mesh: {}'.format(mesh))
        try:
            skin_cluster_name = skin_utils.find_related_skin_cluster(mesh)
            if not skin_cluster_name:
                continue
            attached_joints = maya.cmds.skinCluster(skin_cluster_name,
                                                    query=True,
                                                    inf=True)
            mesh_shape_name = maya.cmds.listRelatives(mesh, shapes=True)[0]
            out_influences_array = api_skin.get_skin_weights(
                skin_cluster_name, mesh_shape_name)
            maya.cmds.skinCluster(mesh_shape_name, edit=True, unbind=True)
            maya.cmds.delete(mesh, ch=True)
            maya.cmds.makeIdentity(mesh, apply=True)
            new_skin_cluster_name = maya.cmds.skinCluster(
                attached_joints,
                mesh,
                toSelectedBones=True,
                bindMethod=0,
                normalizeWeights=True)[0]
            api_skin.set_skin_weights(new_skin_cluster_name, mesh_shape_name,
                                      out_influences_array)
            out_dict['result'].append(mesh)
        except Exception as exc:
            out_dict[
                'msg'] = 'Was not possible to freeze skinned meshes: "{}" | {}'.format(
                    meshes, exc)
            return out_dict

    dcc.select_node(meshes)

    out_dict['success'] = True

    return out_dict
Exemple #14
0
def get_valid_joints(joints=None):

    valid_joints = list()
    joints = joints or dcc.selected_nodes_of_type(node_type='joint',
                                                  full_path=False)
    joints = python.force_list(joints)
    for joint in joints:
        if not dcc.object_type(joint) == 'joint':
            continue
        valid_joints.append(joint)
    if not valid_joints:
        valid_joints = dcc.list_nodes(node_type='joint')

    return valid_joints
Exemple #15
0
def snap_joints_to_curve(joints=None, curve=None, num_joints=1):

    out_dict = {'success': False, 'result': dict()}

    valid_joints = list()
    joints = joints or dcc.selected_nodes_of_type(node_type='joint')
    joints = python.force_list(joints)
    for joint in joints:
        if not dcc.object_type(joint) == 'joint':
            continue
        valid_joints.append(joint)
    if not valid_joints:
        out_dict['msg'] = 'No joints to snap to curve found.'
        return out_dict

    valid_curves = list()
    curves = curve or dcc.selected_nodes_of_type(node_type='transform')
    curves = python.force_list(curves)
    for curve in curves:
        if not curve_utils.is_a_curve(curve):
            continue
        valid_curves.append(curve)

    try:
        for curve in valid_curves:
            new_joints = curve_utils.snap_joints_to_curve(valid_joints,
                                                          curve=curve,
                                                          count=num_joints)
            out_dict['result'][curve] = new_joints
    except Exception as exc:
        out_dict[
            'msg'] = 'Was not possible to snap joints to curve: {}'.format(exc)
        return out_dict

    out_dict['success'] = True

    return out_dict
Exemple #16
0
def match_scale(source_transform=None, target_transform=None):
    """
    Matches scale of the source node to the scale of the given target node(s)
    """

    out_dict = {'success': False, 'result': list()}

    selection = dcc.selected_nodes_of_type(node_type='transform')
    source_transform = source_transform or selection[
        0] if python.index_exists_in_list(selection, 0) else None
    if not source_transform:
        out_dict[
            'msg'] = 'No source transform given to match against target scale.'
        return out_dict
    target_transform = target_transform or selection[1:] if len(
        selection) > 1 else None
    if not source_transform:
        out_dict[
            'msg'] = 'No target transform(s) given to match source scale against.'
        return out_dict
    source_transform = python.force_list(source_transform)
    target_transform = python.force_list(target_transform)

    percentage = 100.0 / len(source_transform)

    for i, source in enumerate(source_transform):
        library.Command.progressCommand.emit(
            percentage * (i + 1), 'Matching scale: {}'.format(source))
        try:
            maya.cmds.delete(
                maya.cmds.scaleConstraint(target_transform,
                                          source,
                                          maintainOffset=False))
            out_dict['result'].append(source)
        except Exception as exc:
            out_dict[
                'msg'] = 'Was not possible to match node "{}" scale to "{}" : {}'.format(
                    source_transform, target_transform, exc)
            return out_dict

    matched_nodes = out_dict.get('result', None)
    if matched_nodes:
        dcc.select_node(matched_nodes)

    out_dict['success'] = True

    return out_dict
    def manual_orient_joints(self, data, reply):

        orient_type = data.get('orient_type', 'add')
        x_axis = data.get('x_axis', 0.0)
        y_axis = data.get('y_axis', 0.0)
        z_axis = data.get('z_axis', 0.0)
        affect_children = data.get('affect_children', False)

        if orient_type == 'add':
            tweak = 1.0
        else:
            tweak = -1.0

        tweak_rot = [x_axis * tweak, y_axis * tweak, z_axis * tweak]

        joints = dcc.selected_nodes_of_type(node_type='joint')
        if not joints:
            return

        for jnt in joints:
            dcc.set_node_rotation_axis_in_object_space(jnt, tweak_rot[0],
                                                       tweak_rot[1],
                                                       tweak_rot[2])
            dcc.zero_scale_joint(jnt)
            dcc.freeze_transforms(jnt, preserve_pivot_transforms=True)

            if affect_children:
                childs = dcc.list_children(
                    jnt,
                    children_type=['transform', 'joint'],
                    full_path=False,
                    all_hierarchy=True) or list()
                for child in childs:
                    parent = dcc.node_parent(child)
                    dcc.set_parent_to_world(child)
                    dcc.set_node_rotation_axis_in_object_space(
                        child, tweak_rot[0], tweak_rot[1], tweak_rot[2])
                    dcc.zero_scale_joint(child)
                    dcc.freeze_transforms(child,
                                          preserve_pivot_transforms=True)
                    dcc.set_parent(child, parent)

        dcc.select_node(joints, replace_selection=True)

        reply['success'] = True
Exemple #18
0
def mirror_mesh(mesh=None):
    """
    Mirror given meshes
    """

    out_dict = {'success': False, 'result': list()}

    meshes = mesh or dcc.selected_nodes_of_type(node_type='transform')
    meshes = python.force_list(meshes)
    if not meshes:
        out_dict['msg'] = 'No meshes to mirror selected.'
        return out_dict

    for mesh in meshes:
        try:
            parent_node = dcc.node_parent(mesh)
            mirror_geo_name = xform_utils.find_transform_right_side(
                mesh, check_if_exists=False)
            mirror_geo = maya.cmds.duplicate(mesh, n=mirror_geo_name or None)
            root = maya.cmds.group(empty=True, world=True)
            maya.cmds.parent(mirror_geo, root)
            maya.cmds.setAttr('{}.rx'.format(root), 180)
            for axis in 'xyz':
                maya.cmds.setAttr('{}.s{}'.format(root, axis), -1)
            maya.cmds.parent(mirror_geo, world=True)
            maya.cmds.delete(root)
            maya.cmds.makeIdentity(mirror_geo,
                                   apply=True,
                                   t=False,
                                   r=True,
                                   s=True,
                                   n=False,
                                   pn=True)
            if parent_node:
                dcc.set_parent(mirror_geo, parent_node)
            out_dict['result'].append(mirror_geo)
        except Exception as exc:
            out_dict[
                'msg'] = 'Was not possible to mirror meshes "{}" : {}'.format(
                    meshes, exc)
            return out_dict

    out_dict['success'] = True

    return out_dict
    def reset_joints_orient_to_world(self, data, reply):
        apply_to_hierarchy = data.get('apply_to_hierarchy', False)

        if apply_to_hierarchy:
            dcc.select_hierarchy()

        joints = dcc.selected_nodes_of_type(node_type='joint', full_path=False)
        if not joints:
            reply['msg'] = 'No joints selected'
            reply['success'] = False
            return

        for jnt in reversed(joints):
            childs = dcc.list_children(jnt,
                                       all_hierarchy=False,
                                       children_type=['transform', 'joint'])

            # If the joints has direct childs, unparent that childs and store names
            if childs:
                if len(childs) > 0:
                    childs = dcc.set_parent_to_world(childs)

            # Get parent of this joints for later use
            parent = dcc.node_parent(jnt, full_path=False) or ''

            if parent:
                dcc.set_parent_to_world(jnt)

            # Clear joint axis
            dcc.zero_scale_joint(jnt)
            dcc.freeze_transforms(jnt, preserve_pivot_transforms=True)
            dcc.zero_orient_joint(jnt)

            # Reparent
            if parent:
                dcc.set_parent(jnt, parent)

            # Reparent child
            if childs:
                if len(childs) > 0:
                    dcc.set_parent(childs, jnt)

        dcc.select_node(joints, replace_selection=True)

        reply['success'] = True
    def set_rotation_axis(self, data, reply):
        rotation_axis = data.get('rotation_axis', '')
        affect_children = data.get('affect_children', False)

        sel = dcc.selected_nodes_of_type(
            node_type=['joint', 'transform']) or list()
        for obj in sel:
            dcc.set_rotation_axis(obj, rotation_axis)
            if affect_children:
                childs = dcc.list_children(
                    obj,
                    children_type=['transform', 'joint'],
                    full_path=True,
                    all_hierarchy=True) or list()
                for child in childs:
                    dcc.set_rotation_axis(child, rotation_axis)

        reply['success'] = True
Exemple #21
0
def toggle_selected_local_rotation_axis(flag=None):
    """
    Toggles the visibility of selected joints local rotation axis
    """

    out_dict = {'success': False, 'result': dict()}

    joints = dcc.selected_nodes_of_type(node_type='joint')
    if not joints:
        out_dict['msg'] = 'No joints to toggle LRA of found.'
        return out_dict

    dcc.set_joint_local_rotation_axis_visibility(flag=flag,
                                                 joints_to_apply=joints)

    out_dict['success'] = True

    return out_dict
Exemple #22
0
def combine_meshes(meshes=None, new_mesh_name=None):
    """
    Combines given meshes into one transform
    """

    out_dict = {'success': False, 'result': None}

    meshes = meshes or dcc.selected_nodes_of_type(node_type='transform')
    meshes = python.force_list(meshes)
    if not meshes:
        out_dict['msg'] = 'No meshes to combine selected.'
        return out_dict
    if len(meshes) < 2:
        out_dict['msg'] = 'You need to select at least two meshes to combine.'
        return out_dict
    new_mesh_name = new_mesh_name or dcc.node_short_name(meshes[0])

    parent_node = None
    node_parents = list(set([dcc.node_parent(mesh) for mesh in meshes]))
    if all(parent == node_parents[0] for parent in node_parents):
        parent_node = node_parents[0]

    try:
        combined_mesh = dcc.combine_meshes(construction_history=False)
        if not combined_mesh:
            out_dict[
                'msg'] = 'Combine operation was done but not combined mesh was generated'
            return out_dict
        combined_mesh = dcc.rename_node(combined_mesh, new_mesh_name)
        if parent_node:
            dcc.set_parent(combined_mesh, parent_node)

        out_dict['result'] = combined_mesh
    except Exception as exc:
        out_dict[
            'msg'] = 'Was not possible to combine meshes "{}" : {}'.format(
                meshes, exc)
        return out_dict

    out_dict['success'] = True

    return out_dict
    def set_manual_orient_joints(self, data, reply):
        x_axis = data.get('x_axis', 0.0)
        y_axis = data.get('y_axis', 0.0)
        z_axis = data.get('z_axis', 0.0)
        affect_children = data.get('affect_children', False)

        childs = list()

        tweak_rot = [x_axis, y_axis, z_axis]

        joints = dcc.selected_nodes_of_type(node_type='joint', full_path=False)
        if not joints:
            return

        for jnt in joints:
            if not affect_children:
                childs = dcc.list_children(
                    jnt,
                    children_type=['transform', 'joint'],
                    full_path=False,
                    all_hierarchy=False) or list()
                for child in childs:
                    dcc.set_parent_to_world(child)

            # Set the rotation axis
            for i, axis in enumerate(['x', 'y', 'z']):
                dcc.set_attribute_value(jnt,
                                        'jointOrient{}'.format(axis.upper()),
                                        tweak_rot[i])

            # Clear joint axis
            dcc.zero_scale_joint(jnt)
            dcc.freeze_transforms(jnt, preserve_pivot_transforms=True)

            if childs:
                for child in childs:
                    dcc.set_parent(child, jnt)

        dcc.select_node(joints, replace_selection=True)

        reply['success'] = True
def combine_skinned_meshes(meshes=None):

    out_dict = {'success': False, 'result': None}

    meshes = meshes or dcc.selected_nodes_of_type('transform')
    if not meshes:
        out_dict['msg'] = 'No meshes to combine found.'
        return out_dict

    try:
        result = skin_utils.combine_skinned_meshes(meshes)
        out_dict['result'] = result
    except Exception as exc:
        out_dict[
            'msg'] = 'Was not possible to transfers UVs to skinned geometry: {}'.format(
                exc)
        return out_dict

    out_dict['success'] = True

    return out_dict
def select_influencing_joints(mesh_node=None):

    out_dict = {'success': False, 'result': None}

    mesh_nodes = mesh_node or dcc.selected_nodes_of_type(node_type='transform')
    mesh_nodes = python.force_list(mesh_nodes)
    mesh_node = mesh_nodes[0] if mesh_nodes else None
    if not mesh_node:
        out_dict['msg'] = 'No mesh selected to retrieve influences of'
        return out_dict

    try:
        result = skin_utils.select_influencing_joints(mesh_node)
        out_dict['result'] = result
    except Exception as exc:
        out_dict[
            'msg'] = 'Was not possible to select influencing joints: {}'.format(
                exc)
        return out_dict

    out_dict['success'] = True

    return out_dict
Exemple #26
0
def toggle_local_rotation_axis(joints=None):
    """
     Toggles the visibility of all (if the user has nothing selected) or all joints local rotation axis
     """

    out_dict = {'success': False, 'result': dict()}

    valid_joints = list()
    joints = joints or dcc.selected_nodes_of_type(node_type='joint')
    joints = python.force_list(joints)
    for joint in joints:
        if not dcc.object_type(joint) == 'joint':
            continue
        valid_joints.append(joint)
    if not valid_joints:
        valid_joints = None

    dcc.set_joint_local_rotation_axis_visibility(flag=None,
                                                 joints_to_apply=valid_joints)

    out_dict['success'] = True

    return out_dict
def prune_skin_weights(mesh=None, show_options=False, **kwargs):

    out_dict = {'success': False, 'result': None}

    transforms = mesh or dcc.selected_nodes_of_type('transform')
    transforms = python.force_list(transforms)
    if not transforms:
        out_dict['msg'] = 'No meshes to prune skin weights of found.'
        return out_dict

    try:
        result = skin_utils.prune_skin_weights(mesh=mesh,
                                               show_options=show_options,
                                               **kwargs)
        out_dict['result'] = result
    except Exception as exc:
        out_dict['msg'] = 'Was not possible to prune skin weights: {}'.format(
            exc)
        return out_dict

    out_dict['success'] = True

    return out_dict
def unbind_influences_quick(skinned_objects=None,
                            influences_to_unbind=None,
                            delete=False):
    """
    Unbind given influences from given meshes and stores the unbind influences weights into other influences
    The weights reassignation is handled by Maya
    :param skinned_objects: list(str), meshes which joints need to be removed
    :param influences_to_unbind: list(str), list of joints that need to be unbind
    :param delete: bool, Whether or not to delete unbind influences after unbind process is completed
    :return: bool
    """

    selected_transforms = dcc.selected_nodes_of_type('transform')
    selected_joints = dcc.selected_nodes_of_type('joint')
    influences_to_unbind = influences_to_unbind or selected_joints
    if not skinned_objects:
        skinned_objects = [
            xform for xform in selected_transforms
            if xform not in selected_joints
        ]
    if not skinned_objects or not influences_to_unbind:
        return False
    skinned_objects = python.force_list(skinned_objects)
    influences_to_unbind = python.force_list(influences_to_unbind)
    influences_to_unbind_short = [
        dcc.node_short_name(joint_node) for joint_node in influences_to_unbind
    ]

    skin_clusters = list()
    skin_percentage = 100.0 / len(skinned_objects)

    for i, skin_object in enumerate(skinned_objects):

        library.Command.progressCommand.emit(
            skin_percentage * (i + 1), 'Unbinding Influence: {}'.format(i))

        skin_cluster_name = skin_utils.find_related_skin_cluster(skin_object)
        if not skin_cluster_name:
            continue
        joints_attached = maya.cmds.skinCluster(skin_cluster_name,
                                                query=True,
                                                inf=True)

        influence_verts = skin_utils.get_influence_vertices(
            influences_to_unbind, skin_object)
        if not influence_verts:
            continue

        joints = list()
        for joint_to_remove in influences_to_unbind_short:
            if joint_to_remove not in joints_attached:
                continue
            joints.append((joint_to_remove, 0.0))

        maya.cmds.select(influence_verts, replace=True)
        maya.cmds.skinPercent(skin_cluster_name,
                              transformValue=joints,
                              normalize=True)

        skin_clusters.append(skin_cluster_name)

    for skin_cluster in skin_clusters:
        joints_attached = maya.cmds.skinCluster(skin_cluster,
                                                query=True,
                                                inf=True)
        for jnt in influences_to_unbind_short:
            if jnt not in joints_attached:
                continue
            maya.cmds.skinCluster(skin_cluster, edit=True, removeInfluence=jnt)

    if delete:
        for joint_to_remove in influences_to_unbind:
            child_joints = maya.cmds.listRelatives(joint_to_remove,
                                                   children=True)
            parent = maya.cmds.listRelatives(joint_to_remove, parent=True)
            if not child_joints:
                continue
            if not parent:
                maya.cmds.parent(child_joints, world=True)
                continue
            maya.cmds.parent(child_joints, parent)
        maya.cmds.delete(influences_to_unbind)

    return True
def unbind_influences(skinned_objects=None,
                      influences_to_unbind=None,
                      delete=False,
                      use_parent=True):
    """
    Unbind given influences from given meshes and stores the unbind influences weights into other influences

    :param skinned_objects: list(str), meshes which joints need to be removed
    :param influences_to_unbind: list(str), list of joints that need to be unbind
    :param delete: bool, Whether or not to delete unbind influences after unbind process is completed
    :param use_parent: bool, If True, removed influences weights will be stored on its parent; if False it will look
        for the closest joint using a point cloud system
    :return: bool
    """

    selected_transforms = dcc.selected_nodes_of_type('transform')
    selected_joints = dcc.selected_nodes_of_type('joint')
    influences_to_unbind = influences_to_unbind or selected_joints
    if not skinned_objects:
        skinned_objects = [
            xform for xform in selected_transforms
            if xform not in selected_joints
        ]
    if not skinned_objects or not influences_to_unbind:
        return False
    skinned_objects = python.force_list(skinned_objects)
    influences_to_unbind = python.force_list(influences_to_unbind)
    influences_to_unbind_short = [
        dcc.node_short_name(joint_node) for joint_node in influences_to_unbind
    ]

    skin_clusters = list()
    skin_percentage = 100.0 / len(skinned_objects)

    for skin_index, skin_object in enumerate(skinned_objects):
        skin_cluster_name = skin_utils.find_related_skin_cluster(skin_object)
        if not skin_cluster_name:
            continue
        joints_attached = maya.cmds.skinCluster(skin_cluster_name,
                                                query=True,
                                                inf=True)

        if not use_parent:
            for joint_to_remove in influences_to_unbind_short:
                if joint_to_remove in joints_attached:
                    joints_attached.remove(joint_to_remove)

        source_positions = list()
        source_joints = list()
        for joint_attached in joints_attached:
            pos = maya.cmds.xform(joint_attached,
                                  query=True,
                                  worldSpace=True,
                                  t=True)
            source_positions.append(pos)
            source_joints.append([joint_attached, pos])

        source_kdtree = kdtree.KDTree.construct_from_data(source_positions)

        joint_percentage = skin_percentage / len(influences_to_unbind)
        for joint_index, jnt in enumerate(influences_to_unbind):
            jnt1 = jnt
            if use_parent:
                jnt2 = maya.cmds.listRelatives(jnt, parent=True)
                jnt2 = jnt2[0] if jnt2 else None
                if jnt2 is None:
                    remove_pos = maya.cmds.xform(jnt,
                                                 query=True,
                                                 worldSpace=True,
                                                 t=True)
                    points = source_kdtree.query(query_point=remove_pos, t=1)
                    for index, position in enumerate(source_joints):
                        if position[1] != points[0]:
                            continue
                        jnt2 = position[0]
            else:
                remove_pos = maya.cmds.xform(jnt,
                                             query=True,
                                             worldSpace=True,
                                             t=True)
                points = source_kdtree.query(query_point=remove_pos, t=True)
                for index, position in enumerate(source_joints):
                    if position[1] != points[0]:
                        continue
                    jnt2 = position[0]

            move_skin_weights(jnt1, jnt2, skin_object)

            library.Command.progressCommand.emit(
                ((joint_index + 1) * joint_percentage) +
                (skin_index * skin_percentage), 'Unbinding Influence: {}')

        skin_clusters.append(skin_cluster_name)

    for skin_cluster in skin_clusters:
        joints_attached = maya.cmds.skinCluster(skin_cluster,
                                                query=True,
                                                inf=True)
        for jnt in influences_to_unbind_short:
            if jnt not in joints_attached:
                continue
            maya.cmds.skinCluster(skin_cluster, edit=True, removeInfluence=jnt)

    if delete:
        for joint_to_remove in influences_to_unbind:
            child_joints = maya.cmds.listRelatives(joint_to_remove,
                                                   children=True)
            parent = maya.cmds.listRelatives(joint_to_remove, parent=True)
            if not child_joints:
                continue
            if not parent:
                maya.cmds.parent(child_joints, world=True)
                continue
            maya.cmds.parent(child_joints, parent)
        maya.cmds.delete(influences_to_unbind)

    return True
    def orient_joints(self, data, reply):
        aim_axis_index = data.get('aim_axis_index', 0.0)
        aim_axis_reverse = data.get('aim_axis_reverse', False)
        up_axis_index = data.get('up_axis_index', 0.0)
        up_axis_reverse = data.get('up_axis_reverse', False)
        up_world_axis_x = data.get('up_world_axis_x', 0.0)
        up_world_axis_y = data.get('up_world_axis_y', 0.0)
        up_world_axis_z = data.get('up_world_axis_z', 0.0)
        apply_to_hierarchy = data.get('apply_to_hierarchy', False)

        reset_joints = list()

        # Get up and aim axis
        aim_axis = [0, 0, 0]
        up_axis = [0, 0, 0]
        world_up_axis = [up_world_axis_x, up_world_axis_y, up_world_axis_z]

        if aim_axis_index == up_axis_index:
            LOGGER.warning(
                'aim and up axis are the same, maybe orientation wont work correctly!'
            )

        aim_axis_reverse_value = 1.0 if not aim_axis_reverse else -1.0
        up_axis_reverse_value = 1.0 if not up_axis_reverse else -1.0

        aim_axis[aim_axis_index] = aim_axis_reverse_value
        up_axis[up_axis_index] = up_axis_reverse_value

        # Get selected joints
        if apply_to_hierarchy:
            dcc.select_hierarchy()

        joints = dcc.selected_nodes_of_type(node_type='joint', full_path=False)
        if not joints:
            reply['msg'] = 'No joints selected'
            reply['success'] = False
            return

        for jnt in reversed(joints):
            childs = dcc.list_children(jnt,
                                       all_hierarchy=False,
                                       children_type=['transform', 'joint'])

            # If the joints has direct childs, unparent that childs and store names
            if childs:
                if len(childs) > 0:
                    childs = dcc.set_parent_to_world(childs)
            childs = python.force_list(childs)

            # Get parent of this joints for later use
            parent = ''
            parents = dcc.node_parent(jnt)
            if parents:
                parent = parents[0]

            # Aim to the child
            aim_target = ''
            if childs:
                for child in childs:
                    if dcc.node_type(child) == 'joint':
                        aim_target = child
                        break

            if aim_target != '':

                # Apply an aim constraint from the joint to its child (target)
                dcc.delete_node(
                    dcc.create_aim_constraint(jnt,
                                              aim_target,
                                              aim_axis=aim_axis,
                                              up_axis=up_axis,
                                              world_up_axis=world_up_axis,
                                              world_up_type='vector',
                                              weight=1.0))

                # Clear joint axis
                dcc.zero_scale_joint(jnt)
                dcc.freeze_transforms(jnt, preserve_pivot_transforms=True)

            elif parent != '':
                reset_joints.append(jnt)

            # Reparent child
            if childs:
                if len(childs) > 0:
                    dcc.set_parent(childs, jnt)

        for jnt in reset_joints:
            # If there is no target, the joint will take its parent orientation
            for axis in ['x', 'y', 'z']:
                dcc.set_attribute_value(
                    jnt, 'jointOrient{}'.format(axis.upper()),
                    dcc.get_attribute_value(jnt, 'r{}'.format(axis)))
                dcc.set_attribute_value(jnt, 'r{}'.format(axis), 0)

        dcc.select_node(joints, replace_selection=True)

        reply['success'] = True