From c00c9908eb7a2030de232346cf595257bb12cab4 Mon Sep 17 00:00:00 2001 From: "kaosat.dev" Date: Sat, 25 May 2024 10:46:14 +0200 Subject: [PATCH] feat(Blenvy): a lot of verious tweaks & fixes * fixed/ overhauld asset & blueprint scanning * added polling for blueprints (not 100% sure yet) * add-on-prefs => settings * removed the now obsolete auto-export operator & preperences * a lot of other minor changes --- tools/blenvy/TODO.md | 7 +- tools/blenvy/__init__.py | 3 +- tools/blenvy/assets/assets_scan.py | 28 +-- tools/blenvy/assets/operators.py | 5 +- tools/blenvy/assets/ui.py | 7 +- .../bevy_components/registry/operators.py | 10 +- tools/blenvy/bevy_components/registry/ui.py | 20 +- tools/blenvy/blueprints/blueprint_helpers.py | 12 +- .../blenvy/blueprints/blueprints_registry.py | 29 ++- tools/blenvy/blueprints/blueprints_scan.py | 4 +- tools/blenvy/blueprints/ui.py | 7 +- tools/blenvy/core/blenvy_manager.py | 1 + tools/blenvy/core/operators.py | 2 +- tools/blenvy/core/scene_helpers.py | 18 ++ tools/blenvy/gltf_auto_export/__init__.py | 6 +- .../auto_export/auto_export.py | 47 ++-- .../auto_export/export_blueprints.py | 18 +- .../auto_export/export_gltf.py | 13 +- .../auto_export/export_main_scenes.py | 37 +-- .../auto_export/get_blueprints_to_export.py | 17 +- .../auto_export/get_levels_to_export.py | 14 +- .../gltf_auto_export/auto_export/operators.py | 228 ------------------ .../auto_export/preferences.py | 201 --------------- .../auto_export/prepare_and_export.py | 2 +- .../helpers/generate_and_export.py | 7 +- .../generate_complete_preferences_dict.py | 7 +- .../helpers/helpers_scenes.py | 23 +- .../helpers/to_remove_later.py | 14 +- .../modules/export_materials.py | 12 +- tools/blenvy/gltf_auto_export/settings.py | 4 +- 30 files changed, 199 insertions(+), 604 deletions(-) delete mode 100644 tools/blenvy/gltf_auto_export/auto_export/operators.py delete mode 100644 tools/blenvy/gltf_auto_export/auto_export/preferences.py diff --git a/tools/blenvy/TODO.md b/tools/blenvy/TODO.md index a6856d3..f693055 100644 --- a/tools/blenvy/TODO.md +++ b/tools/blenvy/TODO.md @@ -71,7 +71,7 @@ Components: General things to solve: - [x] save settings - [x] load settings - - [ ] add_blueprints_data + - [ ] add blueprints data - [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 @@ -83,6 +83,5 @@ General issues: - "parents" can only be blueprints - they normally need/have unique export paths (otherwise, user error, perhaps show it ?) - perhaps a simple hashing of the parent's path would be enought - - [ ] addon-prefs => settings - - - [ ] generate_gltf_export_preferences => should not use add-on prefs at all ? since we are not overriding gltf settings that way anymore ? \ No newline at end of file + - [x] addon-prefs => settings + - [x] generate_gltf_export_preferences => should not use add-on prefs at all ? since we are not overriding gltf settings that way anymore ? \ No newline at end of file diff --git a/tools/blenvy/__init__.py b/tools/blenvy/__init__.py index 989404f..4d88849 100644 --- a/tools/blenvy/__init__.py +++ b/tools/blenvy/__init__.py @@ -31,7 +31,6 @@ from .bevy_components.components.ui import (BEVY_COMPONENTS_PT_ComponentsPanel) # auto export from .gltf_auto_export import gltf_post_export_callback -from .gltf_auto_export.auto_export.operators import AutoExportGLTF from .gltf_auto_export.auto_export.tracker import AutoExportTracker from .gltf_auto_export.settings import AutoExportSettings @@ -114,7 +113,6 @@ classes = [ GENERIC_MAP_OT_actions, # gltf auto export - AutoExportGLTF, AutoExportTracker, AutoExportSettings, @@ -146,6 +144,7 @@ def post_save(scene, depsgraph): @persistent def post_load(file_name): + print("POST LOAD") registry = bpy.context.window_manager.components_registry if registry is not None: registry.load_settings() diff --git a/tools/blenvy/assets/assets_scan.py b/tools/blenvy/assets/assets_scan.py index 93e407c..254a9db 100644 --- a/tools/blenvy/assets/assets_scan.py +++ b/tools/blenvy/assets/assets_scan.py @@ -4,12 +4,12 @@ import bpy from .asset_helpers import does_asset_exist, get_user_assets, get_user_assets_as_list -def scan_assets(scene, blueprints_data, addon_prefs): - project_root_path = getattr(addon_prefs, "project_root_path") - export_output_folder = getattr(addon_prefs,"export_output_folder") - levels_path = getattr(addon_prefs,"levels_path") - blueprints_path = getattr(addon_prefs, "blueprints_path") - export_gltf_extension = getattr(addon_prefs, "export_gltf_extension") +def scan_assets(scene, blueprints_data, settings): + project_root_path = getattr(settings, "project_root_path") + export_output_folder = getattr(settings,"export_output_folder") + levels_path = getattr(settings,"levels_path") + blueprints_path = getattr(settings, "blueprints_path") + export_gltf_extension = getattr(settings, "export_gltf_extension") relative_blueprints_path = os.path.relpath(blueprints_path, project_root_path) blueprint_instance_names_for_scene = blueprints_data.blueprint_instances_per_main_scene.get(scene.name, None) @@ -61,9 +61,9 @@ def get_userTextures(): textures.extend([x.image.filepath for x in mat_slot.material.node_tree.nodes if x.type=='TEX_IMAGE']) print("textures", textures) -def get_blueprint_assets_tree(blueprint, blueprints_data, parent, addon_prefs): - blueprints_path = getattr(addon_prefs, "blueprints_path") - export_gltf_extension = getattr(addon_prefs, "export_gltf_extension") +def get_blueprint_assets_tree(blueprint, blueprints_data, parent, settings): + blueprints_path = getattr(settings, "blueprints_path") + export_gltf_extension = getattr(settings, "export_gltf_extension") assets_list = [] @@ -80,7 +80,7 @@ def get_blueprint_assets_tree(blueprint, blueprints_data, parent, addon_prefs): assets_list.append({"name": child_blueprint.name, "path": blueprint_exported_path, "type": "MODEL", "generated": True,"internal":blueprint.local, "parent": blueprint.name}) # and add sub stuff - sub_assets_lists = get_blueprint_assets_tree(child_blueprint, blueprints_data, parent=child_blueprint.name, addon_prefs=addon_prefs) + sub_assets_lists = get_blueprint_assets_tree(child_blueprint, blueprints_data, parent=child_blueprint.name, settings=settings) assets_list += sub_assets_lists direct_assets = get_user_assets_as_list(blueprint.collection) @@ -90,9 +90,9 @@ def get_blueprint_assets_tree(blueprint, blueprints_data, parent, addon_prefs): assets_list += direct_assets return assets_list -def get_main_scene_assets_tree(main_scene, blueprints_data, addon_prefs): - blueprints_path = getattr(addon_prefs, "blueprints_path") - export_gltf_extension = getattr(addon_prefs, "export_gltf_extension") +def get_main_scene_assets_tree(main_scene, blueprints_data, settings): + blueprints_path = getattr(settings, "blueprints_path") + export_gltf_extension = getattr(settings, "export_gltf_extension") blueprint_instance_names_for_scene = blueprints_data.blueprint_instances_per_main_scene.get(main_scene.name, None) assets_list = get_user_assets_as_list(main_scene) @@ -109,7 +109,7 @@ def get_main_scene_assets_tree(main_scene, blueprints_data, addon_prefs): if blueprint_exported_path is not None and not does_asset_exist(assets_list, blueprint_exported_path): assets_list.append({"name": blueprint.name, "path": blueprint_exported_path, "type": "MODEL", "generated": True, "internal":blueprint.local, "parent": None}) - assets_list += get_blueprint_assets_tree(blueprint, blueprints_data, parent=blueprint.name, addon_prefs=addon_prefs) + assets_list += get_blueprint_assets_tree(blueprint, blueprints_data, parent=blueprint.name, settings=settings) print("TOTAL ASSETS", assets_list) return assets_list diff --git a/tools/blenvy/assets/operators.py b/tools/blenvy/assets/operators.py index 4c1f850..8307fe6 100644 --- a/tools/blenvy/assets/operators.py +++ b/tools/blenvy/assets/operators.py @@ -52,7 +52,6 @@ class OT_add_bevy_asset(Operator): ) # type: ignore def execute(self, context): - assets = [] blueprint_assets = self.target_type == 'BLUEPRINT' target = None if blueprint_assets: @@ -61,7 +60,9 @@ class OT_add_bevy_asset(Operator): target = bpy.data.scenes[self.target_name] assets = get_user_assets(target) asset = {"name": self.asset_name, "type": self.asset_type, "path": self.asset_path} + print('assets', assets, target) if not does_asset_exist(target, asset): + print("add asset", target, asset) upsert_asset(target, asset) #assets.append({"name": self.asset_name, "type": self.asset_type, "path": self.asset_path, "internal": False}) @@ -202,7 +203,7 @@ class OT_test_bevy_assets(Operator): blenvy = context.window_manager.blenvy settings = blenvy blueprints_registry = context.window_manager.blueprints_registry - blueprints_registry.add_blueprints_data() + blueprints_registry.refresh_blueprints() blueprints_data = blueprints_registry.blueprints_data for scene in blenvy.main_scenes: diff --git a/tools/blenvy/assets/ui.py b/tools/blenvy/assets/ui.py index 8a474bf..50c748e 100644 --- a/tools/blenvy/assets/ui.py +++ b/tools/blenvy/assets/ui.py @@ -74,7 +74,7 @@ class Blenvy_assets(bpy.types.Panel): asset_registry = context.window_manager.assets_registry blueprints_registry = context.window_manager.blueprints_registry - blueprints_registry.add_blueprints_data() + #blueprints_registry.refresh_blueprints() blueprints_data = blueprints_registry.blueprints_data name = "world" @@ -85,9 +85,12 @@ class Blenvy_assets(bpy.types.Panel): settings = SimpleNamespace(**settings) if panel: - for scene in blenvy.main_scenes: + #print("dfs") + for scene_selector in blenvy.main_scenes: + scene = bpy.data.scenes[scene_selector.name] #get_main_scene_assets_tree(scene, blueprints_data, settings) user_assets = get_user_assets(scene) + #print("user assets", user_assets, scene) row = panel.row() scene_assets_panel = draw_assets(layout=row, name=scene.name, title=f"{scene.name} Assets", asset_registry=asset_registry, user_assets=user_assets, target_type="SCENE", target_name=scene.name) """if scene.name in blueprints_data.blueprint_instances_per_main_scene: diff --git a/tools/blenvy/bevy_components/registry/operators.py b/tools/blenvy/bevy_components/registry/operators.py index 8ada9a5..5b3c483 100644 --- a/tools/blenvy/bevy_components/registry/operators.py +++ b/tools/blenvy/bevy_components/registry/operators.py @@ -206,14 +206,14 @@ class OT_select_object(Operator): bl_label = "Select object" bl_options = {"UNDO"} - object_name: StringProperty( - name="object_name", - description="object to select's name ", + target_name: StringProperty( + name="target name", + description="target to select's name ", ) # type: ignore def execute(self, context): - if self.object_name: - object = bpy.data.objects[self.object_name] + if self.target_name: + object = bpy.data.objects[self.target_name] scenes_of_object = list(object.users_scene) if len(scenes_of_object) > 0: bpy.ops.object.select_all(action='DESELECT') diff --git a/tools/blenvy/bevy_components/registry/ui.py b/tools/blenvy/bevy_components/registry/ui.py index a495fd4..3c73740 100644 --- a/tools/blenvy/bevy_components/registry/ui.py +++ b/tools/blenvy/bevy_components/registry/ui.py @@ -3,6 +3,8 @@ import bpy from bpy_types import (UIList) from bpy.props import (StringProperty) +from ..utils import get_selection_type + from ..components.operators import OT_rename_component, RemoveComponentFromAllItemsOperator, RemoveComponentOperator from .operators import( COMPONENTS_OT_REFRESH_PROPGROUPS_FROM_CUSTOM_PROPERTIES_ALL, @@ -78,7 +80,7 @@ class BEVY_COMPONENTS_PT_AdvancedToolsPanel(bpy.types.Panel): col.label(text=item) - def draw_invalid_or_unregistered(self, layout, status, component_name, object): + def draw_invalid_or_unregistered(self, layout, status, component_name, target): available_components = bpy.context.window_manager.components_list registry = bpy.context.window_manager.components_registry registry_has_type_infos = registry.has_type_infos() @@ -89,8 +91,8 @@ class BEVY_COMPONENTS_PT_AdvancedToolsPanel(bpy.types.Panel): col.label(text=component_name) col = row.column() - operator = col.operator(OT_select_object.bl_idname, text=object.name) - operator.object_name = object.name + operator = col.operator("object.select", text=target.name) + operator.target_name = target.name col = row.column() col.label(text=status) @@ -99,22 +101,24 @@ class BEVY_COMPONENTS_PT_AdvancedToolsPanel(bpy.types.Panel): col.prop(available_components, "list", text="") col = row.column() - operator = col.operator(OT_rename_component.bl_idname, text="", icon="SHADERFX") #rename + operator = col.operator("object.rename_bevy_component", text="", icon="SHADERFX") #rename new_name = registry.type_infos[available_components.list]['long_name'] if available_components.list in registry.type_infos else "" operator.original_name = component_name - operator.target_objects = json.dumps([object.name]) + operator.target_objects = json.dumps([target.name]) operator.new_name = new_name col.enabled = registry_has_type_infos and component_name != "" and component_name != new_name col = row.column() - operator = col.operator(RemoveComponentOperator.bl_idname, text="", icon="X") - operator.object_name = object.name + operator = col.operator("object.remove_bevy_component", text="", icon="X") + operator.item_name = target.name operator.component_name = component_name + operator.item_type = get_selection_type(target) + col = row.column() col = row.column() - operator = col.operator(OT_select_component_name_to_replace.bl_idname, text="", icon="EYEDROPPER") #text="select for rename", + operator = col.operator("object.select_component_name_to_replace", text="", icon="EYEDROPPER") #text="select for rename", operator.component_name = component_name def draw(self, context): diff --git a/tools/blenvy/blueprints/blueprint_helpers.py b/tools/blenvy/blueprints/blueprint_helpers.py index 247ccde..5074640 100644 --- a/tools/blenvy/blueprints/blueprint_helpers.py +++ b/tools/blenvy/blueprints/blueprint_helpers.py @@ -25,12 +25,12 @@ def inject_export_path_into_internal_blueprints(internal_blueprints, blueprints_ blueprint_exported_path = os.path.join(blueprints_path, f"{blueprint.name}{gltf_extension}") blueprint.collection["export_path"] = blueprint_exported_path -def inject_blueprints_list_into_main_scene(scene, blueprints_data, addon_prefs): - project_root_path = getattr(addon_prefs, "project_root_path") - assets_path = getattr(addon_prefs,"assets_path") - levels_path = getattr(addon_prefs,"levels_path") - blueprints_path = getattr(addon_prefs, "blueprints_path") - export_gltf_extension = getattr(addon_prefs, "export_gltf_extension") +def inject_blueprints_list_into_main_scene(scene, blueprints_data, settings): + project_root_path = getattr(settings, "project_root_path") + assets_path = getattr(settings,"assets_path") + levels_path = getattr(settings,"levels_path") + blueprints_path = getattr(settings, "blueprints_path") + export_gltf_extension = getattr(settings, "export_gltf_extension") # print("injecting assets/blueprints data into scene") assets_list_name = f"assets_list_{scene.name}_components" diff --git a/tools/blenvy/blueprints/blueprints_registry.py b/tools/blenvy/blueprints/blueprints_registry.py index ccefa95..83c3ce7 100644 --- a/tools/blenvy/blueprints/blueprints_registry.py +++ b/tools/blenvy/blueprints/blueprints_registry.py @@ -8,9 +8,20 @@ from bpy_types import (PropertyGroup) from bpy.props import (StringProperty, BoolProperty, FloatProperty, FloatVectorProperty, IntProperty, IntVectorProperty, EnumProperty, PointerProperty, CollectionProperty) from ..settings import load_settings -from ..gltf_auto_export.helpers.helpers_scenes import get_scenes +from ..core.scene_helpers import get_main_and_library_scenes from .blueprints_scan import blueprints_scan + + +def refresh_blueprints(): + try: + blueprints_registry = bpy.context.window_manager.blueprints_registry + blueprints_registry.refresh_blueprints() + #print('refresh blueprints') + except:pass + + return 3 + # this is where we store the information for all available Blueprints class BlueprintsRegistry(PropertyGroup): blueprints_data = {} @@ -40,17 +51,25 @@ class BlueprintsRegistry(PropertyGroup): @classmethod def register(cls): bpy.types.WindowManager.blueprints_registry = PointerProperty(type=BlueprintsRegistry) + bpy.app.timers.register(refresh_blueprints) @classmethod def unregister(cls): + try: + bpy.app.timers.unregister(refresh_blueprints) + except: pass + del bpy.types.WindowManager.blueprints_registry + def add_blueprint(self, blueprint): self.blueprints_list.append(blueprint) - def add_blueprints_data(self): + def refresh_blueprints(self): 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) + settings = blenvy + [main_scene_names, level_scenes, library_scene_names, library_scenes] = get_main_and_library_scenes(settings) + blueprints_data = blueprints_scan(level_scenes, library_scenes, settings) self.blueprints_data = blueprints_data + """for blueprint in blueprints_data.blueprints: + self.add_blueprint(blueprint)""" diff --git a/tools/blenvy/blueprints/blueprints_scan.py b/tools/blenvy/blueprints/blueprints_scan.py index 26292a1..07fef8f 100644 --- a/tools/blenvy/blueprints/blueprints_scan.py +++ b/tools/blenvy/blueprints/blueprints_scan.py @@ -7,8 +7,8 @@ from .blueprint import Blueprint # - marked as asset # - with the "auto_export" flag # https://blender.stackexchange.com/questions/167878/how-to-get-all-collections-of-the-current-scene -def blueprints_scan(main_scenes, library_scenes, addon_prefs): - export_marked_assets = getattr(addon_prefs.auto_export,"export_marked_assets") +def blueprints_scan(main_scenes, library_scenes, settings): + export_marked_assets = getattr(settings.auto_export, "export_marked_assets") blueprints = {} blueprints_from_objects = {} diff --git a/tools/blenvy/blueprints/ui.py b/tools/blenvy/blueprints/ui.py index ef967f3..dbf14a2 100644 --- a/tools/blenvy/blueprints/ui.py +++ b/tools/blenvy/blueprints/ui.py @@ -14,15 +14,18 @@ class GLTF_PT_auto_export_blueprints_list(bpy.types.Panel): @classmethod def poll(cls, context): - return context.window_manager.blenvy.mode == 'BLUEPRINTS' + return context.window_manager.blenvy.mode == 'BLUEPRINTS' if 'blenvy' in context.window_manager else False def draw(self, context): layout = self.layout layout.use_property_split = True layout.use_property_decorate = False # No animation. asset_registry = context.window_manager.assets_registry + blueprint_registry = context.window_manager.blueprints_registry - for blueprint in context.window_manager.blueprints_registry.blueprints_list: + blueprint_registry.refresh_blueprints() + + for blueprint in blueprint_registry.blueprints_data.blueprints: row = layout.row() row.label(icon="RIGHTARROW") row.label(text=blueprint.name) diff --git a/tools/blenvy/core/blenvy_manager.py b/tools/blenvy/core/blenvy_manager.py index c8fd7ab..2b60d81 100644 --- a/tools/blenvy/core/blenvy_manager.py +++ b/tools/blenvy/core/blenvy_manager.py @@ -132,6 +132,7 @@ class BlenvyManager(PropertyGroup): del bpy.types.WindowManager.library_scene def load_settings(self): + print("LOAD SETTINGS") settings = load_settings(self.settings_save_path) if settings is not None: if "mode" in settings: diff --git a/tools/blenvy/core/operators.py b/tools/blenvy/core/operators.py index a9815d0..08896a9 100644 --- a/tools/blenvy/core/operators.py +++ b/tools/blenvy/core/operators.py @@ -8,7 +8,7 @@ class OT_switch_bevy_tooling(Operator): """Switch bevy tooling""" bl_idname = "bevy.tooling_switch" bl_label = "Switch bevy tooling" - bl_options = {"UNDO"} + #bl_options = {} tool: EnumProperty( diff --git a/tools/blenvy/core/scene_helpers.py b/tools/blenvy/core/scene_helpers.py index c7b0051..5b7e9fa 100644 --- a/tools/blenvy/core/scene_helpers.py +++ b/tools/blenvy/core/scene_helpers.py @@ -7,6 +7,24 @@ class SceneSelector(bpy.types.PropertyGroup): display: bpy.props.BoolProperty() # type: ignore +# convenience utility to get lists of scenes +def get_main_and_library_scenes(settings): + level_scene_names= getattr(settings, "main_scene_names", []) #list(map(lambda scene: scene.name, getattr(settings,"main_scenes"))) + library_scene_names = getattr(settings, "library_scene_names", []) #list(map(lambda scene: scene.name, getattr(settings,"library_scenes"))) + + level_scene_names= list(map(lambda scene: scene.name, getattr(settings,"main_scenes"))) + library_scene_names = list(map(lambda scene: scene.name, getattr(settings,"library_scenes"))) + + print("level_scene_names", level_scene_names) + level_scene_names = list(filter(lambda name: name in bpy.data.scenes, level_scene_names)) + library_scene_names = list(filter(lambda name: name in bpy.data.scenes, library_scene_names)) + + level_scenes = list(map(lambda name: bpy.data.scenes[name], level_scene_names)) + library_scenes = list(map(lambda name: bpy.data.scenes[name], library_scene_names)) + + return [level_scene_names, level_scenes, library_scene_names, library_scenes] + + def add_scene_property(scene, scene_component_name, property_data, limit_to=None): root_collection = scene.collection scene_property = None diff --git a/tools/blenvy/gltf_auto_export/__init__.py b/tools/blenvy/gltf_auto_export/__init__.py index f3459b7..27875e1 100644 --- a/tools/blenvy/gltf_auto_export/__init__.py +++ b/tools/blenvy/gltf_auto_export/__init__.py @@ -31,12 +31,12 @@ def gltf_post_export_callback(data): scene = bpy.context.scene if "glTF2ExportSettings" in scene: settings = scene["glTF2ExportSettings"] - export_settings = bpy.data.texts[".blenvy_gltf_settings"] if ".blenvy_gltf_settings" in bpy.data.texts else bpy.data.texts.new(".blenvy_gltf_settings") + gltf_export_settings = bpy.data.texts[".blenvy_gltf_settings"] if ".blenvy_gltf_settings" in bpy.data.texts else bpy.data.texts.new(".blenvy_gltf_settings") # now write new settings - export_settings.clear() + gltf_export_settings.clear() current_gltf_settings = generate_complete_preferences_dict_gltf(dict(settings)) - export_settings.write(json.dumps(current_gltf_settings)) + gltf_export_settings.write(json.dumps(current_gltf_settings)) # now reset the original gltf_settings if gltf_settings_backup != "": scene["glTF2ExportSettings"] = json.loads(gltf_settings_backup) 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 ed06280..ad11848 100644 --- a/tools/blenvy/gltf_auto_export/auto_export/auto_export.py +++ b/tools/blenvy/gltf_auto_export/auto_export/auto_export.py @@ -3,7 +3,7 @@ import os import bpy import traceback -from ..helpers.helpers_scenes import (get_scenes, ) +from ...core.scene_helpers import get_main_and_library_scenes from .get_blueprints_to_export import get_blueprints_to_export from .get_levels_to_export import get_levels_to_export @@ -19,7 +19,7 @@ from ...blueprints.blueprint_helpers import inject_export_path_into_internal_blu """this is the main 'central' function for all auto export """ -def auto_export(changes_per_scene, changed_export_parameters, addon_prefs): +def auto_export(changes_per_scene, changed_export_parameters, settings): # have the export parameters (not auto export, just gltf export) have changed: if yes (for example switch from glb to gltf, compression or not, animations or not etc), we need to re-export everything print ("changed_export_parameters", changed_export_parameters) try: @@ -27,41 +27,34 @@ 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) - # get the preferences for our addon - project_root_path = getattr(addon_prefs, "project_root_path") - assets_path = getattr(addon_prefs,"assets_path") #should we use change detection or not - change_detection = getattr(addon_prefs.auto_export, "change_detection") - 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") + change_detection = getattr(settings.auto_export, "change_detection") + export_scene_settings = getattr(settings.auto_export,"export_scene_settings") + do_export_blueprints = getattr(settings.auto_export,"export_blueprints") + export_materials_library = getattr(settings.auto_export,"export_materials_library") # standard gltf export settings are stored differently standard_gltf_exporter_settings = get_standard_exporter_settings() gltf_extension = standard_gltf_exporter_settings.get("export_format", 'GLB') gltf_extension = '.glb' if gltf_extension == 'GLB' else '.gltf' - - # generate the actual complete output paths - """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 + settings.export_gltf_extension = gltf_extension - [main_scene_names, level_scenes, library_scene_names, library_scenes] = get_scenes(addon_prefs) + [main_scene_names, level_scenes, library_scene_names, library_scenes] = get_main_and_library_scenes(settings) - blueprints_data = blueprints_scan(level_scenes, library_scenes, addon_prefs) + bpy.context.window_manager.blueprints_registry.refresh_blueprints() + blueprints_data = bpy.context.window_manager.blueprints_registry.blueprints_data blueprints_per_scene = blueprints_data.blueprints_per_scenes 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") + blueprints_path = getattr(settings,"blueprints_path") inject_export_path_into_internal_blueprints(internal_blueprints=blueprints_data.internal_blueprints, blueprints_path=blueprints_path, gltf_extension=gltf_extension) for blueprint in blueprints_data.blueprints: bpy.context.window_manager.blueprints_registry.add_blueprint(blueprint) - #bpy.context.window_manager.blueprints_registry.add_blueprints_data() + #bpy.context.window_manager.blueprints_registry.refresh_blueprints() + print("YO YO") if export_scene_settings: # inject/ update scene components @@ -75,15 +68,15 @@ def auto_export(changes_per_scene, changed_export_parameters, addon_prefs): if do_export_blueprints: print("EXPORTING") # get blueprints/collections infos - (blueprints_to_export) = get_blueprints_to_export(changes_per_scene, changed_export_parameters, blueprints_data, addon_prefs) + (blueprints_to_export) = get_blueprints_to_export(changes_per_scene, changed_export_parameters, blueprints_data, settings) # get level/main scenes infos - (main_scenes_to_export) = get_levels_to_export(changes_per_scene, changed_export_parameters, blueprints_data, addon_prefs) + (main_scenes_to_export) = get_levels_to_export(changes_per_scene, changed_export_parameters, blueprints_data, settings) # since materials export adds components we need to call this before blueprints are exported # export materials & inject materials components into relevant objects if export_materials_library: - export_materials(blueprints_data.blueprint_names, library_scenes, addon_prefs) + export_materials(blueprints_data.blueprint_names, library_scenes, settings) # update the list of tracked exports exports_total = len(blueprints_to_export) + len(main_scenes_to_export) + (1 if export_materials_library else 0) @@ -115,13 +108,13 @@ def auto_export(changes_per_scene, changed_export_parameters, addon_prefs): print("export MAIN scenes") for scene_name in main_scenes_to_export: print(" exporting scene:", scene_name) - export_main_scene(bpy.data.scenes[scene_name], blend_file_path, addon_prefs, blueprints_data) + export_main_scene(bpy.data.scenes[scene_name], blend_file_path, settings, blueprints_data) # now deal with blueprints/collections do_export_library_scene = not change_detection or changed_export_parameters or len(blueprints_to_export) > 0 if do_export_library_scene: print("export LIBRARY") - export_blueprints(blueprints_to_export, addon_prefs, blueprints_data) + export_blueprints(blueprints_to_export, settings, blueprints_data) # reset current scene from backup bpy.context.window.scene = old_current_scene @@ -134,7 +127,7 @@ def auto_export(changes_per_scene, changed_export_parameters, addon_prefs): else: for scene_name in main_scene_names: - export_main_scene(bpy.data.scenes[scene_name], blend_file_path, addon_prefs, []) + export_main_scene(bpy.data.scenes[scene_name], blend_file_path, settings, []) @@ -148,7 +141,7 @@ def auto_export(changes_per_scene, changed_export_parameters, addon_prefs): finally: # FIXME: error handling ? also redundant - [main_scene_names, main_scenes, library_scene_names, library_scenes] = get_scenes(addon_prefs) + [main_scene_names, main_scenes, library_scene_names, library_scenes] = get_main_and_library_scenes(settings) if export_scene_settings: # inject/ update scene components 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 0f9cfb8..9cd82a5 100644 --- a/tools/blenvy/gltf_auto_export/auto_export/export_blueprints.py +++ b/tools/blenvy/gltf_auto_export/auto_export/export_blueprints.py @@ -7,32 +7,32 @@ from .export_gltf import (generate_gltf_export_preferences) from ..helpers.helpers_scenes import clear_hollow_scene, copy_hollowed_collection_into -def export_blueprints(blueprints, addon_prefs, blueprints_data): - blueprints_path_full = getattr(addon_prefs, "blueprints_path_full") - gltf_export_preferences = generate_gltf_export_preferences(addon_prefs) +def export_blueprints(blueprints, settings, blueprints_data): + blueprints_path_full = getattr(settings, "blueprints_path_full") + gltf_export_preferences = generate_gltf_export_preferences(settings) try: # save current active collection active_collection = bpy.context.view_layer.active_layer_collection - export_materials_library = getattr(addon_prefs.auto_export, "export_materials_library") + export_materials_library = getattr(settings.auto_export, "export_materials_library") for blueprint in blueprints: print("exporting collection", 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} + gltf_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 if export_materials_library: - export_settings['export_materials'] = 'PLACEHOLDER' + gltf_export_settings['export_materials'] = 'PLACEHOLDER' collection = bpy.data.collections[blueprint.name] # do the actual export generate_and_export( - addon_prefs, + settings, temp_scene_name=TEMPSCENE_PREFIX+collection.name, - export_settings=export_settings, + gltf_export_settings=gltf_export_settings, gltf_output_path=gltf_output_path, - tempScene_filler= lambda temp_collection: copy_hollowed_collection_into(collection, temp_collection, blueprints_data=blueprints_data, addon_prefs=addon_prefs), + tempScene_filler= lambda temp_collection: copy_hollowed_collection_into(collection, temp_collection, blueprints_data=blueprints_data, settings=settings), tempScene_cleaner= lambda temp_scene, params: clear_hollow_scene(original_root_collection=collection, temp_scene=temp_scene, **params) ) diff --git a/tools/blenvy/gltf_auto_export/auto_export/export_gltf.py b/tools/blenvy/gltf_auto_export/auto_export/export_gltf.py index 61458e7..78cc519 100644 --- a/tools/blenvy/gltf_auto_export/auto_export/export_gltf.py +++ b/tools/blenvy/gltf_auto_export/auto_export/export_gltf.py @@ -3,9 +3,8 @@ import os import bpy from .get_standard_exporter_settings import get_standard_exporter_settings -from .preferences import (AutoExportGltfPreferenceNames) -def generate_gltf_export_preferences(addon_prefs): +def generate_gltf_export_preferences(settings): # default values gltf_export_preferences = dict( # export_format= 'GLB', #'GLB', 'GLTF_SEPARATE', 'GLTF_EMBEDDED' @@ -43,10 +42,10 @@ def generate_gltf_export_preferences(addon_prefs): #export_optimize_animation_size=False ) - for key in addon_prefs.__annotations__.keys(): + """for key in settings.__annotations__.keys(): if str(key) not in AutoExportGltfPreferenceNames: - #print("overriding setting", key, "value", getattr(addon_prefs,key)) - pass#gltf_export_preferences[key] = getattr(addon_prefs, key) + #print("overriding setting", key, "value", getattr(settings,key)) + pass#gltf_export_preferences[key] = getattr(settings, key)""" standard_gltf_exporter_settings = get_standard_exporter_settings() @@ -70,8 +69,8 @@ def generate_gltf_export_preferences(addon_prefs): #https://docs.blender.org/api/current/bpy.ops.export_scene.html#bpy.ops.export_scene.gltf -def export_gltf (path, export_settings): - settings = {**export_settings, "filepath": path} +def export_gltf (path, gltf_export_settings): + settings = {**gltf_export_settings, "filepath": path} # print("export settings",settings) os.makedirs(os.path.dirname(path), exist_ok=True) bpy.ops.export_scene.gltf(**settings) 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 00e0bcc..114c608 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 @@ -9,15 +9,15 @@ from ..modules.bevy_dynamic import is_object_dynamic, is_object_static from ..helpers.helpers_scenes import clear_hollow_scene, copy_hollowed_collection_into from ...blueprints.blueprint_helpers import inject_blueprints_list_into_main_scene, remove_blueprints_list_from_main_scene -def export_main_scene(scene, blend_file_path, addon_prefs, blueprints_data): - gltf_export_preferences = generate_gltf_export_preferences(addon_prefs) - assets_path_full = getattr(addon_prefs,"assets_path_full") - levels_path_full = getattr(addon_prefs,"levels_path_full") +def export_main_scene(scene, blend_file_path, settings, blueprints_data): + gltf_export_preferences = generate_gltf_export_preferences(settings) + assets_path_full = getattr(settings,"assets_path_full") + levels_path_full = getattr(settings,"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") + export_blueprints = getattr(settings.auto_export,"export_blueprints") + export_separate_dynamic_and_static_objects = getattr(settings.auto_export, "export_separate_dynamic_and_static_objects") - export_settings = { **gltf_export_preferences, + gltf_export_settings = { **gltf_export_preferences, 'use_active_scene': True, 'use_active_collection':True, 'use_active_collection_with_nested':True, @@ -29,45 +29,46 @@ def export_main_scene(scene, blend_file_path, addon_prefs, blueprints_data): if export_blueprints : gltf_output_path = os.path.join(levels_path_full, scene.name) - #inject_blueprints_list_into_main_scene(scene, blueprints_data, addon_prefs) + #inject_blueprints_list_into_main_scene(scene, blueprints_data, settings) if export_separate_dynamic_and_static_objects: #print("SPLIT STATIC AND DYNAMIC") # first export static objects generate_and_export( - addon_prefs, + settings, temp_scene_name=TEMPSCENE_PREFIX, - export_settings=export_settings, + gltf_export_settings=gltf_export_settings, gltf_output_path=gltf_output_path, - tempScene_filler= lambda temp_collection: copy_hollowed_collection_into(scene.collection, temp_collection, blueprints_data=blueprints_data, filter=is_object_static, addon_prefs=addon_prefs), + tempScene_filler= lambda temp_collection: copy_hollowed_collection_into(scene.collection, temp_collection, blueprints_data=blueprints_data, filter=is_object_static, settings=settings), tempScene_cleaner= lambda temp_scene, params: clear_hollow_scene(original_root_collection=scene.collection, temp_scene=temp_scene, **params) ) # then export all dynamic objects gltf_output_path = os.path.join(levels_path_full, scene.name+ "_dynamic") generate_and_export( - addon_prefs, + settings, temp_scene_name=TEMPSCENE_PREFIX, - export_settings=export_settings, + gltf_export_settings=gltf_export_settings, gltf_output_path=gltf_output_path, - tempScene_filler= lambda temp_collection: copy_hollowed_collection_into(scene.collection, temp_collection, blueprints_data=blueprints_data, filter=is_object_dynamic, addon_prefs=addon_prefs), + tempScene_filler= lambda temp_collection: copy_hollowed_collection_into(scene.collection, temp_collection, blueprints_data=blueprints_data, filter=is_object_dynamic, settings=settings), tempScene_cleaner= lambda temp_scene, params: clear_hollow_scene(original_root_collection=scene.collection, temp_scene=temp_scene, **params) ) else: #print("NO SPLIT") generate_and_export( - addon_prefs, + settings, temp_scene_name=TEMPSCENE_PREFIX, - export_settings=export_settings, + gltf_export_settings=gltf_export_settings, gltf_output_path=gltf_output_path, - tempScene_filler= lambda temp_collection: copy_hollowed_collection_into(scene.collection, temp_collection, blueprints_data=blueprints_data, addon_prefs=addon_prefs), + tempScene_filler= lambda temp_collection: copy_hollowed_collection_into(scene.collection, temp_collection, blueprints_data=blueprints_data, settings=settings), tempScene_cleaner= lambda temp_scene, params: clear_hollow_scene(original_root_collection=scene.collection, temp_scene=temp_scene, **params) ) else: 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) + if settings.auto_export.dry_run == "DISABLED": + export_gltf(gltf_output_path, gltf_export_settings) remove_blueprints_list_from_main_scene(scene) 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 d70653d..8427472 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 @@ -1,16 +1,15 @@ -import bpy -import os -from ..helpers.helpers_scenes import (get_scenes, ) + +from ...core.scene_helpers import get_main_and_library_scenes 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") - 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") +def get_blueprints_to_export(changes_per_scene, changed_export_parameters, blueprints_data, settings): + export_gltf_extension = getattr(settings, "export_gltf_extension", ".glb") + blueprints_path_full = getattr(settings,"blueprints_path_full", "") + change_detection = getattr(settings.auto_export, "change_detection") + collection_instances_combine_mode = getattr(settings.auto_export, "collection_instances_combine_mode") - [main_scene_names, level_scenes, library_scene_names, library_scenes] = get_scenes(addon_prefs) + [main_scene_names, level_scenes, library_scene_names, library_scenes] = get_main_and_library_scenes(settings) internal_blueprints = blueprints_data.internal_blueprints blueprints_to_export = internal_blueprints # just for clarity 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 a97e668..05b3c07 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 @@ -1,6 +1,6 @@ import bpy +from ...core.scene_helpers import get_main_and_library_scenes from ...blueprints.blueprint_helpers import check_if_blueprint_on_disk -from ..helpers.helpers_scenes import (get_scenes, ) # IF collection_instances_combine_mode is not 'split' check for each scene if any object in changes_per_scene has an instance in the scene def changed_object_in_scene(scene_name, changes_per_scene, blueprints_data, collection_instances_combine_mode): @@ -36,14 +36,14 @@ 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") - levels_path_full = getattr(addon_prefs, "levels_path_full") +def get_levels_to_export(changes_per_scene, changed_export_parameters, blueprints_data, settings): + export_gltf_extension = getattr(settings, "export_gltf_extension") + levels_path_full = getattr(settings, "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") + change_detection = getattr(settings.auto_export, "change_detection") + collection_instances_combine_mode = getattr(settings.auto_export, "collection_instances_combine_mode") - [main_scene_names, level_scenes, library_scene_names, library_scenes] = get_scenes(addon_prefs) + [main_scene_names, level_scenes, library_scene_names, library_scenes] = get_main_and_library_scenes(settings) # 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) diff --git a/tools/blenvy/gltf_auto_export/auto_export/operators.py b/tools/blenvy/gltf_auto_export/auto_export/operators.py deleted file mode 100644 index 4c7c079..0000000 --- a/tools/blenvy/gltf_auto_export/auto_export/operators.py +++ /dev/null @@ -1,228 +0,0 @@ -import json -import bpy -from bpy.types import Operator -#from ..ui.main import GLTF_PT_auto_export_general, GLTF_PT_auto_export_main, GLTF_PT_auto_export_root - -from .preferences import (AutoExportGltfAddonPreferences, AutoExportGltfPreferenceNames) -from .auto_export import auto_export -from ..helpers.generate_complete_preferences_dict import generate_complete_preferences_dict_auto - -class AutoExportGLTF(Operator, AutoExportGltfAddonPreferences):#, ExportHelper): - """auto export gltf""" - #bl_idname = "object.xxx" - bl_idname = "export_scenes.auto_gltf" - bl_label = "Apply settings" - bl_options = {'PRESET'} # we do not add UNDO otherwise it leads to an invisible operation that resets the state of the saved serialized scene, breaking compares for normal undo/redo operations - # ExportHelper mixin class uses this - #filename_ext = '' - #filepath: bpy.props.StringProperty(subtype="FILE_PATH", default="") # type: ignore - - #list of settings (other than purely gltf settings) whose change should trigger a re-generation of gltf files - white_list = [ - 'auto_export', - 'project_root_path', - 'assets_path', - 'change_detection', - 'export_scene_settings', - - 'main_scene_names', - 'library_scene_names', - - 'export_blueprints', - 'blueprints_path', - 'export_marked_assets', - 'collection_instances_combine_mode', - - 'levels_path', - 'export_separate_dynamic_and_static_objects', - - 'export_materials_library', - 'materials_path', - ] - - @classmethod - def register(cls): - pass - - @classmethod - def unregister(cls): - pass - - def format_settings(self): - # find all props to save - exceptional = [ - # options that don't start with 'export_' - 'collection_instances_combine_mode', - ] - all_props = self.properties - export_props = { - x: getattr(self, x) for x in dir(all_props) - if (x.startswith("export_") or x in exceptional) and all_props.get(x) is not None - } - # we inject all that we need, the above is not sufficient - for (k, v) in self.properties.items(): - if k in self.white_list or k not in AutoExportGltfPreferenceNames: - value = v - # FIXME: really weird having to do this - if k == "collection_instances_combine_mode": - value = self.collection_instances_combine_mode - if k == "export_materials": - value = self.export_materials - export_props[k] = value - # we add main & library scene names to our preferences - - return export_props - - def save_settings(self, context): - print("save settings") - auto_export_settings = self.format_settings() - - stored_settings = bpy.data.texts[".gltf_auto_export_settings"] if ".gltf_auto_export_settings" in bpy.data.texts else bpy.data.texts.new(".gltf_auto_export_settings") - stored_settings.clear() - - auto_export_settings = generate_complete_preferences_dict_auto(auto_export_settings) - stored_settings.write(json.dumps(auto_export_settings)) - print("saved settings", auto_export_settings) - #print("saving settings", bpy.data.texts[".gltf_auto_export_settings"].as_string(), "raw", json.dumps(export_props)) - - def load_settings(self, context): - print("loading settings") - settings = None - try: - settings = bpy.data.texts[".gltf_auto_export_settings"].as_string() - settings = json.loads(settings) - except: pass - - self.will_save_settings = False - if settings: - #print("loading settings in invoke AutoExportGLTF", settings) - try: - for (k, v) in settings.items(): - #print("loading setting", k, v) - setattr(self, k, v) - self.will_save_settings = True - - # Update filter if user saved settings - if hasattr(self, 'export_format'): - self.filter_glob = '*.glb' if self.export_format == 'GLB' else '*.gltf' - - # inject scenes data - if hasattr(self, 'main_scene_names'): - main_scenes = self.main_scenes - main_scenes.clear() - for item_name in self.main_scene_names: - item = main_scenes.add() - item.name = item_name - - if hasattr(self, 'library_scene_names'): - library_scenes = self.library_scenes - library_scenes.clear() - for item_name in self.library_scene_names: - item = library_scenes.add() - item.name = item_name - - except Exception as error: - print("error", error) - self.report({"ERROR"}, "Loading export settings failed. Removed corrupted settings") - bpy.data.texts.remove(bpy.data.texts[".gltf_auto_export_settings"]) - else: - self.will_save_settings = True - - """ - This should ONLY be run when actually doing exports/aka calling auto_export function, because we only care about the difference in settings between EXPORTS - """ - def did_export_settings_change(self): - return True - # compare both the auto export settings & the gltf settings - previous_auto_settings = bpy.data.texts[".gltf_auto_export_settings_previous"] if ".gltf_auto_export_settings_previous" in bpy.data.texts else None - previous_gltf_settings = bpy.data.texts[".blenvy_gltf_settings_previous"] if ".blenvy_gltf_settings_previous" in bpy.data.texts else None - - current_auto_settings = bpy.data.texts[".gltf_auto_export_settings"] if ".gltf_auto_export_settings" in bpy.data.texts else None - current_gltf_settings = bpy.data.texts[".blenvy_gltf_settings"] if ".blenvy_gltf_settings" in bpy.data.texts else None - - #check if params have changed - - # if there were no setting before, it is new, we need export - changed = False - if previous_auto_settings == None: - #print("previous settings missing, exporting") - changed = True - elif previous_gltf_settings == None: - #print("previous gltf settings missing, exporting") - previous_gltf_settings = bpy.data.texts.new(".blenvy_gltf_settings_previous") - previous_gltf_settings.write(json.dumps({})) - if current_gltf_settings == None: - current_gltf_settings = bpy.data.texts.new(".blenvy_gltf_settings") - current_gltf_settings.write(json.dumps({})) - - changed = True - - else: - auto_settings_changed = sorted(json.loads(previous_auto_settings.as_string()).items()) != sorted(json.loads(current_auto_settings.as_string()).items()) if current_auto_settings != None else False - gltf_settings_changed = sorted(json.loads(previous_gltf_settings.as_string()).items()) != sorted(json.loads(current_gltf_settings.as_string()).items()) if current_gltf_settings != None else False - - """print("auto settings previous", sorted(json.loads(previous_auto_settings.as_string()).items())) - print("auto settings current", sorted(json.loads(current_auto_settings.as_string()).items())) - print("auto_settings_changed", auto_settings_changed) - - print("gltf settings previous", sorted(json.loads(previous_gltf_settings.as_string()).items())) - print("gltf settings current", sorted(json.loads(current_gltf_settings.as_string()).items())) - print("gltf_settings_changed", gltf_settings_changed)""" - - changed = auto_settings_changed or gltf_settings_changed - # now write the current settings to the "previous settings" - if current_auto_settings != None: - previous_auto_settings = bpy.data.texts[".gltf_auto_export_settings_previous"] if ".gltf_auto_export_settings_previous" in bpy.data.texts else bpy.data.texts.new(".gltf_auto_export_settings_previous") - previous_auto_settings.clear() - previous_auto_settings.write(current_auto_settings.as_string()) # TODO : check if this is always valid - - if current_gltf_settings != None: - previous_gltf_settings = bpy.data.texts[".blenvy_gltf_settings_previous"] if ".blenvy_gltf_settings_previous" in bpy.data.texts else bpy.data.texts.new(".blenvy_gltf_settings_previous") - previous_gltf_settings.clear() - previous_gltf_settings.write(current_gltf_settings.as_string()) - - return changed - - def did_objects_change(self): - # FIXME: add it back - return {} - - def execute(self, context): - print("execute auto export", context.window_manager.blenvy.auto_export) - blenvy = context.window_manager.blenvy - auto_export_settings = blenvy.auto_export - bpy.context.window_manager.auto_export_tracker.disable_change_detection() - if self.direct_mode: - self.load_settings(context) - if self.will_save_settings: - self.save_settings(context) - #print("self", self.auto_export) - if auto_export_settings.auto_export: # only do the actual exporting if auto export is actually enabled - print("auto export") - #changes_per_scene = context.window_manager.auto_export_tracker.changed_objects_per_scene - #& do the export - # determine changed objects - changes_per_scene = self.did_objects_change() - # determine changed parameters - params_changed = self.did_export_settings_change() - auto_export(changes_per_scene, params_changed, blenvy) - # cleanup - # reset the list of changes in the tracker - bpy.context.window_manager.auto_export_tracker.clear_changes() - print("AUTO EXPORT DONE") - bpy.app.timers.register(bpy.context.window_manager.auto_export_tracker.enable_change_detection, first_interval=0.1) - else: - print("auto export disabled, skipping") - return {'FINISHED'} - - def invoke(self, context, event): - print("invoke") - bpy.context.window_manager.auto_export_tracker.disable_change_detection() - self.load_settings(context) - return context.window_manager.invoke_props_dialog(self, title="Auto export", width=640) - - def cancel(self, context): - print("cancel") - #bpy.context.window_manager.auto_export_tracker.enable_change_detection() - bpy.app.timers.register(bpy.context.window_manager.auto_export_tracker.enable_change_detection, first_interval=1) - diff --git a/tools/blenvy/gltf_auto_export/auto_export/preferences.py b/tools/blenvy/gltf_auto_export/auto_export/preferences.py deleted file mode 100644 index a0eece8..0000000 --- a/tools/blenvy/gltf_auto_export/auto_export/preferences.py +++ /dev/null @@ -1,201 +0,0 @@ - -import os -from bpy.types import AddonPreferences -from bpy.props import (BoolProperty, - IntProperty, - StringProperty, - EnumProperty, - CollectionProperty - ) - -AutoExportGltfPreferenceNames = [ - 'will_save_settings', - 'direct_mode',# specific to main auto_export operator - - 'show_general_settings', - 'auto_export', - 'project_root_path', - 'assets_path', - 'export_scene_settings', - - 'show_change_detection_settings', - 'change_detection', - - 'show_scene_settings', - 'main_scenes', - 'library_scenes', - 'main_scenes_index', - 'library_scenes_index', - 'main_scene_names', - 'library_scene_names', - - 'show_blueprint_settings', - 'export_blueprints', - 'blueprints_path', - 'export_marked_assets', - 'collection_instances_combine_mode', - - 'levels_path', - 'export_separate_dynamic_and_static_objects', - - 'export_materials_library', - 'materials_path', -] - -def on_export_output_folder_updated(self, context): - #self.project_root_path = os.path.relpath(self.project_root_path) - #self.assets_path = os.path.join(self.project_root_path, self.assets_path) - print("on_foo_updated", self.project_root_path, self.assets_path) - -class AutoExportGltfAddonPreferences(AddonPreferences): - # this must match the add-on name, use '__package__' - # when defining this in a submodule of a python package. - bl_idname = __package__ - bl_options = {'PRESET'} - - #### these are for the operator - will_save_settings: BoolProperty( - name='Remember Export Settings', - description='Store glTF export settings in the Blender project', - default=True - ) # type: ignore - - # use when operator is called directly, works a bit differently than inside the ui - direct_mode: BoolProperty( - default=False - ) # type: ignore - - - auto_export: BoolProperty( - name='Auto export', - description='Automatically export to gltf on save', - default=False - ) # type: ignore - - #### general - # for UI only, workaround for lacking panels - show_general_settings: BoolProperty( - name="show_general settings", - description="show/hide general settings (UI only: has no impact on exports)", - default=True - ) # type: ignore - - project_root_path: StringProperty( - name = "Project Root Path", - description="The root folder of your (Bevy) project (not assets!)", - # subtype='DIR_PATH', - default='../' - #update=on_export_output_folder_updated) # type: ignore - ) - - assets_path: StringProperty( - name='Export folder', - description='The root folder for all exports(relative to the root folder/path) Defaults to "assets" ', - default='./assets', - #subtype='DIR_PATH', - options={'HIDDEN'} - # update=on_export_output_folder_updated - ) # type: ignore - - # for UI only, workaround for lacking panels - show_change_detection_settings: BoolProperty( - name="show change detection settings", - description="show/hide change detection settings (UI only: has no impact on exports)", - default=True - ) # type: ignore - - change_detection: BoolProperty( - name='Change detection', - description='Use change detection to determine what/if should be exported', - default=True - ) # type: ignore - - # scenes - # for UI only, workaround for lacking panels - show_scene_settings: BoolProperty( - name="show scene settings", - description="show/hide scene settings (UI only: has no impact on exports)", - default=True - ) # type: ignore - - # scene components - export_scene_settings: BoolProperty( - name='Export scene settings', - description='Export scene settings ie AmbientLighting, Bloom, AO etc', - default=False - ) # type: ignore - - # blueprint settings - # for UI only, workaround for lacking panels - show_blueprint_settings: BoolProperty( - name="show blueprint settings", - description="show/hide blueprint settings (UI only: has no impact on exports)", - default=True - ) # type: ignore - - export_blueprints: BoolProperty( - name='Export Blueprints', - description='Replaces collection instances with an Empty with a BlueprintName custom property, and enabled a lot more features !', - default=True - ) # type: ignore - - blueprints_path: StringProperty( - name='Blueprints path', - description='path to export the blueprints to (relative to the assets folder)', - default='blueprints', - #subtype='DIR_PATH' - ) # type: ignore - - levels_path: StringProperty( - name='Levels path', - description='path to export the levels (main scenes) to (relative to the assets folder)', - default='levels', - #subtype='DIR_PATH' - ) # type: ignore - - export_separate_dynamic_and_static_objects: BoolProperty( - name="Export levels' dynamic and static objects seperatly", - description="""For MAIN scenes only (aka levels), toggle this to generate 2 files per level: - - one with all dynamic data: collection or instances marked as dynamic/ saveable - - one with all static data: anything else that is NOT marked as dynamic""", - default=False - ) # type: ignore - - export_materials_library: BoolProperty( - name='Export materials library', - description='remove materials from blueprints and use the material library instead', - default=False - ) # type: ignore - - materials_path: StringProperty( - name='Materials path', - description='path to export the materials libraries to (relative to the assets folder)', - default='materials', - #subtype='DIR_PATH' - ) # type: ignore - - """ combine mode can be - - 'Split' (default): replace with an empty, creating links to sub blueprints - - 'Embed' : treat it as an embeded object and do not replace it with an empty - - 'EmbedExternal': embed any instance of a non local collection (ie external assets) - - - 'Inject': inject components from sub collection instances into the curent object => this is now a seperate custom property that you can apply to a collecion instance - """ - - collection_instances_combine_mode : EnumProperty( - name='Collection instances', - items=( - ('Split', 'Split', 'replace collection instances with an empty + blueprint, creating links to sub blueprints (Default, Recomended)'), - ('Embed', 'Embed', 'treat collection instances as embeded objects and do not replace them with an empty'), - ('EmbedExternal', 'EmbedExternal', 'treat instances of external (not specifified in the current blend file) collections (aka assets etc) as embeded objects and do not replace them with empties'), - #('Inject', 'Inject', 'inject components from sub collection instances into the curent object') - ), - default='Split' - ) # type: ignore - - export_marked_assets: BoolProperty( - name='Auto export marked assets', - description='Collections that have been marked as assets will be systematically exported, even if not in use in another scene', - default=True - ) # type: ignore - diff --git a/tools/blenvy/gltf_auto_export/auto_export/prepare_and_export.py b/tools/blenvy/gltf_auto_export/auto_export/prepare_and_export.py index 1febee3..62eb87b 100644 --- a/tools/blenvy/gltf_auto_export/auto_export/prepare_and_export.py +++ b/tools/blenvy/gltf_auto_export/auto_export/prepare_and_export.py @@ -8,8 +8,8 @@ from .settings_diff import get_setting_changes # prepare export by gather the changes to the scenes & settings def prepare_and_export(): print("prepare and export") - blenvy = bpy.context.window_manager.blenvy bpy.context.window_manager.auto_export_tracker.disable_change_detection() + blenvy = bpy.context.window_manager.blenvy auto_export_settings = blenvy.auto_export if auto_export_settings.auto_export: # only do the actual exporting if auto export is actually enabled diff --git a/tools/blenvy/gltf_auto_export/helpers/generate_and_export.py b/tools/blenvy/gltf_auto_export/helpers/generate_and_export.py index 9e0c6e4..00f5221 100644 --- a/tools/blenvy/gltf_auto_export/helpers/generate_and_export.py +++ b/tools/blenvy/gltf_auto_export/helpers/generate_and_export.py @@ -6,11 +6,11 @@ from ...core.helpers_collections import (set_active_collection) generates a temporary scene, fills it with data, cleans up after itself * named using temp_scene_name * filled using the tempScene_filler - * written on disk to gltf_output_path, with the gltf export parameters in export_settings + * written on disk to gltf_output_path, with the gltf export parameters in gltf_export_settings * cleaned up using tempScene_cleaner """ -def generate_and_export(addon_prefs, export_settings, gltf_output_path, temp_scene_name="__temp_scene", tempScene_filler=None, tempScene_cleaner=None): +def generate_and_export(settings, gltf_export_settings, gltf_output_path, temp_scene_name="__temp_scene", tempScene_filler=None, tempScene_cleaner=None): temp_scene = bpy.data.scenes.new(name=temp_scene_name) temp_root_collection = temp_scene.collection @@ -41,7 +41,8 @@ def generate_and_export(addon_prefs, export_settings, gltf_output_path, temp_sce scene_filler_data = tempScene_filler(temp_root_collection) # export the temporary scene try: - export_gltf(gltf_output_path, export_settings) + if settings.auto_export.dry_run == "DISABLED": + export_gltf(gltf_output_path, gltf_export_settings) except Exception as error: print("failed to export gltf !", error) raise error diff --git a/tools/blenvy/gltf_auto_export/helpers/generate_complete_preferences_dict.py b/tools/blenvy/gltf_auto_export/helpers/generate_complete_preferences_dict.py index f6ef742..5a9b020 100644 --- a/tools/blenvy/gltf_auto_export/helpers/generate_complete_preferences_dict.py +++ b/tools/blenvy/gltf_auto_export/helpers/generate_complete_preferences_dict.py @@ -1,5 +1,4 @@ -from ..auto_export.preferences import AutoExportGltfAddonPreferences from io_scene_gltf2 import (ExportGLTF2_Base) # given the input (actual) gltf settings, filters out any invalid/useless params & params that are equal to defaults @@ -28,12 +27,12 @@ def generate_complete_preferences_dict_gltf(settings): return complete_preferences # given the input (actual) auto settings, filters out any invalid/useless params & params that are equal to defaults -def generate_complete_preferences_dict_auto(settings): +def generate_complete_preferences_dict_auto(settings, presets): complete_preferences = {} defaults = {} - for k in AutoExportGltfAddonPreferences.__annotations__: - item = AutoExportGltfAddonPreferences.__annotations__[k] + for k in presets.__annotations__: + item = presets.__annotations__[k] default = item.keywords.get('default', None) #complete_preferences[k] = default defaults[k] = default diff --git a/tools/blenvy/gltf_auto_export/helpers/helpers_scenes.py b/tools/blenvy/gltf_auto_export/helpers/helpers_scenes.py index 40e3667..86923e9 100644 --- a/tools/blenvy/gltf_auto_export/helpers/helpers_scenes.py +++ b/tools/blenvy/gltf_auto_export/helpers/helpers_scenes.py @@ -145,8 +145,8 @@ def duplicate_object(object, parent, combine_mode, destination_collection, bluep duplicate_object(child, copy, combine_mode, destination_collection, blueprints_data, nester+" ") # copies the contents of a collection into another one while replacing library instances with empties -def copy_hollowed_collection_into(source_collection, destination_collection, parent_empty=None, filter=None, blueprints_data=None, addon_prefs={}): - collection_instances_combine_mode = getattr(addon_prefs.auto_export, "collection_instances_combine_mode") +def copy_hollowed_collection_into(source_collection, destination_collection, parent_empty=None, filter=None, blueprints_data=None, settings={}): + collection_instances_combine_mode = getattr(settings.auto_export, "collection_instances_combine_mode") for object in source_collection.objects: if object.name.endswith("____bak"): # some objects could already have been handled, ignore them @@ -172,7 +172,7 @@ def copy_hollowed_collection_into(source_collection, destination_collection, par parent_empty = collection_placeholder, filter = filter, blueprints_data = blueprints_data, - addon_prefs=addon_prefs + settings=settings ) return {} @@ -204,20 +204,3 @@ def clear_hollow_scene(temp_scene, original_root_collection): # reset original names restore_original_names(original_root_collection) - -# convenience utility to get lists of scenes -def get_scenes(addon_prefs): - level_scene_names= getattr(addon_prefs, "main_scene_names", []) #list(map(lambda scene: scene.name, getattr(addon_prefs,"main_scenes"))) - library_scene_names = getattr(addon_prefs, "library_scene_names", []) #list(map(lambda scene: scene.name, getattr(addon_prefs,"library_scenes"))) - - level_scene_names= list(map(lambda scene: scene.name, getattr(addon_prefs,"main_scenes"))) - library_scene_names = list(map(lambda scene: scene.name, getattr(addon_prefs,"library_scenes"))) - - print("level_scene_names", level_scene_names) - level_scene_names = list(filter(lambda name: name in bpy.data.scenes, level_scene_names)) - library_scene_names = list(filter(lambda name: name in bpy.data.scenes, library_scene_names)) - - level_scenes = list(map(lambda name: bpy.data.scenes[name], level_scene_names)) - library_scenes = list(map(lambda name: bpy.data.scenes[name], library_scene_names)) - - return [level_scene_names, level_scenes, library_scene_names, library_scenes] diff --git a/tools/blenvy/gltf_auto_export/helpers/to_remove_later.py b/tools/blenvy/gltf_auto_export/helpers/to_remove_later.py index 8a5198b..b106ae8 100644 --- a/tools/blenvy/gltf_auto_export/helpers/to_remove_later.py +++ b/tools/blenvy/gltf_auto_export/helpers/to_remove_later.py @@ -155,7 +155,7 @@ class glTF2ExportUserExtension: self.Extension = Extension self.properties = bpy.context.scene.ExampleExtensionProperties - def gather_node_hook(self, gltf2_object, blender_object, export_settings): + def gather_node_hook(self, gltf2_object, blender_object, gltf_export_settings): if self.properties.enabled: if gltf2_object.extensions is None: gltf2_object.extensions = {} @@ -193,7 +193,7 @@ def did_export_parameters_change(current_params, previous_params): bpy.context.window.scene = library_scene with bpy.context.temp_override(scene=library_scene): print("active scene", bpy.context.scene) - export_gltf(gltf_output_path, export_settings) + export_gltf(gltf_output_path, gltf_export_settings) bpy.context.window.scene = original_scene""" """ @@ -296,16 +296,16 @@ def duplicate_object2(object, original_name): settings = scene["glTF2ExportSettings"] formatted_settings = dict(settings) - export_settings = bpy.data.texts[".blenvy_gltf_settings"] if ".blenvy_gltf_settings" in bpy.data.texts else bpy.data.texts.new(".blenvy_gltf_settings") + gltf_export_settings = bpy.data.texts[".blenvy_gltf_settings"] if ".blenvy_gltf_settings" in bpy.data.texts else bpy.data.texts.new(".blenvy_gltf_settings") #check if params have changed - bpy.context.window_manager.gltf_settings_changed = sorted(json.loads(export_settings.as_string()).items()) != sorted(formatted_settings.items()) + bpy.context.window_manager.gltf_settings_changed = sorted(json.loads(gltf_export_settings.as_string()).items()) != sorted(formatted_settings.items()) - print("gltf NEW settings", formatted_settings, "OLD settings", export_settings, "CHANGED ?", bpy.context.window_manager.gltf_settings_changed) + print("gltf NEW settings", formatted_settings, "OLD settings", gltf_export_settings, "CHANGED ?", bpy.context.window_manager.gltf_settings_changed) # now write new settings - export_settings.clear() - export_settings.write(json.dumps(formatted_settings)) + gltf_export_settings.clear() + gltf_export_settings.write(json.dumps(formatted_settings)) # now reset the original gltf_settings diff --git a/tools/blenvy/gltf_auto_export/modules/export_materials.py b/tools/blenvy/gltf_auto_export/modules/export_materials.py index 58d3008..055bd0d 100644 --- a/tools/blenvy/gltf_auto_export/modules/export_materials.py +++ b/tools/blenvy/gltf_auto_export/modules/export_materials.py @@ -59,14 +59,14 @@ def clear_materials_scene(temp_scene): # exports the materials used inside the current project: # 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) - materials_path_full = getattr(addon_prefs,"materials_path_full") +def export_materials(collections, library_scenes, settings): + gltf_export_preferences = generate_gltf_export_preferences(settings) + materials_path_full = getattr(settings,"materials_path_full") used_material_names = get_all_materials(collections, library_scenes) current_project_name = Path(bpy.context.blend_data.filepath).stem - export_settings = { **gltf_export_preferences, + gltf_export_settings = { **gltf_export_preferences, 'use_active_scene': True, 'use_active_collection':True, 'use_active_collection_with_nested':True, @@ -80,9 +80,9 @@ def export_materials(collections, library_scenes, addon_prefs): print(" exporting Materials to", gltf_output_path, ".gltf/glb") generate_and_export( - addon_prefs, + settings=settings, + gltf_export_settings=gltf_export_settings, temp_scene_name="__materials_scene", - export_settings=export_settings, gltf_output_path=gltf_output_path, tempScene_filler= lambda temp_collection: generate_materials_scene_content(temp_collection, used_material_names), tempScene_cleaner= lambda temp_scene, params: clear_materials_scene(temp_scene=temp_scene) diff --git a/tools/blenvy/gltf_auto_export/settings.py b/tools/blenvy/gltf_auto_export/settings.py index b5c1fb8..c19871e 100644 --- a/tools/blenvy/gltf_auto_export/settings.py +++ b/tools/blenvy/gltf_auto_export/settings.py @@ -76,9 +76,11 @@ class AutoExportSettings(PropertyGroup): name="dry run", description="debug/ develop helper to enable everything but the actual exporting of files", items=( + ("DISABLED", "Disabled","Run exports normally (no Dry run)"), ("NO_EXPORT", "No export", "do not actually export gltf files"), ("NO_PREPARE", "No prepare", "do not actually export gltf files AND do not prepare the exports either (ie no creating fake scenes etc)"), - ) + ), + default="DISABLED" ) # type: ignore # special property for gltf settings