Compare commits

..

3 Commits

Author SHA1 Message Date
kaosat.dev
f0d7ccd454 chore(auto_export): preferences/properties cleanups 2024-04-26 23:02:09 +02:00
kaosat.dev
74b12b9b06 chore(testing): moved blend files into "art" folder 2024-04-26 23:01:58 +02:00
kaosat.dev
312a432f43 feat(auto_export): ui improvement & goodbye legacy mode ! 2024-04-26 22:50:50 +02:00
12 changed files with 98 additions and 134 deletions

View File

@ -17,7 +17,6 @@ def export_main_scene(scene, folder_path, addon_prefs, blueprints_data):
gltf_export_preferences = generate_gltf_export_preferences(addon_prefs)
export_output_folder = getattr(addon_prefs,"export_output_folder")
export_blueprints = getattr(addon_prefs,"export_blueprints")
legacy_mode = getattr(addon_prefs, "export_legacy_mode")
export_separate_dynamic_and_static_objects = getattr(addon_prefs, "export_separate_dynamic_and_static_objects")
gltf_output_path = os.path.join(folder_path, export_output_folder, scene.name)
@ -31,7 +30,7 @@ def export_main_scene(scene, folder_path, addon_prefs, blueprints_data):
}
if export_blueprints :
if not legacy_mode:
inject_blueprints_list_into_main_scene(scene, blueprints_data)
if export_separate_dynamic_and_static_objects:
@ -72,7 +71,6 @@ def export_main_scene(scene, folder_path, addon_prefs, blueprints_data):
print(" exporting gltf to", gltf_output_path, ".gltf/glb")
export_gltf(gltf_output_path, export_settings)
if not legacy_mode:
remove_blueprints_list_from_main_scene(scene)

View File

@ -1,22 +1,22 @@
import bpy
class SceneLink(bpy.types.PropertyGroup):
name: bpy.props.StringProperty(name="")
scene: bpy.props.PointerProperty(type=bpy.types.Scene)
name: bpy.props.StringProperty(name="") # type: ignore
scene: bpy.props.PointerProperty(type=bpy.types.Scene) # type: ignore
class SceneLinks(bpy.types.PropertyGroup):
name = bpy.props.StringProperty(name="List of scenes to export", default="Unknown")
items: bpy.props.CollectionProperty(type = SceneLink)
items: bpy.props.CollectionProperty(type = SceneLink) # type: ignore
class CUSTOM_PG_sceneName(bpy.types.PropertyGroup):
name: bpy.props.StringProperty()
display: bpy.props.BoolProperty()
name: bpy.props.StringProperty() # type: ignore
display: bpy.props.BoolProperty() # type: ignore
class CollectionToExport(bpy.types.PropertyGroup):
name: bpy.props.StringProperty(name="")
name: bpy.props.StringProperty(name="") # type: ignore
class BlueprintsToExport(bpy.types.PropertyGroup):
name = bpy.props.StringProperty(name="List of collections to export", default="Unknown")
items: bpy.props.CollectionProperty(type = CollectionToExport)
items: bpy.props.CollectionProperty(type = CollectionToExport) # type: ignore

View File

@ -27,30 +27,31 @@ class AutoExportGLTF(Operator, AutoExportGltfAddonPreferences):#, ExportHelper):
#filename_ext = ''
#filepath: bpy.props.StringProperty(subtype="FILE_PATH", default="") # type: ignore
# Filters folders
filter_folder: BoolProperty(
default=True,
options={"HIDDEN"}
) # type: ignore
#list of settings (other than purely gltf settings) whose change should trigger a re-generation of gltf files
white_list = ['auto_export',
'export_main_scene_name',
white_list = [
'auto_export',
'export_root_folder',
'export_output_folder',
'export_library_scene_name',
'export_change_detection',
'export_scene_settings',
'main_scenes',
'library_scenes',
'main_scenes_index',
'library_scenes_index',
'main_scene_names',
'library_scene_names',
'export_blueprints',
'export_blueprints_path',
'export_marked_assets',
'collection_instances_combine_mode',
'export_levels_path',
'export_separate_dynamic_and_static_objects',
'export_materials_library',
'export_materials_path',
'export_scene_settings'
'export_legacy_mode'
]
@classmethod
@ -306,7 +307,6 @@ class AutoExportGLTF(Operator, AutoExportGltfAddonPreferences):#, ExportHelper):
def execute(self, context):
print("execute", self.directory)
bpy.context.window_manager.auto_export_tracker.disable_change_detection()
if self.direct_mode:
self.load_settings(context)
@ -339,7 +339,7 @@ class AutoExportGLTF(Operator, AutoExportGltfAddonPreferences):#, ExportHelper):
self.load_settings(context)
wm = context.window_manager
#wm.fileselect_add(self)
return context.window_manager.invoke_props_dialog(self, title="Auto export", width=600)
return context.window_manager.invoke_props_dialog(self, title="Auto export", width=640)
#context.window_manager.modal_handler_add(self)
return {'RUNNING_MODAL'}
@ -372,10 +372,10 @@ class AutoExportGLTF(Operator, AutoExportGltfAddonPreferences):#, ExportHelper):
section = layout.box()
section.enabled = controls_enabled
section.prop(self, "root_folder")
section.prop(operator, "export_output_folder")
section.prop(self, "export_root_folder")
section.prop(operator, "export_output_folder", text="Export Folder relative to root")
section.prop(operator, "export_scene_settings")
section.prop(operator, "export_legacy_mode")
section.prop(operator, "export_change_detection")
"""header, panel = layout.panel("my_panel_id", default_closed=False)
header.label(text="Hello World")
if panel:
@ -439,14 +439,21 @@ class AutoExportGLTF(Operator, AutoExportGltfAddonPreferences):#, ExportHelper):
section.prop(operator, "export_blueprints")
section = section.box()
section.enabled = controls_enabled and self.export_blueprints
# collections/blueprints
section.prop(operator, "export_blueprints_path")
section.prop(operator, "collection_instances_combine_mode")
section.prop(operator, "export_marked_assets")
section.separator()
section.prop(operator, "export_levels_path")
section.prop(operator, "export_separate_dynamic_and_static_objects")
section.separator()
# materials
section.prop(operator, "export_materials_library")
section = section.box()
section.enabled = controls_enabled and self.export_materials_library
section.prop(operator, "export_materials_path")

View File

@ -11,41 +11,38 @@ from bpy.props import (BoolProperty,
from .internals import (CUSTOM_PG_sceneName)
AutoExportGltfPreferenceNames = [
'will_save_settings',
'direct_mode',# specific to main auto_export operator
'auto_export',
'export_main_scene_name',
'export_root_folder',
'export_output_folder',
'export_library_scene_name',
'export_change_detection',
'export_blueprints',
'export_blueprints_path',
'export_marked_assets',
'collection_instances_combine_mode',
'export_separate_dynamic_and_static_objects',
'export_legacy_mode',
'export_materials_library',
'export_materials_path',
'export_scene_settings',
'main_scenes',
'library_scenes',
'main_scenes_index',
'library_scenes_index',
'direct_mode',# specific to main auto_export operator
'main_scene_names',
'library_scene_names',
'previous_export_settings',
'will_save_settings',
'export_blueprints',
'export_blueprints_path',
'export_marked_assets',
'collection_instances_combine_mode',
'export_levels_path',
'export_separate_dynamic_and_static_objects',
'export_materials_library',
'export_materials_path',
]
def on_export_output_folder_updated(self, context):
#self.root_folder = os.path.relpath(self.root_folder)
#self.export_output_folder = os.path.join(self.root_folder, self.export_output_folder)
print("on_foo_updated", self.root_folder, self.export_output_folder)
#self.export_root_folder = os.path.relpath(self.export_root_folder)
#self.export_output_folder = os.path.join(self.export_root_folder, self.export_output_folder)
print("on_foo_updated", self.export_root_folder, self.export_output_folder)
class AutoExportGltfAddonPreferences(AddonPreferences):
# this must match the add-on name, use '__package__'
@ -65,6 +62,13 @@ class AutoExportGltfAddonPreferences(AddonPreferences):
default=False
) # type: ignore
auto_export: BoolProperty(
name='Auto export',
description='Automatically export to gltf on save',
default=False
) # type: ignore
#### general
# for UI only, workaround for lacking panels
show_general_settings: BoolProperty(
@ -73,26 +77,17 @@ class AutoExportGltfAddonPreferences(AddonPreferences):
default=True
) # type: ignore
root_folder: StringProperty(
export_root_folder: StringProperty(
name = "Project Root Path",
description="The root folder of your (Bevy) project (not assets!)",
subtype='DIR_PATH',
default='../',
update=on_export_output_folder_updated) # type: ignore
auto_export: BoolProperty(
name='Auto export',
description='Automatically export to gltf on save',
default=False
) # type: ignore
export_main_scene_name: StringProperty(
name='Main scene',
description='The name of the main scene/level/world to auto export',
default='Scene'
) # type: ignore
export_output_folder: StringProperty(
name='Export folder (relative)',
description='The root folder for all exports(relative to current file) Defaults to current folder',
default='',
name='Export folder',
description='The root folder for all exports(relative to the root folder/path) Defaults to "assets" ',
default='./assets',
subtype='DIR_PATH',
options={'HIDDEN'},
update=on_export_output_folder_updated
@ -106,16 +101,12 @@ class AutoExportGltfAddonPreferences(AddonPreferences):
default=True
) # type: ignore
export_library_scene_name: StringProperty(
name='Library scene',
description='The name of the library scene to auto export',
default='Library'
) # type: ignore
export_change_detection: BoolProperty(
name='Change detection',
description='Use change detection to determine what/if should be exported',
default=True
) # type: ignore
# scene components
export_scene_settings: BoolProperty(
name='Export scene settings',
@ -136,13 +127,29 @@ class AutoExportGltfAddonPreferences(AddonPreferences):
description='Replaces collection instances with an Empty with a BlueprintName custom property',
default=True
) # type: ignore
export_blueprints_path: StringProperty(
name='Blueprints path',
description='path to export the blueprints to (relative to the Export folder)',
default='library',
description='path to export the blueprints to (relative to the export folder)',
default='./blueprints',
subtype='DIR_PATH'
) # type: ignore
export_levels_path: StringProperty(
name='Levels path',
description='path to export the levels (main scenes) to (relative to the export folder)',
default='./levels',
subtype='DIR_PATH'
) # type: ignore
export_separate_dynamic_and_static_objects: BoolProperty(
name="Export levels' dynamic and static objects seperatly",
description="""For MAIN scenes only (aka levels), toggle this to generate 2 files per level:
- one with all dynamic data: collection or instances marked as dynamic/ saveable
- one with all static data: anything else that is NOT marked as dynamic""",
default=False
) # type: ignore
export_materials_library: BoolProperty(
name='Export materials library',
description='remove materials from blueprints and use the material library instead',
@ -150,8 +157,8 @@ class AutoExportGltfAddonPreferences(AddonPreferences):
) # type: ignore
export_materials_path: StringProperty(
name='Materials path',
description='path to export the materials libraries to (relative to the root folder)',
default='materials',
description='path to export the materials libraries to (relative to the export folder)',
default='./materials',
subtype='DIR_PATH'
) # type: ignore
@ -180,20 +187,6 @@ class AutoExportGltfAddonPreferences(AddonPreferences):
default=True
) # type: ignore
export_separate_dynamic_and_static_objects: BoolProperty(
name='Export dynamic and static objects seperatly',
description="""For MAIN scenes only (aka levels), toggle this to generate 2 files per level:
- one with all dynamic data: collection or instances marked as dynamic/ saveable
- one with all static data: anything else that is NOT marked as dynamic""",
default=False
) # type: ignore
export_legacy_mode: BoolProperty(
name='Legacy mode for Bevy',
description='Toggle this if you want to be compatible with bevy_gltf_blueprints/components < 0.8',
default=True
) # type: ignore
main_scenes: CollectionProperty(name="main scenes", type=CUSTOM_PG_sceneName) # type: ignore
main_scenes_index: IntProperty(name = "Index for main scenes list", default = 0) # type: ignore

View File

@ -91,7 +91,7 @@ def copy_animation_data(source, target):
target["AnimationMarkers"] = f'( {markers_formated} )'
def duplicate_object(object, parent, combine_mode, destination_collection, blueprints_data, legacy_mode, nester=""):
def duplicate_object(object, parent, combine_mode, destination_collection, blueprints_data, nester=""):
copy = None
internal_blueprint_names = [blueprint.name for blueprint in blueprints_data.internal_blueprints]
# print("COMBINE MODE", combine_mode)
@ -104,11 +104,10 @@ def duplicate_object(object, parent, combine_mode, destination_collection, bluep
empty_obj = make_empty(original_name, object.location, object.rotation_euler, object.scale, destination_collection)
"""we inject the collection/blueprint name, as a component called 'BlueprintName', but we only do this in the empty, not the original object"""
empty_obj['BlueprintName'] = '"'+collection_name+'"' if legacy_mode else '("'+collection_name+'")'
empty_obj['BlueprintName'] = '("'+collection_name+'")'
empty_obj['SpawnHere'] = '()'
# we also inject a list of all sub blueprints, so that the bevy side can preload them
if not legacy_mode:
blueprint_name = collection_name
children_per_blueprint = {}
blueprint = blueprints_data.blueprints_per_name.get(blueprint_name, None)
@ -142,12 +141,11 @@ def duplicate_object(object, parent, combine_mode, destination_collection, bluep
copy_animation_data(object, copy)
for child in object.children:
duplicate_object(child, copy, combine_mode, destination_collection, blueprints_data, legacy_mode, nester+" ")
duplicate_object(child, copy, combine_mode, destination_collection, blueprints_data, nester+" ")
# copies the contents of a collection into another one while replacing library instances with empties
def copy_hollowed_collection_into(source_collection, destination_collection, parent_empty=None, filter=None, blueprints_data=None, addon_prefs={}):
collection_instances_combine_mode = getattr(addon_prefs, "collection_instances_combine_mode")
legacy_mode = getattr(addon_prefs, "export_legacy_mode")
for object in source_collection.objects:
if object.name.endswith("____bak"): # some objects could already have been handled, ignore them
@ -157,7 +155,7 @@ def copy_hollowed_collection_into(source_collection, destination_collection, par
#check if a specific collection instance does not have an ovveride for combine_mode
combine_mode = object['_combine'] if '_combine' in object else collection_instances_combine_mode
parent = parent_empty
duplicate_object(object, parent, combine_mode, destination_collection, blueprints_data, legacy_mode)
duplicate_object(object, parent, combine_mode, destination_collection, blueprints_data)
# for every child-collection of the source, copy its content into a new sub-collection of the destination
for collection in source_collection.children:

View File

@ -1,5 +1,5 @@
[pytest]
blender-template = ../../testing/bevy_example/assets/testing.blend
blender-template = ../../testing/bevy_example/art/testing.blend
addopts = -svv
testpaths =
tests

View File

@ -90,7 +90,6 @@ def test_export_complex(setup_data):
export_output_folder="./models",
export_scene_settings=True,
export_blueprints=True,
export_legacy_mode=False,
export_materials_library=True
)
# blueprint1 => has an instance, got changed, should export

View File

@ -114,7 +114,6 @@ def test_export_change_tracking_custom_properties(setup_data):
export_output_folder="./models",
export_scene_settings=True,
export_blueprints=True,
export_legacy_mode=False,
export_materials_library=False
)
@ -143,7 +142,6 @@ def test_export_change_tracking_custom_properties(setup_data):
export_output_folder="./models",
export_scene_settings=True,
export_blueprints=True,
export_legacy_mode=False,
export_materials_library=False
)
@ -193,7 +191,6 @@ def test_export_change_tracking_custom_properties_collection_instances_combine_m
export_output_folder="./models",
export_scene_settings=True,
export_blueprints=True,
export_legacy_mode=False,
export_materials_library=False
)
@ -235,7 +232,6 @@ def test_export_change_tracking_custom_properties_collection_instances_combine_m
export_output_folder="./models",
export_scene_settings=True,
export_blueprints=True,
export_legacy_mode=False,
export_materials_library=False
)
@ -269,7 +265,6 @@ def test_export_change_tracking_custom_properties_collection_instances_combine_m
export_output_folder="./models",
export_scene_settings=True,
export_blueprints=True,
export_legacy_mode=False,
export_materials_library=False
)
modification_times_first = modification_times = list(map(lambda file_path: os.path.getmtime(file_path), model_library_file_paths + [world_file_path]))
@ -286,7 +281,6 @@ def test_export_change_tracking_custom_properties_collection_instances_combine_m
export_output_folder="./models",
export_scene_settings=True,
export_blueprints=True,
export_legacy_mode=False,
export_materials_library=False
)
@ -346,7 +340,6 @@ def test_export_change_tracking_light_properties(setup_data):
export_output_folder="./models",
export_scene_settings=True,
export_blueprints=True,
export_legacy_mode=False,
export_materials_library=False
)
@ -374,7 +367,6 @@ def test_export_change_tracking_light_properties(setup_data):
export_output_folder="./models",
export_scene_settings=True,
export_blueprints=True,
export_legacy_mode=False,
export_materials_library=False
)
@ -403,7 +395,6 @@ def test_export_change_tracking_light_properties(setup_data):
export_output_folder="./models",
export_scene_settings=True,
export_blueprints=True,
export_legacy_mode=False,
export_materials_library=False
)
@ -432,7 +423,6 @@ def test_export_change_tracking_light_properties(setup_data):
export_output_folder="./models",
export_scene_settings=True,
export_blueprints=True,
export_legacy_mode=False,
export_materials_library=False
)
@ -481,7 +471,6 @@ def test_export_change_tracking_camera_properties(setup_data):
export_output_folder="./models",
export_scene_settings=True,
export_blueprints=True,
export_legacy_mode=False,
export_materials_library=False
)
@ -509,7 +498,6 @@ def test_export_change_tracking_camera_properties(setup_data):
export_output_folder="./models",
export_scene_settings=True,
export_blueprints=True,
export_legacy_mode=False,
export_materials_library=False
)
@ -558,7 +546,6 @@ def test_export_change_tracking_material_properties(setup_data):
export_output_folder="./models",
export_scene_settings=True,
export_blueprints=True,
export_legacy_mode=False,
export_materials_library=False
)
@ -586,7 +573,6 @@ def test_export_change_tracking_material_properties(setup_data):
export_output_folder="./models",
export_scene_settings=True,
export_blueprints=True,
export_legacy_mode=False,
export_materials_library=False
)
@ -619,7 +605,6 @@ def test_export_change_tracking_material_properties(setup_data):
export_output_folder="./models",
export_scene_settings=True,
export_blueprints=True,
export_legacy_mode=False,
export_materials_library=False
)
@ -652,7 +637,6 @@ def test_export_change_tracking_material_properties(setup_data):
export_output_folder="./models",
export_scene_settings=True,
export_blueprints=True,
export_legacy_mode=False,
export_materials_library=False
)
@ -715,7 +699,6 @@ def test_export_various_chained_changes(setup_data):
export_output_folder="./models",
export_scene_settings=True,
export_blueprints=True,
export_legacy_mode=False,
export_materials_library=False
)
@ -745,7 +728,6 @@ def test_export_various_chained_changes(setup_data):
export_output_folder="./models",
export_scene_settings=True,
export_blueprints=True,
export_legacy_mode=False,
export_materials_library=False
)
@ -766,7 +748,6 @@ def test_export_various_chained_changes(setup_data):
export_output_folder="./models",
export_scene_settings=True,
export_blueprints=True,
export_legacy_mode=False,
export_materials_library=False
)
@ -797,7 +778,6 @@ def test_export_various_chained_changes(setup_data):
export_output_folder="./models",
export_scene_settings=True,
export_blueprints=True,
export_legacy_mode=False,
export_materials_library=False
)
@ -830,7 +810,6 @@ def test_export_various_chained_changes(setup_data):
export_output_folder="./models",
export_scene_settings=True,
export_blueprints=True,
export_legacy_mode=False,
export_materials_library=False
)
@ -872,7 +851,6 @@ def test_export_various_chained_changes(setup_data):
export_output_folder="./models",
export_scene_settings=True,
export_blueprints=True,
export_legacy_mode=False,
export_materials_library=False
)

View File

@ -66,7 +66,6 @@ def test_export_no_parameters(setup_data):
auto_export=True,
direct_mode=True,
export_output_folder="./models",
export_legacy_mode=False,
export_materials_library=True
)
@ -93,7 +92,6 @@ def test_export_auto_export_parameters_only(setup_data):
auto_export=True,
direct_mode=True,
export_output_folder="./models",
export_legacy_mode=False,
export_materials_library=True
)
@ -134,7 +132,6 @@ def test_export_changed_parameters(setup_data):
export_output_folder="./models",
export_scene_settings=True,
export_blueprints=True,
export_legacy_mode=False,
export_materials_library=True
)
@ -156,7 +153,6 @@ def test_export_changed_parameters(setup_data):
export_output_folder="./models",
export_scene_settings=True,
export_blueprints=True,
export_legacy_mode=False,
export_materials_library=True
)
@ -181,7 +177,6 @@ def test_export_changed_parameters(setup_data):
export_output_folder="./models",
export_scene_settings=True,
export_blueprints=True,
export_legacy_mode=False,
export_materials_library=True
)
@ -197,7 +192,6 @@ def test_export_changed_parameters(setup_data):
export_output_folder="./models",
export_scene_settings=True,
export_blueprints=True,
export_legacy_mode=False,
export_materials_library=True
)
@ -226,7 +220,6 @@ def test_export_changed_parameters(setup_data):
export_output_folder="./models",
export_scene_settings=True,
export_blueprints=True,
export_legacy_mode=False,
export_materials_library=False
)
@ -242,7 +235,6 @@ def test_export_changed_parameters(setup_data):
export_output_folder="./models",
export_scene_settings=True,
export_blueprints=True,
export_legacy_mode=False,
export_materials_library=False
)

View File

@ -144,7 +144,6 @@ class GLTF_PT_auto_export_general(bpy.types.Panel):
layout.active = operator.auto_export
layout.prop(operator, "export_output_folder")
layout.prop(operator, "export_scene_settings")
layout.prop(operator, "export_legacy_mode")
class GLTF_PT_auto_export_change_detection(bpy.types.Panel):