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:
kaosat.dev 2024-08-01 11:07:40 +02:00
parent ee873b06f1
commit 3a528e447a
4 changed files with 53 additions and 19 deletions

View File

@ -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

View File

@ -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)

View File

@ -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,8 +50,8 @@ 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)
@ -64,8 +62,9 @@ def generate_temporary_scene_and_export(settings, gltf_export_settings, gltf_out
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:
print("restoring state of scene")
# restore everything # restore everything
tempScene_cleaner(temp_scene, scene_filler_data) tempScene_cleaner(temp_scene, scene_filler_data)

View File

@ -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)