From c2a847934bb077ae3b2c034dd0c30db11f4f20c2 Mon Sep 17 00:00:00 2001 From: "kaosat.dev" Date: Sun, 19 May 2024 11:04:34 +0200 Subject: [PATCH] feat(blenvy): overhauled path/directory management a bit * full paths are now computed properties * cleanups of path names * various tweaks --- tools/blenvy/TODO.md | 12 ++++--- tools/blenvy/__init__.py | 2 +- .../blenvy/blueprints/blueprints_registry.py | 15 +++------ tools/blenvy/core/blenvy_manager.py | 31 +++++++++++++++++-- ...er_browser.py => assets_folder_browser.py} | 12 +++---- tools/blenvy/core/ui/ui.py | 5 +++ .../auto_export/auto_export.py | 14 +++------ .../auto_export/export_blueprints.py | 4 +-- .../auto_export/export_main_scenes.py | 10 +++--- .../auto_export/get_blueprints_to_export.py | 4 +-- .../auto_export/get_levels_to_export.py | 4 +-- .../modules/export_materials.py | 4 +-- 12 files changed, 70 insertions(+), 47 deletions(-) rename tools/blenvy/core/ui/{folder_browser.py => assets_folder_browser.py} (89%) diff --git a/tools/blenvy/TODO.md b/tools/blenvy/TODO.md index b6c3768..db81a61 100644 --- a/tools/blenvy/TODO.md +++ b/tools/blenvy/TODO.md @@ -37,8 +37,7 @@ Assets: - QUESTION : do we want to include them in the list of assets per level ? - this would enable pre-loading ALL the assets, but is not ideal in most other cases - so add an option ? - - [] the assets of local blueprints - + - [ ] the assets of local blueprints Blueprints: - [x] on save: write IN THE COLLECTION PROPERTIES @@ -50,14 +49,17 @@ Blueprints: - [ ] scan & inject on save - [ ] decide where & when to do & store blueprints data +Components: + - [ ] add support for adding components to collections + General things to solve: - [x] save settings - [x] load settings - [ ] add_blueprints_data -- [ ] rename all path stuff using the old naming convention : "export_blueprints_path_full" -- [ ] generate the full paths directly when setting them in the UI - - [ ] problem : how to deal with defaults: do it on start/load ? +- [x] rename all path stuff using the old naming convention : "blueprints_path_full" +- [x] generate the full paths directly when setting them in the UI + - [x] problem : how to deal with defaults: do it on start/load ? General issues: - there is no safeguard for naming collisions for naming across blender files diff --git a/tools/blenvy/__init__.py b/tools/blenvy/__init__.py index e0081c3..b9dcfb2 100644 --- a/tools/blenvy/__init__.py +++ b/tools/blenvy/__init__.py @@ -51,7 +51,7 @@ from .core.operators import OT_switch_bevy_tooling from .core.scene_helpers import (SceneSelector) from .core.ui.ui import (BLENVY_PT_SidePanel) from .core.ui.scenes_list import SCENES_LIST_OT_actions, SCENE_UL_Blenvy -from .core.ui.folder_browser import OT_OpenAssetsFolderBrowser +from .core.ui.assets_folder_browser import OT_OpenAssetsFolderBrowser # this needs to be here, as it is how Blender's gltf exporter callbacks are defined, at the add-on root level diff --git a/tools/blenvy/blueprints/blueprints_registry.py b/tools/blenvy/blueprints/blueprints_registry.py index fb67f48..ccefa95 100644 --- a/tools/blenvy/blueprints/blueprints_registry.py +++ b/tools/blenvy/blueprints/blueprints_registry.py @@ -45,17 +45,12 @@ class BlueprintsRegistry(PropertyGroup): def unregister(cls): del bpy.types.WindowManager.blueprints_registry - def add_blueprint(self, blueprint): self.blueprints_list.append(blueprint) def add_blueprints_data(self): - print("adding blueprints data") - addon_prefs = load_settings(".gltf_auto_export_settings") - if addon_prefs is not None: - print("addon_prefs", addon_prefs) - addon_prefs["export_marked_assets"] = False - addon_prefs = SimpleNamespace(**addon_prefs) - [main_scene_names, level_scenes, library_scene_names, library_scenes] = get_scenes(addon_prefs) - blueprints_data = blueprints_scan(level_scenes, library_scenes, addon_prefs) - self.blueprints_data = blueprints_data + blenvy = bpy.context.window_manager.blenvy + addon_prefs = blenvy + [main_scene_names, level_scenes, library_scene_names, library_scenes] = get_scenes(addon_prefs) + blueprints_data = blueprints_scan(level_scenes, library_scenes, addon_prefs) + self.blueprints_data = blueprints_data diff --git a/tools/blenvy/core/blenvy_manager.py b/tools/blenvy/core/blenvy_manager.py index f899d3b..c8fd7ab 100644 --- a/tools/blenvy/core/blenvy_manager.py +++ b/tools/blenvy/core/blenvy_manager.py @@ -1,3 +1,4 @@ +import os import bpy from bpy_types import (PropertyGroup) from bpy.props import (EnumProperty, PointerProperty, StringProperty, CollectionProperty, IntProperty) @@ -13,13 +14,13 @@ def update_scene_lists(self, context): upsert_settings(blenvy.settings_save_path, {"common_library_scene_names": [scene.name for scene in blenvy.library_scenes]}) def update_asset_folders(self, context): - blenvy = context.window_manager.blenvy + blenvy = self # context.window_manager.blenvy asset_path_names = ['project_root_path', 'assets_path', 'blueprints_path', 'levels_path', 'materials_path'] for asset_path_name in asset_path_names: upsert_settings(blenvy.settings_save_path, {asset_path_name: getattr(blenvy, asset_path_name)}) def update_mode(self, context): - blenvy = self # context.window_manager.blenvy + blenvy = self upsert_settings(blenvy.settings_save_path, {"mode": blenvy.mode }) class BlenvyManager(PropertyGroup): @@ -37,7 +38,6 @@ class BlenvyManager(PropertyGroup): update=update_mode ) # type: ignore - project_root_path: StringProperty( name = "Project Root Path", description="The root folder of your (Bevy) project (not assets!)", @@ -45,6 +45,11 @@ class BlenvyManager(PropertyGroup): update= update_asset_folders ) # type: ignore + # computed property for the absolute path of assets + project_root_path_full: StringProperty( + get=lambda self: os.path.abspath(os.path.join(os.path.dirname(bpy.data.filepath), self.project_root_path)) + ) # type: ignore + assets_path: StringProperty( name='Export folder', description='The root folder for all exports(relative to the root folder/path) Defaults to "assets" ', @@ -52,6 +57,11 @@ class BlenvyManager(PropertyGroup): options={'HIDDEN'}, update= update_asset_folders ) # type: ignore + + # computed property for the absolute path of assets + assets_path_full: StringProperty( + get=lambda self: os.path.abspath(os.path.join(os.path.dirname(bpy.data.filepath), self.project_root_path, self.assets_path)) + ) # type: ignore blueprints_path: StringProperty( name='Blueprints path', @@ -60,6 +70,11 @@ class BlenvyManager(PropertyGroup): update= update_asset_folders ) # type: ignore + # computed property for the absolute path of blueprints + blueprints_path_full: StringProperty( + get=lambda self: os.path.abspath(os.path.join(os.path.dirname(bpy.data.filepath), self.project_root_path, self.assets_path, self.blueprints_path)) + ) # type: ignore + levels_path: StringProperty( name='Levels path', description='path to export the levels (main scenes) to (relative to the assets folder)', @@ -67,6 +82,11 @@ class BlenvyManager(PropertyGroup): update= update_asset_folders ) # type: ignore + # computed property for the absolute path of blueprints + levels_path_full: StringProperty( + get=lambda self: os.path.abspath(os.path.join(os.path.dirname(bpy.data.filepath), self.project_root_path, self.assets_path, self.levels_path)) + ) # type: ignore + materials_path: StringProperty( name='Materials path', description='path to export the materials libraries to (relative to the assets folder)', @@ -74,6 +94,11 @@ class BlenvyManager(PropertyGroup): update= update_asset_folders ) # type: ignore + # computed property for the absolute path of blueprints + materials_path_full: StringProperty( + get=lambda self: os.path.abspath(os.path.join(os.path.dirname(bpy.data.filepath), self.project_root_path, self.assets_path, self.materials_path)) + ) # type: ignore + main_scenes: CollectionProperty(name="main scenes", type=SceneSelector) # type: ignore main_scenes_index: IntProperty(name = "Index for main scenes list", default = 0, update=update_scene_lists) # type: ignore main_scene_names = [] # FIXME: unsure diff --git a/tools/blenvy/core/ui/folder_browser.py b/tools/blenvy/core/ui/assets_folder_browser.py similarity index 89% rename from tools/blenvy/core/ui/folder_browser.py rename to tools/blenvy/core/ui/assets_folder_browser.py index 3ff2321..bdbb5f8 100644 --- a/tools/blenvy/core/ui/folder_browser.py +++ b/tools/blenvy/core/ui/assets_folder_browser.py @@ -4,7 +4,7 @@ import os from bpy_extras.io_utils import ImportHelper from bpy.types import Operator -from ...core.path_helpers import absolute_path_from_blend_file +from ..path_helpers import absolute_path_from_blend_file class OT_OpenAssetsFolderBrowser(Operator, ImportHelper): """Assets folder's browser""" @@ -46,8 +46,8 @@ class OT_OpenAssetsFolderBrowser(Operator, ImportHelper): asset_path_names = ['blueprints_path', 'levels_path', 'materials_path'] project_root_path = absolute_path_from_blend_file(operator.project_root_path) assets_path = operator.assets_path - export_assets_path_full = absolute_path_from_blend_file(os.path.join(project_root_path, assets_path)) #os.path.join(blend_file_folder_path, project_root_path, assets_path) - #print("export_assets_path_full", export_assets_path_full) + assets_path_full = absolute_path_from_blend_file(os.path.join(project_root_path, assets_path)) #os.path.join(blend_file_folder_path, project_root_path, assets_path) + #print("assets_path_full", assets_path_full) #new_root_path = os.path.join(blend_file_folder_path, new_path) if target_path_name == 'project_root_path': @@ -74,7 +74,7 @@ class OT_OpenAssetsFolderBrowser(Operator, ImportHelper): if relative_path is not None: # and now get absolute path of asset_path # compute 'old' absolute path - old_absolute_path = os.path.abspath(os.path.join(export_assets_path_full, relative_path)) + old_absolute_path = os.path.abspath(os.path.join(assets_path_full, relative_path)) relative_path = os.path.relpath(old_absolute_path, new_assets_path_absolute) setattr(operator, path_name, relative_path) @@ -89,13 +89,13 @@ class OT_OpenAssetsFolderBrowser(Operator, ImportHelper): relative_path = getattr(operator, path_name, None) if relative_path is not None: # compute 'old' absolute path - old_absolute_path = os.path.abspath(os.path.join(export_assets_path_full, relative_path)) + old_absolute_path = os.path.abspath(os.path.join(assets_path_full, relative_path)) relative_path = os.path.relpath(old_absolute_path, new_assets_path_absolute) setattr(operator, path_name, relative_path) setattr(operator, target_path_name, new_assets_path_relative) else: - relative_path = os.path.relpath(new_path, export_assets_path_full) + relative_path = os.path.relpath(new_path, assets_path_full) setattr(operator, target_path_name, relative_path) return {'FINISHED'} \ No newline at end of file diff --git a/tools/blenvy/core/ui/ui.py b/tools/blenvy/core/ui/ui.py index d05bf39..19f5337 100644 --- a/tools/blenvy/core/ui/ui.py +++ b/tools/blenvy/core/ui/ui.py @@ -44,6 +44,11 @@ class BLENVY_PT_SidePanel(bpy.types.Panel): library_scene_active = False active_collection = context.collection + print("BLA", blenvy.assets_path_full) + print("BLA", blenvy.blueprints_path_full) + print("BLA", blenvy.levels_path_full) + print("BLA", blenvy.materials_path_full) + """current_auto_settings = load_settings(".gltf_auto_export_settings") current_gltf_settings = load_settings(".gltf_auto_export_gltf_settings") diff --git a/tools/blenvy/gltf_auto_export/auto_export/auto_export.py b/tools/blenvy/gltf_auto_export/auto_export/auto_export.py index 98d8136..ed06280 100644 --- a/tools/blenvy/gltf_auto_export/auto_export/auto_export.py +++ b/tools/blenvy/gltf_auto_export/auto_export/auto_export.py @@ -27,8 +27,6 @@ def auto_export(changes_per_scene, changed_export_parameters, addon_prefs): file_path = bpy.data.filepath # Get the folder blend_file_path = os.path.dirname(file_path) - - print("settings", dict(addon_prefs)) # get the preferences for our addon project_root_path = getattr(addon_prefs, "project_root_path") assets_path = getattr(addon_prefs,"assets_path") @@ -38,7 +36,6 @@ def auto_export(changes_per_scene, changed_export_parameters, addon_prefs): export_scene_settings = getattr(addon_prefs.auto_export,"export_scene_settings") do_export_blueprints = getattr(addon_prefs.auto_export,"export_blueprints") export_materials_library = getattr(addon_prefs.auto_export,"export_materials_library") - print("export_materials_library", export_materials_library) # standard gltf export settings are stored differently standard_gltf_exporter_settings = get_standard_exporter_settings() @@ -46,10 +43,10 @@ def auto_export(changes_per_scene, changed_export_parameters, addon_prefs): gltf_extension = '.glb' if gltf_extension == 'GLB' else '.gltf' # generate the actual complete output paths - addon_prefs.export_assets_path_full = os.path.join(blend_file_path, project_root_path, assets_path) - addon_prefs.export_blueprints_path_full = os.path.join(addon_prefs.export_assets_path_full, getattr(addon_prefs,"blueprints_path")) - addon_prefs.export_levels_path_full = os.path.join(addon_prefs.export_assets_path_full, getattr(addon_prefs,"levels_path")) - addon_prefs.export_materials_path_full = os.path.join(addon_prefs.export_assets_path_full, getattr(addon_prefs,"materials_path")) + """addon_prefs.assets_path_full = os.path.join(blend_file_path, project_root_path, assets_path) + addon_prefs.blueprints_path_full = os.path.join(addon_prefs.assets_path_full, getattr(addon_prefs,"blueprints_path")) + addon_prefs.levels_path_full = os.path.join(addon_prefs.assets_path_full, getattr(addon_prefs,"levels_path")) + addon_prefs.materials_path_full = os.path.join(addon_prefs.assets_path_full, getattr(addon_prefs,"materials_path"))""" addon_prefs.export_gltf_extension = gltf_extension [main_scene_names, level_scenes, library_scene_names, library_scenes] = get_scenes(addon_prefs) @@ -59,7 +56,6 @@ def auto_export(changes_per_scene, changed_export_parameters, addon_prefs): internal_blueprints = [blueprint.name for blueprint in blueprints_data.internal_blueprints] external_blueprints = [blueprint.name for blueprint in blueprints_data.external_blueprints] - # we inject the blueprints export path blueprints_path = getattr(addon_prefs,"blueprints_path") inject_export_path_into_internal_blueprints(internal_blueprints=blueprints_data.internal_blueprints, blueprints_path=blueprints_path, gltf_extension=gltf_extension) @@ -77,7 +73,7 @@ def auto_export(changes_per_scene, changed_export_parameters, addon_prefs): # export if do_export_blueprints: - print("EXPORTING", blueprints_data) + print("EXPORTING") # get blueprints/collections infos (blueprints_to_export) = get_blueprints_to_export(changes_per_scene, changed_export_parameters, blueprints_data, addon_prefs) diff --git a/tools/blenvy/gltf_auto_export/auto_export/export_blueprints.py b/tools/blenvy/gltf_auto_export/auto_export/export_blueprints.py index 9fc96ca..0f9cfb8 100644 --- a/tools/blenvy/gltf_auto_export/auto_export/export_blueprints.py +++ b/tools/blenvy/gltf_auto_export/auto_export/export_blueprints.py @@ -8,7 +8,7 @@ from ..helpers.helpers_scenes import clear_hollow_scene, copy_hollowed_collectio def export_blueprints(blueprints, addon_prefs, blueprints_data): - export_blueprints_path_full = getattr(addon_prefs, "export_blueprints_path_full") + blueprints_path_full = getattr(addon_prefs, "blueprints_path_full") gltf_export_preferences = generate_gltf_export_preferences(addon_prefs) try: @@ -18,7 +18,7 @@ def export_blueprints(blueprints, addon_prefs, blueprints_data): for blueprint in blueprints: print("exporting collection", blueprint.name) - gltf_output_path = os.path.join(export_blueprints_path_full, blueprint.name) + gltf_output_path = os.path.join(blueprints_path_full, blueprint.name) export_settings = { **gltf_export_preferences, 'use_active_scene': True, 'use_active_collection': True, 'use_active_collection_with_nested':True} # if we are using the material library option, do not export materials, use placeholder instead diff --git a/tools/blenvy/gltf_auto_export/auto_export/export_main_scenes.py b/tools/blenvy/gltf_auto_export/auto_export/export_main_scenes.py index 487bc35..0766470 100644 --- a/tools/blenvy/gltf_auto_export/auto_export/export_main_scenes.py +++ b/tools/blenvy/gltf_auto_export/auto_export/export_main_scenes.py @@ -11,8 +11,8 @@ from ...blueprints.blueprint_helpers import inject_blueprints_list_into_main_sce def export_main_scene(scene, blend_file_path, addon_prefs, blueprints_data): gltf_export_preferences = generate_gltf_export_preferences(addon_prefs) - export_assets_path_full = getattr(addon_prefs,"export_assets_path_full") - export_levels_path_full = getattr(addon_prefs,"export_levels_path_full") + assets_path_full = getattr(addon_prefs,"assets_path_full") + levels_path_full = getattr(addon_prefs,"levels_path_full") export_blueprints = getattr(addon_prefs.auto_export,"export_blueprints") export_separate_dynamic_and_static_objects = getattr(addon_prefs.auto_export, "export_separate_dynamic_and_static_objects") @@ -27,7 +27,7 @@ def export_main_scene(scene, blend_file_path, addon_prefs, blueprints_data): } if export_blueprints : - gltf_output_path = os.path.join(export_levels_path_full, scene.name) + gltf_output_path = os.path.join(levels_path_full, scene.name) #inject_blueprints_list_into_main_scene(scene, blueprints_data, addon_prefs) return @@ -44,7 +44,7 @@ def export_main_scene(scene, blend_file_path, addon_prefs, blueprints_data): ) # then export all dynamic objects - gltf_output_path = os.path.join(export_levels_path_full, scene.name+ "_dynamic") + gltf_output_path = os.path.join(levels_path_full, scene.name+ "_dynamic") generate_and_export( addon_prefs, temp_scene_name=TEMPSCENE_PREFIX, @@ -66,7 +66,7 @@ def export_main_scene(scene, blend_file_path, addon_prefs, blueprints_data): ) else: - gltf_output_path = os.path.join(export_assets_path_full, scene.name) + gltf_output_path = os.path.join(assets_path_full, scene.name) print(" exporting gltf to", gltf_output_path, ".gltf/glb") export_gltf(gltf_output_path, export_settings) diff --git a/tools/blenvy/gltf_auto_export/auto_export/get_blueprints_to_export.py b/tools/blenvy/gltf_auto_export/auto_export/get_blueprints_to_export.py index 7d5dcee..d70653d 100644 --- a/tools/blenvy/gltf_auto_export/auto_export/get_blueprints_to_export.py +++ b/tools/blenvy/gltf_auto_export/auto_export/get_blueprints_to_export.py @@ -6,7 +6,7 @@ from ...blueprints.blueprint_helpers import find_blueprints_not_on_disk # TODO: this should also take the split/embed mode into account: if a nested collection changes AND embed is active, its container collection should also be exported def get_blueprints_to_export(changes_per_scene, changed_export_parameters, blueprints_data, addon_prefs): export_gltf_extension = getattr(addon_prefs, "export_gltf_extension", ".glb") - export_blueprints_path_full = getattr(addon_prefs,"export_blueprints_path_full", "") + blueprints_path_full = getattr(addon_prefs,"blueprints_path_full", "") change_detection = getattr(addon_prefs.auto_export, "change_detection") collection_instances_combine_mode = getattr(addon_prefs.auto_export, "collection_instances_combine_mode") @@ -23,7 +23,7 @@ def get_blueprints_to_export(changes_per_scene, changed_export_parameters, bluep # first check if all collections have already been exported before (if this is the first time the exporter is run # in your current Blender session for example) - blueprints_not_on_disk = find_blueprints_not_on_disk(internal_blueprints, export_blueprints_path_full, export_gltf_extension) + blueprints_not_on_disk = find_blueprints_not_on_disk(internal_blueprints, blueprints_path_full, export_gltf_extension) for scene in library_scenes: if scene.name in changes_per_scene: diff --git a/tools/blenvy/gltf_auto_export/auto_export/get_levels_to_export.py b/tools/blenvy/gltf_auto_export/auto_export/get_levels_to_export.py index f9af6f5..a97e668 100644 --- a/tools/blenvy/gltf_auto_export/auto_export/get_levels_to_export.py +++ b/tools/blenvy/gltf_auto_export/auto_export/get_levels_to_export.py @@ -38,7 +38,7 @@ def changed_object_in_scene(scene_name, changes_per_scene, blueprints_data, coll # this also takes the split/embed mode into account: if a collection instance changes AND embed is active, its container level/world should also be exported def get_levels_to_export(changes_per_scene, changed_export_parameters, blueprints_data, addon_prefs): export_gltf_extension = getattr(addon_prefs, "export_gltf_extension") - export_levels_path_full = getattr(addon_prefs, "export_levels_path_full") + levels_path_full = getattr(addon_prefs, "levels_path_full") change_detection = getattr(addon_prefs.auto_export, "change_detection") collection_instances_combine_mode = getattr(addon_prefs.auto_export, "collection_instances_combine_mode") @@ -47,6 +47,6 @@ def get_levels_to_export(changes_per_scene, changed_export_parameters, blueprint # determine list of main scenes to export # we have more relaxed rules to determine if the main scenes have changed : any change is ok, (allows easier handling of changes, render settings etc) - main_scenes_to_export = [scene_name for scene_name in main_scene_names if not change_detection or changed_export_parameters or scene_name in changes_per_scene.keys() or changed_object_in_scene(scene_name, changes_per_scene, blueprints_data, collection_instances_combine_mode) or not check_if_blueprint_on_disk(scene_name, export_levels_path_full, export_gltf_extension) ] + main_scenes_to_export = [scene_name for scene_name in main_scene_names if not change_detection or changed_export_parameters or scene_name in changes_per_scene.keys() or changed_object_in_scene(scene_name, changes_per_scene, blueprints_data, collection_instances_combine_mode) or not check_if_blueprint_on_disk(scene_name, levels_path_full, export_gltf_extension) ] return (main_scenes_to_export) \ No newline at end of file diff --git a/tools/blenvy/gltf_auto_export/modules/export_materials.py b/tools/blenvy/gltf_auto_export/modules/export_materials.py index de5d5f0..58d3008 100644 --- a/tools/blenvy/gltf_auto_export/modules/export_materials.py +++ b/tools/blenvy/gltf_auto_export/modules/export_materials.py @@ -61,7 +61,7 @@ def clear_materials_scene(temp_scene): # the name of the output path is /_materials_library.gltf/glb def export_materials(collections, library_scenes, addon_prefs): gltf_export_preferences = generate_gltf_export_preferences(addon_prefs) - export_materials_path_full = getattr(addon_prefs,"export_materials_path_full") + materials_path_full = getattr(addon_prefs,"materials_path_full") used_material_names = get_all_materials(collections, library_scenes) current_project_name = Path(bpy.context.blend_data.filepath).stem @@ -75,7 +75,7 @@ def export_materials(collections, library_scenes, addon_prefs): 'export_apply':True } - gltf_output_path = os.path.join(export_materials_path_full, current_project_name + "_materials_library") + gltf_output_path = os.path.join(materials_path_full, current_project_name + "_materials_library") print(" exporting Materials to", gltf_output_path, ".gltf/glb")