feat(auto_export): restructured & improved changed parameters detection
* now all centralized in the operator's did_export_settings_change() function * now works correctly ! ie only compares the parameters for auto & gltf at the time of exporting ! ie it does not matter anymore how many parameters you changed, until you save/export * this solves a lot of randomness bugs in change detection * related & various cleanups
This commit is contained in:
parent
73e81c2b64
commit
73441f34a4
|
@ -10,6 +10,9 @@ bl_info = {
|
|||
"tracker_url": "https://github.com/kaosat-dev/Blender_bevy_components_workflow/issues/new",
|
||||
"category": "Import-Export"
|
||||
}
|
||||
import os
|
||||
from pathlib import Path
|
||||
import json
|
||||
import bpy
|
||||
from bpy.types import Context
|
||||
from bpy.props import (StringProperty, BoolProperty, PointerProperty)
|
||||
|
@ -174,9 +177,7 @@ def register():
|
|||
|
||||
# add our addon to the toolbar
|
||||
bpy.types.TOPBAR_MT_file_export.append(menu_func_import)
|
||||
|
||||
bpy.types.WindowManager.gltf_exporter_running = BoolProperty(default=False)
|
||||
bpy.types.WindowManager.gltf_settings_changed = BoolProperty(default=False)
|
||||
bpy.types.WindowManager.gltf_settings_backup = StringProperty(default="")
|
||||
|
||||
def unregister():
|
||||
for cls in classes:
|
||||
|
@ -185,8 +186,45 @@ def unregister():
|
|||
|
||||
bpy.app.handlers.depsgraph_update_post.remove(post_update)
|
||||
bpy.app.handlers.save_post.remove(post_save)
|
||||
del bpy.types.WindowManager.gltf_exporter_running
|
||||
|
||||
global gltf_settings_backup
|
||||
|
||||
def glTF2_pre_export_callback(data):
|
||||
pass #print("pre_export", data)
|
||||
# we backup any existing gltf export settings, if there where any
|
||||
scene = bpy.context.scene
|
||||
if "glTF2ExportSettings" in scene:
|
||||
existing_setting = scene["glTF2ExportSettings"]
|
||||
gltf_settings_backup = existing_setting
|
||||
|
||||
def glTF2_post_export_callback(data):
|
||||
gltf_settings_backup = ""
|
||||
#print("post_export", data)
|
||||
gltf_filepath = data["gltf_filepath"]
|
||||
filename = Path(gltf_filepath).stem
|
||||
|
||||
if filename == "dummy": # TODO: potentially use a hidden gltf exporter extension with an additional parameter instead of this hack
|
||||
if os.path.exists(gltf_filepath):
|
||||
print("removing dummy file")
|
||||
os.unlink(gltf_filepath)
|
||||
|
||||
# get the parameters
|
||||
scene = bpy.context.scene
|
||||
if "glTF2ExportSettings" in scene:
|
||||
settings = scene["glTF2ExportSettings"]
|
||||
export_settings = bpy.data.texts[".gltf_auto_export_gltf_settings"] if ".gltf_auto_export_gltf_settings" in bpy.data.texts else bpy.data.texts.new(".gltf_auto_export_gltf_settings")
|
||||
# now write new settings
|
||||
export_settings.clear()
|
||||
export_settings.write(json.dumps(dict(settings)))
|
||||
# now reset the original gltf_settings
|
||||
if gltf_settings_backup != "":
|
||||
print("resetting original gltf settings")
|
||||
#scene["glTF2ExportSettings"] = gltf_settings_backup
|
||||
else:
|
||||
print("no pre_existing settings")
|
||||
if "glTF2ExportSettings" in scene:
|
||||
del scene["glTF2ExportSettings"]
|
||||
gltf_settings_backup = ""
|
||||
|
||||
if "gltf_auto_export" == "__main__":
|
||||
register()
|
||||
|
|
|
@ -68,7 +68,7 @@ class AutoExportGLTF(Operator, AutoExportGltfAddonPreferences, ExportHelper):
|
|||
except:
|
||||
return True
|
||||
|
||||
def save_settings(self, context):
|
||||
def format_settings(self):
|
||||
# find all props to save
|
||||
exceptional = [
|
||||
# options that don't start with 'export_'
|
||||
|
@ -93,6 +93,10 @@ class AutoExportGLTF(Operator, AutoExportGltfAddonPreferences, ExportHelper):
|
|||
|
||||
export_props['main_scene_names'] = list(map(lambda scene_data: scene_data.name, getattr(self,"main_scenes")))
|
||||
export_props['library_scene_names'] = list(map(lambda scene_data: scene_data.name, getattr(self,"library_scenes")))
|
||||
return export_props
|
||||
|
||||
def save_settings(self, context):
|
||||
export_props = self.format_settings()
|
||||
self.properties['main_scene_names'] = export_props['main_scene_names']
|
||||
self.properties['library_scene_names'] = export_props['library_scene_names']
|
||||
|
||||
|
@ -142,28 +146,65 @@ class AutoExportGLTF(Operator, AutoExportGltfAddonPreferences, ExportHelper):
|
|||
self.report({"ERROR"}, "Loading export settings failed. Removed corrupted settings")
|
||||
bpy.data.texts.remove(bpy.data.texts[".gltf_auto_export_settings"])
|
||||
|
||||
"""
|
||||
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):
|
||||
print("comparing settings")
|
||||
# compare both the auto export settings & the gltf settings
|
||||
previous_export_settings = bpy.data.texts[".gltf_auto_export_settings"] if ".gltf_auto_export_settings" in bpy.data.texts else None
|
||||
changed_gltf_settings = bpy.context.window_manager.gltf_settings_changed
|
||||
# if there was no setting before, it is new, we need export
|
||||
print("changed settings", changed_gltf_settings, previous_export_settings.as_string())
|
||||
if previous_export_settings == None:
|
||||
return changed_gltf_settings
|
||||
else:
|
||||
export_settings = {}
|
||||
for (k, v) in self.properties.items():
|
||||
if k in self.white_list or k not in AutoExportGltfPreferenceNames:
|
||||
export_settings[k] = v
|
||||
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[".gltf_auto_export_gltf_settings_previous"] if ".gltf_auto_export_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[".gltf_auto_export_gltf_settings"] if ".gltf_auto_export_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 or previous_gltf_settings == None:
|
||||
print("previous settings missing, exporting")
|
||||
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"
|
||||
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
|
||||
|
||||
previous_gltf_settings = bpy.data.texts[".gltf_auto_export_gltf_settings_previous"] if ".gltf_auto_export_gltf_settings_previous" in bpy.data.texts else bpy.data.texts.new(".gltf_auto_export_gltf_settings_previous")
|
||||
previous_gltf_settings.clear()
|
||||
previous_gltf_settings.write(current_gltf_settings.as_string())
|
||||
|
||||
print("changed", changed)
|
||||
return changed
|
||||
|
||||
"""# if there was no setting before, it is new, we need export
|
||||
print("changed settings IN OPERATOR", changed_gltf_settings, previous_export_settings)
|
||||
if previous_export_settings == None:
|
||||
return True # we can disregard the gltf settings, we need to save either way
|
||||
else:
|
||||
export_settings = self.format_settings()
|
||||
if len(export_settings.keys()) == 0: # first time after we already used the addon, since we already have export settings, but they have not yet been applied
|
||||
return changed_gltf_settings
|
||||
|
||||
# print("foo", json.loads(previous_export_settings.as_string()).items())
|
||||
print("previous", sorted(json.loads(previous_export_settings.as_string()).items()))
|
||||
print("current", sorted(export_settings.items()))
|
||||
changed = sorted(json.loads(previous_export_settings.as_string()).items()) != sorted(export_settings.items())
|
||||
|
||||
print("changed final", changed and changed_gltf_settings)
|
||||
return changed and changed_gltf_settings
|
||||
print("changed FINAL: auto_settings", changed, "gltf_settings", changed_gltf_settings, "combo", changed or changed_gltf_settings)
|
||||
return changed and changed_gltf_settings"""
|
||||
|
||||
def execute(self, context):
|
||||
# disable change detection while the operator runs
|
||||
|
@ -171,13 +212,15 @@ class AutoExportGLTF(Operator, AutoExportGltfAddonPreferences, ExportHelper):
|
|||
if self.direct_mode:
|
||||
self.load_settings(context)
|
||||
if self.will_save_settings:
|
||||
print("SAVING SETTINGS")
|
||||
self.save_settings(context)
|
||||
|
||||
changes_per_scene = context.window_manager.auto_export_tracker.changed_objects_per_scene
|
||||
#determine changed parameters
|
||||
params_changed = self.did_export_settings_change()
|
||||
|
||||
#& do the export
|
||||
if self.direct_mode: #Do not auto export when applying settings in the menu, do it on save only
|
||||
#determine changed parameters
|
||||
params_changed = self.did_export_settings_change()
|
||||
auto_export(changes_per_scene, params_changed, self)
|
||||
# cleanup
|
||||
bpy.app.timers.register(bpy.context.window_manager.auto_export_tracker.enable_change_detection, first_interval=1)
|
||||
|
|
|
@ -48,113 +48,18 @@ class AutoExportTracker(PropertyGroup):
|
|||
# all our logic is done, mark this as done
|
||||
print("EXPORT DONE")
|
||||
|
||||
|
||||
@classmethod
|
||||
def gltf_exporter_handler(cls):
|
||||
# FOr some reason, the active operator here is always None, so using a workaround
|
||||
# active_operator = bpy.context.active_operator
|
||||
print("here", bpy.context.window_manager.gltf_exporter_running)
|
||||
|
||||
if bpy.context.window_manager.gltf_exporter_running:
|
||||
try:
|
||||
dummy_file_path = "/home/ckaos/projects/bevy/Blender_bevy_components_worklflow/testing/bevy_example/assets/dummy.glb"
|
||||
|
||||
import os
|
||||
if os.path.exists(dummy_file_path):
|
||||
print("dummy file exists, assuming it worked")
|
||||
os.unlink(dummy_file_path)
|
||||
|
||||
# get the parameters
|
||||
scene = bpy.context.scene
|
||||
if "glTF2ExportSettings" in scene:
|
||||
settings = scene["glTF2ExportSettings"]
|
||||
formatted_settings = dict(settings)
|
||||
|
||||
export_settings = bpy.data.texts[".gltf_auto_export_gltf_settings"] if ".gltf_auto_export_gltf_settings" in bpy.data.texts else bpy.data.texts.new(".gltf_auto_export_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())
|
||||
|
||||
print("gltf NEW settings", formatted_settings, "OLD settings", export_settings, "CHANGED ?", bpy.context.window_manager.gltf_settings_changed)
|
||||
|
||||
# now write new settings
|
||||
export_settings.clear()
|
||||
export_settings.write(json.dumps(formatted_settings))
|
||||
|
||||
|
||||
# now reset the original gltf_settings
|
||||
if getattr(cls, "existing_gltf_settings", None) != None:
|
||||
print("resetting original gltf settings")
|
||||
scene["glTF2ExportSettings"] = cls.existing_gltf_settings
|
||||
else:
|
||||
print("no pre_existing settings")
|
||||
if "glTF2ExportSettings" in scene:
|
||||
del scene["glTF2ExportSettings"]
|
||||
cls.existing_gltf_settings = None
|
||||
except:pass
|
||||
bpy.context.window_manager.gltf_exporter_running = False
|
||||
return None
|
||||
|
||||
|
||||
else:
|
||||
try:
|
||||
bpy.app.timers.unregister(cls.gltf_exporter_handler)
|
||||
except:pass
|
||||
return None
|
||||
return 1
|
||||
|
||||
@classmethod
|
||||
def deps_update_handler(cls, scene, depsgraph):
|
||||
# print("change detection enabled", cls.change_detection_enabled)
|
||||
active_operator = bpy.context.active_operator
|
||||
if active_operator:
|
||||
print("Operator", active_operator.bl_label, active_operator.bl_idname, "bla", bpy.context.window_manager.gltf_exporter_running)
|
||||
if active_operator.bl_idname == "EXPORT_SCENE_OT_gltf" and not bpy.context.window_manager.gltf_exporter_running:
|
||||
print("matching")
|
||||
try:
|
||||
bpy.app.timers.unregister(cls.gltf_exporter_handler)
|
||||
except:pass
|
||||
bpy.app.timers.register(cls.gltf_exporter_handler, first_interval=3)
|
||||
|
||||
# print("Operator", active_operator.bl_label, active_operator.bl_idname)
|
||||
if active_operator.bl_idname == "EXPORT_SCENE_OT_gltf" :
|
||||
# we force saving params
|
||||
active_operator.will_save_settings = True
|
||||
|
||||
# we backup any existing gltf export settings, if there where any
|
||||
scene = bpy.context.scene
|
||||
if "glTF2ExportSettings" in scene:
|
||||
existing_setting = scene["glTF2ExportSettings"]
|
||||
cls.existing_gltf_settings = existing_setting
|
||||
bpy.context.window_manager.gltf_exporter_running = True
|
||||
|
||||
|
||||
else:
|
||||
if bpy.context.window_manager.gltf_exporter_running:
|
||||
bpy.context.window_manager.gltf_exporter_running = False
|
||||
"""if active_operator.bl_idname == "EXPORT_SCENE_OT_gltf":
|
||||
scene = bpy.context.scene
|
||||
if "glTF2ExportSettings" in scene:
|
||||
existing_setting = scene["glTF2ExportSettings"]
|
||||
cls.existing_gltf_settings = existing_setting
|
||||
print("we just executed the correct operator")
|
||||
if active_operator.bl_idname == "EXPORT_SCENES_OT_auto_gltf":
|
||||
# we force saving params
|
||||
active_operator.will_save_settings = True
|
||||
else:
|
||||
import os
|
||||
dummy_file_path = "/home/ckaos/projects/bevy/Blender_bevy_components_worklflow/testing/bevy_example/assets/dummy.glb"
|
||||
if os.path.exists(dummy_file_path):
|
||||
print("dummy file exists")
|
||||
os.unlink(dummy_file_path)
|
||||
# get the parameters
|
||||
scene = bpy.context.scene
|
||||
settings = scene["glTF2ExportSettings"]
|
||||
print("gltf settings", dict(settings))
|
||||
|
||||
# now reset the original gltf_settings
|
||||
if hasattr(cls, "existing_gltf_settings"):
|
||||
print("resetting original gltf settings")
|
||||
scene["glTF2ExportSettings"] = cls.existing_gltf_settings
|
||||
else:
|
||||
del scene["glTF2ExportSettings"]"""
|
||||
|
||||
|
||||
if scene.name != "temp_scene":
|
||||
# print("depsgraph_update_post", scene.name)
|
||||
|
|
|
@ -241,3 +241,90 @@ def duplicate_object2(object, original_name):
|
|||
new_obj.animation_data.action = object.animation_data.action.copy()
|
||||
|
||||
return new_obj
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if active_operator:
|
||||
# print("Operator", active_operator.bl_label, active_operator.bl_idname, "bla", bpy.context.window_manager.gltf_exporter_running)
|
||||
if active_operator.bl_idname == "EXPORT_SCENE_OT_gltf" : #and not bpy.context.window_manager.gltf_exporter_running:
|
||||
# we force saving params
|
||||
active_operator.will_save_settings = True
|
||||
if active_operator.bl_idname == "EXPORT_SCENES_OT_auto_gltf":
|
||||
# we force saving params
|
||||
active_operator.will_save_settings = True
|
||||
|
||||
|
||||
"""
|
||||
print("matching")
|
||||
try:
|
||||
bpy.app.timers.unregister(cls.gltf_exporter_handler)
|
||||
except:pass
|
||||
bpy.app.timers.register(cls.gltf_exporter_handler, first_interval=3)
|
||||
# we backup any existing gltf export settings, if there where any
|
||||
scene = bpy.context.scene
|
||||
if "glTF2ExportSettings" in scene:
|
||||
existing_setting = scene["glTF2ExportSettings"]
|
||||
cls.existing_gltf_settings = existing_setting
|
||||
bpy.context.window_manager.gltf_exporter_running = True
|
||||
|
||||
|
||||
else:
|
||||
if bpy.context.window_manager.gltf_exporter_running:
|
||||
bpy.context.window_manager.gltf_exporter_running = False"""
|
||||
|
||||
|
||||
"""@classmethod
|
||||
def gltf_exporter_handler(cls):
|
||||
# FOr some reason, the active operator here is always None, so using a workaround
|
||||
# active_operator = bpy.context.active_operator
|
||||
print("here", bpy.context.window_manager.gltf_exporter_running)
|
||||
|
||||
if bpy.context.window_manager.gltf_exporter_running:
|
||||
try:
|
||||
dummy_file_path = "/home/ckaos/projects/bevy/Blender_bevy_components_worklflow/testing/bevy_example/assets/dummy.glb"
|
||||
|
||||
import os
|
||||
if os.path.exists(dummy_file_path):
|
||||
print("dummy file exists, assuming it worked")
|
||||
os.unlink(dummy_file_path)
|
||||
|
||||
# get the parameters
|
||||
scene = bpy.context.scene
|
||||
if "glTF2ExportSettings" in scene:
|
||||
settings = scene["glTF2ExportSettings"]
|
||||
formatted_settings = dict(settings)
|
||||
|
||||
export_settings = bpy.data.texts[".gltf_auto_export_gltf_settings"] if ".gltf_auto_export_gltf_settings" in bpy.data.texts else bpy.data.texts.new(".gltf_auto_export_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())
|
||||
|
||||
print("gltf NEW settings", formatted_settings, "OLD settings", export_settings, "CHANGED ?", bpy.context.window_manager.gltf_settings_changed)
|
||||
|
||||
# now write new settings
|
||||
export_settings.clear()
|
||||
export_settings.write(json.dumps(formatted_settings))
|
||||
|
||||
|
||||
# now reset the original gltf_settings
|
||||
if getattr(cls, "existing_gltf_settings", None) != None:
|
||||
print("resetting original gltf settings")
|
||||
scene["glTF2ExportSettings"] = cls.existing_gltf_settings
|
||||
else:
|
||||
print("no pre_existing settings")
|
||||
if "glTF2ExportSettings" in scene:
|
||||
del scene["glTF2ExportSettings"]
|
||||
cls.existing_gltf_settings = None
|
||||
except:pass
|
||||
bpy.context.window_manager.gltf_exporter_running = False
|
||||
return None
|
||||
|
||||
|
||||
else:
|
||||
try:
|
||||
bpy.app.timers.unregister(cls.gltf_exporter_handler)
|
||||
except:pass
|
||||
return None
|
||||
return 1"""
|
Loading…
Reference in New Issue