Example #1
0
    def _get_curve_type(self, curve):
        curve_type_value = None
        if dcc.attribute_exists(curve, 'curveType'):
            curve_type_value = dcc.get_attribute_value(curve, 'curveType')
        elif dcc.attribute_exists(curve, 'type'):
            curve_type_value = dcc.get_attribute_value(curve, 'type')

        return curve_type_value
Example #2
0
 def _update_curve_data(self, transform, curve_data):
     if dcc.attribute_exists(transform,
                             'curveType') or dcc.attribute_exists(
                                 transform, 'type'):
         value = dcc.get_attribute_value(transform, 'curveType')
         if value:
             curve_data['type'] = value
     if dcc.attribute_exists(transform, 'type'):
         value = dcc.get_attribute_value(transform, 'type')
         if value:
             curve_data['type'] = value
Example #3
0
    def exists(self):
        """
        Returns whether or not node with attribute exists in current scene
        :return: bool
        """

        return dcc.attribute_exists(self.name, self.attr)
Example #4
0
    def set_curve_type(self, type_name=None, keep_color=True, **kwargs):
        """
        Updates the curves of the control with the given control type
        :param type_name: str
        :param keep_color: bool
        """

        if not type_name:
            if dcc.attribute_exists(self.get(), 'curveType'):
                type_name = dcc.get_attribute_value(self.get(), 'curveType')

        shapes = shape_utils.get_shapes(self.get())
        color = kwargs.pop('color', None)
        kwargs['color'] = color or (node_utils.get_rgb_color(shapes[0])
                                    if shapes else 0)

        super(MayaRigControl, self).set_curve_type(type_name=type_name,
                                                   keep_color=keep_color,
                                                   **kwargs)

        self.update_shapes()
        string_attr = attr_utils.StringAttribute('curveType')
        string_attr.create(self._name)
        string_attr.set_value(type_name)

        return True
Example #5
0
def set_skeleton_generator_attrs(skeleton_generator_node, attrs_dict):

    for attr_name, attr_value in attrs_dict.items():
        if not dcc.attribute_exists(skeleton_generator_node, attr_name):
            logger.warning(
                'Impossible to set {} because that attribute was not found in '
                'HIK Skeleton generator node "{}"'.format(attr_name, skeleton_generator_node))
            continue
        dcc.set_attribute_value(skeleton_generator_node, attr_name, attr_value)
Example #6
0
    def has_attribute(self, attribute_name):
        """
        Returns whether or not wrapped native DCC object has an attribute with the given name
        :param attribute_name: str, name of the attribute we are looking for
        :return: bool, True if the attribute exists in the wrapped native DCC object; False otherwise.
        """

        node_name = node_utils.get_name(self._dcc_native_object, fullname=True)
        return dcc.attribute_exists(node_name, attribute_name)
    def set_local_rotation_axis(data, reply):
        state = data.get('state', False)

        sel = dcc.selected_nodes()
        for obj in sel:
            if dcc.attribute_exists(obj, 'displayLocalAxis'):
                dcc.set_attribute_value(obj, 'displayLocalAxis', state)

        reply['success'] = True
Example #8
0
def set_skeleton_generator_defaults(skeleton_generator_node):
    """
    Sets given Skeleton Generator node to its defaults values
    :param skeleton_generator_node: str
    """

    for attr_name, default_value in HIK_SKELETON_GENERATOR_DEFAULTS.items():
        if not dcc.attribute_exists(skeleton_generator_node, attr_name):
            logger.warning(
                'Impossible to reset {} because that attribute was not found in '
                'HIK Skeleton generator node: "{}"'.format(attr_name, skeleton_generator_node))
            continue
        dcc.set_attribute_value(skeleton_generator_node, attr_name, default_value)
Example #9
0
def get_render_globals_attribute(attribute_name, default_value=None):
    """
    Internal function that returns value of the given attribute of the render global Maya node
    :param attribute_name: str, name of the attribute to get
    :param default_value: object, value that is returned if the attribute does not exists
    :return: object
    """

    render_globals_node = get_render_globals_node_name()
    if not dcc.attribute_exists(render_globals_node, attribute_name):
        LOGGER.warning(
            'Attribute "{}" does not exists in RenderGlobals node "{}"!'.
            format(attribute_name, render_globals_node))
        return default_value

    return dcc.get_attribute_value(render_globals_node, attribute_name)
Example #10
0
def get_default_resolution_attribute(attribute_name, default_value=None):
    """
    Internal function that returns value of the given attribute of the default resolution Maya node
    :param attribute_name: str, name of the attribute to get
    :param default_value: object, value that is returned if the attribute does not exists
    :return: object
    """

    default_resolution_node = get_default_resolution_node_name()
    if not dcc.attribute_exists(default_resolution_node, attribute_name):
        LOGGER.warning(
            'Attribute "{}" does not exists in DefaultResolution node "{}"!'.
            format(attribute_name, default_resolution_node))
        return default_value

    return dcc.get_attribute_value(default_resolution_node, attribute_name)
def add_control_tracker_attributes(
        control_name,
        control_type='circle',
        translate=(0.0, 0.0, 0.0),
        rotate=(0.0, 0.0, 0.0),
        scale=(1.0, 1.0, 1.0),
        color=None,
):
    """
    Add control tracker attributes
    :param control_name: str, name of the control lwe want to track
    :param control_type: str, control type of the control
    :param translate: tuple(float, float, float), initial translation value
    :param rotate: tuple(float, float, float), initial rotation value
    :param scale: tuple(float, float, float), initial scale value
    :param color: list(float), initial color as linear color
    """

    xform_utils.add_transform_tracker_attributes(control_name,
                                                 translate=translate,
                                                 rotate=rotate,
                                                 scale=scale)

    if not color:
        shapes = dcc.list_shapes_of_type(control_name, shape_type='nurbsCurve')
        if shapes:
            color = node_utils.get_rgb_color(shapes[0], linear=True)
    if not color:
        color = (0.0, 0.0, 0.0)
    color_utils.add_color_tracker_attributes(control_name, color)

    for i, attr_name in enumerate(
            consts.ALL_CONTROL_TYPE_TRACKER_ATTRIBUTE_NAMES):
        if not dcc.attribute_exists(control_name, attr_name):
            dcc.add_string_attribute(control_name, attr_name)

    dcc.set_attribute_value(control_name,
                            consts.TRACKER_CONTROL_TYPE_ATTR_NAME,
                            control_type)
    dcc.set_attribute_value(control_name,
                            consts.TRACKER_CONTROL_TYPE_DEFAULT_ATTR_NAME,
                            control_type)
Example #12
0
def set_render_globals_attribute(attribute_name, attribute_value):
    """
    Internal function that returns value of the given attribute of the render global Maya node
    :param attribute_name: str, name of the attribute to get
    :param attribute_value: object, value used to set attribute to
    :return: object
    """

    render_globals_node = get_render_globals_node_name()
    if not dcc.attribute_exists(render_globals_node, attribute_name):
        LOGGER.warning(
            'Attribute "{}" does not exists in RenderGlobasls node "{}"!'.
            format(attribute_name, render_globals_node))
        return False

    try:
        return dcc.set_attribute_value(render_globals_node, attribute_name,
                                       attribute_value)
    except Exception as exc:
        LOGGER.error(
            'Was impossible to set attribute "{}" in RenderGlobals node "{}" with value "{}" | "{}"'
            .format(attribute_name, render_globals_node, attribute_value, exc))
        return False
    def _import_skin_weights(self, data_path, mesh):
        if not dcc.node_exists(mesh) or not os.path.isdir(data_path):
            return False

        try:
            if not dcc.is_plugin_loaded('ngSkinTools2'):
                dcc.load_plugin('ngSkinTools2')
            import ngSkinTools2
            from ngSkinTools2 import api as ngst_api
        except ImportError:
            logger.warning(
                'NgSkinTools 2.0 is not installed. Impossible to import ngSkin data'
            )
            return False

        ng_skin_data_path = path_utils.join_path(data_path, 'ngdata.json')
        if not path_utils.is_file(ng_skin_data_path):
            logger.warning(
                'No Ng Skin Data file found: "{}", aborting import skin weights operation ...'
                .format(ng_skin_data_path))
            return False

        is_valid_mesh = False
        shape_types = ['mesh', 'nurbsSurface', 'nurbsCurve', 'lattice']
        for shape_type in shape_types:
            if shape_utils.has_shape_of_type(mesh, shape_type):
                is_valid_mesh = True
                break
        if not is_valid_mesh:
            logger.warning(
                'Node "{}" is not a valid mesh node! Currently supported nodes include: {}'
                .format(mesh, shape_types))
            return False

        logger.info('Importing skin clusters {} --> "{}"'.format(
            mesh, data_path))

        influence_dict = self._get_influences(data_path)
        if not influence_dict:
            logger.warning('No influences data found for: {}'.format(mesh))
            return False

        influences = influence_dict.keys()
        if not influences:
            logger.warning('No influences found for: "{}"'.format(mesh))
            return False
        influences.sort()
        logger.debug('Influences found for {}: {}'.format(mesh, influences))

        short_name = dcc.node_short_name(mesh)
        transfer_mesh = None

        if shape_utils.has_shape_of_type(mesh, 'mesh'):
            orig_mesh = self._import_mesh_obj(data_path)
            if orig_mesh:
                mesh_match = geo_utils.is_mesh_compatible(orig_mesh, mesh)
                if not mesh_match:
                    transfer_mesh = mesh
                    mesh = orig_mesh
                else:
                    dcc.delete_node(orig_mesh)

        # Check if there are duplicated influences and also for the creation of influences that does not currently
        # in the scene
        add_joints = list()
        remove_entries = list()
        for influence in influences:
            joints = dcc.list_nodes(influence, full_path=True)
            if type(joints) == list and len(joints) > 1:
                add_joints.append(joints[0])
                conflicting_count = len(joints)
                logger.warning(
                    'Found {} joints with name {}. Using only the first one: {}'
                    .format(conflicting_count, influence, joints[0]))
                remove_entries.append(influence)
                influence = joints[0]
            if not dcc.node_exists(influence):
                dcc.clear_selection()
                dcc.create_joint(
                    name=influence,
                    position=influence_dict[influence]['position'])
        for entry in remove_entries:
            influences.remove(entry)
        influences += add_joints

        settings_data = dict()
        settings_path = path_utils.join_path(data_path, 'settings.info')
        if path_utils.is_file(settings_path):
            lines = fileio.get_file_lines(settings_path)
            for line in lines:
                test_line = line.strip()
                if not test_line:
                    continue
                line_list = eval(line)
                attr_name = line_list[0]
                value = line_list[1]
                settings_data[attr_name] = value

        # Create skin cluster and removes if it already exists
        skin_cluster = deform_utils.find_deformer_by_type(mesh, 'skinCluster')
        if skin_cluster:
            dcc.delete_node(skin_cluster)

        skin_node_name = settings_data.pop('skinNodeName',
                                           'skin_{}'.format(short_name))
        skin_cluster = maya.cmds.skinCluster(
            influences, mesh, tsb=True,
            n=dcc.find_unique_name(skin_node_name))[0]
        dcc.set_attribute_value(skin_cluster, 'normalizeWeights', 0)
        skin_utils.set_skin_weights_to_zero(skin_cluster)

        # TODO: This Influence mapping configuration should be generated during export and imported here as JSON file
        # Import ng skin data
        config = ngst_api.InfluenceMappingConfig()
        config.use_distance_matching = True
        config.use_label_matching = True
        config.use_name_matching = True

        ngst_api.import_json(mesh,
                             file=ng_skin_data_path,
                             influences_mapping_config=config)

        maya.cmds.skinCluster(skin_cluster, edit=True, normalizeWeights=1)
        maya.cmds.skinCluster(skin_cluster,
                              edit=True,
                              forceNormalizeWeights=True)

        for attr_name, value in settings_data.items():
            if attr_name == 'blendWeights':
                skin_utils.set_skin_blend_weights(skin_cluster, value)
            else:
                if dcc.attribute_exists(skin_cluster, attr_name):
                    dcc.set_attribute_value(skin_cluster, attr_name, value)

        if transfer_mesh:
            logger.info(
                'Import sking weights: mesh topology does not match. Trying to transfer topology ...'
            )
            skin_utils.skin_mesh_from_mesh(mesh, transfer_mesh)
            dcc.delete_node(mesh)

        logger.info('Import skinCluster weights: {} from {}'.format(
            short_name, data_path))

        return True
    def save(self, *args, **kwargs):
        """
        Saves NG Skin weights file
        """

        dependencies = dict()

        filepath = self.format_identifier()
        if not filepath:
            logger.warning(
                'Impossible to save NGSkin Cluster Weights file because save file path not defined!'
            )
            return

        objects = kwargs.get('objects', None)
        if not objects:
            objects = dcc.client().selected_nodes(full_path=True)
        if not objects:
            logger.warning(
                'Nothing selected to export skin weights of. Please, select a mesh,'
                ' curve, NURBS surface or lattice with skin weights to export')
            return False

        logger.debug('Saving {} | {}'.format(filepath, kwargs))

        try:
            if not dcc.is_plugin_loaded('ngSkinTools2'):
                dcc.load_plugin('ngSkinTools2')
            import ngSkinTools2
            from ngSkinTools2 import api as ngst_api
        except ImportError:
            logger.warning(
                'NgSkinTools 2.0 is not installed. Impossible to export ngSkin data'
            )
            return False

        valid_nodes = list()

        # Check that all objects that we are going to export have at least one skin cluster node associated
        # Make sure also that all objects skin output folder have been created
        obj_dirs = OrderedDict()
        skin_nodes = OrderedDict()
        geo_paths = OrderedDict()
        skin_weights = OrderedDict()
        for obj in objects:
            if dcc.client().node_is_a_shape(obj):
                obj = dcc.client().node_parent(obj, full_path=True)
            obj_filename = obj
            if obj.find('|') > -1:
                obj_filename = obj_filename.replace('|', '.')
                if obj_filename.startswith('.'):
                    obj_filename = obj_filename[1:]
            if obj_filename.find(':') > -1:
                obj_filename = obj_filename.replace(':', '-')

            skin = dcc.client().find_deformer_by_type(obj, 'skinCluster')
            if not skin:
                logger.warning(
                    'Skip skin weights export for object because no skinCluster found!'
                    .format(obj))
                continue
            valid_nodes.append((obj, obj_filename, skin))

        if not valid_nodes:
            logger.warning(
                'Skin exported failed! No objects found with skinClusters applied!'
            )
            return False

        # Create skin folder only is valid nodes are available
        file_name = '.{}'.format(os.path.basename(filepath))
        file_folder = path_utils.join_path(os.path.dirname(filepath),
                                           file_name)
        if not os.path.isdir(file_folder):
            skin_folder = folder.create_folder(file_folder, make_unique=True)
            dependencies[skin_folder] = 'skin_folder'

        for node_data in valid_nodes:
            obj, obj_filename, skin = node_data

            geo_path = path_utils.join_path(file_folder, obj_filename)
            if path_utils.is_dir(geo_path):
                folder.delete_folder(obj_filename, file_folder)
            geo_path = folder.create_folder(obj_filename, file_folder)
            if not geo_path:
                logger.error(
                    'Unable to create skin weights directory: "{}" in "{}"'.
                    format(obj_filename, file_folder))
                return False
            dependencies[geo_path] = 'geo_path'

            weights = dcc.client().get_skin_weights(skin)

            obj_dirs[obj] = obj_filename
            skin_nodes[obj] = skin
            geo_paths[obj] = geo_path
            skin_weights[obj] = weights

        for (obj, skin_node), (_, geo_path), (_, skin_weights) in zip(
                skin_nodes.items(), geo_paths.items(), skin_weights.items()):

            logger.info('Exporting weights: {} > {} --> "{}"'.format(
                obj, skin_node, geo_path))

            info_lines = list()
            info_file = fileio.create_file('influence.info', geo_path)

            for influence in skin_weights:
                if influence is None or influence == 'None':
                    continue
                weight_list = skin_weights[influence]
                if not weight_list:
                    continue

                influence_name = skin_utils.get_skin_influence_at_index(
                    influence, skin_node)
                if not influence_name or not dcc.node_exists(influence_name):
                    continue

                influence_position = dcc.node_world_space_translation(
                    influence_name)
                influence_line = "{'%s' : {'position' : %s}}" % (
                    influence_name, str(influence_position))
                info_lines.append(influence_line)

            writer = fileio.FileWriter(info_file)
            writer.write(info_lines)

            settings_file = fileio.create_file('settings.info', geo_path)
            setting_lines = list()
            if shape_utils.has_shape_of_type(obj, 'mesh'):
                self._export_mesh_obj(obj, geo_path)

            setting_lines.append("['skinNodeName', '{}']".format(
                dcc.node_short_name(skin_node)))
            if dcc.attribute_exists(skin_node, 'blendWeights'):
                blend_weights = skin_utils.get_skin_blend_weights(skin_node)
                setting_lines.append(
                    "['blendWeights', {}]".format(blend_weights))
            if dcc.attribute_exists(skin_node, 'skinningMethod'):
                skin_method = dcc.get_attribute_value(skin_node,
                                                      'skinningMethod')
                setting_lines.append(
                    "['skinningMethod', {}]".format(skin_method))

            write_settings = fileio.FileWriter(settings_file)
            write_settings.write(setting_lines)

            ng_skin_file_name = os.path.join(geo_path, 'ngdata.json')
            ngst_api.export_json(obj, file=ng_skin_file_name)

            logger.info(
                'Skin weights exported successfully: {} > {} --> "{}"'.format(
                    obj, skin_node, geo_path))

        data_to_save = OrderedDict()
        for obj, obj_filename in obj_dirs.items():
            data_to_save[obj] = {'enabled': True, 'folder': obj_filename}
        with open(filepath, 'w') as fh:
            json.dump(data_to_save, fh)

        logger.info('Skin weights export operation completed successfully!')

        return True
def is_control(transform_node, only_tagged=False, **kwargs):
    """
    Returns whether or not given transform is a rig control
    :param transform_node: str
    :param only_tagged: bool
    :return: bool
    """

    maybe_control = False

    names_to_skip = python.force_list(kwargs.get('names_to_skip', list()))
    prefixes_to_check = python.force_list(
        kwargs.get('prefixes_to_check', list()))
    prefixes_to_skip = python.force_list(kwargs.get('prefixes_to_skip',
                                                    list()))
    suffixes_to_check = python.force_list(
        kwargs.get('suffixes_to_check', list()))
    suffixes_to_skip = python.force_list(kwargs.get('suffixes_to_skip',
                                                    list()))
    attributes_to_check = python.force_list(
        kwargs.get('attributes_to_check', list()))
    attributes_to_skip = python.force_list(
        kwargs.get('attributes_to_skip', list()))
    names_to_skip.extend(consts.CONTROLS_NAMES_TO_SKIP)
    prefixes_to_check.extend(consts.CONTROLS_PREFIXES)
    prefixes_to_skip.extend(consts.CONTROLS_PREFIXES_TO_SKIP)
    suffixes_to_check.extend(consts.CONTROLS_SUFFIXES)
    suffixes_to_skip.extend(consts.CONTROLS_SUFFIXES_TO_SKIP)
    attributes_to_check.extend(consts.CONTROLS_ATTRIBUTES)
    attributes_to_skip.extend(consts.CONTROLS_ATTRIBUTES_TO_SKIP)
    names_to_skip = tuple(set(names_to_skip))
    prefixes_to_check = tuple(set(prefixes_to_check))
    prefixes_to_skip = tuple(set(prefixes_to_skip))
    suffixes_to_check = tuple(set(suffixes_to_check))
    suffixes_to_skip = tuple(set(suffixes_to_skip))
    attributes_to_check = tuple(set(attributes_to_check))
    attributes_to_skip = tuple(set(attributes_to_skip))

    # TODO: We could use nomenclature to check control validity

    transform = name_utils.remove_namespace_from_string(transform_node)

    if only_tagged:
        if dcc.attribute_exists(transform, 'tag'):
            value = dcc.get_attribute_value(transform, 'tag')
            if value:
                return True
        return False
    else:
        # Check names
        if transform in names_to_skip:
            return False

        # Check prefix and suffix
        if transform.startswith(prefixes_to_skip) or transform.endswith(
                suffixes_to_skip):
            return False
        if transform.startswith(prefixes_to_check) or transform.endswith(
                suffixes_to_check):
            maybe_control = True

        # Check attributes
        for attr_to_skip in attributes_to_skip:
            if dcc.attribute_exists(transform, attr_to_skip):
                return False
        for attr_to_check in attributes_to_check:
            if dcc.attribute_exists(transform, attr_to_check):
                return True
        if dcc.attribute_exists(transform, 'tag'):
            value = dcc.get_attribute_value(transform, 'tag')
            if value:
                maybe_control = True
        if dcc.attribute_exists(transform,
                                'curveType') or dcc.attribute_exists(
                                    transform, 'type'):
            value = dcc.get_attribute_value(transform, 'curveType')
            if value:
                maybe_control = True
        if dcc.attribute_exists(transform, 'type'):
            value = dcc.get_attribute_value(transform, 'type')
            if value:
                maybe_control = True

        if maybe_control:
            if dcc.node_has_shape_of_type(
                    transform, 'nurbsCurve') or dcc.node_has_shape_of_type(
                        transform, 'nurbsSurface'):
                return True

    return False