mirror of
https://github.com/kaosat-dev/Blender_bevy_components_workflow.git
synced 2024-12-23 08:04:10 +00:00
feat(auto_export): exploration, changes, debug etc for change detection weirdness
This commit is contained in:
parent
11e8786b59
commit
64fd308fd3
@ -116,7 +116,6 @@ classes = [
|
||||
GLTF_PT_auto_export_SidePanel,
|
||||
|
||||
AutoExportTracker,
|
||||
|
||||
]
|
||||
|
||||
def glTF2_pre_export_callback(data):
|
||||
@ -191,10 +190,6 @@ def register():
|
||||
bpy.types.TOPBAR_MT_file_export.append(menu_func_import)
|
||||
bpy.types.WindowManager.gltf_settings_backup = StringProperty(default="")
|
||||
|
||||
# FIXME: perhaps move this to tracker
|
||||
bpy.types.WindowManager.exports_count = IntProperty(default=0)
|
||||
|
||||
|
||||
"""bpy.utils.register_class(AutoExportExtensionProperties)
|
||||
bpy.types.Scene.AutoExportExtensionProperties = bpy.props.PointerProperty(type=AutoExportExtensionProperties)"""
|
||||
|
||||
@ -207,7 +202,6 @@ def unregister():
|
||||
bpy.app.handlers.save_post.remove(post_save)
|
||||
|
||||
"""bpy.utils.unregister_class(AutoExportExtensionProperties)"""
|
||||
del bpy.types.WindowManager.exports_count
|
||||
|
||||
if "gltf_auto_export" == "__main__":
|
||||
register()
|
||||
|
@ -109,20 +109,23 @@ def auto_export(changes_per_scene, changed_export_parameters, addon_prefs):
|
||||
|
||||
main_scenes_to_export = [scene_name for scene_name in main_scene_names if not export_change_detection or changed_export_parameters or scene_name in changes_per_scene.keys() or not check_if_blueprint_on_disk(scene_name, export_levels_path, gltf_extension)]
|
||||
|
||||
bpy.context.window_manager.exports_count = len(collections_to_export)
|
||||
bpy.context.window_manager.exports_count += len(main_scenes_to_export)
|
||||
bpy.context.window_manager.auto_export_tracker.exports_count = len(collections_to_export)
|
||||
bpy.context.window_manager.auto_export_tracker.exports_count += len(main_scenes_to_export)
|
||||
if export_materials_library:
|
||||
bpy.context.window_manager.exports_count += 1
|
||||
bpy.context.window_manager.auto_export_tracker.exports_count += 1
|
||||
|
||||
print("--------------")
|
||||
print("-------------------------------")
|
||||
print("collections: all:", collections)
|
||||
print("collections: changed:", changed_collections)
|
||||
print("collections: not found on disk:", collections_not_on_disk)
|
||||
print("collections: in library:", library_collections)
|
||||
print("collections: to export:", collections_to_export)
|
||||
print("collections: per_scene:", collections_per_scene)
|
||||
print("--------------")
|
||||
print("MAIN SCENES TO EXPORT", main_scenes_to_export)
|
||||
print("-------------------------------")
|
||||
print("BLUEPRINTS: to export:", collections_to_export)
|
||||
print("-------------------------------")
|
||||
print("MAIN SCENES: to export:", main_scenes_to_export)
|
||||
print("-------------------------------")
|
||||
|
||||
|
||||
# backup current active scene
|
||||
@ -131,19 +134,20 @@ def auto_export(changes_per_scene, changed_export_parameters, addon_prefs):
|
||||
old_selections = bpy.context.selected_objects
|
||||
|
||||
# first export any main/level/world scenes
|
||||
print("export MAIN scenes")
|
||||
for scene_name in main_scene_names:
|
||||
# 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)
|
||||
do_export_main_scene = not export_change_detection or changed_export_parameters or scene_name in changes_per_scene.keys() or not check_if_blueprint_on_disk(scene_name, export_levels_path, gltf_extension)
|
||||
if do_export_main_scene:
|
||||
print(" exporting scene:", scene_name)
|
||||
export_main_scene(bpy.data.scenes[scene_name], folder_path, addon_prefs, library_collections)
|
||||
if len(main_scenes_to_export) > 0:
|
||||
print("export MAIN scenes")
|
||||
for scene_name in main_scene_names:
|
||||
# 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)
|
||||
do_export_main_scene = not export_change_detection or changed_export_parameters or scene_name in changes_per_scene.keys() or not check_if_blueprint_on_disk(scene_name, export_levels_path, gltf_extension)
|
||||
if do_export_main_scene:
|
||||
print(" exporting scene:", scene_name)
|
||||
export_main_scene(bpy.data.scenes[scene_name], folder_path, addon_prefs, library_collections)
|
||||
|
||||
|
||||
# now deal with blueprints/collections
|
||||
do_export_library_scene = not export_change_detection or changed_export_parameters or len(collections_to_export) > 0 # export_library_scene_name in changes_per_scene.keys()
|
||||
print("export LIBRARY")
|
||||
if do_export_library_scene:
|
||||
print("export LIBRARY")
|
||||
# we only want to go through the library scenes where our collections to export are present
|
||||
for (scene_name, collections_to_export) in collections_per_scene.items():
|
||||
print(" exporting collections from scene:", scene_name)
|
||||
@ -164,6 +168,8 @@ def auto_export(changes_per_scene, changed_export_parameters, addon_prefs):
|
||||
for scene_name in main_scene_names:
|
||||
export_main_scene(bpy.data.scenes[scene_name], folder_path, addon_prefs, [])
|
||||
|
||||
print("we are done with all export work",bpy.context.window_manager.auto_export_tracker.change_detection_enabled)
|
||||
|
||||
except Exception as error:
|
||||
print(traceback.format_exc())
|
||||
|
||||
|
@ -168,13 +168,13 @@ class AutoExportGLTF(Operator, AutoExportGltfAddonPreferences, ExportHelper):
|
||||
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 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)
|
||||
print("gltf_settings_changed", gltf_settings_changed)"""
|
||||
|
||||
changed = auto_settings_changed or gltf_settings_changed
|
||||
# now write the current settings to the "previous settings"
|
||||
@ -191,6 +191,7 @@ class AutoExportGLTF(Operator, AutoExportGltfAddonPreferences, ExportHelper):
|
||||
return changed
|
||||
|
||||
def execute(self, context):
|
||||
print("execute")
|
||||
# disable change detection while the operator runs
|
||||
bpy.context.window_manager.auto_export_tracker.disable_change_detection()
|
||||
if self.direct_mode:
|
||||
@ -206,12 +207,14 @@ class AutoExportGLTF(Operator, AutoExportGltfAddonPreferences, ExportHelper):
|
||||
params_changed = self.did_export_settings_change()
|
||||
auto_export(changes_per_scene, params_changed, self)
|
||||
# cleanup
|
||||
if bpy.context.window_manager.exports_count == 0: # we need this in case there was nothing to export, to make sure change detection is enabled again
|
||||
print("YOLOOO")
|
||||
bpy.context.window_manager.auto_export_tracker.enable_change_detection()
|
||||
print("AUTO EXPORT DONE")
|
||||
if bpy.context.window_manager.auto_export_tracker.exports_count == 0: # we need this in case there was nothing to export, to make sure change detection is enabled again
|
||||
pass #print("YOLOOO")
|
||||
#py.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)
|
||||
#bpy.context.window_manager.auto_export_tracker.enable_change_detection()
|
||||
# FIXME: wrong logic, this should be called only in an glTF2_post_export_callback
|
||||
bpy.app.timers.register(bpy.context.window_manager.auto_export_tracker.enable_change_detection, first_interval=1)
|
||||
#bpy.app.timers.register(bpy.context.window_manager.auto_export_tracker.enable_change_detection, first_interval=1)
|
||||
else:
|
||||
print("auto export disabled, skipping")
|
||||
return {'FINISHED'}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import json
|
||||
import bpy
|
||||
from bpy.types import (PropertyGroup)
|
||||
from bpy.props import (PointerProperty)
|
||||
from bpy.props import (PointerProperty, IntProperty)
|
||||
|
||||
from .internals import CollectionsToExport
|
||||
|
||||
@ -15,6 +15,12 @@ class AutoExportTracker(PropertyGroup):
|
||||
last_operator = None
|
||||
dummy_file_path = ""
|
||||
|
||||
exports_count : IntProperty(
|
||||
name='exports_count',
|
||||
description='Number of exports in progress',
|
||||
default=0
|
||||
) # type: ignore
|
||||
|
||||
@classmethod
|
||||
def register(cls):
|
||||
bpy.types.WindowManager.auto_export_tracker = PointerProperty(type=AutoExportTracker)
|
||||
@ -53,7 +59,7 @@ class AutoExportTracker(PropertyGroup):
|
||||
|
||||
@classmethod
|
||||
def deps_update_handler(cls, scene, depsgraph):
|
||||
print("change detection enabled", cls.change_detection_enabled)
|
||||
print("change detection enabled", cls.change_detection_enabled, bpy.context.window_manager.auto_export_tracker.change_detection_enabled)
|
||||
active_operator = bpy.context.active_operator
|
||||
if active_operator:
|
||||
# print("Operator", active_operator.bl_label, active_operator.bl_idname)
|
||||
@ -74,8 +80,8 @@ class AutoExportTracker(PropertyGroup):
|
||||
active_operator.will_save_settings = True
|
||||
active_operator.auto_export = True
|
||||
|
||||
if scene.name != "temp_scene":
|
||||
# print("depsgraph_update_post", scene.name)
|
||||
if not scene.name.startswith("__temp_scene"):
|
||||
print("depsgraph_update_post", scene.name)
|
||||
changed_scene = scene.name or ""
|
||||
|
||||
# only deal with changes if we are no in the mids of saving/exporting
|
||||
@ -90,7 +96,8 @@ class AutoExportTracker(PropertyGroup):
|
||||
if isinstance(obj.id, bpy.types.Object):
|
||||
# get the actual object
|
||||
object = bpy.data.objects[obj.id.name]
|
||||
#print("changed object", obj.id.name)
|
||||
print("changed object", obj.id.name)
|
||||
print("FOO","transforms", obj.is_updated_transform, "geometry", obj.is_updated_geometry)
|
||||
cls.changed_objects_per_scene[scene.name][obj.id.name] = object
|
||||
elif isinstance(obj.id, bpy.types.Material): # or isinstance(obj.id, bpy.types.ShaderNodeTree):
|
||||
# print("changed material", obj.id, "scene", scene.name,)
|
||||
@ -114,19 +121,27 @@ class AutoExportTracker(PropertyGroup):
|
||||
for update in depsgraph.updates:
|
||||
print("update", update)"""
|
||||
|
||||
def disable_change_detection(self,):
|
||||
def disable_change_detection(self):
|
||||
print("disable change detection")
|
||||
self.change_detection_enabled = False
|
||||
self.__class__.change_detection_enabled = False
|
||||
|
||||
return None
|
||||
|
||||
def enable_change_detection(self):
|
||||
print("enable change detection")
|
||||
self.change_detection_enabled = True
|
||||
self.__class__.change_detection_enabled = True
|
||||
# bpy.context.window_manager.auto_export_tracker.change_detection_enabled = True
|
||||
print("bpy.context.window_manager.auto_export_tracker.change_detection_enabled", bpy.context.window_manager.auto_export_tracker.change_detection_enabled)
|
||||
return None
|
||||
|
||||
def export_finished(self):
|
||||
print("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAHHHHHHHH export_finished")
|
||||
bpy.context.window_manager.exports_count -= 1
|
||||
if bpy.context.window_manager.exports_count == 0:
|
||||
print("YOLOOO")
|
||||
bpy.context.window_manager.auto_export_tracker.exports_count -= 1
|
||||
if bpy.context.window_manager.auto_export_tracker.exports_count == 0:
|
||||
#print("preparing to reset change detection")
|
||||
#bpy.app.timers.register(bpy.context.window_manager.auto_export_tracker.enable_change_detection, first_interval=1)
|
||||
|
||||
self.enable_change_detection()
|
||||
return None
|
||||
|
@ -1,8 +1,10 @@
|
||||
import bpy
|
||||
import os
|
||||
import json
|
||||
import mathutils
|
||||
import pytest
|
||||
import shutil
|
||||
import pathlib
|
||||
|
||||
@pytest.fixture
|
||||
def setup_data(request):
|
||||
@ -133,9 +135,20 @@ def test_export_changed_parameters(setup_data):
|
||||
models_library_path = os.path.join(models_path, "library")
|
||||
model_library_file_paths = list(map(lambda file_name: os.path.join(models_library_path, file_name), sorted(os.listdir(models_library_path))))
|
||||
modification_times_first = list(map(lambda file_path: os.path.getmtime(file_path), model_library_file_paths + [world_file_path]))
|
||||
#print("files", model_library_file_paths)
|
||||
|
||||
mapped_files_to_timestamps_and_index = {}
|
||||
for (index, file_path) in enumerate(model_library_file_paths+ [world_file_path]):
|
||||
file_path = pathlib.Path(file_path).stem
|
||||
mapped_files_to_timestamps_and_index[file_path] = (modification_times_first[index], index)
|
||||
print("files", mapped_files_to_timestamps_and_index)
|
||||
#print("mod times", modification_times_first)
|
||||
|
||||
# export again with no changes
|
||||
print("----------------")
|
||||
print("no changes")
|
||||
print("----------------")
|
||||
bpy.context.window_manager.auto_export_tracker.enable_change_detection() # FIXME: should not be needed, but ..
|
||||
|
||||
auto_export_operator(
|
||||
auto_export=True,
|
||||
direct_mode=True,
|
||||
@ -154,7 +167,7 @@ def test_export_changed_parameters(setup_data):
|
||||
print("main scene change")
|
||||
print("----------------")
|
||||
|
||||
#py.context.window_manager.auto_export_tracker.enable_change_detection() # FIXME: should not be needed, but ..
|
||||
bpy.context.window_manager.auto_export_tracker.enable_change_detection() # FIXME: should not be needed, but ..
|
||||
bpy.data.objects["Cube"].location = [1, 0, 0]
|
||||
|
||||
auto_export_operator(
|
||||
@ -169,6 +182,14 @@ def test_export_changed_parameters(setup_data):
|
||||
|
||||
modification_times = list(map(lambda file_path: os.path.getmtime(file_path), model_library_file_paths + [world_file_path]))
|
||||
assert modification_times != modification_times_first
|
||||
# only the "world" file should have changed
|
||||
world_file_index = mapped_files_to_timestamps_and_index["World"][1]
|
||||
other_files_modification_times = [value for index, value in enumerate(modification_times) if index not in [world_file_index]]
|
||||
other_files_modification_times_first = [value for index, value in enumerate(modification_times_first) if index not in [world_file_index]]
|
||||
|
||||
assert modification_times[world_file_index] != modification_times_first[world_file_index]
|
||||
assert other_files_modification_times == other_files_modification_times_first
|
||||
# reset the comparing
|
||||
modification_times_first = modification_times
|
||||
|
||||
|
||||
@ -176,6 +197,7 @@ def test_export_changed_parameters(setup_data):
|
||||
print("----------------")
|
||||
print("library change")
|
||||
print("----------------")
|
||||
bpy.context.window_manager.auto_export_tracker.enable_change_detection() # FIXME: should not be needed, but ..
|
||||
|
||||
bpy.data.objects["Blueprint1_mesh"].location = [1, 2, 1]
|
||||
auto_export_operator(
|
||||
@ -190,14 +212,31 @@ def test_export_changed_parameters(setup_data):
|
||||
|
||||
modification_times = list(map(lambda file_path: os.path.getmtime(file_path), model_library_file_paths + [world_file_path]))
|
||||
assert modification_times != modification_times_first
|
||||
# only the "world" file should have changed
|
||||
blueprint1_file_index = mapped_files_to_timestamps_and_index["Blueprint1"][1]
|
||||
other_files_modification_times = [value for index, value in enumerate(modification_times) if index not in [blueprint1_file_index]]
|
||||
other_files_modification_times_first = [value for index, value in enumerate(modification_times_first) if index not in [blueprint1_file_index]]
|
||||
|
||||
assert modification_times[blueprint1_file_index] != modification_times_first[blueprint1_file_index]
|
||||
assert other_files_modification_times == other_files_modification_times_first
|
||||
# reset the comparing
|
||||
modification_times_first = modification_times
|
||||
|
||||
|
||||
|
||||
# now same, but using an operator
|
||||
print("----------------")
|
||||
print("change using operator")
|
||||
print("----------------")
|
||||
bpy.context.window_manager.auto_export_tracker.enable_change_detection() # FIXME: should not be needed, but ..
|
||||
|
||||
with bpy.context.temp_override(active_object=bpy.data.objects["Cube"]):
|
||||
print("translate using operator")
|
||||
bpy.ops.transform.translate(value=mathutils.Vector((2.0, 1.0, -5.0)))
|
||||
bpy.ops.transform.rotate(value=0.378874, constraint_axis=(False, False, True), mirror=False, proportional_edit_falloff='SMOOTH', proportional_size=1)
|
||||
bpy.ops.object.transform_apply()
|
||||
bpy.ops.transform.translate(value=(0.5, 0, 0), constraint_axis=(True, False, False))
|
||||
|
||||
bpy.ops.transform.translate(value=(20.0, 0.0, 0.0))
|
||||
|
||||
auto_export_operator(
|
||||
auto_export=True,
|
||||
|
Loading…
Reference in New Issue
Block a user