Anim: Add `bone_collection.parent` accessor to RNA

Add a read-only property `bone_collection.parent` to RNA that returns
the parent bone collection.

This performs two scans of the array (one to find the bone collection's
index, and the other to find the parent index). This might look bad, but
as long as `Object.children` still loops, in Python, over all of
`bpy.data.objects`, this should also be acceptable.
This commit is contained in:
Sybren A. Stüvel 2024-01-02 12:47:35 +01:00
parent 5fb64d76e7
commit 9f38c6e887
2 changed files with 32 additions and 0 deletions

View File

@ -246,6 +246,26 @@ static int rna_iterator_bone_collection_children_length(PointerRNA *ptr)
return bcoll->child_count;
}
static PointerRNA rna_BoneCollection_parent_get(PointerRNA *ptr)
{
bArmature *arm = (bArmature *)ptr->owner_id;
const BoneCollection *bcoll = (BoneCollection *)ptr->data;
/* Note that this performs two scans of the array. This might look bad, but as
* long as `Object.children` still loops in Python over all of
* `bpy.data.objects`, this should also be acceptable. */
using namespace blender::animrig;
const int bcoll_index = armature_bonecoll_find_index(arm, bcoll);
const int parent_index = armature_bonecoll_find_parent_index(arm, bcoll_index);
if (parent_index < 0) {
return PointerRNA_NULL;
}
BoneCollection *parent = arm->collection_array[parent_index];
return RNA_pointer_create(&arm->id, &RNA_BoneCollection, parent);
}
static int rna_BoneCollections_active_index_get(PointerRNA *ptr)
{
bArmature *arm = (bArmature *)ptr->data;
@ -2240,6 +2260,15 @@ static void rna_def_bonecollection(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON);
prop = RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "BoneCollection");
RNA_def_property_pointer_funcs(prop, "rna_BoneCollection_parent_get", nullptr, nullptr, nullptr);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop,
"Parent",
"Parent bone collection. Note that accessing this requires a scan of "
"all the bone collections to find the parent");
RNA_api_bonecollection(srna);
}

View File

@ -61,6 +61,8 @@ class BoneCollectionTest(unittest.TestCase):
self.assertEqual([r1_child1, r1_child1_001], list(root1.children), 'root1.children should have its children')
self.assertEqual([r2_child1, r2_child2], list(root2.children), 'root2.children should have its children')
self.assertEqual([], list(r1_child1.children))
self.assertIsNone(root1.parent)
self.assertEqual(root1, r1_child1.parent)
# Check the array order.
self.assertEqual([root1, root2, r1_child1, r1_child1_001, r2_child1, r2_child2], list(bcolls.all))
@ -73,6 +75,7 @@ class BoneCollectionTest(unittest.TestCase):
self.assertEqual([root2], list(r1_child1.children))
self.assertEqual([r1_child1, r1_child1_001], list(root1.children), 'root1.children should have its children')
self.assertEqual([r2_child1, r2_child2], list(root2.children), 'root2.children should have its children')
self.assertEqual(r1_child1, root2.parent)
# Check the array order.
self.assertEqual([root1, r1_child1, r1_child1_001, r2_child1, r2_child2, root2], list(bcolls.all))