Esempio n. 1
0
    def is_settable(self, valid_connections=None):
        """
        Returns True if the attribute can be set; False otherwise.
        :param valid_connections: list(str) or None
        """

        valid_connections = python.force_list(valid_connections)
        if not self.exists():
            return False

        if not dcc.list_attributes(self.fullname,
                                   unlocked=True,
                                   keyable=True,
                                   multi=True,
                                   scalar=True):
            return False

        connection = dcc.list_connections(self.name,
                                          self.attr,
                                          destination=False)
        if connection:
            connection_type = dcc.node_type(connection)
            for valid_type in valid_connections:
                if connection_type.startswith(valid_type):
                    return True
            return False

        return True
Esempio n. 2
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
Esempio n. 3
0
    def is_connected(self, ignore_connections=None):
        """
        Returns True if the attribute is connected; False otherwise.
        :param ignore_connections: list(str) or None
        :return: bool
        """

        ignore_connections = python.force_list(ignore_connections)
        try:
            connection = dcc.list_connections(self.name,
                                              self.attr,
                                              destination=False)
        except ValueError:
            return False

        if not connection:
            return False

        if ignore_connections:
            connection_type = dcc.node_type(connection)
            for ignore_type in ignore_connections:
                if connection_type.startswith(ignore_type):
                    return False

        return True
Esempio n. 4
0
def mirror_hierarchy_joints():
    """
    Mirror hierarchy joints
    """

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

    all_joints = list()

    valid_joints = get_valid_joints()
    if not valid_joints:
        out_dict['msg'] = 'No joints to mirror found.'
        return out_dict

    for joint in valid_joints:
        all_joints.append(joint)
        children = dcc.list_children(joint,
                                     full_path=False,
                                     children_type='transform')
        found = list()
        if children:
            for child in children:
                if dcc.node_type(child).find('Constraint') > -1:
                    continue
                found.append(child)
        all_joints.extend(found)

    all_joints = list(set(all_joints))

    dcc.mirror_transform(transforms=all_joints, create_if_missing=True)

    out_dict['success'] = True

    return out_dict
def duplicate_control(control_name,
                      duplicate_name=None,
                      use_selected_name=True,
                      copy_tracker=True,
                      delete_node_shapes=False):
    """
    Duplicates the given control transform node to a new transform parented to the world
    :param control_name: str, name of the control to duplicate
    :param duplicate_name: str, name of the duplicated control
    :param use_selected_name: bool, Whether or not
    :param copy_tracker:
    :param delete_node_shapes:
    :return:
    """

    if not duplicate_name and use_selected_name:
        duplicate_name = control_name
    duplicated_control = xform_utils.duplicate_transform_without_children(
        control_name,
        node_name=duplicate_name,
        delete_shapes=delete_node_shapes)

    if dcc.node_parent(duplicated_control):
        duplicated_control = dcc.set_parent_to_world(duplicated_control)

    if dcc.node_type(duplicated_control) == 'joint':
        pass

    return duplicated_control
    def _get_curve_transform(self, curve):
        parent = curve
        if dcc.node_exists(curve):
            if dcc.node_type(curve) == 'nurbsCurve':
                parent = dcc.node_parent(curve)
            else:
                parent = curve

        return parent
Esempio n. 7
0
    def _get_node_types(self):
        node_types = set()
        for btn in self._category_buttons:
            dcc_type = btn.property('dcc_type')
            if dcc_type:
                node_types.add(dcc_type)
            else:
                dcc_fn = btn.property('dcc_fn')
                if dcc_fn:
                    dcc_args = btn.property('dcc_args')
                    if dcc.is_maya():
                        valid_args = dict()
                        for arg_name, arg_value in dcc_args.items():
                            valid_args[str(arg_name)] = arg_value
                        nodes = getattr(maya.cmds, dcc_fn)(**valid_args)
                        for node in nodes:
                            node_type = dcc.node_type(node)
                            node_types.add(node_type)

        return list(node_types)
    def from_objects(cls, objects, left_side=None, right_side=None, mirror_plane=None):
        """
        Creates a new mirror table instance from the given objects
        :param objects: list(str)
        :param left_side: str
        :param right_side: str
        :param mirror_plane: MirrorPlane or str
        :return: MirrorTable
        """

        mirror_plane = mirror_plane or MirrorPlane.YZ
        if python.is_string(mirror_plane):
            if mirror_plane.lower() == 'yz':
                mirror_plane = MirrorPlane.YZ
            elif mirror_plane.lower() == 'xz':
                mirror_plane = MirrorPlane.XZ
            elif mirror_plane.lower() == 'xy':
                mirror_plane = MirrorPlane.XY

        if left_side:
            left_side = left_side.split(',')
            left_side = [split.strip() for split in left_side]
        if right_side:
            right_side = right_side.split(',')
            right_side = [split.strip() for split in right_side]

        mirror_table = cls()
        mirror_table.set_metadata('left', left_side)
        mirror_table.set_metadata('right', right_side)
        mirror_table.set_metadata('mirrorPlane', mirror_plane)

        for obj in objects:
            node_type = dcc.node_type(obj)
            if node_type in VALID_NODE_TYPES:
                mirror_table.add_objects(obj)
            else:
                logger.info('Node of type {} is not supported. Node name: {}'.format(node_type, obj))

        return mirror_table
Esempio n. 9
0
    def _update_names_list(self, nodes):
        """
        Internal function that updates names list with given node names
        :param nodes: list(str)
        """

        nodes_to_discard = self._get_nodes_to_discard() or list()

        nodes = list(set(nodes))

        for obj in nodes:
            if obj in nodes_to_discard:
                continue
            node_type = dcc.node_type(obj)
            if node_type not in self._get_node_types(
            ) and not self._others_btn.isChecked():
                is_valid = False
                for node_type in self._get_node_types():
                    is_valid = dcc.check_object_type(obj,
                                                     node_type,
                                                     check_sub_types=True)
                    if is_valid:
                        break
                if not is_valid:
                    continue

            node_name = dcc.node_short_name(obj)
            item = QTreeWidgetItem(self._names_list, [node_name])
            item.obj = node_name
            item.preview_name = ''
            item.full_name = obj
            if dcc.is_maya():
                sel = api.SelectionList()
                sel.add(obj)
                item.handle = maya.OpenMaya.MObjectHandle(
                    sel.get_depend_node(0))

            self._names_list.addTopLevelItem(item)
    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