def optimize_scenery(script_settings):
    try:
        # instantiate the msfsProject and create the necessary resources if it does not exist
        msfs_project = MsfsProject(script_settings.projects_path,
                                   script_settings.project_name,
                                   script_settings.definition_file,
                                   script_settings.author_name,
                                   script_settings.sources_path)

        check_configuration(
            script_settings,
            msfs_project,
            check_optimisation=True,
            check_lily_texture_packer=script_settings.bake_textures_enabled)

        if script_settings.backup_enabled:
            msfs_project.backup(
                Path(os.path.abspath(__file__)).stem.replace(
                    SCRIPT_PREFIX, str()))

        clean_scene()
        msfs_project.optimize(script_settings)

        if script_settings.build_package_enabled:
            build_package(msfs_project, script_settings)

        pr_bg_green("Script correctly applied" + CEND)

    except ScriptError as ex:
        error_report = "".join(ex.value)
        isolated_print(constants.EOL + error_report)
        pr_bg_red("Script aborted" + CEND)
    except RuntimeError as ex:
        isolated_print(constants.EOL + str(ex))
        pr_bg_red("Script aborted" + CEND)
def split_tiles(script_settings):
    try:
        # instantiate the msfsProject and create the necessary resources if it does not exist
        msfs_project = MsfsProject(script_settings.projects_path,
                                   script_settings.project_name,
                                   script_settings.definition_file,
                                   script_settings.author_name,
                                   script_settings.sources_path)

        check_configuration(script_settings, msfs_project)

        if script_settings.backup_enabled:
            msfs_project.backup(
                Path(os.path.abspath(__file__)).stem.replace(
                    SCRIPT_PREFIX, str()))

        msfs_project.split_tiles()

        if script_settings.build_package_enabled:
            build_package(msfs_project, script_settings)

        pr_bg_green("Script correctly applied" + constants.CEND)

    except ScriptError as ex:
        error_report = str().join(ex.value)
        isolated_print(constants.EOL + error_report)
        pr_bg_red("Script aborted" + constants.CEND)
    except RuntimeError as ex:
        isolated_print(constants.EOL + str(ex))
        pr_bg_red("Script aborted" + constants.CEND)
Example #3
0
def clean_scene():
    if not bpy.data:
        return

    bpy.ops.object.select_all(action=SELECT_ACTION)

    for block in bpy.data.meshes:
        if block.users == 0:
            bpy.data.meshes.remove(block)

    for block in bpy.data.materials:
        if block.users == 0:
            bpy.data.materials.remove(block)

    for block in bpy.data.textures:
        if block.users == 0:
            bpy.data.textures.remove(block)

    for block in bpy.data.images:
        if block.users == 0:
            bpy.data.images.remove(block)

    bpy.ops.object.delete()

    # Now cycles through the dangling datablocks and remove them.
    for me in bpy.data.meshes:
        if not remove_mesh_from_memory(me.name):
            isolated_print("Unable to remove [%s]." % me.name)

    print(EOL)
    print("3d scene cleaned", EOL)
Example #4
0
 def fix_tiles_lightning_issues(self, settings):
     isolated_print(EOL)
     lods = [lod for tile in self.tiles.values() for lod in tile.lods]
     pbar = ProgressBar(list(lods), title="FIX TILES LIGHTNING ISSUES")
     for lod in lods:
         lod.optimization_in_progress = False
         lod.prepare_for_msfs()
         pbar.update("%s lightning issues fixed" % lod.name)
Example #5
0
 def backup(self, backup_subfolder, all_files=True):
     isolated_print(EOL)
     self.backup_files(backup_subfolder)
     if all_files:
         self.backup_tiles(backup_subfolder)
         self.backup_colliders(backup_subfolder)
     self.backup_scene_objects(backup_subfolder)
     self.backup_shapes(backup_subfolder)
Example #6
0
def export_to_optimized_gltf_files(file, texture_folder, use_selection=False):
    isolated_print("export to", file, "with associated textures", EOL)
    bpy.ops.export_scene.gltf(export_format=GLTF_SEPARATE_EXPORT_FORMAT,
                              export_extras=True,
                              filepath=file,
                              export_texture_dir=texture_folder,
                              use_selection=use_selection)
    model_file = MsfsGltf(file)
    model_file.add_optimization_tag()
    model_file.dump()
def check_lily_texture_packer_availability(settings, warning_msg=str()):
    texture_packer_enabled = False
    try:
        if LILY_TEXTURE_PACKER_ADDON in bpy.context.preferences.addons:
            texture_packer_enabled = True
            pr_ok_green(
                str("Lily texture packer enabled").ljust(RESULT_MSG_LENGTH))
    except:
        pass

    if not texture_packer_enabled:
        pr_ko_orange(
            str("Lily texture packer disabled").ljust(RESULT_MSG_LENGTH))
        settings.bake_textures_enabled = False
        isolated_print(
            CORANGE + warning_msg +
            " Lily texture packer is not enabled in your blender addons. Baking of the tile textures is disabled"
            + CEND + EOL)
Example #8
0
    def update(self, description=str()):
        if self.range <= 0:
            return

        self.idx += 1
        progress = self.idx / self.range
        block = int(round(self.length * progress))
        description = DONE_PROCESS if progress >= 1 else description
        msg = self.__get_color(progress) + "\r[{0}] {1}%: {2}".format(
            "\u25A0" * block + "-" * (self.length - block),
            round(progress * 100, 2), description + CEND)

        sys.stdout = sys.__stdout__
        sys.stdout.write(msg.ljust(MSG_LENGTH))
        sys.stdout.flush()
        sys.stdout = open(os.devnull, 'w')
        time.sleep(self.sleep)

        if progress >= 1:
            isolated_print(EOL)
def init_msfs_scenery_project(script_settings):
    try:
        print_title("INIT SCENERY PROJECT")

        # instantiate the msfsProject and create the necessary resources if it does not exist
        MsfsProject(script_settings.projects_path,
                    script_settings.project_name,
                    script_settings.definition_file,
                    script_settings.author_name,
                    script_settings.sources_path,
                    init_structure=True)

        pr_bg_green("Script correctly applied" + constants.CEND)

    except ScriptError as ex:
        error_report = "".join(ex.value)
        isolated_print(constants.EOL + error_report)
        pr_bg_red("Script aborted" + constants.CEND)
    except RuntimeError as ex:
        isolated_print(constants.EOL + str(ex))
        pr_bg_red("Script aborted" + constants.CEND)
Example #10
0
    def optimize(self, settings):
        isolated_print(EOL)
        dest_format = settings.output_texture_format
        src_format = JPG_TEXTURE_FORMAT if dest_format == PNG_TEXTURE_FORMAT else PNG_TEXTURE_FORMAT
        lods = [lod for tile in self.tiles.values() for lod in tile.lods]
        self.__convert_tiles_textures(src_format, dest_format)
        self.update_min_size_values(settings)
        # some tile lods are not optimized
        if self.__optimization_needed():
            self.__create_optimization_folders()
            self.__optimize_tile_lods(self.__retrieve_lods_to_process())

        pbar = ProgressBar(list(lods), title="PREPARE THE TILES FOR MSFS")
        for lod in lods:
            lod.folder = os.path.dirname(
                lod.folder) if self.__optimization_needed() else lod.folder
            lod.optimization_in_progress = False
            lod.prepare_for_msfs()
            pbar.update("%s prepared for msfs" % lod.name)

        self.objects_xml.update_objects_position(self, settings)
def compress_built_package(script_settings):
    try:
        # instantiate the msfsProject and create the necessary resources if it does not exist
        msfs_project = MsfsProject(script_settings.projects_path,
                                   script_settings.project_name,
                                   script_settings.definition_file,
                                   script_settings.author_name,
                                   script_settings.sources_path,
                                   fast_init=True)

        check_configuration(script_settings,
                            msfs_project,
                            check_built_package=True,
                            check_compressonator=True)

        isolated_print(EOL)
        print_title("COMPRESS BUILT PACKAGE")

        msfs_project.compress_built_package(script_settings)

        if script_settings.build_package_enabled:
            build_package(msfs_project, script_settings)

        pr_bg_green("Script correctly applied" + constants.CEND)

    except ScriptError as ex:
        error_report = "".join(ex.value)
        isolated_print(constants.EOL + error_report)
        pr_bg_red("Script aborted" + constants.CEND)
    except RuntimeError as ex:
        isolated_print(constants.EOL + str(ex))
        pr_bg_red("Script aborted" + constants.CEND)
    def optimize(self, bake_textures_enabled, output_texture_format):
        model_files = [model_file for model_file in Path(self.folder).glob(GLTF_FILE_PATTERN) if not self.__is_optimized(model_file)]
        if not model_files:
            return
        new_gltf = os.path.join(os.path.dirname(self.folder), Path(self.folder).name + GLTF_FILE_EXT)

        # Import the gltf files located in the object folder
        import_model_files(model_files)

        if bake_textures_enabled and self.has_unbaked_textures():
            isolated_print("bake textures for", self.name)
            bake_texture_files(self.folder, self.name + "." + output_texture_format)

        isolated_print("fix bounding box for", self.name)
        fix_object_bounding_box()
        export_to_optimized_gltf_files(new_gltf, TEXTURE_FOLDER)

        if os.path.isfile(new_gltf):
            shutil.rmtree(self.folder)
            self.folder = os.path.dirname(self.folder)
            self.optimization_in_progress = False
            self.__retrieve_gltf_resources()
Example #13
0
    def __convert_tiles_textures(self, src_format, dest_format):
        textures = self.__retrieve_tiles_textures(src_format)

        if textures:
            isolated_print(
                src_format +
                " texture files detected in the tiles of the project! Try to install pip, then convert them"
            )
            print_title("INSTALL PILLOW")
            install_python_lib("Pillow")

            pbar = ProgressBar(textures,
                               title="CONVERT " + src_format.upper() +
                               " TEXTURE FILES TO " + dest_format.upper())
            for texture in textures:
                file = texture.file
                if not texture.convert_format(src_format, dest_format):
                    raise ScriptError(
                        "An error was detected while converting texture files in "
                        + self.texture_folder + " ! Please convert them to " +
                        dest_format +
                        " format prior to launch the script, or remove them")
                else:
                    pbar.update("%s converted to %s" % (file, dest_format))
Example #14
0
 def clean(self):
     isolated_print(EOL)
     self.__clean_objects(self.tiles)
     self.__clean_objects(self.colliders)
     self.__clean_objects(self.objects)
Example #15
0
 def update_objects_position(self, settings):
     isolated_print(EOL)
     self.objects_xml.update_objects_position(self, settings)
def check_configuration(settings,
                        msfs_project,
                        check_optimisation=False,
                        check_lily_texture_packer=False,
                        check_built_package=False,
                        check_compressonator=False):
    error_msg = "Configuration error found ! "
    warning_msg = "Configuration warning ! "

    print_title("CHECK CONFIGURATION FOR " + msfs_project.project_name +
                " PROJECT")

    # check if the projects folder exists
    if not os.path.isdir(msfs_project.parent_path):
        pr_ko_red(str("projects_path value").ljust(RESULT_MSG_LENGTH))
        raise ScriptError(
            error_msg + "The folder containing your projects (" +
            msfs_project.parent_path +
            ") was not found. Please check the projects_path value")
    pr_ok_green(str("projects_path value").ljust(RESULT_MSG_LENGTH))

    # check the projects name
    if not os.path.isdir(msfs_project.project_folder):
        pr_ko_red(str("project_name value").ljust(RESULT_MSG_LENGTH))
        raise ScriptError(error_msg + "Project folder " +
                          msfs_project.project_folder +
                          " not found. Please check the project_name value")
    pr_ok_green(str("project_name value").ljust(RESULT_MSG_LENGTH))

    # check if the msfs_project file is reachable
    if not os.path.isfile(msfs_project.project_definition_xml_path):
        pr_ko_red(str("project_file_name value").ljust(RESULT_MSG_LENGTH))
        raise ScriptError(
            error_msg + "Project file (" +
            msfs_project.project_definition_xml_path +
            ") not found. Please check the project_file_name value")
    pr_ok_green(str("project_file_name value").ljust(RESULT_MSG_LENGTH))

    # check if the fspackagetool.exe file is reachable
    if not os.path.isfile(settings.msfs_build_exe_path):
        pr_ko_orange(str("msfs_build_exe_path value").ljust(RESULT_MSG_LENGTH))
        settings.build_package_enabled = False
        isolated_print(
            CORANGE + warning_msg + settings.msfs_build_exe_path +
            " bin file not found. Automatic package building is disabled" +
            CEND + EOL)
    else:
        pr_ok_green(str("msfs_build_exe_path value").ljust(RESULT_MSG_LENGTH))

    # check if the package definitions folder exists
    if not os.path.isdir(msfs_project.package_definitions_folder):
        pr_ko_red(
            str("package_definitions_folder value").ljust(RESULT_MSG_LENGTH))
        raise ScriptError(
            error_msg +
            "The folder containing the package definitions of the msfs_project ("
            + msfs_project.package_definitions_folder +
            ") was not found. Please check the package_definitions_folder value"
        )
    pr_ok_green(
        str("package_definitions_folder value").ljust(RESULT_MSG_LENGTH))

    # check if the package definitions file name is reachable
    if not os.path.isfile(msfs_project.package_definitions_xml_path):
        pr_ko_red(
            str("package_definitions_file_name value").ljust(
                RESULT_MSG_LENGTH))
        raise ScriptError(
            error_msg + "Package definitions file (" +
            msfs_project.package_definitions_xml_path +
            ") not found. Please check the package_definitions_file_name value"
        )
    pr_ok_green(
        str("package_definitions_file_name value").ljust(RESULT_MSG_LENGTH))

    # check if the objects folder exists
    if not os.path.isdir(msfs_project.model_lib_folder):
        pr_ko_red(str("objects_folder value").ljust(RESULT_MSG_LENGTH))
        raise ScriptError(
            error_msg +
            "The folder containing the objects of the msfs_project (" +
            msfs_project.model_lib_folder +
            ") was not found. Please check the objects_folder value")
    pr_ok_green(str("objects_folder value").ljust(RESULT_MSG_LENGTH))

    # check if the folder containing the description files of the scene exists
    if not os.path.isdir(msfs_project.scene_folder):
        pr_ko_red(str("scene_folder value").ljust(RESULT_MSG_LENGTH))
        raise ScriptError(
            error_msg +
            "The folder containing the description files of the scene (" +
            msfs_project.scene_folder +
            ") was not found. Please check the scene_folder value")
    pr_ok_green(str("scene_folder value").ljust(RESULT_MSG_LENGTH))

    # check if the description file of the scene is reachable
    if not os.path.isfile(msfs_project.scene_objects_xml_file_path):
        pr_ko_red(str("scene_file_name value").ljust(RESULT_MSG_LENGTH))
        raise ScriptError(
            error_msg + "Description file of the scene (" +
            msfs_project.scene_objects_xml_file_path +
            ") not found. Please check the scene_file_name value")
    pr_ok_green(str("scene_file_name value").ljust(RESULT_MSG_LENGTH))

    # check if the folder containing the textures of the scene exists
    if not os.path.isdir(msfs_project.texture_folder):
        pr_ko_red(str("textures_folder value").ljust(RESULT_MSG_LENGTH))
        raise ScriptError(
            error_msg + "The folder containing the textures of the scene (" +
            msfs_project.texture_folder +
            ") was not found. Please check the textures_folder value")
    pr_ok_green(str("textures_folder value").ljust(RESULT_MSG_LENGTH))

    if check_optimisation:
        if not install_python_lib("Pillow"):
            pr_ko_red(str("Pillow lib installation").ljust(RESULT_MSG_LENGTH))
            raise ScriptError(
                error_msg +
                "Pillow python lib is not correctly installed. Please check what can prevent this library to be installed correctly"
            )
    pr_ok_green(str("Pillow lib installation").ljust(RESULT_MSG_LENGTH))

    # check if Lily texture packer is installed
    if check_lily_texture_packer and settings.bake_textures_enabled:
        check_lily_texture_packer_availability(settings,
                                               warning_msg=warning_msg)

    if check_built_package:
        # check if the folder containing project package exists
        if not os.path.isdir(msfs_project.built_project_package_folder):
            pr_ko_red(
                str("built_project_package_folder value").ljust(
                    RESULT_MSG_LENGTH))
            raise ScriptError(
                error_msg +
                "The folder containing built package of the project (" +
                msfs_project.built_project_package_folder +
                ") was not found. Please check the built_project_package_folder value"
            )
        pr_ok_green(
            str("built_project_package_folder value").ljust(RESULT_MSG_LENGTH))

    if check_compressonator:
        # check if the compressonatorcli.exe file is reachable
        if not os.path.isfile(settings.compressonator_exe_path):
            pr_ko_red(
                str("compressonator_exe_path value").ljust(RESULT_MSG_LENGTH))
            raise ScriptError(
                error_msg + settings.compressonator_exe_path +
                "file was not found. Please check the compressonator_exe_path value or install compressonator"
            )
        else:
            pr_ok_green(
                str("compressonator_exe_path value").ljust(RESULT_MSG_LENGTH))