From 63adbb19fb820fcaf5de00315724dc30e5da4694 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Thu, 5 Dec 2024 12:18:48 +0100 Subject: [PATCH] Anim: Always name the slot "Legacy Slot" when versioning legacy Actions When creating Action Slots for legacy Actions, always name those slots "Legacy Slot". Before this commit, the slot was named after the ID that is animated by the Action; this matches what Blender will do when animating that ID from scratch. The old versioning behaviour caused issues when dealing with legacy Actions: if there are multiple Actions in a file (for example multiple run cycle animations) and only one of those was assigned to the character (the rest has a fake user), Blender would only name that one action slot after the character. The "fake user" Actions would just be get a slot named "Slot". This causes issues when toggling between the different Actions, as Blender will not automatically assign a slot when switching from the character- named one to the "Slot" one. Ref: #129563, #130261 Pull Request: https://projects.blender.org/blender/blender/pulls/131425 --- source/blender/blenloader/intern/versioning_400.cc | 9 +++------ tests/python/bl_animation_action.py | 8 ++++---- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/source/blender/blenloader/intern/versioning_400.cc b/source/blender/blenloader/intern/versioning_400.cc index f71ce442d90..c98b10eb277 100644 --- a/source/blender/blenloader/intern/versioning_400.cc +++ b/source/blender/blenloader/intern/versioning_400.cc @@ -139,7 +139,9 @@ static void convert_action_in_place(blender::animrig::Action &action) Slot &slot = action.slot_add(); slot.idtype = idtype; - slot.identifier_ensure_prefix(); + + const std::string slot_identifier{slot.identifier_prefix_for_idtype() + DATA_("Legacy Slot")}; + action.slot_identifier_define(slot, slot_identifier); Layer &layer = action.layer_add("Layer"); blender::animrig::Strip &strip = layer.strip_add(action, @@ -244,11 +246,6 @@ static void version_legacy_actions_to_layered(Main *bmain) blender::Vector &user_infos = item.value; Slot &slot_to_assign = *action.slot(0); - if (user_infos.size() == 1) { - /* Rename the slot after its single user. If there are multiple users, the name is unchanged - * because there is no good way to determine a name. */ - action.slot_identifier_set(*bmain, slot_to_assign, user_infos[0].id->name); - } for (ActionUserInfo &action_user : user_infos) { const ActionSlotAssignmentResult result = generic_assign_action_slot( &slot_to_assign, diff --git a/tests/python/bl_animation_action.py b/tests/python/bl_animation_action.py index efe85cb3614..0ba4d556131 100644 --- a/tests/python/bl_animation_action.py +++ b/tests/python/bl_animation_action.py @@ -513,8 +513,8 @@ class VersioningTest(unittest.TestCase): self.assertEqual(len(strip.channelbags[0].groups), 1) self.assertEqual(len(strip.channelbags[0].groups[0].channels), 9) - # Multi user slots do not get named after their users. - self.assertEqual(action.slots[0].identifier, "OBSlot") + # Slots created from legacy Actions are always called "Legacy SLot". + self.assertEqual(action.slots[0].identifier, "OBLegacy Slot") def test_action_constraint(self): constrained_object = bpy.data.objects["action_constraint_constrained"] @@ -546,8 +546,8 @@ class VersioningTest(unittest.TestCase): self.assertEqual(len(strip.channelbags[0].groups[0].channels), 10) self.assertEqual(len(strip.channelbags[0].groups[1].channels), 10) - # Slots with a single user are named after their user. - self.assertEqual(action.slots[0].identifier, "OBarmature_object") + # Slots on converted Actions are always called "Legacy Slot" + self.assertEqual(action.slots[0].identifier, "OBLegacy Slot") for fcurve in strip.channelbags[0].groups[0].channels: self.assertEqual(fcurve.group.name, "Bone")