From b1572e316e516e0c2b4a5d962a77e9f95a86ecdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20Br=C3=BCckner?= Date: Fri, 10 Apr 2020 23:06:37 +0200 Subject: [PATCH 1/3] Proxy: Add option to keep local trait properties when syncing --- blender/arm/props.py | 1 + blender/arm/props_ui.py | 5 +++++ blender/arm/proxy.py | 31 +++++++++++++++++++++++++++++-- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/blender/arm/props.py b/blender/arm/props.py index af222807..e11302a9 100755 --- a/blender/arm/props.py +++ b/blender/arm/props.py @@ -124,6 +124,7 @@ def init_properties(): bpy.types.Object.arm_proxy_sync_materials = BoolProperty(name="Materials", description="Keep materials synchronized with proxy object", default=True, update=arm.proxy.proxy_sync_materials) bpy.types.Object.arm_proxy_sync_modifiers = BoolProperty(name="Modifiers", description="Keep modifiers synchronized with proxy object", default=True, update=arm.proxy.proxy_sync_modifiers) bpy.types.Object.arm_proxy_sync_traits = BoolProperty(name="Traits", description="Keep traits synchronized with proxy object", default=True, update=arm.proxy.proxy_sync_traits) + bpy.types.Object.arm_proxy_sync_trait_props = BoolProperty(name="Trait Property Values", description="Keep trait property values synchronized with proxy object", default=True, update=arm.proxy.proxy_sync_traits) # For speakers bpy.types.Speaker.arm_play_on_start = BoolProperty(name="Play on Start", description="Play this sound automatically", default=False) bpy.types.Speaker.arm_loop = BoolProperty(name="Loop", description="Loop this sound", default=False) diff --git a/blender/arm/props_ui.py b/blender/arm/props_ui.py index 65b6c313..bea19b16 100644 --- a/blender/arm/props_ui.py +++ b/blender/arm/props_ui.py @@ -1320,6 +1320,9 @@ class ARM_PT_ProxyPanel(bpy.types.Panel): layout.prop(obj, "arm_proxy_sync_materials") layout.prop(obj, "arm_proxy_sync_modifiers") layout.prop(obj, "arm_proxy_sync_traits") + row = layout.row() + row.enabled = obj.arm_proxy_sync_traits + row.prop(obj, "arm_proxy_sync_trait_props") layout.operator("arm.proxy_toggle_all") layout.operator("arm.proxy_apply_all") @@ -1349,6 +1352,7 @@ class ArmProxyToggleAllButton(bpy.types.Operator): obj.arm_proxy_sync_materials = b obj.arm_proxy_sync_modifiers = b obj.arm_proxy_sync_traits = b + obj.arm_proxy_sync_trait_props = b return{'FINISHED'} class ArmProxyApplyAllButton(bpy.types.Operator): @@ -1365,6 +1369,7 @@ class ArmProxyApplyAllButton(bpy.types.Operator): obj.arm_proxy_sync_materials = context.object.arm_proxy_sync_materials obj.arm_proxy_sync_modifiers = context.object.arm_proxy_sync_modifiers obj.arm_proxy_sync_traits = context.object.arm_proxy_sync_traits + obj.arm_proxy_sync_trait_props = context.object.arm_proxy_sync_trait_props return{'FINISHED'} class ArmSyncProxyButton(bpy.types.Operator): diff --git a/blender/arm/proxy.py b/blender/arm/proxy.py index 558bd68f..3304d979 100644 --- a/blender/arm/proxy.py +++ b/blender/arm/proxy.py @@ -1,3 +1,5 @@ +from typing import Any, Dict + import bpy def proxy_sync_loc(self, context): @@ -107,11 +109,36 @@ def sync_collection(cSrc, cDst): for prop in properties: setattr(mDst, prop, getattr(mSrc, prop)) -def sync_traits(obj): +def sync_traits(obj: bpy.types.Object): + """Synchronizes the traits of the given object with the traits of + its proxy. + If `arm.proxy_sync_trait_props` is `False`, the values of the trait + properties are kept where possible. + """ + # (Optionally) keep the old property values + for i in range(len(obj.arm_traitlist)): + values: Dict[str, Dict[str, Any]] = {} + + if not obj.arm_proxy_sync_trait_props: + for prop in obj.arm_traitlist[i].arm_traitpropslist: + values[obj.name][prop.name] = prop.get_value() + sync_collection(obj.proxy.arm_traitlist, obj.arm_traitlist) - for i in range(0, len(obj.arm_traitlist)): + + for i in range(len(obj.arm_traitlist)): sync_collection(obj.proxy.arm_traitlist[i].arm_traitpropslist, obj.arm_traitlist[i].arm_traitpropslist) + # Set stored property values + if not obj.arm_proxy_sync_trait_props: + for prop in obj.arm_traitlist[i].arm_traitpropslist: + if value.get(obj.name) is None: + continue + + value = values[obj.name].get(prop.name) + if value is not None: + prop.set_value(value) + + def sync_materials(obj): # Blender likes to crash here:( pass From df30e9b68158265e1fa181d3c2b43c91ece01a80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20Br=C3=BCckner?= Date: Fri, 10 Apr 2020 23:10:01 +0200 Subject: [PATCH 2/3] Set `arm_proxy_sync_trait_props` to `False` by default --- blender/arm/props.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blender/arm/props.py b/blender/arm/props.py index e11302a9..0cdb249d 100755 --- a/blender/arm/props.py +++ b/blender/arm/props.py @@ -124,7 +124,7 @@ def init_properties(): bpy.types.Object.arm_proxy_sync_materials = BoolProperty(name="Materials", description="Keep materials synchronized with proxy object", default=True, update=arm.proxy.proxy_sync_materials) bpy.types.Object.arm_proxy_sync_modifiers = BoolProperty(name="Modifiers", description="Keep modifiers synchronized with proxy object", default=True, update=arm.proxy.proxy_sync_modifiers) bpy.types.Object.arm_proxy_sync_traits = BoolProperty(name="Traits", description="Keep traits synchronized with proxy object", default=True, update=arm.proxy.proxy_sync_traits) - bpy.types.Object.arm_proxy_sync_trait_props = BoolProperty(name="Trait Property Values", description="Keep trait property values synchronized with proxy object", default=True, update=arm.proxy.proxy_sync_traits) + bpy.types.Object.arm_proxy_sync_trait_props = BoolProperty(name="Trait Property Values", description="Keep trait property values synchronized with proxy object", default=False, update=arm.proxy.proxy_sync_traits) # For speakers bpy.types.Speaker.arm_play_on_start = BoolProperty(name="Play on Start", description="Play this sound automatically", default=False) bpy.types.Speaker.arm_loop = BoolProperty(name="Loop", description="Loop this sound", default=False) From c3eac025b35d44851b3d0464a3a1be19ce6212f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20Br=C3=BCckner?= Date: Sat, 11 Apr 2020 14:22:22 +0200 Subject: [PATCH 3/3] Small improvements + fix for multiple traits per object --- blender/arm/proxy.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/blender/arm/proxy.py b/blender/arm/proxy.py index 3304d979..fab18aed 100644 --- a/blender/arm/proxy.py +++ b/blender/arm/proxy.py @@ -116,12 +116,11 @@ def sync_traits(obj: bpy.types.Object): properties are kept where possible. """ # (Optionally) keep the old property values + values: Dict[bpy.types.Object, Dict[str, Dict[str, Any]]] = {} for i in range(len(obj.arm_traitlist)): - values: Dict[str, Dict[str, Any]] = {} - if not obj.arm_proxy_sync_trait_props: for prop in obj.arm_traitlist[i].arm_traitpropslist: - values[obj.name][prop.name] = prop.get_value() + values[obj][obj.arm_traitlist[i].name][prop.name] = prop.get_value() sync_collection(obj.proxy.arm_traitlist, obj.arm_traitlist) @@ -130,11 +129,16 @@ def sync_traits(obj: bpy.types.Object): # Set stored property values if not obj.arm_proxy_sync_trait_props: - for prop in obj.arm_traitlist[i].arm_traitpropslist: - if value.get(obj.name) is None: - continue + if values.get(obj) is None: + continue - value = values[obj.name].get(prop.name) + value = values[obj].get(obj.arm_traitlist[i].name) + if value is None: + continue + + for prop in obj.arm_traitlist[i].arm_traitpropslist: + + value = values[obj].get(prop.name) if value is not None: prop.set_value(value)