feat(Blenvy:Blender): finally ! added a clean way of dealing with failed gltf exports
* no more re-raised errors * no more remaining "___temp_scenes" or object renames aka no more breaking user's blend files * also added boilerplate for displaying more accurate traceback & used it to still display the export errors correctly
This commit is contained in:
parent
ee873b06f1
commit
3a528e447a
1
TODO.md
1
TODO.md
|
@ -340,5 +340,6 @@ Bevy Side:
|
||||||
- [ ] the ability to map external TEXT files to data in BLender (git-able, hand editable)
|
- [ ] the ability to map external TEXT files to data in BLender (git-able, hand editable)
|
||||||
- [x] make aabbs calculation non configurable, getting rid of the last setting (for now)
|
- [x] make aabbs calculation non configurable, getting rid of the last setting (for now)
|
||||||
- [ ] add information & screenshots about adding assets to the Blender add-on docs
|
- [ ] add information & screenshots about adding assets to the Blender add-on docs
|
||||||
|
- [x] finally deal cleanly with gltf export failures & make sure to always reset the state of the blend file
|
||||||
|
|
||||||
clear && pytest -svv --blender-template ../../testing/bevy_example/art/testing_library.blend --blender-executable /home/ckaos/tools/blender/blender-4.1.0-linux-x64/blender tests/test_bevy_integration_prepare.py && pytest -svv --blender-executable /home/ckaos/tools/blender/blender-4.1.0-linux-x64/blender tests/test_bevy_integration.py
|
clear && pytest -svv --blender-template ../../testing/bevy_example/art/testing_library.blend --blender-executable /home/ckaos/tools/blender/blender-4.1.0-linux-x64/blender tests/test_bevy_integration_prepare.py && pytest -svv --blender-executable /home/ckaos/tools/blender/blender-4.1.0-linux-x64/blender tests/test_bevy_integration.py
|
|
@ -83,3 +83,4 @@ def export_gltf (path, gltf_export_settings):
|
||||||
# print("export settings",settings)
|
# print("export settings",settings)
|
||||||
os.makedirs(os.path.dirname(path), exist_ok=True)
|
os.makedirs(os.path.dirname(path), exist_ok=True)
|
||||||
bpy.ops.export_scene.gltf(**settings)
|
bpy.ops.export_scene.gltf(**settings)
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
import json
|
|
||||||
import bpy
|
import bpy
|
||||||
from blenvy.core.helpers_collections import (set_active_collection)
|
from blenvy.core.helpers_collections import (set_active_collection)
|
||||||
from blenvy.core.object_makers import (make_empty)
|
from blenvy.core.object_makers import (make_empty)
|
||||||
from .duplicate_object import duplicate_object
|
from .duplicate_object import duplicate_object
|
||||||
from .export_gltf import export_gltf
|
from .export_gltf import export_gltf
|
||||||
from blenvy.core.scene_helpers import add_scene_property
|
|
||||||
from ..constants import custom_properties_to_filter_out
|
from ..constants import custom_properties_to_filter_out
|
||||||
from ..utils import remove_unwanted_custom_properties
|
from ..utils import remove_unwanted_custom_properties
|
||||||
|
from ....core.utils import exception_traceback, show_message_box
|
||||||
|
|
||||||
"""
|
"""
|
||||||
generates a temporary scene, fills it with data, cleans up after itself
|
generates a temporary scene, fills it with data, cleans up after itself
|
||||||
|
@ -52,22 +50,23 @@ def generate_temporary_scene_and_export(settings, gltf_export_settings, gltf_out
|
||||||
# detect scene mistmatch
|
# detect scene mistmatch
|
||||||
scene_mismatch = bpy.context.scene.name != bpy.context.window.scene.name
|
scene_mismatch = bpy.context.scene.name != bpy.context.window.scene.name
|
||||||
if scene_mismatch:
|
if scene_mismatch:
|
||||||
raise Exception("Context scene mismatch, aborting", bpy.context.scene.name, bpy.context.window.scene.name)
|
show_message_box("Error in Gltf Exporter", icon="ERROR", lines=[f"Context scene mismatch, aborting: {bpy.context.scene.name} vs {bpy.context.window.scene.name}"])
|
||||||
|
else:
|
||||||
set_active_collection(bpy.context.scene, temp_root_collection.name)
|
set_active_collection(bpy.context.scene, temp_root_collection.name)
|
||||||
# generate contents of temporary scene
|
# generate contents of temporary scene
|
||||||
scene_filler_data = tempScene_filler(temp_root_collection)
|
scene_filler_data = tempScene_filler(temp_root_collection)
|
||||||
# export the temporary scene
|
# export the temporary scene
|
||||||
try:
|
try:
|
||||||
print("dry_run MODE", settings.auto_export.dry_run)
|
print("dry_run MODE", settings.auto_export.dry_run)
|
||||||
if settings.auto_export.dry_run == "DISABLED":
|
if settings.auto_export.dry_run == "DISABLED":
|
||||||
export_gltf(gltf_output_path, gltf_export_settings)
|
export_gltf(gltf_output_path, gltf_export_settings)
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
print("failed to export gltf !", error)
|
print("failed to export gltf !", error)
|
||||||
raise error
|
show_message_box("Error in Gltf Exporter", icon="ERROR", lines=exception_traceback(error))
|
||||||
finally:
|
finally:
|
||||||
# restore everything
|
print("restoring state of scene")
|
||||||
tempScene_cleaner(temp_scene, scene_filler_data)
|
# restore everything
|
||||||
|
tempScene_cleaner(temp_scene, scene_filler_data)
|
||||||
|
|
||||||
# reset active scene
|
# reset active scene
|
||||||
bpy.context.window.scene = active_scene
|
bpy.context.window.scene = active_scene
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
import sys
|
||||||
|
import inspect
|
||||||
|
import bpy
|
||||||
|
|
||||||
|
def full_stack_lines(tb=None):
|
||||||
|
text = []
|
||||||
|
try:
|
||||||
|
if tb is None:
|
||||||
|
tb = sys.exc_info()[2]
|
||||||
|
|
||||||
|
text.append('Traceback (most recent call last):')
|
||||||
|
for item in reversed(inspect.getouterframes(tb.tb_frame)[1:]):
|
||||||
|
text.append(' File "{1}", line {2}, in {3}\n'.format(*item))
|
||||||
|
for line in item[4]:
|
||||||
|
text.append(' ' + line.lstrip())
|
||||||
|
for item in inspect.getinnerframes(tb):
|
||||||
|
text.append(' File "{1}", line {2}, in {3}\n'.format(*item))
|
||||||
|
for line in item[4]:
|
||||||
|
text.append(' ' + line.lstrip())
|
||||||
|
except: pass
|
||||||
|
return text
|
||||||
|
|
||||||
|
def exception_traceback(error):
|
||||||
|
traceback_formated = [str(error)]
|
||||||
|
traceback_formated += full_stack_lines()
|
||||||
|
return traceback_formated
|
||||||
|
|
||||||
|
def show_message_box(title = "Message Box", icon = 'INFO', lines=""):
|
||||||
|
myLines=lines
|
||||||
|
def draw(self, context):
|
||||||
|
for n in myLines:
|
||||||
|
self.layout.label(text=n)
|
||||||
|
bpy.context.window_manager.popup_menu(draw, title = title, icon = icon)
|
Loading…
Reference in New Issue