diff --git a/scripts/addons_core/io_scene_gltf2/blender/exp/animation/action.py b/scripts/addons_core/io_scene_gltf2/blender/exp/animation/action.py index 80713dce778..d7faec35f54 100644 --- a/scripts/addons_core/io_scene_gltf2/blender/exp/animation/action.py +++ b/scripts/addons_core/io_scene_gltf2/blender/exp/animation/action.py @@ -34,7 +34,7 @@ class ActionsData: self.actions[id(action.action)] = action else: for slot in action.slots: - self.actions[id(action.action)].add_slot(slot.slot, slot.id_root, slot.track) + self.actions[id(action.action)].add_slot(slot.slot, slot.target_id_type, slot.track) def get(self): # sort animations alphabetically (case insensitive) so they have a defined order and match Blender's Action list @@ -70,28 +70,28 @@ class ActionData: self.action = action self.slots = [] - def add_slot(self, slot, id_root, track): + def add_slot(self, slot, target_id_type, track): # If slot already exists with None track (so active action/slot) => Replace it with the track (NLA) f = [s for s in self.slots if s.slot.handle == slot.handle and s.track is None] if len(f) > 0: self.slots.remove(f[0]) - new_slot = SlotData(slot, id_root, track) + new_slot = SlotData(slot, target_id_type, track) self.slots.append(new_slot) def sort(self): # Implement sorting, to be sure to get: # TRS first, and then SK sort_items = {'OBJECT': 1, 'KEY': 2} - self.slots.sort(key=lambda x: sort_items.get(x.id_root)) + self.slots.sort(key=lambda x: sort_items.get(x.target_id_type)) def has_slots(self): return len(self.slots) > 0 class SlotData: - def __init__(self, slot, id_root, track): + def __init__(self, slot, target_id_type, track): self.slot = slot - self.id_root = id_root + self.target_id_type = target_id_type self.track = track @@ -188,7 +188,7 @@ def prepare_actions_range(export_settings): for action_data in blender_actions.values(): blender_action = action_data.action for slot in action_data.slots: - type_ = slot.id_root + type_ = slot.target_id_type track = slot.track # Frame range is set on action level, not on slot level @@ -445,7 +445,7 @@ def gather_action_animations(obj_uuid: int, for slot in action_data.slots: blender_action = action_data.action track_name = slot.track - on_type = slot.id_root + on_type = slot.target_id_type # Set action as active, to be able to bake if needed if on_type == "OBJECT": # Not for shapekeys! @@ -605,7 +605,7 @@ def gather_action_animations(obj_uuid: int, all_channels) # If we are in a SK animation (without any TRS animation), and we need to bake - if len([a for a in blender_actions.values() if len([s for s in a.slots if s.id_root == "OBJECT"]) != 0]) == 0 and slot.id_root == "KEY": + if len([a for a in blender_actions.values() if len([s for s in a.slots if s.target_id_type == "OBJECT"]) != 0]) == 0 and slot.target_id_type == "KEY": if export_settings['gltf_bake_animation'] is True and export_settings['gltf_force_sampling'] is True: # We also have to check if this is a skinned mesh, because we don't have to force animation baking on this case # (skinned meshes TRS must be ignored, says glTF specification) @@ -618,7 +618,7 @@ def gather_action_animations(obj_uuid: int, if channels is not None: all_channels.extend(channels) - if len([a for a in blender_actions.values() if len([s for s in a.slots if s.id_root == "KEY"]) != 0]) == 0 \ + if len([a for a in blender_actions.values() if len([s for s in a.slots if s.target_id_type == "KEY"]) != 0]) == 0 \ and export_settings['gltf_morph_anim'] \ and blender_object.type == "MESH" \ and blender_object.data is not None \ @@ -759,7 +759,7 @@ def __get_blender_actions(obj_uuid: str, else: # Store Action info new_action = ActionData(blender_object.animation_data.action) - new_action.add_slot(blender_object.animation_data.action_slot, blender_object.animation_data.action_slot.id_root, None) # Active action => No track + new_action.add_slot(blender_object.animation_data.action_slot, blender_object.animation_data.action_slot.target_id_type, None) # Active action => No track actions.add_action(new_action) # Collect associated strips from NLA tracks. @@ -785,7 +785,7 @@ def __get_blender_actions(obj_uuid: str, # Store Action info new_action = ActionData(strip.action) - new_action.add_slot(strip.action_slot, strip.action_slot.id_root, track.name) + new_action.add_slot(strip.action_slot, strip.action_slot.target_id_type, track.name) actions.add_action(new_action) # For caching, actions linked to SK must be after actions about TRS @@ -803,7 +803,7 @@ def __get_blender_actions(obj_uuid: str, else: # Store Action info new_action = ActionData(blender_object.data.shape_keys.animation_data.action) - new_action.add_slot(blender_object.data.shape_keys.animation_data.action_slot, blender_object.data.shape_keys.animation_data.action_slot.id_root, None) + new_action.add_slot(blender_object.data.shape_keys.animation_data.action_slot, blender_object.data.shape_keys.animation_data.action_slot.target_id_type, None) actions.add_action(new_action) if export_settings['gltf_animation_mode'] == "ACTIONS": @@ -821,7 +821,7 @@ def __get_blender_actions(obj_uuid: str, # Store Action info new_action = ActionData(strip.action) - new_action.add_slot(strip.action_slot, strip.action_slot.id_root, track.name) + new_action.add_slot(strip.action_slot, strip.action_slot.target_id_type, track.name) actions.add_action(new_action) # If there are only 1 armature, include all animations, even if not in NLA @@ -832,7 +832,7 @@ def __get_blender_actions(obj_uuid: str, if len(export_settings['vtree'].get_all_node_of_type(VExportNode.ARMATURE)) == 1: # Keep all actions on objects (no Shapekey animation) for act in bpy.data.actions: - for slot in [s for s in act.slots if s.id_root == "OBJECT"]: + for slot in [s for s in act.slots if s.target_id_type == "OBJECT"]: # We need to check this is an armature action # Checking that at least 1 bone is animated if not __is_armature_slot(act, slot): @@ -847,7 +847,7 @@ def __get_blender_actions(obj_uuid: str, continue # We ignore this action new_action = ActionData(act) - new_action.add_slot(slot, slot.id_root, None) + new_action.add_slot(slot, slot.target_id_type, None) actions.add_action(new_action) export_user_extensions('gather_actions_hook', export_settings, blender_object, actions) @@ -897,18 +897,18 @@ def __get_blender_actions_broadcast(obj_uuid, export_settings): for slot in blender_action.slots: - if slot.id_root == "OBJECT": + if slot.target_id_type == "OBJECT": # Do not export actions on objects without animation data if blender_object.animation_data is None: continue if blender_object and blender_object.type == "ARMATURE" and __is_armature_slot(blender_action, slot): - new_action.add_slot(slot, slot.id_root, None) + new_action.add_slot(slot, slot.target_id_type, None) elif blender_object and blender_object.type == "MESH" and not __is_armature_slot(blender_action, slot): - new_action.add_slot(slot, slot.id_root, None) + new_action.add_slot(slot, slot.target_id_type, None) - elif slot.id_root == "KEY": + elif slot.target_id_type == "KEY": if blender_object.type != "MESH" or blender_object.data is None or blender_object.data.shape_keys is None or blender_object.data.shape_keys.animation_data is None: continue # Checking that the object has some SK and some animation on it @@ -916,7 +916,7 @@ def __get_blender_actions_broadcast(obj_uuid, export_settings): continue if blender_object.type != "MESH": continue - new_action.add_slot(slot, slot.id_root, None) + new_action.add_slot(slot, slot.target_id_type, None) else: pass # TODOSLOT slot-3 diff --git a/scripts/addons_core/io_scene_gltf2/blender/exp/animation/anim_utils.py b/scripts/addons_core/io_scene_gltf2/blender/exp/animation/anim_utils.py index 83a72d2bf39..2aa99e9d6c9 100644 --- a/scripts/addons_core/io_scene_gltf2/blender/exp/animation/anim_utils.py +++ b/scripts/addons_core/io_scene_gltf2/blender/exp/animation/anim_utils.py @@ -75,7 +75,7 @@ def reset_sk_data(blender_object, datas, export_settings) -> None: return else: # For actions - if len([i for i in datas.values() if len([s for s in i.slots if s.id_root == "KEY"]) != 0]) <= 1: + if len([i for i in datas.values() if len([s for s in i.slots if s.target_id_type == "KEY"]) != 0]) <= 1: return if blender_object.type != "MESH": diff --git a/scripts/addons_core/io_scene_gltf2/blender/imp/animation.py b/scripts/addons_core/io_scene_gltf2/blender/imp/animation.py index 99be1af61a2..cc72ca4180c 100644 --- a/scripts/addons_core/io_scene_gltf2/blender/imp/animation.py +++ b/scripts/addons_core/io_scene_gltf2/blender/imp/animation.py @@ -22,7 +22,7 @@ class BlenderAnimation(): # Caches the action/slot for each object, keyed by: # - anim_idx # - obj_name - # - id_root + # - target_id_type gltf.action_cache = {} # Things we need to stash when we're done. gltf.needs_stash = [] diff --git a/scripts/addons_core/io_scene_gltf2/blender/imp/animation_pointer.py b/scripts/addons_core/io_scene_gltf2/blender/imp/animation_pointer.py index 8d06ec49645..8627a5f6c34 100644 --- a/scripts/addons_core/io_scene_gltf2/blender/imp/animation_pointer.py +++ b/scripts/addons_core/io_scene_gltf2/blender/imp/animation_pointer.py @@ -44,20 +44,20 @@ class BlenderPointerAnim(): import_user_extensions('gather_import_animation_pointer_channel_before_hook', gltf, animation, channel) - # For some asset_type, we need to check what is the real id_root + # For some asset_type, we need to check what is the real ID type. if asset_type == "MATERIAL": if len(pointer_tab) == 4 and pointer_tab[1] == "materials" and \ pointer_tab[3] == "alphaCutoff": - id_root = "MATERIAL" + target_id_type = "MATERIAL" else: - id_root = "NODETREE" + target_id_type = "NODETREE" elif asset_type == "MATERIAL_PBR": - id_root = "NODETREE" + target_id_type = "NODETREE" else: - id_root = asset_type + target_id_type = asset_type action, slot = BlenderPointerAnim.get_or_create_action_and_slot( - gltf, anim_idx, asset, asset_idx, id_root, name_=name) + gltf, anim_idx, asset, asset_idx, target_id_type, name_=name) keys = BinaryData.get_data_from_accessor(gltf, animation.samplers[channel.sampler].input) values = BinaryData.get_data_from_accessor(gltf, animation.samplers[channel.sampler].output) @@ -720,27 +720,27 @@ class BlenderPointerAnim(): if asset_type == "CAMERA": name = asset.name stash = asset.blender_object_data - id_root = "CAMERA" + target_id_type = "CAMERA" elif asset_type == "LIGHT": name = asset['name'] stash = asset['blender_object_data'] - id_root = "LIGHT" + target_id_type = "LIGHT" elif asset_type == "MATERIAL": name = asset.name stash = asset.blender_mat - id_root = "MATERIAL" + target_id_type = "MATERIAL" elif asset_type == "NODETREE": name = name_ if name_ is not None else asset.name stash = asset.blender_nodetree - id_root = "NODETREE" + target_id_type = "NODETREE" elif asset_type == "TEX_TRANSFORM": name = name_ if name_ is not None else asset.name stash = asset['blender_nodetree'] - id_root = "NODETREE" + target_id_type = "NODETREE" elif asset_type == "EXT": name = name_ if name_ is not None else asset.name stash = asset['blender_nodetree'] - id_root = "NODETREE" + target_id_type = "NODETREE" objects = gltf.action_cache.get(anim_idx) if not objects: @@ -768,10 +768,10 @@ class BlenderPointerAnim(): action.layers[0].strips[0].channelbags.new(slot) gltf.action_cache[anim_idx]['object_slots'][name] = {} - gltf.action_cache[anim_idx]['object_slots'][name][slot.id_root] = (action, slot) + gltf.action_cache[anim_idx]['object_slots'][name][slot.target_id_type] = (action, slot) else: - # We have slots, check if we have the right slot (based on id_root) - ac_sl = slots.get(id_root) + # We have slots, check if we have the right slot (based on target_id_type) + ac_sl = slots.get(target_id_type) if not ac_sl: action = gltf.action_cache[anim_idx]['action'] slot = action.slots.new(stash.id_type, "Slot") @@ -779,7 +779,7 @@ class BlenderPointerAnim(): action.layers[0].strips[0].channelbags.new(slot) - gltf.action_cache[anim_idx]['object_slots'][name][slot.id_root] = (action, slot) + gltf.action_cache[anim_idx]['object_slots'][name][slot.target_id_type] = (action, slot) else: action, slot = ac_sl diff --git a/scripts/addons_core/io_scene_gltf2/blender/imp/animation_utils.py b/scripts/addons_core/io_scene_gltf2/blender/imp/animation_utils.py index a5d8fb2dfc5..db84b2967dc 100644 --- a/scripts/addons_core/io_scene_gltf2/blender/imp/animation_utils.py +++ b/scripts/addons_core/io_scene_gltf2/blender/imp/animation_utils.py @@ -146,9 +146,9 @@ def get_or_create_action_and_slot(gltf, vnode_idx, anim_idx, path): action.layers[0].strips[0].channelbags.new(slot) gltf.action_cache[anim_idx]['object_slots'][obj.name] = {} - gltf.action_cache[anim_idx]['object_slots'][obj.name][slot.id_root] = (action, slot) + gltf.action_cache[anim_idx]['object_slots'][obj.name][slot.target_id_type] = (action, slot) else: - # We have slots, check if we have the right slot (based on id_root) + # We have slots, check if we have the right slot (based on target_id_type) ac_sl = slots.get(use_id) if not ac_sl: action = gltf.action_cache[anim_idx]['action'] @@ -166,7 +166,7 @@ def get_or_create_action_and_slot(gltf, vnode_idx, anim_idx, path): action.layers[0].strips[0].channelbags.new(slot) - gltf.action_cache[anim_idx]['object_slots'][obj.name][slot.id_root] = (action, slot) + gltf.action_cache[anim_idx]['object_slots'][obj.name][slot.target_id_type] = (action, slot) else: action, slot = ac_sl diff --git a/scripts/startup/bl_ui/space_dopesheet.py b/scripts/startup/bl_ui/space_dopesheet.py index cfb5ec3fe70..db06b44c138 100644 --- a/scripts/startup/bl_ui/space_dopesheet.py +++ b/scripts/startup/bl_ui/space_dopesheet.py @@ -696,8 +696,8 @@ class DOPESHEET_PT_action_slot(Panel): # Draw the ID type of the slot. try: - enum_items = slot.bl_rna.properties['id_root'].enum_items - idtype_label = enum_items[slot.id_root].name + enum_items = slot.bl_rna.properties['target_id_type'].enum_items + idtype_label = enum_items[slot.target_id_type].name except (KeyError, IndexError, AttributeError) as ex: idtype_label = str(ex) @@ -706,7 +706,7 @@ class DOPESHEET_PT_action_slot(Panel): split.label(text="Type") split.alignment = 'LEFT' - split.label(text=idtype_label, icon_value=slot.id_root_icon) + split.label(text=idtype_label, icon_value=slot.target_id_type_icon) ####################################### diff --git a/source/blender/makesrna/intern/rna_action.cc b/source/blender/makesrna/intern/rna_action.cc index 081895d8366..5be9e1d033c 100644 --- a/source/blender/makesrna/intern/rna_action.cc +++ b/source/blender/makesrna/intern/rna_action.cc @@ -69,7 +69,7 @@ const EnumPropertyItem rna_enum_strip_type_items[] = { /* Cannot use rna_enum_dummy_DEFAULT_items because the UNSPECIFIED entry needs * to exist as it is the default. */ -const EnumPropertyItem default_ActionSlot_id_root_items[] = { +const EnumPropertyItem default_ActionSlot_target_id_type_items[] = { {0, "UNSPECIFIED", ICON_NONE, @@ -294,7 +294,7 @@ static std::optional rna_ActionSlot_path(const PointerRNA *ptr) return fmt::format("slots[\"{}\"]", identifier_esc); } -int rna_ActionSlot_id_root_icon_get(PointerRNA *ptr) +int rna_ActionSlot_target_id_type_icon_get(PointerRNA *ptr) { animrig::Slot &slot = rna_data_slot(ptr); return UI_icon_from_idcode(slot.idtype); @@ -1492,17 +1492,24 @@ static std::optional rna_DopeSheet_path(const PointerRNA *ptr) return "dopesheet"; } -static const EnumPropertyItem *rna_ActionSlot_id_root_itemf(bContext * /* C */, - PointerRNA * /* ptr */, - PropertyRNA * /* prop */, - bool *r_free) +/** + * Used for both `action.id_root` and `slot.target_id_type`. + * + * Note that `action.id_root` is deprecated, as it is only relevant to legacy + * Animato actions. So in practice this function is primarily here for + * `slot.target_id_type`. + */ +static const EnumPropertyItem *rna_ActionSlot_target_id_type_itemf(bContext * /* C */, + PointerRNA * /* ptr */, + PropertyRNA * /* prop */, + bool *r_free) { /* These items don't change, as the ID types are hard-coded. So better to * cache the list of enum items. */ - static EnumPropertyItem *_rna_ActionSlot_id_root_items = nullptr; + static EnumPropertyItem *_rna_ActionSlot_target_id_type_items = nullptr; - if (_rna_ActionSlot_id_root_items) { - return _rna_ActionSlot_id_root_items; + if (_rna_ActionSlot_target_id_type_items) { + return _rna_ActionSlot_target_id_type_items; } int totitem = 0; @@ -1520,7 +1527,7 @@ static const EnumPropertyItem *rna_ActionSlot_id_root_itemf(bContext * /* C */, i++; } - RNA_enum_item_add(&items, &totitem, &default_ActionSlot_id_root_items[0]); + RNA_enum_item_add(&items, &totitem, &default_ActionSlot_target_id_type_items[0]); RNA_enum_item_end(&items, &totitem); @@ -1529,11 +1536,11 @@ static const EnumPropertyItem *rna_ActionSlot_id_root_itemf(bContext * /* C */, * Blender use memory after it is freed: * * >>> slot = C.object.animation_data.action_slot - * >>> enum_item = s.bl_rna.properties['id_root'].enum_items[slot.id_root] + * >>> enum_item = s.bl_rna.properties['target_id_type'].enum_items[slot.target_id_type] * >>> print(enum_item.name) */ *r_free = false; - _rna_ActionSlot_id_root_items = items; + _rna_ActionSlot_target_id_type_items = items; BKE_blender_atexit_register(MEM_freeN, items); @@ -1990,18 +1997,18 @@ static void rna_def_action_slot(BlenderRNA *brna) "Used when connecting an Action to a data-block, to find the correct slot handle. This is " "the display name, prefixed by two characters determined by the slot's ID type"); - prop = RNA_def_property(srna, "id_root", PROP_ENUM, PROP_NONE); + prop = RNA_def_property(srna, "target_id_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, nullptr, "idtype"); - RNA_def_property_enum_items(prop, default_ActionSlot_id_root_items); - RNA_def_property_enum_funcs(prop, nullptr, nullptr, "rna_ActionSlot_id_root_itemf"); + RNA_def_property_enum_items(prop, default_ActionSlot_target_id_type_items); + RNA_def_property_enum_funcs(prop, nullptr, nullptr, "rna_ActionSlot_target_id_type_itemf"); RNA_def_property_flag(prop, PROP_ENUM_NO_CONTEXT); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text( - prop, "ID Root Type", "Type of data-block that can be animated by this slot"); + prop, "Target ID Type", "Type of data-block that this slot is intended to animate"); RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_ID); - prop = RNA_def_property(srna, "id_root_icon", PROP_INT, PROP_NONE); - RNA_def_property_int_funcs(prop, "rna_ActionSlot_id_root_icon_get", nullptr, nullptr); + prop = RNA_def_property(srna, "target_id_type_icon", PROP_INT, PROP_NONE); + RNA_def_property_int_funcs(prop, "rna_ActionSlot_target_id_type_icon_get", nullptr, nullptr); RNA_def_property_clear_flag(prop, PROP_EDITABLE); prop = RNA_def_property(srna, "name_display", PROP_STRING, PROP_NONE); @@ -2695,8 +2702,8 @@ static void rna_def_action_legacy(BlenderRNA *brna, StructRNA *srna) * but is still available/editable in 'emergencies' */ prop = RNA_def_property(srna, "id_root", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, nullptr, "idroot"); - RNA_def_property_enum_items(prop, default_ActionSlot_id_root_items); - RNA_def_property_enum_funcs(prop, nullptr, nullptr, "rna_ActionSlot_id_root_itemf"); + RNA_def_property_enum_items(prop, default_ActionSlot_target_id_type_items); + RNA_def_property_enum_funcs(prop, nullptr, nullptr, "rna_ActionSlot_target_id_type_itemf"); RNA_def_property_flag(prop, PROP_ENUM_NO_CONTEXT); RNA_def_property_ui_text(prop, "ID Root Type", diff --git a/tests/python/bl_animation_action.py b/tests/python/bl_animation_action.py index 0ba4d556131..261cd2489a7 100644 --- a/tests/python/bl_animation_action.py +++ b/tests/python/bl_animation_action.py @@ -27,13 +27,13 @@ class ActionSlotCreationTest(unittest.TestCase): slot3 = self.action.slots.new('LIGHT', "Bob") self.assertEqual("OBBob", slot1.identifier) - self.assertEqual('OBJECT', slot1.id_root) + self.assertEqual('OBJECT', slot1.target_id_type) self.assertEqual("CABob", slot2.identifier) - self.assertEqual('CAMERA', slot2.id_root) + self.assertEqual('CAMERA', slot2.target_id_type) self.assertEqual("LABob", slot3.identifier) - self.assertEqual('LIGHT', slot3.id_root) + self.assertEqual('LIGHT', slot3.target_id_type) def test_same_name_same_type(self): slot1 = self.action.slots.new('OBJECT', "Bob") @@ -41,13 +41,13 @@ class ActionSlotCreationTest(unittest.TestCase): slot3 = self.action.slots.new('OBJECT', "Bob") self.assertEqual("OBBob", slot1.identifier) - self.assertEqual('OBJECT', slot1.id_root) + self.assertEqual('OBJECT', slot1.target_id_type) self.assertEqual("OBBob.001", slot2.identifier) - self.assertEqual('OBJECT', slot2.id_root) + self.assertEqual('OBJECT', slot2.target_id_type) self.assertEqual("OBBob.002", slot3.identifier) - self.assertEqual('OBJECT', slot3.id_root) + self.assertEqual('OBJECT', slot3.target_id_type) def test_invalid_arguments(self): with self.assertRaises(TypeError): diff --git a/tests/python/bl_animation_nla_strip.py b/tests/python/bl_animation_nla_strip.py index 976d6c19f46..c725363a859 100644 --- a/tests/python/bl_animation_nla_strip.py +++ b/tests/python/bl_animation_nla_strip.py @@ -124,7 +124,7 @@ class NLAStripActionSlotSelectionTest(AbstractNlaStripTest): strip1 = track.strips.new("name", 1, action) self.assertEqual(action.slots[0], strip1.action_slot) - self.assertEqual('OBJECT', action.slots[0].id_root, "Slot should have been rooted to object") + self.assertEqual('OBJECT', action.slots[0].target_id_type, "Slot should have been rooted to object") strip2 = track.strips.new("name", 10, action) self.assertEqual(action.slots[0], strip2.action_slot) @@ -144,11 +144,13 @@ class NLAStripActionSlotSelectionTest(AbstractNlaStripTest): strip = track.strips.new("name", 1, action1) self.assertEqual(action1.slots[0], strip.action_slot) - self.assertEqual('OBJECT', action1.slots[0].id_root, "Slot of Action 1 should have been rooted to object") + self.assertEqual('OBJECT', action1.slots[0].target_id_type, + "Slot of Action 1 should have been rooted to object") strip.action = action2 self.assertEqual(action2.slots[0], strip.action_slot) - self.assertEqual('OBJECT', action2.slots[0].id_root, "Slot of Action 2 should have been rooted to object") + self.assertEqual('OBJECT', action2.slots[0].target_id_type, + "Slot of Action 2 should have been rooted to object") if __name__ == "__main__":