diff --git a/tools/blenvy/TODO.md b/tools/blenvy/TODO.md index 5e39d7c..a362344 100644 --- a/tools/blenvy/TODO.md +++ b/tools/blenvy/TODO.md @@ -65,10 +65,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 + - [x] Settings handling: + - [x] move saveable settings out to a settings file + - [x] update save & load + - [x] add handling of polling frequency & enabling General things to solve: @@ -103,7 +103,7 @@ General issues: - [x] fix auto export workflow - [ ] should we write the previous _xxx data only AFTER a sucessfull export only ? - [x] add hashing of modifiers/ geometry nodes in serialize scene -- [ ] add ability to FORCE export specific blueprints & levels +- [x] add ability to FORCE export specific blueprints & levels - [ ] undo after a save removes any saved "serialized scene" data ? DIG into this - [ ] handle scene renames between saves (breaks diffing) - [ ] change scene selector to work on actual scenes aka to deal with renamed scenes diff --git a/tools/blenvy/add_ons/auto_export/blueprints/get_blueprints_to_export.py b/tools/blenvy/add_ons/auto_export/blueprints/get_blueprints_to_export.py index 235295d..1306591 100644 --- a/tools/blenvy/add_ons/auto_export/blueprints/get_blueprints_to_export.py +++ b/tools/blenvy/add_ons/auto_export/blueprints/get_blueprints_to_export.py @@ -2,7 +2,11 @@ from blenvy.core.scene_helpers import get_main_and_library_scenes from blenvy.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 is_blueprint_always_export(blueprint): + return blueprint.collection['always_export'] if 'always_export' in blueprint.collection else False + +# this also takes 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, settings): export_gltf_extension = getattr(settings, "export_gltf_extension", ".glb") blueprints_path_full = getattr(settings,"blueprints_path_full", "") @@ -33,8 +37,10 @@ def get_blueprints_to_export(changes_per_scene, changed_export_parameters, bluep # FIXME: double check this: why are we combining these two ? changed_blueprints += changed_local_blueprints + # also deal with blueprints that are always marked as "always_export" + blueprints_always_export = [blueprint for blueprint in internal_blueprints if is_blueprint_always_export(blueprint)] - blueprints_to_export = list(set(changed_blueprints + blueprints_not_on_disk)) + blueprints_to_export = list(set(changed_blueprints + blueprints_not_on_disk + blueprints_always_export)) # filter out blueprints that are not marked & deal with the different combine modes diff --git a/tools/blenvy/add_ons/auto_export/common/prepare_and_export.py b/tools/blenvy/add_ons/auto_export/common/prepare_and_export.py index 51b6d39..e5c9730 100644 --- a/tools/blenvy/add_ons/auto_export/common/prepare_and_export.py +++ b/tools/blenvy/add_ons/auto_export/common/prepare_and_export.py @@ -15,9 +15,10 @@ def prepare_and_export(): # determine changed objects per_scene_changes = get_changes_per_scene(settings=blenvy) # determine changed parameters - setting_changes = get_setting_changes() + setting_changes = False # get_setting_changes() # do the actual export - # auto_export(per_scene_changes, setting_changes, blenvy) + blenvy.auto_export.dry_run = 'NO_EXPORT'#'DISABLED'# + auto_export(per_scene_changes, setting_changes, blenvy) # cleanup # TODO: these are likely obsolete diff --git a/tools/blenvy/add_ons/auto_export/common/tracker.py b/tools/blenvy/add_ons/auto_export/common/tracker.py index 72772a9..9bb9b77 100644 --- a/tools/blenvy/add_ons/auto_export/common/tracker.py +++ b/tools/blenvy/add_ons/auto_export/common/tracker.py @@ -77,14 +77,14 @@ class AutoExportTracker(PropertyGroup): @classmethod def deps_post_update_handler(cls, scene, depsgraph): # print("change detection enabled", cls.change_detection_enabled) - print("change detected", list(map(lambda x: x.name, list(bpy.data.scenes)))) + #print("change detected", list(map(lambda x: x.name, list(bpy.data.scenes)))) """ops = bpy.context.window_manager.operators print("last operators", ops) for op in ops: print("operator", op)""" - active_operator = bpy.context.active_operator - if active_operator: + active_operator = getattr(bpy.context.active_operator, 'active_operator' , None) + if active_operator is not None: #print("Operator", active_operator.bl_label, active_operator.bl_idname) if active_operator.bl_idname == "EXPORT_SCENE_OT_gltf" and active_operator.gltf_export_id == "gltf_auto_export": # we backup any existing gltf export settings, if there were any diff --git a/tools/blenvy/add_ons/auto_export/levels/get_levels_to_export.py b/tools/blenvy/add_ons/auto_export/levels/get_levels_to_export.py index 9f7a38f..b50d45e 100644 --- a/tools/blenvy/add_ons/auto_export/levels/get_levels_to_export.py +++ b/tools/blenvy/add_ons/auto_export/levels/get_levels_to_export.py @@ -1,3 +1,4 @@ +import bpy from blenvy.core.scene_helpers import get_main_and_library_scenes from blenvy.blueprints.blueprint_helpers import check_if_blueprint_on_disk @@ -33,19 +34,32 @@ def changed_object_in_scene(scene_name, changes_per_scene, blueprints_data, coll return level_needs_export return False +def is_level_always_export(scene_name): + scene = bpy.data.scenes[scene_name] + return scene['always_export'] if 'always_export' in scene else False -# 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, settings): +def should_level_be_exported(scene_name, changed_export_parameters, changes_per_scene, blueprints_data, settings): export_gltf_extension = getattr(settings, "export_gltf_extension") levels_path_full = getattr(settings, "levels_path_full") change_detection = getattr(settings.auto_export, "change_detection") collection_instances_combine_mode = getattr(settings.auto_export, "collection_instances_combine_mode") + # the list of conditions to determine IF a level should be exported or not + return ( + not change_detection + or changed_export_parameters + or is_level_always_export(scene_name) + 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) + ) + +# 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, settings): [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) - 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) ] + main_scenes_to_export = [scene_name for scene_name in main_scene_names if should_level_be_exported(scene_name, changed_export_parameters, changes_per_scene, blueprints_data, settings)] return (main_scenes_to_export) \ No newline at end of file diff --git a/tools/blenvy/assets/asset_helpers.py b/tools/blenvy/assets/asset_helpers.py index 64f5a26..4484eca 100644 --- a/tools/blenvy/assets/asset_helpers.py +++ b/tools/blenvy/assets/asset_helpers.py @@ -5,7 +5,7 @@ def get_user_assets(scene_or_collection): return user_assets def get_generated_assets(scene_or_collection): - generated_assets = [] + generated_assets = getattr(scene_or_collection, 'generated_assets', []) return generated_assets def get_user_assets_as_list(scene_or_collection): diff --git a/tools/blenvy/assets/assets_registry.py b/tools/blenvy/assets/assets_registry.py index 24ab2ab..5a32300 100644 --- a/tools/blenvy/assets/assets_registry.py +++ b/tools/blenvy/assets/assets_registry.py @@ -40,6 +40,10 @@ class AssetsRegistry(PropertyGroup): def register(cls): bpy.types.Scene.user_assets = CollectionProperty(name="user assets", type=Asset) bpy.types.Collection.user_assets = CollectionProperty(name="user assets", type=Asset) + + bpy.types.Scene.generated_assets = CollectionProperty(name="generated assets", type=Asset) + bpy.types.Collection.generated_assets = CollectionProperty(name="generated assets", type=Asset) + bpy.types.WindowManager.assets_registry = PointerProperty(type=AssetsRegistry) @@ -49,6 +53,9 @@ class AssetsRegistry(PropertyGroup): del bpy.types.Scene.user_assets del bpy.types.Collection.user_assets + del bpy.types.Scene.generated_assets + del bpy.types.Collection.generated_assets + def add_asset(self, name, type, path, internal): # internal means it cannot be edited by the user, aka auto generated in_list = [asset for asset in self.assets_list if (asset["path"] == path)] in_list = len(in_list) > 0 diff --git a/tools/blenvy/assets/assets_scan.py b/tools/blenvy/assets/assets_scan.py index 254a9db..c3564b0 100644 --- a/tools/blenvy/assets/assets_scan.py +++ b/tools/blenvy/assets/assets_scan.py @@ -63,7 +63,7 @@ def get_userTextures(): def get_blueprint_assets_tree(blueprint, blueprints_data, parent, settings): blueprints_path = getattr(settings, "blueprints_path") - export_gltf_extension = getattr(settings, "export_gltf_extension") + export_gltf_extension = getattr(settings.auto_export, "export_gltf_extension", ".glb") assets_list = [] @@ -92,7 +92,7 @@ def get_blueprint_assets_tree(blueprint, blueprints_data, parent, settings): 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") + export_gltf_extension = getattr(settings.auto_export, "export_gltf_extension", ".glb") 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) diff --git a/tools/blenvy/assets/ui.py b/tools/blenvy/assets/ui.py index 5991c56..8693d62 100644 --- a/tools/blenvy/assets/ui.py +++ b/tools/blenvy/assets/ui.py @@ -4,8 +4,11 @@ from .assets_scan import get_main_scene_assets_tree from .asset_helpers import get_user_assets, does_asset_exist def draw_assets(layout, name, title, asset_registry, target_type, target_name, editable=True, user_assets= [], generated_assets = []): + number_of_user_assets = len(user_assets) + number_of_generated_assets = len(generated_assets) + header, panel = layout.panel(f"assets{name}", default_closed=False) - header.label(text=title, icon="ASSET_MANAGER") + header.label(text=title + f"({number_of_user_assets + number_of_generated_assets})", icon="ASSET_MANAGER") if panel: if editable: @@ -92,9 +95,8 @@ class Blenvy_assets(bpy.types.Panel): #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() row.prop(scene, "always_export") diff --git a/tools/blenvy/blueprints/blueprints_registry.py b/tools/blenvy/blueprints/blueprints_registry.py index 84f8b06..bee3536 100644 --- a/tools/blenvy/blueprints/blueprints_registry.py +++ b/tools/blenvy/blueprints/blueprints_registry.py @@ -72,6 +72,3 @@ class BlueprintsRegistry(PropertyGroup): blueprints_data = blueprints_scan(level_scenes, library_scenes, settings) self.blueprints_data = blueprints_data return blueprints_data - #print("bla", self.blueprints_data) - """for blueprint in blueprints_data.blueprints: - self.add_blueprint(blueprint)""" diff --git a/tools/blenvy/blueprints/operators.py b/tools/blenvy/blueprints/operators.py index 949272c..fb80a2c 100644 --- a/tools/blenvy/blueprints/operators.py +++ b/tools/blenvy/blueprints/operators.py @@ -2,6 +2,7 @@ import os import bpy from bpy_types import (Operator) from bpy.props import (StringProperty) +from blenvy.core.helpers_collections import set_active_collection class OT_select_blueprint(Operator): """Select blueprint """ @@ -27,7 +28,8 @@ class OT_select_blueprint(Operator): bpy.ops.object.select_all(action='DESELECT') bpy.context.window.scene = scene bpy.context.view_layer.objects.active = None - bpy.context.view_layer.active_layer_collection = bpy.context.view_layer.layer_collection.children[self.blueprint_collection_name] + set_active_collection(scene, self.blueprint_collection_name) + #bpy.context.view_layer.active_layer_collection = bpy.context.view_layer.layer_collection.children[self.blueprint_collection_name] #bpy.context.view_layer.collections.active = collection # bpy.context.view_layer.active_layer_collection = collection """for o in collection.objects: diff --git a/tools/blenvy/levels/ui.py b/tools/blenvy/levels/ui.py index bf54728..19149ba 100644 --- a/tools/blenvy/levels/ui.py +++ b/tools/blenvy/levels/ui.py @@ -1,7 +1,6 @@ from types import SimpleNamespace import bpy -from ..assets.assets_scan import get_main_scene_assets_tree -from ..assets.asset_helpers import get_user_assets +from ..assets.asset_helpers import get_generated_assets, get_user_assets from ..assets.ui import draw_assets class Blenvy_levels(bpy.types.Panel): @@ -37,6 +36,7 @@ class Blenvy_levels(bpy.types.Panel): if panel: user_assets = get_user_assets(scene) + generated_assets = get_generated_assets(scene) row = panel.row() #row.label(text="row") """col = row.column() @@ -54,23 +54,8 @@ class Blenvy_levels(bpy.types.Panel): col = split.column() - scene_assets_panel = draw_assets(layout=col, name=f"{scene.name}_assets", title=f"Assets", asset_registry=asset_registry, user_assets=user_assets, target_type="SCENE", target_name=scene.name) + scene_assets_panel = draw_assets(layout=col, name=f"{scene.name}_assets", title=f"Assets", asset_registry=asset_registry, user_assets=user_assets, generated_assets=generated_assets, target_type="SCENE", target_name=scene.name) settings = {"blueprints_path": "blueprints", "export_gltf_extension": ".glb"} settings = SimpleNamespace(**settings) - - """if panel: - 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() - header.prop(scene, "always_export") - - sub_header, sub_panel = row.box().panel(f"assets{name}", default_closed=False) - - - scene_assets_panel = draw_assets(layout=sub_panel, name=scene.name, title=f"{scene.name} Assets", asset_registry=asset_registry, user_assets=user_assets, target_type="SCENE", target_name=scene.name) - """ \ No newline at end of file