From 26e75742b213bebc874fae0347f3ec5519ea24b0 Mon Sep 17 00:00:00 2001 From: "kaosat.dev" Date: Sat, 25 May 2024 11:57:10 +0200 Subject: [PATCH] feat(Blenvy): * fixed handling of gltf dummy file & settings storage * experimenting with best approach for settings diffing for auto export * started (wip) moving out bevy_components settings from registry to indenpendant settings * minor tweaks --- tools/blenvy/TODO.md | 7 +- tools/blenvy/auto_export/__init__.py | 15 +++-- .../auto_export/export/prepare_and_export.py | 2 +- .../auto_export/export/settings_diff.py | 9 ++- tools/blenvy/auto_export/export/tracker.py | 15 ++++- tools/blenvy/auto_export/settings.py | 6 -- .../bevy_components/registry/registry.py | 1 + tools/blenvy/bevy_components/settings.py | 65 +++++++++++++++++++ tools/blenvy/core/scene_helpers.py | 1 - 9 files changed, 99 insertions(+), 22 deletions(-) create mode 100644 tools/blenvy/bevy_components/settings.py diff --git a/tools/blenvy/TODO.md b/tools/blenvy/TODO.md index f693055..2b4760c 100644 --- a/tools/blenvy/TODO.md +++ b/tools/blenvy/TODO.md @@ -66,6 +66,10 @@ Components: - [ ] handle missing types in registry for keys & values - [ ] Add correct upgrade handling from individual component to bevy_components + - [ ] Settings handling: + - [ ] move saveable settings out to a settings file + - [ ] update save & load + - [ ] add handling of polling frequency & enabling General things to solve: @@ -84,4 +88,5 @@ General issues: - 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 - [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 + - [x] generate_gltf_export_preferences => should not use add-on prefs at all ? since we are not overriding gltf settings that way anymore ? + - [ ] remove hard coded path for standard gltf settings \ No newline at end of file diff --git a/tools/blenvy/auto_export/__init__.py b/tools/blenvy/auto_export/__init__.py index 27875e1..a8672a2 100644 --- a/tools/blenvy/auto_export/__init__.py +++ b/tools/blenvy/auto_export/__init__.py @@ -4,7 +4,7 @@ import bpy from .helpers.generate_complete_preferences_dict import generate_complete_preferences_dict_gltf def cleanup_file(): - gltf_filepath = "/home/ckaos/projects/bevy/Blender_bevy_components_worklflow/testing/bevy_example/assets/____dummy____.glb" + gltf_filepath = bpy.context.window_manager.auto_export_tracker.dummy_file_path if os.path.exists(gltf_filepath): os.remove(gltf_filepath) return None @@ -14,18 +14,19 @@ def cleanup_file(): def gltf_post_export_callback(data): #print("post_export", data) blenvy = bpy.context.window_manager.blenvy - bpy.context.window_manager.auto_export_tracker.export_finished() + tracker = bpy.context.window_manager.auto_export_tracker + tracker.export_finished() - gltf_settings_backup = blenvy.auto_export.gltf_settings_backup + gltf_settings_backup = tracker.gltf_settings_backup gltf_filepath = data["gltf_filepath"] gltf_export_id = data['gltf_export_id'] if gltf_export_id == "gltf_auto_export": # some more absurdity: apparently the file is not QUITE done when the export callback is called, so we have to introduce this timer to remove the temporary file correctly - bpy.context.window_manager.auto_export_tracker.dummy_file_path = gltf_filepath + tracker.dummy_file_path = gltf_filepath try: bpy.app.timers.unregister(cleanup_file) except:pass - bpy.app.timers.register(cleanup_file, first_interval=1) + bpy.app.timers.register(cleanup_file, first_interval=2) # get the parameters scene = bpy.context.scene @@ -43,9 +44,9 @@ def gltf_post_export_callback(data): else: if "glTF2ExportSettings" in scene: del scene["glTF2ExportSettings"] - blenvy.auto_export.gltf_settings_backup = "" + tracker.gltf_settings_backup = "" # the absurd length one has to go through to RESET THE OPERATOR because it has global state !!!!! AAAAAHHH - last_operator = bpy.context.window_manager.auto_export_tracker.last_operator + last_operator = tracker.last_operator last_operator.filepath = "" last_operator.gltf_export_id = "" \ No newline at end of file diff --git a/tools/blenvy/auto_export/export/prepare_and_export.py b/tools/blenvy/auto_export/export/prepare_and_export.py index 62eb87b..c5dfe40 100644 --- a/tools/blenvy/auto_export/export/prepare_and_export.py +++ b/tools/blenvy/auto_export/export/prepare_and_export.py @@ -16,7 +16,7 @@ def prepare_and_export(): # determine changed objects per_scene_changes = get_changes_per_scene() # determine changed parameters - setting_changes = get_setting_changes() + setting_changes = get_setting_changes(auto_export_settings) # do the actual export auto_export(per_scene_changes, setting_changes, blenvy) diff --git a/tools/blenvy/auto_export/export/settings_diff.py b/tools/blenvy/auto_export/export/settings_diff.py index 426294a..f44d033 100644 --- a/tools/blenvy/auto_export/export/settings_diff.py +++ b/tools/blenvy/auto_export/export/settings_diff.py @@ -4,6 +4,7 @@ from ...settings import are_settings_identical, load_settings, upsert_settings # which settings are specific to auto_export # TODO: can we infer this ? auto_export_parameter_names = [ + # blenvy core 'project_root_path', 'assets_path', 'blueprints_path', @@ -12,6 +13,7 @@ auto_export_parameter_names = [ #'main_scene_names', #'library_scene_names', + # auto export 'export_scene_settings', 'export_blueprints', 'export_separate_dynamic_and_static_objects', @@ -20,13 +22,14 @@ auto_export_parameter_names = [ 'export_marked_assets' ] -def get_setting_changes(): +def get_setting_changes(auto_export_settings): + print("get setting changes", dict(auto_export_settings)) previous_gltf_settings = load_settings(".blenvy_gltf_settings_previous") current_gltf_settings = load_settings(".blenvy_gltf_settings") gltf_settings_changed = not are_settings_identical(previous_gltf_settings, current_gltf_settings) previous_export_settings = load_settings(".blenvy_export_settings_previous") - current_export_settings = load_settings(".blenvy_export_settings") + current_export_settings = dict(auto_export_settings) #load_settings(".blenvy_export_settings") export_settings_changed = not are_settings_identical(previous_export_settings, current_export_settings) # if there were no setting before, it is new, we need export @@ -37,7 +40,7 @@ def get_setting_changes(): # write the new settings to the old settings upsert_settings(".blenvy_gltf_settings_previous", current_gltf_settings) - upsert_settings(".blenvy_export_settings_previous", current_gltf_settings) + upsert_settings(".blenvy_export_settings_previous", current_export_settings) return gltf_settings_changed or export_settings_changed diff --git a/tools/blenvy/auto_export/export/tracker.py b/tools/blenvy/auto_export/export/tracker.py index edc5e1a..95388c8 100644 --- a/tools/blenvy/auto_export/export/tracker.py +++ b/tools/blenvy/auto_export/export/tracker.py @@ -14,9 +14,18 @@ class AutoExportTracker(PropertyGroup): change_detection_enabled = True export_params_changed = False - gltf_settings_backup = None last_operator = None - dummy_file_path = "" + + + dummy_file_path: StringProperty()# type: ignore + # special property for gltf settings + gltf_settings_backup: StringProperty( + name="gltf settings backup", + description="backup for existing gltf settings so that we can restore them" + ) # type: ignore + + + exports_total : IntProperty( name='exports_total', @@ -77,7 +86,7 @@ class AutoExportTracker(PropertyGroup): scene = bpy.context.scene if "glTF2ExportSettings" in scene: existing_setting = scene["glTF2ExportSettings"] - bpy.context.window_manager.gltf_settings_backup = json.dumps(dict(existing_setting)) + bpy.context.window_manager.auto_export_tracker.gltf_settings_backup = json.dumps(dict(existing_setting)) # we force saving params active_operator.will_save_settings = True diff --git a/tools/blenvy/auto_export/settings.py b/tools/blenvy/auto_export/settings.py index c19871e..bfb6d4f 100644 --- a/tools/blenvy/auto_export/settings.py +++ b/tools/blenvy/auto_export/settings.py @@ -83,10 +83,4 @@ class AutoExportSettings(PropertyGroup): default="DISABLED" ) # type: ignore - # special property for gltf settings - gltf_settings_backup: StringProperty( - name="gltf settings backup", - description="backup for existing gltf settings so that we can restore them" - ) # type: ignore - diff --git a/tools/blenvy/bevy_components/registry/registry.py b/tools/blenvy/bevy_components/registry/registry.py index 84fe40e..fc1e143 100644 --- a/tools/blenvy/bevy_components/registry/registry.py +++ b/tools/blenvy/bevy_components/registry/registry.py @@ -63,6 +63,7 @@ class ComponentsRegistry(PropertyGroup): description="path to the registry schema file", default="registry.json" )# type: ignore + schemaFullPath : bpy.props.StringProperty( name="schema full path", description="path to the registry schema file", diff --git a/tools/blenvy/bevy_components/settings.py b/tools/blenvy/bevy_components/settings.py new file mode 100644 index 0000000..35394e9 --- /dev/null +++ b/tools/blenvy/bevy_components/settings.py @@ -0,0 +1,65 @@ +import bpy +from bpy_types import (PropertyGroup) +from bpy.props import (EnumProperty, PointerProperty, StringProperty, BoolProperty, CollectionProperty, IntProperty) + + +# helper function to deal with timer +def toggle_watcher(self, context): + #print("toggling watcher", self.watcher_enabled, watch_schema, self, bpy.app.timers) + if not self.watcher_enabled: + try: + bpy.app.timers.unregister(watch_schema) + except Exception as error: + pass + else: + self.watcher_active = True + bpy.app.timers.register(watch_schema) + +def watch_schema(): + self = bpy.context.window_manager.components_registry + # print("watching schema file for changes") + try: + stamp = os.stat(self.schemaFullPath).st_mtime + stamp = str(stamp) + if stamp != self.schemaTimeStamp and self.schemaTimeStamp != "": + print("FILE CHANGED !!", stamp, self.schemaTimeStamp) + # see here for better ways : https://stackoverflow.com/questions/11114492/check-if-a-file-is-not-open-nor-being-used-by-another-process + """try: + os.rename(path, path) + #return False + except OSError: # file is in use + print("in use") + #return True""" + #bpy.ops.object.reload_registry() + # we need to add an additional delay as the file might not have loaded yet + bpy.app.timers.register(lambda: bpy.ops.object.reload_registry(), first_interval=1) + + self.schemaTimeStamp = stamp + except Exception as error: + pass + return self.watcher_poll_frequency if self.watcher_enabled else None + + +class ComponentsSettings(PropertyGroup): + schemaPath: StringProperty( + name="schema path", + description="path to the registry schema file", + default="registry.json" + )# type: ignore + + watcher_enabled: BoolProperty(name="Watcher_enabled", default=True, update=toggle_watcher)# type: ignore + watcher_active: BoolProperty(name = "Flag for watcher status", default = False)# type: ignore + + watcher_poll_frequency: IntProperty( + name="watcher poll frequency", + description="frequency (s) at wich to poll for changes to the registry file", + min=1, + max=10, + default=1 + )# type: ignore + + schemaTimeStamp: StringProperty( + name="last timestamp of schema file", + description="", + default="" + )# type: ignore diff --git a/tools/blenvy/core/scene_helpers.py b/tools/blenvy/core/scene_helpers.py index 5b7e9fa..5ee9aba 100644 --- a/tools/blenvy/core/scene_helpers.py +++ b/tools/blenvy/core/scene_helpers.py @@ -15,7 +15,6 @@ def get_main_and_library_scenes(settings): 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))