diff --git a/source/blender/makesrna/intern/rna_action.cc b/source/blender/makesrna/intern/rna_action.cc index 32f59dac25c..823e9117ff0 100644 --- a/source/blender/makesrna/intern/rna_action.cc +++ b/source/blender/makesrna/intern/rna_action.cc @@ -601,6 +601,16 @@ static std::optional rna_Channelbag_path(const PointerRNA *ptr) return std::nullopt; } +static PointerRNA rna_Channelbag_slot_get(PointerRNA *ptr) +{ + animrig::Action &action = rna_action(ptr); + animrig::Channelbag &channelbag = rna_data_channelbag(ptr); + animrig::Slot *slot = action.slot_for_handle(channelbag.slot_handle); + BLI_assert(slot); + + return rna_pointer_inherit_refine(ptr, &RNA_ActionSlot, slot); +} + static void rna_iterator_Channelbag_fcurves_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { @@ -2493,6 +2503,12 @@ static void rna_def_action_channelbag(BlenderRNA *brna) prop = RNA_def_property(srna, "slot_handle", PROP_INT, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); + prop = RNA_def_property(srna, "slot", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "ActionSlot"); + RNA_def_property_ui_text(prop, "Slot", "The Slot that the Channelbag's animation data is for"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_pointer_funcs(prop, "rna_Channelbag_slot_get", nullptr, nullptr, nullptr); + /* Channelbag.fcurves */ prop = RNA_def_property(srna, "fcurves", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_funcs(prop, diff --git a/tests/python/bl_animation_action.py b/tests/python/bl_animation_action.py index 7f1af80544d..19072174418 100644 --- a/tests/python/bl_animation_action.py +++ b/tests/python/bl_animation_action.py @@ -559,6 +559,7 @@ class ChannelbagsTest(unittest.TestCase): self.strip.key_insert(self.slot, "location", 1, 47.0, 327.0) self.assertEqual("location", channelbag.fcurves[0].data_path, "Keys for the channelbag's slot should go into the channelbag") + self.assertEqual(self.slot, channelbag.slot) self.strip.channelbags.remove(channelbag) self.assertEqual([], list(self.strip.channelbags)) @@ -570,6 +571,7 @@ class ChannelbagsTest(unittest.TestCase): channelbag = self.strip.channelbag(self.slot, ensure=True) self.assertEqual([channelbag], list(self.strip.channelbags)) + self.assertEqual(self.slot, channelbag.slot) def test_create_remove_fcurves(self): channelbag = self.strip.channelbags.new(self.slot) @@ -676,6 +678,24 @@ class ChannelbagsTest(unittest.TestCase): self.assertEquals([fcurve5, fcurve3], group1.channels[:]) self.assertEquals([fcurve5, fcurve3, fcurve2, fcurve4, fcurve0, fcurve1], channelbag.fcurves[:]) + def test_channelbag_slot_properties(self): + slot_1 = self.slot + slot_2 = self.action.slots.new('MATERIAL', "Test2") + slot_3 = self.action.slots.new('CAMERA', "Test3") + + channelbag_1 = self.strip.channelbags.new(slot_1) + channelbag_2 = self.strip.channelbags.new(slot_2) + channelbag_3 = self.strip.channelbags.new(slot_3) + + self.assertEqual(slot_1.handle, channelbag_1.slot_handle) + self.assertEqual(slot_1, channelbag_1.slot) + + self.assertEqual(slot_2.handle, channelbag_2.slot_handle) + self.assertEqual(slot_2, channelbag_2.slot) + + self.assertEqual(slot_3.handle, channelbag_3.slot_handle) + self.assertEqual(slot_3, channelbag_3.slot) + class DataPathTest(unittest.TestCase): def setUp(self):