Example #1
0
        def execute(self, context):

            scs_globals = _get_scs_globals()

            if self.type == "DefaultExportPath":
                obj = context.scene.scs_props
                prop = "default_export_filepath"
            elif self.type == "GameObjectExportPath":
                obj = context.active_object.scs_props
                prop = "scs_root_object_export_filepath"
            elif self.type == "GameObjectAnimExportPath":
                obj = _object_utils.get_scs_root(
                    context.active_object).scs_props
                prop = "scs_root_object_anim_export_filepath"
            else:
                obj = context.active_object.scs_props
                prop = "scs_skeleton_custom_export_dirpath"

            if _path_utils.startswith(self.directory,
                                      scs_globals.scs_project_path):
                setattr(
                    obj, prop,
                    _path_utils.relative_path(scs_globals.scs_project_path,
                                              self.directory))
            else:
                setattr(obj, prop, "//")
                self.report({
                    'ERROR'
                }, "Selected path is not within SCS Project Base Path,\npath will be reset to SCS Project Base Path instead."
                            )
                return {'CANCELLED'}

            return {'FINISHED'}
Example #2
0
        def execute(self, context):

            scs_globals = _get_scs_globals()

            if self.type == "DefaultExportPath":
                obj = context.scene.scs_props
                prop = "default_export_filepath"
            elif self.type == "GameObjectExportPath":
                obj = context.active_object.scs_props
                prop = "scs_root_object_export_filepath"
            elif self.type == "GameObjectAnimExportPath":
                obj = _object_utils.get_scs_root(context.active_object).scs_props
                prop = "scs_root_object_anim_export_filepath"
            else:
                obj = context.active_object.scs_props
                prop = "scs_skeleton_custom_export_dirpath"

            if _path_utils.startswith(self.directory, scs_globals.scs_project_path):
                setattr(obj, prop, _path_utils.relative_path(scs_globals.scs_project_path, self.directory))
            else:
                setattr(obj, prop, "//")
                self.report({'ERROR'}, "Selected path is not within SCS Project Base Path,\npath will be reset to SCS Project Base Path instead.")
                return {'CANCELLED'}

            return {'FINISHED'}
Example #3
0
        def execute(self, context):
            lprint("D " + self.bl_idname, report_errors=-1, report_warnings=-1)

            if not _path_utils.startswith(self.directory,
                                          _get_scs_globals().scs_project_path):
                message = "E Selected path is not inside SCS Project Base Path! Animation can't be exported to this directory."
                lprint(message)
                self.report({'ERROR'}, message[2:])
                return {'CANCELLED'}

            armature = context.active_object
            scs_root_obj = _object_utils.get_scs_root(armature)
            anim_inventory = scs_root_obj.scs_object_animation_inventory

            skeleton_filepath = _path_utils.get_skeleton_relative_filepath(
                armature, self.directory, scs_root_obj.name)

            if 0 <= self.index < len(anim_inventory):

                anim = anim_inventory[self.index]
                _export.pia.export(scs_root_obj, armature, anim,
                                   self.directory, skeleton_filepath)

            lprint("", report_errors=1, report_warnings=1)
            return {'FINISHED'}
Example #4
0
        def execute(self, context):
            """Set Material Substance library filepath."""
            scs_globals = _get_scs_globals()

            if _path_utils.startswith(self.filepath, scs_globals.scs_project_path):
                self.filepath = _path_utils.relative_path(scs_globals.scs_project_path, self.filepath)

            scs_globals.matsubs_library_rel_path = self.filepath
            return {'FINISHED'}
Example #5
0
        def execute(self, context):
            """Set Hookup directory path."""
            scs_globals = _get_scs_globals()

            if _path_utils.startswith(self.directory, scs_globals.scs_project_path):
                self.directory = _path_utils.relative_path(scs_globals.scs_project_path, self.directory)

            scs_globals.hookup_library_rel_path = self.directory
            return {'FINISHED'}
Example #6
0
        def execute(self, context):
            """Set Traffic Rules library filepath."""
            scs_globals = _get_scs_globals()

            if _path_utils.startswith(self.filepath, scs_globals.scs_project_path):
                self.filepath = _path_utils.relative_path(scs_globals.scs_project_path, self.filepath)

            scs_globals.traffic_rules_library_rel_path = self.filepath
            return {'FINISHED'}
Example #7
0
        def execute(self, context):
            """Set Sign directory path."""
            scs_globals = _get_scs_globals()

            if _path_utils.startswith(self.filepath, scs_globals.scs_project_path):
                self.filepath = _path_utils.relative_path(scs_globals.scs_project_path, self.filepath)

            scs_globals.sign_library_rel_path = self.filepath
            return {'FINISHED'}
Example #8
0
        def execute(self, context):
            """Set Sign directory path."""
            scs_globals = _get_scs_globals()

            if _path_utils.startswith(self.filepath,
                                      scs_globals.scs_project_path):
                self.filepath = _path_utils.relative_path(
                    scs_globals.scs_project_path, self.filepath)

            scs_globals.sign_library_rel_path = self.filepath
            return {'FINISHED'}
Example #9
0
        def execute(self, context):
            """Set Material Substance library filepath."""
            scs_globals = _get_scs_globals()

            if _path_utils.startswith(self.filepath,
                                      scs_globals.scs_project_path):
                self.filepath = _path_utils.relative_path(
                    scs_globals.scs_project_path, self.filepath)

            scs_globals.matsubs_library_rel_path = self.filepath
            return {'FINISHED'}
Example #10
0
        def execute(self, context):
            """Set Hookup directory path."""
            scs_globals = _get_scs_globals()

            if _path_utils.startswith(self.directory,
                                      scs_globals.scs_project_path):
                self.directory = _path_utils.relative_path(
                    scs_globals.scs_project_path, self.directory)

            scs_globals.hookup_library_rel_path = self.directory
            return {'FINISHED'}
Example #11
0
        def execute(self, context):
            """Set Traffic Rules library filepath."""
            scs_globals = _get_scs_globals()

            if _path_utils.startswith(self.filepath,
                                      scs_globals.scs_project_path):
                self.filepath = _path_utils.relative_path(
                    scs_globals.scs_project_path, self.filepath)

            scs_globals.traffic_rules_library_rel_path = self.filepath
            return {'FINISHED'}
Example #12
0
        def execute(self, context):
            lprint("D " + self.bl_idname, report_errors=-1, report_warnings=-1)

            if not _path_utils.startswith(self.directory, _get_scs_globals().scs_project_path):
                message = "E Selected path is not inside SCS Project Base Path! Animation can't be exported to this directory."
                lprint(message)
                self.report({'ERROR'}, message[2:])
                return {'CANCELLED'}

            armature = context.active_object
            scs_root_obj = _object_utils.get_scs_root(armature)
            anim_inventory = scs_root_obj.scs_object_animation_inventory

            skeleton_filepath = _path_utils.get_skeleton_relative_filepath(armature, self.directory, scs_root_obj.name)

            if 0 <= self.index < len(anim_inventory):

                anim = anim_inventory[self.index]
                _export.pia.export(scs_root_obj, armature, anim, self.directory, skeleton_filepath)

            lprint("", report_errors=1, report_warnings=1)
            return {'FINISHED'}
Example #13
0
def batch_export(operator_instance,
                 init_obj_list,
                 name_suffix="",
                 menu_filepath=None):
    """This function calls other sorting functions and depending on the resulting output
    dictionary it exports all available 'SCS Game Objects' into specified locations.

    :param operator_instance: operator from within this function is called (used for report)
    :type operator_instance: bpy.types.Operator
    :param init_obj_list: initial object list which should be exported
    :type init_obj_list: tuple of Blender objects
    :param name_suffix: files name suffix (exchange format is using .ef)
    :type name_suffix: str
    :param menu_filepath: filepath used from menu export
    :type menu_filepath: str
    """

    lprint("", report_errors=-1, report_warnings=-1
           )  # Clear the 'error_messages' and 'warning_messages'
    game_objects_dict = _object_utils.sort_out_game_objects_for_export(
        init_obj_list)

    # exclude game objects that were manually omitted from export by property
    game_objects_dict = _object_utils.exclude_switched_off(game_objects_dict)

    if game_objects_dict:
        scs_game_objects_exported = []
        scs_game_objects_rejected = []

        global_filepath = _path_utils.get_global_export_path()

        for root_object in game_objects_dict:

            if not _name_utils.is_valid_scs_root_object_name(root_object.name):
                lprint(
                    "E Rejecting Game Object with invalid SCS Root Object name: %r.\n\t   "
                    "Only a-z, A-Z, 0-9 and \"._-\" characters can be used." %
                    root_object.name)
                scs_game_objects_rejected.append("> \"" + root_object.name +
                                                 "\"")
                continue

            game_object_list = game_objects_dict[root_object]
            if len(game_object_list) == 0:
                lprint(
                    "E Rejecting empty Game Object with SCS Root Object name: %r\n\t   "
                    +
                    "Game Object has to have at least one mesh object or model locator!",
                    (root_object.name, ))
                scs_game_objects_rejected.append("> \"" + root_object.name +
                                                 "\"")
                continue

            # GET CUSTOM FILE PATH
            custom_filepath = _path_utils.get_custom_scs_root_export_path(
                root_object)

            # MAKE FINAL FILEPATH
            if menu_filepath:
                filepath = _path_utils.readable_norm(menu_filepath)
                filepath_message = "Export path selected in file browser:\n\t   \"" + filepath + "\""
            elif custom_filepath:
                filepath = _path_utils.readable_norm(custom_filepath)
                filepath_message = "Custom export path used for \"" + root_object.name + "\" is:\n\t   \"" + filepath + "\""
            else:
                filepath = _path_utils.readable_norm(global_filepath)
                filepath_message = "Default export path used for \"" + root_object.name + "\":\n\t   \"" + filepath + "\""

            scs_project_path = _path_utils.readable_norm(
                _get_scs_globals().scs_project_path)
            if os.path.isdir(filepath) and _path_utils.startswith(
                    filepath, scs_project_path) and scs_project_path != "":

                # EXPORT ENTRY POINT
                export_success = pix.export(filepath, name_suffix, root_object,
                                            game_object_list)

                if export_success:
                    scs_game_objects_exported.append("> \"" +
                                                     root_object.name +
                                                     "\" exported to: '" +
                                                     filepath + "'")
                else:
                    scs_game_objects_rejected.append("> \"" +
                                                     root_object.name + "\"")

            else:
                if filepath:
                    message = (
                        "No valid export path found!\n\t   " +
                        "Export path does not exists or it's not inside SCS Project Base Path.\n\t   "
                        + "SCS Project Base Path:\n\t   \"" +
                        scs_project_path + "\"\n\t   " + filepath_message)
                else:
                    message = "No valid export path found! Please check 'SCS Project Base Path' first."
                lprint('E ' + message)
                operator_instance.report({'ERROR'},
                                         message.replace("\t", "").replace(
                                             "   ", ""))
                return {'CANCELLED'}

        if not lprint(
                "\nI Export procces completed, summaries are printed below!",
                report_errors=True,
                report_warnings=True):
            operator_instance.report(
                {'INFO'},
                "Export successfully completed, exported %s game object(s)!" %
                len(scs_game_objects_exported))
            bpy.ops.wm.scs_tools_show_3dview_report(
                'INVOKE_DEFAULT',
                abort=True)  # abort 3d view reporting operator

        if len(scs_game_objects_exported) > 0:
            message = "EXPORTED GAME OBJECTS (" + str(
                len(scs_game_objects_exported)
            ) + "):\n\t   " + "=" * 26 + "\n\t   "
            for scs_game_object_export_message in scs_game_objects_exported:
                message += scs_game_object_export_message + "\n\t   "
            message += "=" * 26
            lprint("I " + message)

        if len(scs_game_objects_rejected) > 0:
            message = "REJECTED GAME OBJECTS (" + str(
                len(scs_game_objects_rejected)
            ) + "):\n\t   " + "=" * 26 + "\n\t   "
            for scs_game_object_export_message in scs_game_objects_rejected:
                message += scs_game_object_export_message + "\n\t   "
            message += "=" * 26
            lprint("I " + message)

        if len(scs_game_objects_exported) + len(
                scs_game_objects_rejected) == 0:
            message = "Nothing to export! Please setup at least one SCS Root Object."
            lprint('E ' + message)
            operator_instance.report({'ERROR'}, message)
            return {'CANCELLED'}
    else:
        message = "No Game Objects to export because:\n\t   " \
                  "1. Selection export is used and none of selected objects belongs to any SCS Game Object or\n\t   " \
                  "2. all of the SCS Root Objects were manually exluded from export or\n\t   " \
                  "3. there is no SCS Root Objects in the scene."
        lprint('E ' + message)
        operator_instance.report({'ERROR'}, message.replace("\n\t   ", "\n"))
        return {'CANCELLED'}

    return {'FINISHED'}
Example #14
0
def batch_export(operator_instance, init_obj_list, menu_filepath=None):
    """This function calls other sorting functions and depending on the resulting output
    dictionary it exports all available 'SCS Game Objects' into specified locations.

    :param operator_instance: operator from within this function is called (used for report)
    :type operator_instance: bpy.types.Operator
    :param init_obj_list: initial object list which should be exported
    :type init_obj_list: tuple of Blender objects
    :param menu_filepath: filepath used from menu export
    :type menu_filepath: str
    """

    lprint("", report_errors=-1, report_warnings=-1)  # Clear the 'error_messages' and 'warning_messages'
    game_objects_dict = _object_utils.sort_out_game_objects_for_export(init_obj_list)

    # exclude game objects that were manually omitted from export by property
    game_objects_dict = _object_utils.exclude_switched_off(game_objects_dict)

    if game_objects_dict:
        scs_game_objects_exported = []
        scs_game_objects_rejected = []

        global_filepath = _path_utils.get_global_export_path()

        for root_object in game_objects_dict:

            # update root object location to invoke update tagging on it and
            # then update scene to make sure all children objects will have all transforms up to date
            # NOTE: needed because Blender doesn't update objects on invisible layers on it's own
            root_object.location = root_object.location
            for scene in bpy.data.scenes:
                scene.update()

            game_object_list = game_objects_dict[root_object]

            # GET CUSTOM FILE PATH
            custom_filepath = _path_utils.get_custom_scs_root_export_path(root_object)

            # MAKE FINAL FILEPATH
            if menu_filepath:
                filepath = menu_filepath
                filepath_message = 'Export path selected in file browser:\n\t   "' + filepath + '"'
            elif custom_filepath:
                filepath = custom_filepath
                filepath_message = 'Custom export path used for "' + root_object.name + '" is:\n\t   "' + filepath + '"'
            else:
                filepath = global_filepath
                filepath_message = 'Default export path used for "' + root_object.name + '":\n\t   "' + filepath + '"'

            scs_project_path = _get_scs_globals().scs_project_path
            if (
                os.path.isdir(filepath)
                and _path_utils.startswith(filepath, scs_project_path)
                and scs_project_path != ""
            ):

                # EXPORT ENTRY POINT
                export_success = pix.export(filepath, root_object, game_object_list)

                if export_success:
                    scs_game_objects_exported.append('> "' + root_object.name + "\" exported to: '" + filepath + "'")
                else:
                    scs_game_objects_rejected.append('> "' + root_object.name + '"')

            else:
                if filepath:
                    message = (
                        "No valid export path found!\n\t   "
                        + "Export path does not exists or it's not inside SCS Project Base Path.\n\t   "
                        + 'SCS Project Base Path:\n\t   "'
                        + scs_project_path
                        + '"\n\t   '
                        + filepath_message
                    )
                else:
                    message = 'No valid export path found! Please check "SCS Project Base Path" first.'
                lprint("E " + message)
                operator_instance.report({"ERROR"}, message.replace("\t", "").replace("   ", ""))
                return {"CANCELLED"}

        if not lprint(
            "\nI Export procces completed, summaries are printed below!", report_errors=True, report_warnings=True
        ):
            operator_instance.report({"INFO"}, "Export successfully completed!")
            bpy.ops.wm.show_3dview_report("INVOKE_DEFAULT", abort=True)  # abort 3d view reporting operator

        if len(scs_game_objects_exported) > 0:
            print("\n\nEXPORTED GAME OBJECTS (" + str(len(scs_game_objects_exported)) + "):\n" + "=" * 26)
            for scs_game_object_export_message in scs_game_objects_exported:
                print(scs_game_object_export_message)

        if len(scs_game_objects_rejected) > 0:
            print("\n\nREJECTED GAME OBJECTS (" + str(len(scs_game_objects_rejected)) + "):\n" + "=" * 26)
            for scs_game_object_export_message in scs_game_objects_rejected:
                print(scs_game_object_export_message)

        if len(scs_game_objects_exported) + len(scs_game_objects_rejected) == 0:
            message = "Nothing to export! Please set at least one 'SCS Root Object'."
            lprint("E " + message)
            operator_instance.report({"ERROR"}, message)
            return {"CANCELLED"}
    else:
        message = (
            "No 'SCS Root Object' present or all of them were manually exluded from export in their settings.\n\t   "
            "(For more information, please refer to 'SCS Blender Tools' documentation.)"
        )
        lprint("E " + message)
        operator_instance.report({"ERROR"}, message.replace("\n\t   ", "\n"))
        return {"CANCELLED"}

    return {"FINISHED"}
Example #15
0
def get_texture_path_from_material(material, texture_type, export_path):
    """Get's relative path for Texture section of tobj from given texture_type.
    If tobj is not yet created it also creates tobj for it.

    :param material: Blender material
    :type material: bpy.types.Material
    :param texture_type: type of texture which should be readed from material (example "texture_base")
    :type texture_type: str
    :return: relative path for Texture section data of PIT material
    :rtype: str
    """

    # overwrite tobj value directly if specified
    if getattr(material.scs_props, "shader_" + texture_type + "_use_imported",
               False):
        return getattr(material.scs_props,
                       "shader_" + texture_type + "_imported_tobj", "")

    # use tobj value from shader preset if texture is locked and has default value
    if "scs_shader_attributes" in material and "textures" in material[
            "scs_shader_attributes"]:
        for tex_entry in material["scs_shader_attributes"]["textures"].values(
        ):
            if "Tag" in tex_entry and texture_type in tex_entry["Tag"]:
                if "Lock" in tex_entry and tex_entry["Lock"] == "True":
                    if "Value" in tex_entry and tex_entry["Value"] != "":
                        return tex_entry["Value"]

    # CALCULATING TOBJ AND TEXTURE PATHS
    texture_raw_path = getattr(material.scs_props, "shader_" + texture_type,
                               "NO PATH")
    tobj_rel_filepath = tobj_abs_filepath = texture_abs_filepath = ""
    scs_project_path = _get_scs_globals().scs_project_path.rstrip("\\").rstrip(
        "/")

    extensions, texture_raw_path = _path_utils.get_texture_extens_and_strip_path(
        texture_raw_path)

    for ext in extensions:
        if texture_raw_path.startswith("//"):  # relative

            # search for relative path inside current scs project base and
            # possible dlc/mod parent folders; use first found
            for infix in ("", "../base/", "../../base/"):

                curr_path = os.path.join(scs_project_path,
                                         infix + texture_raw_path[2:] + ext)

                if os.path.isfile(curr_path):

                    tobj_rel_filepath = texture_raw_path.replace("//", "/")

                    # if tobj is used by user then get texture path from tobj
                    # otherwise get tobj path from texture path
                    if ext == ".tobj":
                        tobj_abs_filepath = curr_path
                        texture_abs_filepath = _path_utils.get_texture_path_from_tobj(
                            curr_path)
                    else:
                        tobj_abs_filepath = _path_utils.get_tobj_path_from_shader_texture(
                            curr_path, check_existance=False)
                        texture_abs_filepath = curr_path
                    break

            # break searching for texture if texture was found
            if tobj_rel_filepath != "":
                break

        elif ext != ".tobj" and os.path.isfile(texture_raw_path +
                                               ext):  # absolute

            texture_raw_path_with_ext = texture_raw_path + ext

            # if we are exporting somewhere into SCS Project Base Path texture still can be saved
            if scs_project_path != "" and _path_utils.startswith(
                    export_path, scs_project_path):

                tex_dir, tex_filename = os.path.split(
                    texture_raw_path_with_ext)
                tobj_filename = tex_filename + ".tobj"

                # copy texture beside exported files
                try:
                    shutil.copy2(texture_raw_path_with_ext,
                                 os.path.join(export_path, tex_filename))
                except OSError as e:
                    # ignore copying the same file
                    # NOTE: happens if absolute texture paths are used
                    # even if they are referring to texture inside scs project path
                    if type(e).__name__ != "SameFileError":
                        raise e

                # copy also TOBJ if exists
                texture_raw_tobj_path = str(tex_dir) + os.sep + tobj_filename
                if os.path.isfile(texture_raw_tobj_path):
                    shutil.copy2(texture_raw_tobj_path,
                                 os.path.join(export_path, tobj_filename))

                # get copied TOBJ relative path to current scs project path
                tobj_rel_filepath = ""
                if export_path != scs_project_path:
                    tobj_rel_filepath = os.sep + os.path.relpath(
                        export_path, scs_project_path)

                tobj_rel_filepath = tobj_rel_filepath + os.sep + tobj_filename[:
                                                                               -5]
                tobj_abs_filepath = os.path.join(export_path, tobj_filename)
                texture_abs_filepath = texture_raw_path_with_ext
                break

            else:
                lprint(
                    "E Can not properly export texture %r from material %r!\n\t   "
                    +
                    "Make sure you are exporting somewhere into Project Base Path and texture is properly set!",
                    (texture_raw_path, material.name))
                return ""

    else:
        lprint(
            "E Texture file %r from material %r doesn't exists inside current Project Base Path.\n\t   "
            +
            "TOBJ  won't be exported and reference will remain empty, expect problems!",
            (texture_raw_path, material.name))
        return ""

    # CREATE TOBJ FILE
    if not os.path.isfile(tobj_abs_filepath):  # only if it does not exists yet

        # export tobj only if file of texture exists
        if os.path.isfile(texture_abs_filepath):
            texture_name = os.path.basename(
                _path_utils.strip_sep(texture_abs_filepath))
            _tobj.export(tobj_abs_filepath, texture_name, set())
        else:
            lprint(
                "E Texture file %r from material %r doesn't exists, TOBJ can not be exported!",
                (texture_raw_path, material.name))

    # make sure that Windows users will export proper paths
    tobj_rel_filepath = tobj_rel_filepath.replace("\\", "/")

    return tobj_rel_filepath
Example #16
0
def batch_export(operator_instance, init_obj_list, menu_filepath=None):
    """This function calls other sorting functions and depending on the resulting output
    dictionary it exports all available 'SCS Game Objects' into specified locations.

    :param operator_instance: operator from within this function is called (used for report)
    :type operator_instance: bpy.types.Operator
    :param init_obj_list: initial object list which should be exported
    :type init_obj_list: tuple of Blender objects
    :param menu_filepath: filepath used from menu export
    :type menu_filepath: str
    """

    lprint("", report_errors=-1, report_warnings=-1
           )  # Clear the 'error_messages' and 'warning_messages'
    game_objects_dict = _object_utils.sort_out_game_objects_for_export(
        init_obj_list)

    # exclude game objects that were manually omitted from export by property
    game_objects_dict = _object_utils.exclude_switched_off(game_objects_dict)

    if game_objects_dict:
        scs_game_objects_exported = []
        scs_game_objects_rejected = []

        global_filepath = _path_utils.get_global_export_path()

        for root_object in game_objects_dict:

            # update root object location to invoke update tagging on it and
            # then update scene to make sure all children objects will have all transforms up to date
            # NOTE: needed because Blender doesn't update objects on invisible layers on it's own
            root_object.location = root_object.location
            for scene in bpy.data.scenes:
                scene.update()

            game_object_list = game_objects_dict[root_object]

            # GET CUSTOM FILE PATH
            custom_filepath = _path_utils.get_custom_scs_root_export_path(
                root_object)

            # MAKE FINAL FILEPATH
            if menu_filepath:
                filepath = menu_filepath
                filepath_message = "Export path selected in file browser:\n\t   \"" + filepath + "\""
            elif custom_filepath:
                filepath = custom_filepath
                filepath_message = "Custom export path used for \"" + root_object.name + "\" is:\n\t   \"" + filepath + "\""
            else:
                filepath = global_filepath
                filepath_message = "Default export path used for \"" + root_object.name + "\":\n\t   \"" + filepath + "\""

            scs_project_path = _get_scs_globals().scs_project_path
            if os.path.isdir(filepath) and _path_utils.startswith(
                    filepath, scs_project_path) and scs_project_path != "":

                # EXPORT ENTRY POINT
                export_success = pix.export(filepath, root_object,
                                            game_object_list)

                if export_success:
                    scs_game_objects_exported.append("> \"" +
                                                     root_object.name +
                                                     "\" exported to: '" +
                                                     filepath + "'")
                else:
                    scs_game_objects_rejected.append("> \"" +
                                                     root_object.name + "\"")

            else:
                if filepath:
                    message = (
                        "No valid export path found!\n\t   " +
                        "Export path does not exists or it's not inside SCS Project Base Path.\n\t   "
                        + "SCS Project Base Path:\n\t   \"" +
                        scs_project_path + "\"\n\t   " + filepath_message)
                else:
                    message = "No valid export path found! Please check \"SCS Project Base Path\" first."
                lprint('E ' + message)
                operator_instance.report({'ERROR'},
                                         message.replace("\t", "").replace(
                                             "   ", ""))
                return {'CANCELLED'}

        if not lprint(
                "\nI Export procces completed, summaries are printed below!",
                report_errors=True,
                report_warnings=True):
            operator_instance.report({'INFO'},
                                     "Export successfully completed!")
            bpy.ops.wm.show_3dview_report(
                'INVOKE_DEFAULT',
                abort=True)  # abort 3d view reporting operator

        if len(scs_game_objects_exported) > 0:
            print("\n\nEXPORTED GAME OBJECTS (" +
                  str(len(scs_game_objects_exported)) + "):\n" + "=" * 26)
            for scs_game_object_export_message in scs_game_objects_exported:
                print(scs_game_object_export_message)

        if len(scs_game_objects_rejected) > 0:
            print("\n\nREJECTED GAME OBJECTS (" +
                  str(len(scs_game_objects_rejected)) + "):\n" + "=" * 26)
            for scs_game_object_export_message in scs_game_objects_rejected:
                print(scs_game_object_export_message)

        if len(scs_game_objects_exported) + len(
                scs_game_objects_rejected) == 0:
            message = "Nothing to export! Please set at least one 'SCS Root Object'."
            lprint('E ' + message)
            operator_instance.report({'ERROR'}, message)
            return {'CANCELLED'}
    else:
        message = "No 'SCS Root Object' present or all of them were manually exluded from export in their settings.\n\t   " \
                  "(For more information, please refer to 'SCS Blender Tools' documentation.)"
        lprint('E ' + message)
        operator_instance.report({'ERROR'}, message.replace("\n\t   ", "\n"))
        return {'CANCELLED'}

    return {'FINISHED'}
Example #17
0
def _get_texture_path_from_material(material, texture_type, export_path):
    """Get's relative path for Texture section of tobj from given texture_type.
    If tobj is not yet created it also creates tobj for it.

    :param material: Blender material
    :type material: bpy.types.Material
    :param texture_type: type of texture which should be readed from material (example "texture_base")
    :type texture_type: str
    :return: relative path for Texture section data of PIT material
    :rtype: str
    """

    # overwrite tobj value directly if specified
    if getattr(material.scs_props, "shader_" + texture_type + "_use_imported", False):
        return getattr(material.scs_props, "shader_" + texture_type + "_imported_tobj", "")

    # use tobj value from shader preset if texture is locked and has default value
    if "scs_shader_attributes" in material and "textures" in material["scs_shader_attributes"]:
        for tex_entry in material["scs_shader_attributes"]["textures"].values():
            if "Tag" in tex_entry and texture_type in tex_entry["Tag"]:
                if "Lock" in tex_entry and tex_entry["Lock"] == "True":
                    if "Value" in tex_entry and tex_entry["Value"] != "":
                        return tex_entry["Value"]

    # CALCULATING TOBJ AND TEXTURE PATHS
    texture_raw_path = getattr(material.scs_props, "shader_" + texture_type, "NO PATH")
    tobj_rel_filepath = tobj_abs_filepath = texture_abs_filepath = ""
    scs_project_path = _get_scs_globals().scs_project_path.rstrip("\\").rstrip("/")

    extensions, texture_raw_path = _path_utils.get_texture_extens_and_strip_path(texture_raw_path)

    for ext in extensions:
        if texture_raw_path.startswith("//"):  # relative

            # search for relative path inside current scs project base and
            # possible dlc/mod parent folders; use first found
            for infix in ("", "../base/", "../../base/"):

                curr_path = os.path.join(scs_project_path, infix + texture_raw_path[2:] + ext)

                if os.path.isfile(curr_path):

                    tobj_rel_filepath = texture_raw_path.replace("//", "/")

                    # if tobj is used by user then get texture path from tobj
                    # otherwise get tobj path from texture path
                    if ext == ".tobj":
                        tobj_abs_filepath = curr_path
                        texture_abs_filepath = _path_utils.get_texture_path_from_tobj(curr_path)
                    else:
                        tobj_abs_filepath = _path_utils.get_tobj_path_from_shader_texture(curr_path, check_existance=False)
                        texture_abs_filepath = curr_path
                    break

            # break searching for texture if texture was found
            if tobj_rel_filepath != "":
                break

        elif ext != ".tobj" and os.path.isfile(texture_raw_path + ext):  # absolute

            texture_raw_path_with_ext = texture_raw_path + ext

            # if we are exporting somewhere into SCS Project Base Path texture still can be saved
            if scs_project_path != "" and _path_utils.startswith(export_path, scs_project_path):

                tex_dir, tex_filename = os.path.split(texture_raw_path_with_ext)
                tobj_filename = tex_filename + ".tobj"

                # copy texture beside exported files
                try:
                    shutil.copy2(texture_raw_path_with_ext, os.path.join(export_path, tex_filename))
                except OSError as e:
                    # ignore copying the same file
                    # NOTE: happens if absolute texture paths are used
                    # even if they are referring to texture inside scs project path
                    if type(e).__name__ != "SameFileError":
                        raise e

                # copy also TOBJ if exists
                texture_raw_tobj_path = str(tex_dir) + os.sep + tobj_filename
                if os.path.isfile(texture_raw_tobj_path):
                    shutil.copy2(texture_raw_tobj_path, os.path.join(export_path, tobj_filename))

                # get copied TOBJ relative path to current scs project path
                tobj_rel_filepath = ""
                if export_path != scs_project_path:
                    tobj_rel_filepath = os.sep + os.path.relpath(export_path, scs_project_path)

                tobj_rel_filepath = tobj_rel_filepath + os.sep + tobj_filename[:-5]
                tobj_abs_filepath = os.path.join(export_path, tobj_filename)
                texture_abs_filepath = texture_raw_path_with_ext
                break

            else:
                lprint("E Can not properly export texture %r from material %r!\n\t   " +
                       "Make sure you are exporting somewhere into Project Base Path and texture is properly set!",
                       (texture_raw_path, material.name))
                return ""

    else:
        lprint("E Texture file %r from material %r doesn't exists inside current Project Base Path.\n\t   " +
               "TOBJ  won't be exported and reference will remain empty, expect problems!",
               (texture_raw_path, material.name))
        return ""

    # CREATE TOBJ FILE
    if not os.path.isfile(tobj_abs_filepath):  # only if it does not exists yet

        # export tobj only if file of texture exists
        if os.path.isfile(texture_abs_filepath):
            texture_name = os.path.basename(_path_utils.strip_sep(texture_abs_filepath))
            _tobj.export(tobj_abs_filepath, texture_name, set())
        else:
            lprint("E Texture file %r from material %r doesn't exists, TOBJ can not be exported!",
                   (texture_raw_path, material.name))

    # make sure that Windows users will export proper paths
    tobj_rel_filepath = tobj_rel_filepath.replace("\\", "/")

    return tobj_rel_filepath