Blender_bevy_components_wor.../tools/gltf_auto_export/__init__.py

228 lines
8.9 KiB
Python

bl_info = {
"name": "gltf_auto_export",
"author": "kaosigh",
"version": (0, 10, 0),
"blender": (3, 4, 0),
"location": "File > Import-Export",
"description": "glTF/glb auto-export",
"warning": "",
"wiki_url": "https://github.com/kaosat-dev/Blender_bevy_components_workflow",
"tracker_url": "https://github.com/kaosat-dev/Blender_bevy_components_workflow/issues/new",
"category": "Import-Export"
}
import bpy
import os
from bpy.app.handlers import persistent
from bpy.props import (IntProperty)
from . import helpers
from .internals import (SceneLink,
SceneLinks,
CollectionToExport,
CollectionsToExport,
CUSTOM_PG_sceneName
)
from .auto_export import auto_export
from .preferences import (AutoExportGltfPreferenceNames,
AutoExportGltfAddonPreferences
)
from .ui.main import (GLTF_PT_auto_export_main,
GLTF_PT_auto_export_root,
GLTF_PT_auto_export_blueprints,
GLTF_PT_auto_export_collections_list,
GLTF_PT_auto_export_gltf,
SCENE_UL_GLTF_auto_export,
AutoExportGLTF
)
from .ui.various import (SCENES_LIST_OT_actions)
from .helpers_scenes import (is_scene_ok)
bpy.context.window_manager['changed_objects_per_scene'] = {}
bpy.context.window_manager['previous_params'] = {}
bpy.context.window_manager['__gltf_auto_export_initialized'] = False
bpy.context.window_manager['__gltf_auto_export_gltf_params_changed'] = False
bpy.context.window_manager['__gltf_auto_export_saving'] = False
######################################################
""" there are two places where we load settings for auto_export from:
- in ui/main AutoExportGLTF -> invoke
- in auto_export.py -> auto_export
This is a workaround needed because of the way the settings are stored , perhaps there is a better way to deal with it ? ie by calling the AutoExportGLTF operator from the auto_export function ?
"""
#see here for original gltf exporter infos https://github.com/KhronosGroup/glTF-Blender-IO/blob/main/addons/io_scene_gltf2/__init__.py
@persistent
def deps_update_handler(scene, depsgraph):
if scene.name != "temp_scene": # actually do we care about anything else than the main scene(s) ?
#print("depsgraph_update_post", scene.name)
print("-------------")
changed = scene.name or ""
# only deal with changes if we are no in the mids of saving/exporting
#if not bpy.context.window_manager['__gltf_auto_export_saving']:
# depsgraph = bpy.context.evaluated_depsgraph_get()
if not 'changed_objects_per_scene' in bpy.context.window_manager:
bpy.context.window_manager['changed_objects_per_scene'] = {}
if not changed in bpy.context.window_manager['changed_objects_per_scene']:
bpy.context.window_manager['changed_objects_per_scene'][changed] = {}
for obj in depsgraph.updates:
if isinstance(obj.id, bpy.types.Object):
# get the actual object
object = bpy.data.objects[obj.id.name]
print("changed object", obj.id.name)
bpy.context.window_manager['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,)
material = bpy.data.materials[obj.id.name]
#now find which objects are using the material
for obj in bpy.data.objects:
for slot in obj.material_slots:
if slot.material == material:
bpy.context.window_manager['changed_objects_per_scene'][scene.name][obj.name] = obj
bpy.context.window_manager.changedScene = changed
@persistent
def save_handler(dummy):
print("-------------")
print("saved", bpy.data.filepath)
# mark saving as in progress, this is needed to ignore any changes from the depsgraph done during saving
# bpy.context.window_manager['__gltf_auto_export_saving'] = True
if not 'changed_objects_per_scene' in bpy.context.window_manager:
bpy.context.window_manager['changed_objects_per_scene'] = {}
changes_per_scene = bpy.context.window_manager['changed_objects_per_scene']
if not 'previous_params' in bpy.context.window_manager:
bpy.context.window_manager['previous_params'] = {}
#determine changed parameters
addon_prefs = bpy.context.preferences.addons["gltf_auto_export"].preferences
prefs = {}
for (k,v) in addon_prefs.items():
if k not in AutoExportGltfPreferenceNames:
prefs[k] = v
previous_params = bpy.context.window_manager['previous_params'] if 'previous_params' in bpy.context.window_manager else {}
set1 = set(previous_params.items())
set2 = set(prefs.items())
difference = dict(set1 ^ set2)
changed_param_names = list(set(difference.keys())- set(AutoExportGltfPreferenceNames))
changed_parameters = len(changed_param_names) > 0
# do the export
auto_export(changes_per_scene, changed_parameters)
# save the parameters
# todo add back
for (k, v) in prefs.items():
bpy.context.window_manager['previous_params'][k] = v
# reset a few things after exporting
# reset wether the gltf export paramters were changed since the last save
bpy.context.window_manager['__gltf_auto_export_gltf_params_changed'] = False
# reset whether there have been changed objects since the last save
bpy.context.window_manager['changed_objects_per_scene'] = {}
# all our logic is done, mark this as done
#bpy.context.window_manager['__gltf_auto_export_saving'] = False
print("EXPORT DONE")
def get_changedScene(self):
return self["changedScene"]
def set_changedScene(self, value):
self["changedScene"] = value
classes = [
SceneLink,
SceneLinks,
CUSTOM_PG_sceneName,
SCENE_UL_GLTF_auto_export,
SCENES_LIST_OT_actions,
AutoExportGLTF,
AutoExportGltfAddonPreferences,
CollectionToExport,
CollectionsToExport,
GLTF_PT_auto_export_main,
GLTF_PT_auto_export_root,
GLTF_PT_auto_export_blueprints,
GLTF_PT_auto_export_collections_list,
GLTF_PT_auto_export_gltf
]
def menu_func_import(self, context):
self.layout.operator(AutoExportGLTF.bl_idname, text="glTF auto Export (.glb/gltf)")
def register():
for cls in classes:
bpy.utils.register_class(cls)
bpy.types.Scene.main_scene = bpy.props.PointerProperty(type=bpy.types.Scene, name="main scene", description="main_scene_chooser", poll=is_scene_ok)
bpy.types.Scene.library_scene = bpy.props.PointerProperty(type=bpy.types.Scene, name="library scene", description="library_scene_picker", poll=is_scene_ok)
# setup handlers for updates & saving
bpy.app.handlers.depsgraph_update_post.append(deps_update_handler)
bpy.app.handlers.save_post.append(save_handler)
bpy.types.WindowManager.changedScene = bpy.props.StringProperty(get=get_changedScene, set=set_changedScene)
bpy.types.WindowManager.exportedCollections = bpy.props.CollectionProperty(type=CollectionsToExport)
# add our addon to the toolbar
bpy.types.TOPBAR_MT_file_export.append(menu_func_import)
## just experiments
bpy.types.Scene.main_scenes_list_index = IntProperty(name = "Index for main scenes list", default = 0)
bpy.types.Scene.library_scenes_list_index = IntProperty(name = "Index for library scenes list", default = 0)
"""
mock_main_scenes = []
main_scenes = bpy.context.preferences.addons["gltf_auto_export"].preferences.main_scenes
for item_name in mock_main_scenes:
item = main_scenes.add()
item.name = item_name
mock_library_scenes = []
library_scenes = bpy.context.preferences.addons["gltf_auto_export"].preferences.library_scenes
for item_name in mock_library_scenes:
item = library_scenes.add()
item.name = item_name"""
bpy.context.preferences.addons["gltf_auto_export"].preferences.main_scenes_index = 0
bpy.context.preferences.addons["gltf_auto_export"].preferences.library_scenes_index = 0
def unregister():
for cls in classes:
bpy.utils.unregister_class(cls)
bpy.types.TOPBAR_MT_file_export.remove(menu_func_import)
# remove handlers & co
bpy.app.handlers.depsgraph_update_post.remove(deps_update_handler)
bpy.app.handlers.save_post.remove(save_handler)
del bpy.types.WindowManager.changedScene
del bpy.types.WindowManager.exportedCollections
del bpy.types.Scene.main_scene
del bpy.types.Scene.library_scene
del bpy.types.Scene.main_scenes_list_index
del bpy.types.Scene.library_scenes_list_index
if "gltf_auto_export" == "__main__":
register()