diff --git a/tools/gltf_auto_export/tests/test_change_tracking.py b/tools/gltf_auto_export/tests/test_change_tracking.py index 1b5441c..c1fabff 100644 --- a/tools/gltf_auto_export/tests/test_change_tracking.py +++ b/tools/gltf_auto_export/tests/test_change_tracking.py @@ -5,7 +5,6 @@ import mathutils import pytest import shutil import pathlib -import rna_prop_ui @pytest.fixture def setup_data(request): @@ -136,12 +135,7 @@ def test_export_change_tracking_custom_properties(setup_data): print("main scene change (custom property)") print("----------------") - bpy.context.window_manager.auto_export_tracker.enable_change_detection() # FIXME: should not be needed, but .. bpy.data.objects["Cube"]["test_property"] = 42 - - #force an update - rna_prop_ui.rna_idprop_ui_create(bpy.data.objects["Cube"], "________temp", default=0) - rna_prop_ui.rna_idprop_ui_prop_clear(bpy.data.objects["Cube"], "________temp") auto_export_operator( auto_export=True, @@ -162,9 +156,296 @@ def test_export_change_tracking_custom_properties(setup_data): assert modification_times[world_file_index] != modification_times_first[world_file_index] assert other_files_modification_times == other_files_modification_times_first + +def test_export_change_tracking_light_properties(setup_data): + root_path = "../../testing/bevy_example" + assets_root_path = os.path.join(root_path, "assets") + models_path = os.path.join(assets_root_path, "models") + auto_export_operator = bpy.ops.export_scenes.auto_gltf + + # with change detection + # first, configure things + # we use the global settings for that + export_props = { + "main_scene_names" : ['World'], + "library_scene_names": ['Library'], + } + + # store settings for the auto_export part + stored_auto_settings = bpy.data.texts[".gltf_auto_export_settings"] if ".gltf_auto_export_settings" in bpy.data.texts else bpy.data.texts.new(".gltf_auto_export_settings") + stored_auto_settings.clear() + stored_auto_settings.write(json.dumps(export_props)) + + gltf_settings = { + "export_animations": False, + "export_optimize_animation_size": False + } + # and store settings for the gltf part + stored_gltf_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") + stored_gltf_settings.clear() + stored_gltf_settings.write(json.dumps(gltf_settings)) + + auto_export_operator( + auto_export=True, + direct_mode=True, + export_output_folder="./models", + export_scene_settings=True, + export_blueprints=True, + export_legacy_mode=False, + export_materials_library=False + ) + + world_file_path = os.path.join(models_path, "World.glb") + assert os.path.exists(world_file_path) == True + + models_library_path = os.path.join(models_path, "library") + model_library_file_paths = list(map(lambda file_name: os.path.join(models_library_path, file_name), sorted(os.listdir(models_library_path)))) + modification_times_first = list(map(lambda file_path: os.path.getmtime(file_path), model_library_file_paths + [world_file_path])) + + mapped_files_to_timestamps_and_index = {} + for (index, file_path) in enumerate(model_library_file_paths+ [world_file_path]): + file_path = pathlib.Path(file_path).stem + mapped_files_to_timestamps_and_index[file_path] = (modification_times_first[index], index) + + print("----------------") + print("main scene change (light, energy)") + print("----------------") + + bpy.data.lights["Light"].energy = 100 + + auto_export_operator( + auto_export=True, + direct_mode=True, + export_output_folder="./models", + export_scene_settings=True, + export_blueprints=True, + export_legacy_mode=False, + export_materials_library=False + ) + + modification_times = list(map(lambda file_path: os.path.getmtime(file_path), model_library_file_paths + [world_file_path])) + assert modification_times != modification_times_first + # only the "world" file should have changed + world_file_index = mapped_files_to_timestamps_and_index["World"][1] + other_files_modification_times = [value for index, value in enumerate(modification_times) if index not in [world_file_index]] + other_files_modification_times_first = [value for index, value in enumerate(modification_times_first) if index not in [world_file_index]] + + assert modification_times[world_file_index] != modification_times_first[world_file_index] + assert other_files_modification_times == other_files_modification_times_first + # reset the comparing modification_times_first = modification_times + print("----------------") + print("main scene change (light, shadow_cascade_count)") + print("----------------") + + bpy.data.lights["Light"].shadow_cascade_count = 2 + + auto_export_operator( + auto_export=True, + direct_mode=True, + export_output_folder="./models", + export_scene_settings=True, + export_blueprints=True, + export_legacy_mode=False, + export_materials_library=False + ) + + modification_times = list(map(lambda file_path: os.path.getmtime(file_path), model_library_file_paths + [world_file_path])) + assert modification_times != modification_times_first + # only the "world" file should have changed + world_file_index = mapped_files_to_timestamps_and_index["World"][1] + other_files_modification_times = [value for index, value in enumerate(modification_times) if index not in [world_file_index]] + other_files_modification_times_first = [value for index, value in enumerate(modification_times_first) if index not in [world_file_index]] + + assert modification_times[world_file_index] != modification_times_first[world_file_index] + assert other_files_modification_times == other_files_modification_times_first + + # reset the comparing + modification_times_first = modification_times + + print("----------------") + print("main scene change (light, use_shadow)") + print("----------------") + + bpy.data.lights["Light"].use_shadow = False + + auto_export_operator( + auto_export=True, + direct_mode=True, + export_output_folder="./models", + export_scene_settings=True, + export_blueprints=True, + export_legacy_mode=False, + export_materials_library=False + ) + + modification_times = list(map(lambda file_path: os.path.getmtime(file_path), model_library_file_paths + [world_file_path])) + assert modification_times != modification_times_first + # only the "world" file should have changed + world_file_index = mapped_files_to_timestamps_and_index["World"][1] + other_files_modification_times = [value for index, value in enumerate(modification_times) if index not in [world_file_index]] + other_files_modification_times_first = [value for index, value in enumerate(modification_times_first) if index not in [world_file_index]] + + assert modification_times[world_file_index] != modification_times_first[world_file_index] + assert other_files_modification_times == other_files_modification_times_first + + +def test_export_change_tracking_camera_properties(setup_data): + root_path = "../../testing/bevy_example" + assets_root_path = os.path.join(root_path, "assets") + models_path = os.path.join(assets_root_path, "models") + auto_export_operator = bpy.ops.export_scenes.auto_gltf + + # with change detection + # first, configure things + # we use the global settings for that + export_props = { + "main_scene_names" : ['World'], + "library_scene_names": ['Library'], + } + + # store settings for the auto_export part + stored_auto_settings = bpy.data.texts[".gltf_auto_export_settings"] if ".gltf_auto_export_settings" in bpy.data.texts else bpy.data.texts.new(".gltf_auto_export_settings") + stored_auto_settings.clear() + stored_auto_settings.write(json.dumps(export_props)) + + gltf_settings = { + "export_animations": False, + "export_optimize_animation_size": False + } + # and store settings for the gltf part + stored_gltf_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") + stored_gltf_settings.clear() + stored_gltf_settings.write(json.dumps(gltf_settings)) + + auto_export_operator( + auto_export=True, + direct_mode=True, + export_output_folder="./models", + export_scene_settings=True, + export_blueprints=True, + export_legacy_mode=False, + export_materials_library=False + ) + + world_file_path = os.path.join(models_path, "World.glb") + assert os.path.exists(world_file_path) == True + + models_library_path = os.path.join(models_path, "library") + model_library_file_paths = list(map(lambda file_name: os.path.join(models_library_path, file_name), sorted(os.listdir(models_library_path)))) + modification_times_first = list(map(lambda file_path: os.path.getmtime(file_path), model_library_file_paths + [world_file_path])) + + mapped_files_to_timestamps_and_index = {} + for (index, file_path) in enumerate(model_library_file_paths+ [world_file_path]): + file_path = pathlib.Path(file_path).stem + mapped_files_to_timestamps_and_index[file_path] = (modification_times_first[index], index) + + print("----------------") + print("main scene change (camera)") + print("----------------") + + bpy.data.cameras["Camera"].angle = 0.5 + + auto_export_operator( + auto_export=True, + direct_mode=True, + export_output_folder="./models", + export_scene_settings=True, + export_blueprints=True, + export_legacy_mode=False, + export_materials_library=False + ) + + modification_times = list(map(lambda file_path: os.path.getmtime(file_path), model_library_file_paths + [world_file_path])) + assert modification_times != modification_times_first + # only the "world" file should have changed + world_file_index = mapped_files_to_timestamps_and_index["World"][1] + other_files_modification_times = [value for index, value in enumerate(modification_times) if index not in [world_file_index]] + other_files_modification_times_first = [value for index, value in enumerate(modification_times_first) if index not in [world_file_index]] + + assert modification_times[world_file_index] != modification_times_first[world_file_index] + assert other_files_modification_times == other_files_modification_times_first + + +def test_export_change_tracking_material_properties(setup_data): + root_path = "../../testing/bevy_example" + assets_root_path = os.path.join(root_path, "assets") + models_path = os.path.join(assets_root_path, "models") + auto_export_operator = bpy.ops.export_scenes.auto_gltf + + # with change detection + # first, configure things + # we use the global settings for that + export_props = { + "main_scene_names" : ['World'], + "library_scene_names": ['Library'], + } + + # store settings for the auto_export part + stored_auto_settings = bpy.data.texts[".gltf_auto_export_settings"] if ".gltf_auto_export_settings" in bpy.data.texts else bpy.data.texts.new(".gltf_auto_export_settings") + stored_auto_settings.clear() + stored_auto_settings.write(json.dumps(export_props)) + + gltf_settings = { + "export_animations": False, + "export_optimize_animation_size": False + } + # and store settings for the gltf part + stored_gltf_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") + stored_gltf_settings.clear() + stored_gltf_settings.write(json.dumps(gltf_settings)) + + auto_export_operator( + auto_export=True, + direct_mode=True, + export_output_folder="./models", + export_scene_settings=True, + export_blueprints=True, + export_legacy_mode=False, + export_materials_library=False + ) + + world_file_path = os.path.join(models_path, "World.glb") + assert os.path.exists(world_file_path) == True + + models_library_path = os.path.join(models_path, "library") + model_library_file_paths = list(map(lambda file_name: os.path.join(models_library_path, file_name), sorted(os.listdir(models_library_path)))) + modification_times_first = list(map(lambda file_path: os.path.getmtime(file_path), model_library_file_paths + [world_file_path])) + + mapped_files_to_timestamps_and_index = {} + for (index, file_path) in enumerate(model_library_file_paths+ [world_file_path]): + file_path = pathlib.Path(file_path).stem + mapped_files_to_timestamps_and_index[file_path] = (modification_times_first[index], index) + + print("----------------") + print("main scene change (material)") + print("----------------") + + bpy.data.materials["Material.001"].blend_method = 'CLIP' + + auto_export_operator( + auto_export=True, + direct_mode=True, + export_output_folder="./models", + export_scene_settings=True, + export_blueprints=True, + export_legacy_mode=False, + export_materials_library=False + ) + + modification_times = list(map(lambda file_path: os.path.getmtime(file_path), model_library_file_paths + [world_file_path])) + assert modification_times != modification_times_first + # only the "world" file should have changed + world_file_index = mapped_files_to_timestamps_and_index["World"][1] + other_files_modification_times = [value for index, value in enumerate(modification_times) if index not in [world_file_index]] + other_files_modification_times_first = [value for index, value in enumerate(modification_times_first) if index not in [world_file_index]] + + assert modification_times[world_file_index] != modification_times_first[world_file_index] + assert other_files_modification_times == other_files_modification_times_first + + """ - setup gltf parameters & auto_export parameters - calls exporter on the testing scene @@ -175,7 +456,7 @@ def test_export_change_tracking_custom_properties(setup_data): - removes generated files """ -def test_export_changed_parameters(setup_data): +def test_export_various_changes(setup_data): root_path = "../../testing/bevy_example" assets_root_path = os.path.join(root_path, "assets") models_path = os.path.join(assets_root_path, "models") @@ -354,7 +635,7 @@ def test_export_changed_parameters(setup_data): print("----------------") bpy.context.window_manager.auto_export_tracker.enable_change_detection() # FIXME: should not be needed, but .. - with bpy.context.temp_override(active_object=bpy.data.objects["Cube"]): + with bpy.context.temp_override(active_object=bpy.data.objects["Cube"], selected_objects=[bpy.data.objects["Cube"]]): print("translate using operator") bpy.ops.transform.translate(value=mathutils.Vector((2.0, 1.0, -5.0))) bpy.ops.transform.rotate(value=0.378874, constraint_axis=(False, False, True), mirror=False, proportional_edit_falloff='SMOOTH', proportional_size=1)