Пример #1
0
def export(root_object, filepath, name_suffix, used_parts, used_materials):
    """Export PIT.

    :param root_object: SCS root object
    :type root_object: bpy.types.Object
    :param filepath: PIT file path
    :type filepath: str
    :param name_suffix: file name suffix
    :type name_suffix: str
    :param used_parts: parts transitional structure for accessing stored parts from PIM, PIC and PIP
    :type used_parts: io_scs_tools.exp.transition_structs.parts.PartsTrans
    :param used_materials: materials transitional structure for accessing stored materials from PIM
    :type used_materials: io_scs_tools.exp.transition_structs.materials.MaterialsTrans
    :return: True if successful; False otherwise;
    :rtype: bool
    """

    scs_globals = _get_scs_globals()

    file_name = root_object.name

    print("\n************************************")
    print("**      SCS PIT Exporter          **")
    print("**      (c)2014 SCS Software      **")
    print("************************************\n")

    # DATA GATHERING
    look_list = []
    variant_list = []

    saved_active_look = root_object.scs_props.active_scs_look
    looks_inventory = root_object.scs_object_look_inventory
    looks_count = len(looks_inventory)
    if looks_count <= 0:
        looks_count = 1

    used_materials_pairs = used_materials.get_as_pairs()
    for i in range(0, looks_count):

        # apply each look from inventory first
        if len(looks_inventory) > 0:
            root_object.scs_props.active_scs_look = i  # set index for curret look
            _looks.apply_active_look(
                root_object
            )  # apply look manually, as active look setter method works only when user sets index from UI

            curr_look_name = looks_inventory[i].name
        else:  # if no looks create default
            curr_look_name = "default"

        material_dict = {}
        material_list = []
        # get materials data
        for material_name, material in used_materials_pairs:
            if material is None:
                material_name = str("_default_material_-_default_settings_")

                # DEFAULT MATERIAL
                material_export_data = default_material(material_name)
                material_list.append(material_name)

            else:
                # print('material name: %r' % material.name)
                material_list.append(material)

                # MATERIAL EFFECT
                effect_name = material.scs_props.mat_effect_name

                # PRESET SHADERS
                flags = 0
                attribute_cnt = texture_cnt = 0
                attribute_sections = []
                texture_sections = []
                active_shader_preset_name = material.scs_props.active_shader_preset_name

                # SUBSTANCE
                substance_value = material.scs_props.substance
                # only write substance to material if it's assigned
                if substance_value != "None" and substance_value != "":

                    substance_data = _SectionData("Attribute")
                    substance_data.props.append(("Format", "STRING"))
                    substance_data.props.append(("Tag", "substance"))
                    substance_data.props.append(
                        ("Value", ["i", (substance_value, )]))
                    attribute_sections.append(substance_data)
                    attribute_cnt += 1

                if _shader_presets.has_preset(
                        active_shader_preset_name
                ) and active_shader_preset_name != "<none>":

                    preset = _shader_presets.get_preset(
                        active_shader_preset_name)
                    flavors_str = effect_name[len(preset.effect):]
                    section = _shader_presets.get_section(
                        active_shader_preset_name, flavors_str)

                    # FLAGS
                    for prop in section.props:

                        if prop[0] == "Flags":
                            flags = int(not material.scs_props.enable_aliasing)
                            break

                    # COLLECT ATTRIBUTES AND TEXTURES
                    for item in section.sections:

                        # if attribute is hidden in shader preset ignore it on export
                        # this is useful for flavor hiding some attributes from original material
                        # eg: airbrush on "truckpaint" hides R G B aux attributes which are not present
                        # when using airbrush flavor
                        hidden = item.get_prop_value("Hide")
                        if hidden and hidden == "True":
                            continue

                        preview_only = item.get_prop_value("PreviewOnly")
                        if preview_only and preview_only == "True":
                            continue

                        # ATTRIBUTES
                        if item.type == "Attribute":
                            # print('     Attribute:')

                            attribute_data = _SectionData("Attribute")
                            for rec in item.props:
                                # print('       rec: %r' % str(rec))
                                if rec[0] == "Format":
                                    attribute_data.props.append(
                                        (rec[0], rec[1]))
                                elif rec[0] == "Tag":
                                    # tag_prop = rec[1].replace("[", "").replace("]", "")
                                    # attribute_data.props.append((rec[0], tag_prop))
                                    attribute_data.props.append(
                                        (rec[0], rec[1]))
                                elif rec[0] == "Value":
                                    format_prop = item.get_prop("Format")[1]
                                    tag_prop = item.get_prop("Tag")[1]
                                    tag_prop = tag_prop.replace("[",
                                                                "").replace(
                                                                    "]", "")
                                    # print('         format_prop: %r' % str(format_prop))
                                    # print('         tag_prop: %r' % str(tag_prop))
                                    if "aux" in tag_prop:
                                        aux_props = getattr(
                                            material.scs_props,
                                            "shader_attribute_" + tag_prop)
                                        value = []
                                        for aux_prop in aux_props:
                                            value.append(aux_prop.value)

                                        # extract list if there is only one value inside and tagged as FLOAT
                                        # otherwise it gets saved as: "Value: ( [0.0] )" instead of: "Value: ( 0.0 )"
                                        if len(
                                                value
                                        ) == 1 and format_prop == "FLOAT":
                                            value = value[0]

                                    else:
                                        value = getattr(
                                            material.scs_props,
                                            "shader_attribute_" + tag_prop,
                                            "NO TAG")
                                    # print('         value: %s' % str(value))
                                    if format_prop == 'FLOAT':
                                        attribute_data.props.append(
                                            (rec[0], ["&&", (value, )]))
                                    elif format_prop == 'INT':
                                        attribute_data.props.append(
                                            (rec[0], ["ii", (value, )]))
                                    else:
                                        attribute_data.props.append(
                                            (rec[0], ["i", tuple(value)]))
                            attribute_sections.append(attribute_data)
                            attribute_cnt += 1

                        # TEXTURES
                        elif item.type == "Texture":
                            # print('     Texture:')

                            texture_data = _SectionData("Texture")
                            for rec in item.props:
                                # print('       rec: %r' % str(rec))
                                if rec[0] == "Tag":
                                    tag_prop = rec[1].split(":")[1]
                                    tag = str("texture[" + str(texture_cnt) +
                                              "]:" + tag_prop)
                                    texture_data.props.append((rec[0], tag))
                                elif rec[0] == "Value":
                                    tag_prop = item.get_prop("Tag")[1].split(
                                        ":")[1]
                                    # print('         tag_prop: %r' % str(tag_prop))

                                    # create and get path to tobj
                                    tobj_rel_path = get_texture_path_from_material(
                                        material, tag_prop,
                                        os.path.dirname(filepath))

                                    texture_data.props.append(
                                        (rec[0], tobj_rel_path))

                            texture_sections.append(texture_data)
                            texture_cnt += 1

                    material_export_data = _SectionData("Material")
                    material_export_data.props.append(("Alias", material.name))
                    material_export_data.props.append(("Effect", effect_name))
                    material_export_data.props.append(("Flags", flags))
                    material_export_data.props.append(
                        ("AttributeCount", attribute_cnt))
                    material_export_data.props.append(
                        ("TextureCount", texture_cnt))
                    for attribute in attribute_sections:
                        material_export_data.sections.append(attribute)
                    for texture in texture_sections:
                        material_export_data.sections.append(texture)

                elif active_shader_preset_name == "<imported>":

                    material_attributes = material['scs_shader_attributes'][
                        'attributes'].to_dict().values()
                    material_textures = material['scs_shader_attributes'][
                        'textures'].to_dict().values()

                    material_export_data = _SectionData("Material")
                    material_export_data.props.append(("Alias", material.name))
                    material_export_data.props.append(("Effect", effect_name))
                    material_export_data.props.append(
                        ("Flags", int(not material.scs_props.enable_aliasing)))
                    material_export_data.props.append(
                        ("AttributeCount", len(material_attributes)))
                    material_export_data.props.append(
                        ("TextureCount", len(material_textures)))

                    for attribute_dict in material_attributes:
                        attribute_section = _SectionData("Attribute")

                        format_value = ""
                        for attr_prop in sorted(attribute_dict.keys()):

                            # get the format of current attribute (we assume that "Format" attribute is before "Value" attribute in this for loop)
                            if attr_prop == "Format":
                                format_value = attribute_dict[attr_prop]

                            if attr_prop == "Value" and (
                                    "FLOAT" in format_value or "STRING"
                                    in format_value or "INT" in format_value):

                                tag_prop = attribute_dict["Tag"].replace(
                                    "[", "").replace("]", "")
                                if "aux" in tag_prop:
                                    aux_props = getattr(
                                        material.scs_props,
                                        "shader_attribute_" + tag_prop)
                                    value = []
                                    for aux_prop in aux_props:
                                        value.append(aux_prop.value)
                                else:
                                    value = getattr(
                                        material.scs_props,
                                        "shader_attribute_" + tag_prop, None)
                                    if isinstance(value, float):
                                        value = [value]

                                if value is None:
                                    attribute_section.props.append(
                                        (attr_prop, [
                                            "i",
                                            tuple(attribute_dict[attr_prop])
                                        ]))
                                else:
                                    attribute_section.props.append(
                                        (attr_prop, ["i", tuple(value)]))

                            elif attr_prop == "Tag" and "aux" in attribute_dict[
                                    attr_prop]:
                                attribute_section.props.append(
                                    (attr_prop, "aux[" +
                                     attribute_dict[attr_prop][3:] + "]"))
                            else:
                                attribute_section.props.append(
                                    (attr_prop, attribute_dict[attr_prop]))

                        material_export_data.sections.append(attribute_section)

                    for texture_dict in material_textures:
                        texture_section = _SectionData("Texture")

                        tag_id_string = ""
                        for tex_prop in sorted(texture_dict.keys()):

                            if tex_prop == "Tag":
                                tag_id_string = texture_dict[tex_prop].split(
                                    ':')[1]

                            if tex_prop == "Value" and tag_id_string != "":

                                tobj_rel_path = get_texture_path_from_material(
                                    material, tag_id_string,
                                    os.path.dirname(filepath))
                                texture_section.props.append(
                                    (tex_prop, tobj_rel_path))

                            else:
                                texture_section.props.append(
                                    (tex_prop, texture_dict[tex_prop]))

                        material_export_data.sections.append(texture_section)

                else:  # when user made material presets were there, but there is no preset library at export for some reason

                    lprint(
                        "W Shader preset used on %r not found in Shader Presets Library (Did you set correct path?), "
                        "exporting default material instead!",
                        (material_name, ))

                    material_name = str("_" + material_name +
                                        "_-_default_settings_")
                    material_export_data = default_material(material_name)

            material_dict[material_name] = material_export_data

        # create materials sections for looks
        material_sections = fill_material_sections(material_list,
                                                   material_dict)
        look_data = {
            "name": curr_look_name,
            "material_sections": material_sections
        }
        look_list.append(look_data)

    # restore look applied before export
    root_object.scs_props.active_scs_look = saved_active_look  # set index for curret look
    _looks.apply_active_look(
        root_object
    )  # apply look manually, as active look setter method works only when user sets index from UI

    # PARTS AND VARIANTS...
    used_parts_names = used_parts.get_as_list()
    if len(root_object.scs_object_variant_inventory) == 0:
        # If there is no Variant, add the Default one...
        part_list = fill_part_list(root_object.scs_object_part_inventory,
                                   used_parts_names,
                                   all_parts=True)
        variant_list.append((_VARIANT_consts.default_name, part_list), )
    else:
        for variant in root_object.scs_object_variant_inventory:
            part_list = fill_part_list(variant.parts, used_parts_names)
            variant_list.append((variant.name, part_list), )

    # DATA CREATION
    header_section = fill_header_section(1, file_name,
                                         scs_globals.export_write_signature)
    look_section = fill_look_sections(look_list)
    # part_sections = fill_part_section(part_list)
    variant_section = fill_variant_sections(variant_list)
    comment_header_section = fill_comment_header_section(
        look_list, variant_list)
    global_section = fill_global_section(len(look_list), len(variant_list),
                                         used_parts.count(),
                                         len(used_materials_pairs))

    # DATA ASSEMBLING
    pit_container = [comment_header_section, header_section, global_section]
    for section in look_section:
        pit_container.append(section)
    for section in variant_section:
        pit_container.append(section)

    # FILE EXPORT
    ind = "    "
    pit_filepath = str(filepath + ".pit" + name_suffix)
    result = _pix_container.write_data_to_file(pit_container, pit_filepath,
                                               ind)

    # print("************************************")
    return result
Пример #2
0
        def execute(self, context):
            lprint("I " + self.bl_label + "...")

            from io_scs_tools.internals import shader_presets as _shader_presets

            mat = context.material
            mat_scs_props = mat.scs_props
            """:type: io_scs_tools.properties.material.MaterialSCSTools"""
            preset = _shader_presets.get_preset(
                mat_scs_props.active_shader_preset_name)

            # extract only flavor effect part of string
            flavor_effect_part = mat_scs_props.mat_effect_name[len(preset.
                                                                   effect):]

            new_flavor_state = not self.flavor_enabled
            flavors_suffix = ""
            for flavor in preset.flavors:
                flavor_variant_found = False
                for flavor_variant in flavor.variants:

                    if flavor_variant.suffix == self.flavor_name:
                        # add founded flavor to flavors suffix only if enabled
                        if new_flavor_state:
                            flavors_suffix += "." + flavor_variant.suffix

                        flavor_variant_found = True
                        break

                # if one variant of flavor is found skip all other variants
                if flavor_variant_found:
                    continue

                # make sure to add all other enabled flavors to flavors suffix
                for flavor_variant in flavor.variants:

                    is_in_middle = "." + flavor_variant.suffix + "." in flavor_effect_part
                    is_on_end = flavor_effect_part.endswith(
                        "." + flavor_variant.suffix)

                    if is_in_middle or is_on_end:
                        flavors_suffix += "." + flavor_variant.suffix

            # if desired combination doesn't exists, abort switching and notify user
            if not _shader_presets.has_section(preset.name, flavors_suffix):
                message = "Enabling %r flavor aborted! Wanted shader combination: %r is not supported!" % (
                    self.flavor_name, preset.effect + flavors_suffix)
                lprint("E " + message)
                self.report({'WARNING'}, message)
                return {'FINISHED'}

            # finally set new shader data to material
            section = _shader_presets.get_section(preset.name, flavors_suffix)
            context.material.scs_props.mat_effect_name = preset.effect + flavors_suffix
            _material_utils.set_shader_data_to_material(
                context.material, section)

            # sync shader types on all scs roots by updating looks on them
            # to avoid different shader types on different scs roots for same material
            for scs_root in _object_utils.gather_scs_roots(bpy.data.objects):
                _looks.update_look_from_material(scs_root, mat, True)

            return {'FINISHED'}