mirror of
https://github.com/kaosat-dev/Blender_bevy_components_workflow.git
synced 2024-11-22 20:00:53 +00:00
Compare commits
2 Commits
64fd308fd3
...
8683a6482f
Author | SHA1 | Date | |
---|---|---|---|
|
8683a6482f | ||
|
cf4673c1e3 |
@ -17,8 +17,8 @@ pub struct BlueprintAnimationPlayerLink(pub Entity);
|
||||
|
||||
#[derive(Component, Reflect, Default, Debug)]
|
||||
#[reflect(Component)]
|
||||
/// storage for animations for a given entity (hierarchy), essentially a clone of gltf's `named_animations`
|
||||
pub struct InstanceAnimations {
|
||||
/// storage for scene level animations for a given entity (hierarchy), essentially a clone of gltf's `named_animations`
|
||||
pub struct SceneAnimations {
|
||||
pub named_animations: HashMap<String, Handle<AnimationClip>>,
|
||||
}
|
||||
|
||||
@ -27,7 +27,7 @@ pub struct InstanceAnimations {
|
||||
/// so that the root entity knows which of its children contains an actualy `AnimationPlayer` component
|
||||
/// this is for convenience, because currently , Bevy's gltf parsing inserts `AnimationPlayers` "one level down"
|
||||
/// ie armature/root for animated models, which means more complex queries to trigger animations that we want to avoid
|
||||
pub struct InstanceAnimationPlayerLink(pub Entity);
|
||||
pub struct SceneAnimationPlayerLink(pub Entity);
|
||||
|
||||
/// Stores Animation information: name, frame informations etc
|
||||
#[derive(Reflect, Default, Debug)]
|
||||
@ -78,8 +78,8 @@ pub fn trigger_instance_animation_markers_events(
|
||||
animation_infos: Query<(
|
||||
Entity,
|
||||
&AnimationMarkers,
|
||||
&InstanceAnimationPlayerLink,
|
||||
&InstanceAnimations,
|
||||
&SceneAnimationPlayerLink,
|
||||
&SceneAnimations,
|
||||
&AnimationInfos,
|
||||
)>,
|
||||
animation_players: Query<&AnimationPlayer>,
|
||||
|
@ -120,7 +120,7 @@ impl Plugin for BlueprintsPlugin {
|
||||
.register_type::<MaterialInfo>()
|
||||
.register_type::<SpawnHere>()
|
||||
.register_type::<BlueprintAnimations>()
|
||||
.register_type::<InstanceAnimations>()
|
||||
.register_type::<SceneAnimations>()
|
||||
.register_type::<AnimationInfo>()
|
||||
.register_type::<AnimationInfos>()
|
||||
.register_type::<Vec<AnimationInfo>>()
|
||||
|
@ -3676,7 +3676,7 @@
|
||||
"type": "object",
|
||||
"typeInfo": "Struct"
|
||||
},
|
||||
"bevy_gltf_blueprints::animation::InstanceAnimations": {
|
||||
"bevy_gltf_blueprints::animation::SceneAnimations": {
|
||||
"additionalProperties": false,
|
||||
"isComponent": true,
|
||||
"isResource": false,
|
||||
@ -3690,8 +3690,8 @@
|
||||
"required": [
|
||||
"named_animations"
|
||||
],
|
||||
"short_name": "InstanceAnimations",
|
||||
"title": "bevy_gltf_blueprints::animation::InstanceAnimations",
|
||||
"short_name": "SceneAnimations",
|
||||
"title": "bevy_gltf_blueprints::animation::SceneAnimations",
|
||||
"type": "object",
|
||||
"typeInfo": "Struct"
|
||||
},
|
||||
|
@ -2,7 +2,7 @@ use std::time::Duration;
|
||||
|
||||
use bevy_gltf_blueprints::{
|
||||
AnimationInfos, AnimationMarkerReached, BlueprintAnimationPlayerLink, BlueprintAnimations,
|
||||
InstanceAnimationPlayerLink, InstanceAnimations,
|
||||
SceneAnimationPlayerLink, SceneAnimations,
|
||||
};
|
||||
|
||||
use bevy::{gltf::Gltf, prelude::*};
|
||||
@ -58,7 +58,7 @@ pub fn animations(
|
||||
name, entity
|
||||
);
|
||||
println!("Found match {:?}", gltf.named_animations);
|
||||
commands.entity(entity).insert(InstanceAnimations {
|
||||
commands.entity(entity).insert(SceneAnimations {
|
||||
named_animations: gltf.named_animations.clone(),
|
||||
});
|
||||
for ancestor in parents.iter_ancestors(entity) {
|
||||
@ -66,7 +66,7 @@ pub fn animations(
|
||||
// println!("found match with animationPlayer !! {:?}",names.get(ancestor));
|
||||
commands
|
||||
.entity(entity)
|
||||
.insert(InstanceAnimationPlayerLink(ancestor));
|
||||
.insert(SceneAnimationPlayerLink(ancestor));
|
||||
}
|
||||
// info!("{:?} is an ancestor of {:?}", ancestor, player);
|
||||
}
|
||||
@ -77,17 +77,17 @@ pub fn animations(
|
||||
|
||||
pub fn play_animations(
|
||||
animated_marker1: Query<
|
||||
(&InstanceAnimationPlayerLink, &InstanceAnimations),
|
||||
(&SceneAnimationPlayerLink, &SceneAnimations),
|
||||
(With<AnimationInfos>, With<Marker1>),
|
||||
>,
|
||||
animated_marker2: Query<
|
||||
(&InstanceAnimationPlayerLink, &InstanceAnimations),
|
||||
(&SceneAnimationPlayerLink, &SceneAnimations),
|
||||
(With<AnimationInfos>, With<Marker2>),
|
||||
>,
|
||||
animated_marker3: Query<
|
||||
(
|
||||
&InstanceAnimationPlayerLink,
|
||||
&InstanceAnimations,
|
||||
&SceneAnimationPlayerLink,
|
||||
&SceneAnimations,
|
||||
&BlueprintAnimationPlayerLink,
|
||||
&BlueprintAnimations,
|
||||
),
|
||||
|
@ -5,6 +5,7 @@ import traceback
|
||||
|
||||
from .export_main_scenes import export_main_scene
|
||||
from .export_blueprints import check_if_blueprint_on_disk, check_if_blueprints_exist, export_blueprints_from_collections
|
||||
from .get_standard_exporter_settings import get_standard_exporter_settings
|
||||
|
||||
from ..helpers.helpers_scenes import (get_scenes, )
|
||||
from ..helpers.helpers_collections import (get_collections_in_library, get_exportable_collections, get_collections_per_scene, find_collection_ascendant_target_collection)
|
||||
@ -34,9 +35,8 @@ def auto_export(changes_per_scene, changed_export_parameters, addon_prefs):
|
||||
[main_scene_names, level_scenes, library_scene_names, library_scenes] = get_scenes(addon_prefs)
|
||||
|
||||
# standard gltf export settings are stored differently
|
||||
standard_gltf_exporter_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")
|
||||
print("standard_gltf_exporter_settings", standard_gltf_exporter_settings.as_string())
|
||||
standard_gltf_exporter_settings = json.loads(standard_gltf_exporter_settings.as_string())
|
||||
|
||||
standard_gltf_exporter_settings = get_standard_exporter_settings()
|
||||
|
||||
print("main scenes", main_scene_names, "library_scenes", library_scene_names)
|
||||
print("export_output_folder", export_output_folder)
|
||||
|
@ -1,6 +1,7 @@
|
||||
import os
|
||||
import bpy
|
||||
|
||||
from ..constants import TEMPSCENE_PREFIX
|
||||
from ..helpers.generate_and_export import generate_and_export
|
||||
from .export_gltf import (generate_gltf_export_preferences)
|
||||
from ..helpers.helpers_scenes import clear_hollow_scene, copy_hollowed_collection_into
|
||||
@ -24,7 +25,7 @@ def export_collections(collections, folder_path, library_scene, addon_prefs, glt
|
||||
collection = bpy.data.collections[collection_name]
|
||||
generate_and_export(
|
||||
addon_prefs,
|
||||
temp_scene_name="__temp_scene_"+collection.name,
|
||||
temp_scene_name=TEMPSCENE_PREFIX+collection.name,
|
||||
export_settings=export_settings,
|
||||
gltf_output_path=gltf_output_path,
|
||||
tempScene_filler= lambda temp_collection: copy_hollowed_collection_into(collection, temp_collection, library_collections=library_collections, addon_prefs=addon_prefs),
|
||||
|
@ -2,6 +2,7 @@ import json
|
||||
import os
|
||||
import bpy
|
||||
|
||||
from .get_standard_exporter_settings import get_standard_exporter_settings
|
||||
from .preferences import (AutoExportGltfPreferenceNames)
|
||||
|
||||
def generate_gltf_export_preferences(addon_prefs):
|
||||
@ -48,9 +49,7 @@ def generate_gltf_export_preferences(addon_prefs):
|
||||
gltf_export_preferences[key] = getattr(addon_prefs, key)
|
||||
|
||||
|
||||
standard_gltf_exporter_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")
|
||||
standard_gltf_exporter_settings = json.loads(standard_gltf_exporter_settings.as_string())
|
||||
"""standard_gltf_exporter_settings = get_standard_exporter_settings()"""
|
||||
standard_gltf_exporter_settings = get_standard_exporter_settings()
|
||||
#print("standard settings", standard_gltf_exporter_settings)
|
||||
|
||||
constant_keys = [
|
||||
|
@ -1,6 +1,7 @@
|
||||
import os
|
||||
import bpy
|
||||
|
||||
from ..constants import TEMPSCENE_PREFIX
|
||||
from ..helpers.generate_and_export import generate_and_export
|
||||
from .export_gltf import (generate_gltf_export_preferences, export_gltf)
|
||||
from ..modules.bevy_dynamic import is_object_dynamic, is_object_static
|
||||
@ -38,7 +39,7 @@ def export_main_scene(scene, folder_path, addon_prefs, library_collections):
|
||||
# first export static objects
|
||||
generate_and_export(
|
||||
addon_prefs,
|
||||
temp_scene_name="__temp_scene",
|
||||
temp_scene_name=TEMPSCENE_PREFIX,
|
||||
export_settings=export_settings,
|
||||
gltf_output_path=gltf_output_path,
|
||||
tempScene_filler= lambda temp_collection: copy_hollowed_collection_into(scene.collection, temp_collection, library_collections=library_collections, filter=is_object_static, addon_prefs=addon_prefs),
|
||||
@ -49,7 +50,7 @@ def export_main_scene(scene, folder_path, addon_prefs, library_collections):
|
||||
gltf_output_path = os.path.join(folder_path, export_output_folder, scene.name+ "_dynamic")
|
||||
generate_and_export(
|
||||
addon_prefs,
|
||||
temp_scene_name="__temp_scene",
|
||||
temp_scene_name=TEMPSCENE_PREFIX,
|
||||
export_settings=export_settings,
|
||||
gltf_output_path=gltf_output_path,
|
||||
tempScene_filler= lambda temp_collection: copy_hollowed_collection_into(scene.collection, temp_collection, library_collections=library_collections, filter=is_object_dynamic, addon_prefs=addon_prefs),
|
||||
@ -60,7 +61,7 @@ def export_main_scene(scene, folder_path, addon_prefs, library_collections):
|
||||
#print("NO SPLIT")
|
||||
generate_and_export(
|
||||
addon_prefs,
|
||||
temp_scene_name="__temp_scene",
|
||||
temp_scene_name=TEMPSCENE_PREFIX,
|
||||
export_settings=export_settings,
|
||||
gltf_output_path=gltf_output_path,
|
||||
tempScene_filler= lambda temp_collection: copy_hollowed_collection_into(scene.collection, temp_collection, library_collections=library_collections, addon_prefs=addon_prefs),
|
||||
|
@ -0,0 +1,14 @@
|
||||
import bpy
|
||||
import json
|
||||
|
||||
def get_standard_exporter_settings():
|
||||
standard_gltf_exporter_settings = bpy.data.texts[".gltf_auto_export_gltf_settings"] if ".gltf_auto_export_gltf_settings" in bpy.data.texts else None
|
||||
if standard_gltf_exporter_settings != None:
|
||||
try:
|
||||
standard_gltf_exporter_settings = json.loads(standard_gltf_exporter_settings.as_string())
|
||||
except:
|
||||
standard_gltf_exporter_settings = {}
|
||||
else:
|
||||
standard_gltf_exporter_settings = {}
|
||||
|
||||
return standard_gltf_exporter_settings
|
@ -46,7 +46,6 @@ class AutoExportGLTF(Operator, AutoExportGltfAddonPreferences, ExportHelper):
|
||||
|
||||
bpy.types.WindowManager.main_scenes_list_index = IntProperty(name = "Index for main scenes list", default = 0)
|
||||
bpy.types.WindowManager.library_scenes_list_index = IntProperty(name = "Index for library scenes list", default = 0)
|
||||
bpy.types.WindowManager.previous_export_settings = StringProperty(default="")
|
||||
|
||||
cls.main_scenes_index = 0
|
||||
cls.library_scenes_index = 0
|
||||
@ -59,8 +58,6 @@ class AutoExportGLTF(Operator, AutoExportGltfAddonPreferences, ExportHelper):
|
||||
del bpy.types.WindowManager.main_scenes_list_index
|
||||
del bpy.types.WindowManager.library_scenes_list_index
|
||||
|
||||
del bpy.types.WindowManager.previous_export_settings
|
||||
|
||||
def is_scene_ok(self, scene):
|
||||
try:
|
||||
operator = bpy.context.space_data.active_operator
|
||||
@ -161,9 +158,20 @@ class AutoExportGLTF(Operator, AutoExportGltfAddonPreferences, ExportHelper):
|
||||
|
||||
# if there were no setting before, it is new, we need export
|
||||
changed = False
|
||||
if previous_auto_settings == None or previous_gltf_settings == None:
|
||||
print("previous_auto_settings", previous_auto_settings, "previous_gltf_settings", previous_gltf_settings)
|
||||
if previous_auto_settings == None:
|
||||
print("previous settings missing, exporting")
|
||||
changed = True
|
||||
elif previous_gltf_settings == None:
|
||||
print("previous gltf settings missing, exporting")
|
||||
previous_gltf_settings = bpy.data.texts.new(".gltf_auto_export_gltf_settings_previous")
|
||||
previous_gltf_settings.write(json.dumps({}))
|
||||
if current_gltf_settings == None:
|
||||
current_gltf_settings = bpy.data.texts[".gltf_auto_export_gltf_settings"]
|
||||
current_gltf_settings.write(json.dumps({}))
|
||||
|
||||
changed = True
|
||||
|
||||
else:
|
||||
auto_settings_changed = sorted(json.loads(previous_auto_settings.as_string()).items()) != sorted(json.loads(current_auto_settings.as_string()).items()) if current_auto_settings != None else False
|
||||
gltf_settings_changed = sorted(json.loads(previous_gltf_settings.as_string()).items()) != sorted(json.loads(current_gltf_settings.as_string()).items()) if current_gltf_settings != None else False
|
||||
@ -192,7 +200,6 @@ class AutoExportGLTF(Operator, AutoExportGltfAddonPreferences, ExportHelper):
|
||||
|
||||
def execute(self, context):
|
||||
print("execute")
|
||||
# disable change detection while the operator runs
|
||||
bpy.context.window_manager.auto_export_tracker.disable_change_detection()
|
||||
if self.direct_mode:
|
||||
self.load_settings(context)
|
||||
@ -203,11 +210,13 @@ class AutoExportGLTF(Operator, AutoExportGltfAddonPreferences, ExportHelper):
|
||||
if self.auto_export: # only do the actual exporting if auto export is actually enabled
|
||||
#& do the export
|
||||
if self.direct_mode: #Do not auto export when applying settings in the menu, do it on save only
|
||||
# disable change detection while the operator runs
|
||||
|
||||
#determine changed parameters
|
||||
params_changed = self.did_export_settings_change()
|
||||
auto_export(changes_per_scene, params_changed, self)
|
||||
# cleanup
|
||||
print("AUTO EXPORT DONE")
|
||||
# cleanup
|
||||
print("AUTO EXPORT DONE")
|
||||
if bpy.context.window_manager.auto_export_tracker.exports_count == 0: # we need this in case there was nothing to export, to make sure change detection is enabled again
|
||||
pass #print("YOLOOO")
|
||||
#py.context.window_manager.auto_export_tracker.enable_change_detection()
|
||||
@ -217,14 +226,21 @@ class AutoExportGLTF(Operator, AutoExportGltfAddonPreferences, ExportHelper):
|
||||
#bpy.app.timers.register(bpy.context.window_manager.auto_export_tracker.enable_change_detection, first_interval=1)
|
||||
else:
|
||||
print("auto export disabled, skipping")
|
||||
|
||||
"""if not self.direct_mode:
|
||||
print("enabling")
|
||||
bpy.context.window_manager.auto_export_tracker.enable_change_detection()"""
|
||||
bpy.app.timers.register(bpy.context.window_manager.auto_export_tracker.enable_change_detection, first_interval=1)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
print("invoke")
|
||||
bpy.context.window_manager.auto_export_tracker.disable_change_detection()
|
||||
self.load_settings(context)
|
||||
|
||||
addon_prefs = self
|
||||
[main_scene_names, level_scenes, library_scene_names, library_scenes]=get_scenes(addon_prefs)
|
||||
"""[main_scene_names, level_scenes, library_scene_names, library_scenes]=get_scenes(addon_prefs)
|
||||
(collections, _) = get_exportable_collections(level_scenes, library_scenes, addon_prefs)
|
||||
|
||||
try:
|
||||
@ -235,15 +251,20 @@ class AutoExportGLTF(Operator, AutoExportGltfAddonPreferences, ExportHelper):
|
||||
ui_info = bpy.context.window_manager.exportedCollections.add()
|
||||
ui_info.name = collection_name
|
||||
except Exception as error:
|
||||
self.report({"ERROR"}, "Failed to populate list of exported collections/blueprints")
|
||||
self.report({"ERROR"}, "Failed to populate list of exported collections/blueprints")"""
|
||||
|
||||
wm = context.window_manager
|
||||
wm.fileselect_add(self)
|
||||
|
||||
|
||||
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
def draw(self, context):
|
||||
pass
|
||||
|
||||
def cancel(self, context):
|
||||
print("cancel")
|
||||
#bpy.context.window_manager.auto_export_tracker.enable_change_detection()
|
||||
bpy.app.timers.register(bpy.context.window_manager.auto_export_tracker.enable_change_detection, first_interval=1)
|
||||
|
||||
|
@ -1,8 +1,9 @@
|
||||
import json
|
||||
import bpy
|
||||
from bpy.types import (PropertyGroup)
|
||||
from bpy.props import (PointerProperty, IntProperty)
|
||||
from bpy.props import (PointerProperty, IntProperty, StringProperty)
|
||||
|
||||
from ..constants import TEMPSCENE_PREFIX
|
||||
from .internals import CollectionsToExport
|
||||
|
||||
class AutoExportTracker(PropertyGroup):
|
||||
@ -21,6 +22,8 @@ class AutoExportTracker(PropertyGroup):
|
||||
default=0
|
||||
) # type: ignore
|
||||
|
||||
|
||||
|
||||
@classmethod
|
||||
def register(cls):
|
||||
bpy.types.WindowManager.auto_export_tracker = PointerProperty(type=AutoExportTracker)
|
||||
@ -59,10 +62,15 @@ class AutoExportTracker(PropertyGroup):
|
||||
|
||||
@classmethod
|
||||
def deps_update_handler(cls, scene, depsgraph):
|
||||
print("change detection enabled", cls.change_detection_enabled, bpy.context.window_manager.auto_export_tracker.change_detection_enabled)
|
||||
print("change detection enabled", cls.change_detection_enabled)
|
||||
|
||||
ops = bpy.context.window_manager.operators
|
||||
print("last operators", ops)
|
||||
for op in ops:
|
||||
print("operator", op)
|
||||
active_operator = bpy.context.active_operator
|
||||
if active_operator:
|
||||
# print("Operator", active_operator.bl_label, active_operator.bl_idname)
|
||||
print("Operator", active_operator.bl_label, active_operator.bl_idname)
|
||||
if active_operator.bl_idname == "EXPORT_SCENE_OT_gltf" and active_operator.gltf_export_id == "gltf_auto_export":
|
||||
# we backup any existing gltf export settings, if there were any
|
||||
scene = bpy.context.scene
|
||||
@ -80,19 +88,21 @@ class AutoExportTracker(PropertyGroup):
|
||||
active_operator.will_save_settings = True
|
||||
active_operator.auto_export = True
|
||||
|
||||
if not scene.name.startswith("__temp_scene"):
|
||||
print("depsgraph_update_post", scene.name)
|
||||
changed_scene = scene.name or ""
|
||||
# only deal with changes if we are NOT in the mids of saving/exporting
|
||||
if cls.change_detection_enabled:
|
||||
# ignore anything going on with temporary scenes
|
||||
if not scene.name.startswith(TEMPSCENE_PREFIX):
|
||||
print("depsgraph_update_post", scene.name)
|
||||
changed_scene = scene.name or ""
|
||||
|
||||
# only deal with changes if we are no in the mids of saving/exporting
|
||||
if cls.change_detection_enabled:
|
||||
|
||||
#print("-------------")
|
||||
if not changed_scene in cls.changed_objects_per_scene:
|
||||
cls.changed_objects_per_scene[changed_scene] = {}
|
||||
|
||||
# depsgraph = bpy.context.evaluated_depsgraph_get()
|
||||
print("cls.changed_objects_per_scene", cls.changed_objects_per_scene)
|
||||
depsgraph = bpy.context.evaluated_depsgraph_get()
|
||||
for obj in depsgraph.updates:
|
||||
# print("depsgraph update", obj)
|
||||
print("depsgraph update", obj)
|
||||
if isinstance(obj.id, bpy.types.Object):
|
||||
# get the actual object
|
||||
object = bpy.data.objects[obj.id.name]
|
||||
@ -100,7 +110,7 @@ class AutoExportTracker(PropertyGroup):
|
||||
print("FOO","transforms", obj.is_updated_transform, "geometry", obj.is_updated_geometry)
|
||||
cls.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,)
|
||||
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:
|
||||
@ -113,10 +123,10 @@ class AutoExportTracker(PropertyGroup):
|
||||
items += len(cls.changed_objects_per_scene[scene_name].keys())
|
||||
if items == 0:
|
||||
cls.changed_objects_per_scene.clear()
|
||||
#print("changed_objects_per_scene", cls.changed_objects_per_scene)
|
||||
else:
|
||||
cls.changed_objects_per_scene.clear()
|
||||
|
||||
print("changed_objects_per_scene", cls.changed_objects_per_scene)
|
||||
else:
|
||||
cls.changed_objects_per_scene.clear()
|
||||
|
||||
"""depsgraph = bpy.context.evaluated_depsgraph_get()
|
||||
for update in depsgraph.updates:
|
||||
print("update", update)"""
|
||||
@ -125,13 +135,15 @@ class AutoExportTracker(PropertyGroup):
|
||||
print("disable change detection")
|
||||
self.change_detection_enabled = False
|
||||
self.__class__.change_detection_enabled = False
|
||||
|
||||
return None
|
||||
|
||||
def enable_change_detection(self):
|
||||
print("enable change detection")
|
||||
self.change_detection_enabled = True
|
||||
self.__class__.change_detection_enabled = True
|
||||
#FIXME: not sure about these
|
||||
self.changed_objects_per_scene.clear()
|
||||
self.__class__.changed_objects_per_scene.clear()
|
||||
# bpy.context.window_manager.auto_export_tracker.change_detection_enabled = True
|
||||
print("bpy.context.window_manager.auto_export_tracker.change_detection_enabled", bpy.context.window_manager.auto_export_tracker.change_detection_enabled)
|
||||
return None
|
||||
@ -141,7 +153,7 @@ class AutoExportTracker(PropertyGroup):
|
||||
bpy.context.window_manager.auto_export_tracker.exports_count -= 1
|
||||
if bpy.context.window_manager.auto_export_tracker.exports_count == 0:
|
||||
#print("preparing to reset change detection")
|
||||
#bpy.app.timers.register(bpy.context.window_manager.auto_export_tracker.enable_change_detection, first_interval=1)
|
||||
# bpy.app.timers.register(bpy.context.window_manager.auto_export_tracker.enable_change_detection, first_interval=1)
|
||||
|
||||
self.enable_change_detection()
|
||||
return None
|
||||
|
1
tools/gltf_auto_export/constants.py
Normal file
1
tools/gltf_auto_export/constants.py
Normal file
@ -0,0 +1 @@
|
||||
TEMPSCENE_PREFIX = "__temp_scene"
|
@ -195,11 +195,12 @@ def test_export_changed_parameters(setup_data):
|
||||
|
||||
# now same, but move the cube in the library
|
||||
print("----------------")
|
||||
print("library change")
|
||||
print("library change (blueprint) ")
|
||||
print("----------------")
|
||||
bpy.context.window_manager.auto_export_tracker.enable_change_detection() # FIXME: should not be needed, but ..
|
||||
|
||||
bpy.data.objects["Blueprint1_mesh"].location = [1, 2, 1]
|
||||
|
||||
auto_export_operator(
|
||||
auto_export=True,
|
||||
direct_mode=True,
|
||||
@ -212,16 +213,54 @@ def test_export_changed_parameters(setup_data):
|
||||
|
||||
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
|
||||
# the "world" file should have changed (TODO: double check: this is since changing an instances collection changes the instance too ?)
|
||||
world_file_index = mapped_files_to_timestamps_and_index["World"][1]
|
||||
# and the blueprint1 file too, since that is the collection we changed
|
||||
blueprint1_file_index = mapped_files_to_timestamps_and_index["Blueprint1"][1]
|
||||
other_files_modification_times = [value for index, value in enumerate(modification_times) if index not in [blueprint1_file_index]]
|
||||
other_files_modification_times_first = [value for index, value in enumerate(modification_times_first) if index not in [blueprint1_file_index]]
|
||||
other_files_modification_times = [value for index, value in enumerate(modification_times) if index not in [world_file_index, blueprint1_file_index]]
|
||||
other_files_modification_times_first = [value for index, value in enumerate(modification_times_first) if index not in [world_file_index, blueprint1_file_index]]
|
||||
|
||||
assert modification_times[world_file_index] != modification_times_first[world_file_index]
|
||||
assert modification_times[blueprint1_file_index] != modification_times_first[blueprint1_file_index]
|
||||
assert other_files_modification_times == other_files_modification_times_first
|
||||
# reset the comparing
|
||||
modification_times_first = modification_times
|
||||
|
||||
|
||||
# now change something in a nested blueprint
|
||||
print("----------------")
|
||||
print("library change (nested blueprint) ")
|
||||
print("----------------")
|
||||
bpy.context.window_manager.auto_export_tracker.enable_change_detection() # FIXME: should not be needed, but ..
|
||||
|
||||
bpy.data.objects["Blueprint3_mesh"]["test_component"] = 42
|
||||
|
||||
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
|
||||
# the "world" file should have changed (TODO: double check: this is since changing an instances collection changes the instance too ?)
|
||||
world_file_index = mapped_files_to_timestamps_and_index["World"][1]
|
||||
# and the blueprint1 file too, since that is the collection we changed
|
||||
blueprint1_file_index = mapped_files_to_timestamps_and_index["Blueprint1"][1]
|
||||
other_files_modification_times = [value for index, value in enumerate(modification_times) if index not in [world_file_index, blueprint1_file_index]]
|
||||
other_files_modification_times_first = [value for index, value in enumerate(modification_times_first) if index not in [world_file_index, blueprint1_file_index]]
|
||||
|
||||
assert modification_times[world_file_index] != modification_times_first[world_file_index]
|
||||
assert modification_times[blueprint1_file_index] != modification_times_first[blueprint1_file_index]
|
||||
assert other_files_modification_times == other_files_modification_times_first
|
||||
# reset the comparing
|
||||
modification_times_first = modification_times
|
||||
|
||||
|
||||
|
||||
|
||||
# now same, but using an operator
|
||||
|
@ -47,8 +47,28 @@ def setup_data(request):
|
||||
- checks if timestamps have changed
|
||||
- if all worked => test is a-ok
|
||||
- removes generated files
|
||||
|
||||
"""
|
||||
|
||||
|
||||
def test_export_no_parameters(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
|
||||
|
||||
|
||||
# first test exporting withouth any parameters set, this should export with default parameters gracefully
|
||||
|
||||
auto_export_operator(
|
||||
auto_export=True,
|
||||
direct_mode=True,
|
||||
export_output_folder="./models",
|
||||
export_legacy_mode=False,
|
||||
export_materials_library=True
|
||||
)
|
||||
|
||||
|
||||
|
||||
def test_export_changed_parameters(setup_data):
|
||||
root_path = "../../testing/bevy_example"
|
||||
assets_root_path = os.path.join(root_path, "assets")
|
||||
@ -77,11 +97,6 @@ def test_export_changed_parameters(setup_data):
|
||||
stored_gltf_settings.clear()
|
||||
stored_gltf_settings.write(json.dumps(gltf_settings))
|
||||
|
||||
# move the main cube
|
||||
bpy.data.objects["Cube"].location = [1, 0, 0]
|
||||
# move the cube in the library
|
||||
bpy.data.objects["Blueprint1_mesh"].location = [1, 2, 1]
|
||||
|
||||
auto_export_operator(
|
||||
auto_export=True,
|
||||
direct_mode=True,
|
||||
|
4
tools/gltf_auto_export/todo.md
Normal file
4
tools/gltf_auto_export/todo.md
Normal file
@ -0,0 +1,4 @@
|
||||
- investigate remove_blueprints_list_from_main_scene (could be a case of changes to bpy.data not being applied immediatly)
|
||||
- investigate clearing of changed_objects_per_scene
|
||||
- it seems bevy_components does not trigger updates
|
||||
- undo redo is ignored: ie save, do something, undo it, you still get changes
|
@ -48,6 +48,15 @@ class GLTF_PT_auto_export_SidePanel(bpy.types.Panel):
|
||||
|
||||
op = layout.operator("EXPORT_SCENES_OT_auto_gltf", text="Auto Export Settings")
|
||||
op.auto_export = True
|
||||
|
||||
layout.label(text="changes since last save:")
|
||||
changed_objects_per_scene = {}
|
||||
for scene in context.window_manager.auto_export_tracker.changed_objects_per_scene:
|
||||
if not scene in changed_objects_per_scene.keys():
|
||||
changed_objects_per_scene[scene] = []
|
||||
changed_objects_per_scene[scene]+= context.window_manager.auto_export_tracker.changed_objects_per_scene[scene].keys()
|
||||
|
||||
layout.label(text=str(changed_objects_per_scene))
|
||||
#print("GLTF_PT_export_main", GLTF_PT_export_main.bl_parent_id)
|
||||
|
||||
# main ui in the file => export
|
||||
|
Loading…
Reference in New Issue
Block a user