Anim: make RNA property bone_collection.parent writable
Moving a bone collection to another parent is now possible in Python by assigning to `bone_collection.parent`. Thanks to Sergey for the implementation.
This commit is contained in:
@@ -266,6 +266,34 @@ static PointerRNA rna_BoneCollection_parent_get(PointerRNA *ptr)
|
||||
return RNA_pointer_create(&arm->id, &RNA_BoneCollection, parent);
|
||||
}
|
||||
|
||||
static void rna_BoneCollection_parent_set(PointerRNA *ptr,
|
||||
PointerRNA value,
|
||||
struct ReportList *reports)
|
||||
{
|
||||
using namespace blender::animrig;
|
||||
|
||||
BoneCollection *self = (BoneCollection *)ptr->data;
|
||||
BoneCollection *to_parent = (BoneCollection *)value.data;
|
||||
|
||||
bArmature *armature = (bArmature *)ptr->owner_id;
|
||||
|
||||
const int from_bcoll_index = armature_bonecoll_find_index(armature, self);
|
||||
const int from_parent_index = armature_bonecoll_find_parent_index(armature, from_bcoll_index);
|
||||
const int to_parent_index = armature_bonecoll_find_index(armature, to_parent);
|
||||
|
||||
if (to_parent_index == from_bcoll_index ||
|
||||
armature_bonecoll_is_decendent_of(armature, from_bcoll_index, to_parent_index))
|
||||
{
|
||||
BKE_report(reports, RPT_ERROR, "Cannot make a bone collection a decendent of itself");
|
||||
return;
|
||||
}
|
||||
|
||||
armature_bonecoll_move_to_parent(
|
||||
armature, from_bcoll_index, -1, from_parent_index, to_parent_index);
|
||||
|
||||
WM_main_add_notifier(NC_OBJECT | ND_BONE_COLLECTION, nullptr);
|
||||
}
|
||||
|
||||
static int rna_BoneCollections_active_index_get(PointerRNA *ptr)
|
||||
{
|
||||
bArmature *arm = (bArmature *)ptr->data;
|
||||
@@ -2269,8 +2297,9 @@ static void rna_def_bonecollection(BlenderRNA *brna)
|
||||
|
||||
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_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_pointer_funcs(
|
||||
prop, "rna_BoneCollection_parent_get", "rna_BoneCollection_parent_set", nullptr, nullptr);
|
||||
RNA_def_property_ui_text(prop,
|
||||
"Parent",
|
||||
"Parent bone collection. Note that accessing this requires a scan of "
|
||||
|
||||
@@ -111,6 +111,37 @@ class BoneCollectionTest(unittest.TestCase):
|
||||
# Check the array order.
|
||||
self.assertEqual([root1, r1_child1, root2, r1_child1_001, r2_child1, r2_child2], list(bcolls.all))
|
||||
|
||||
def test_parent_property(self):
|
||||
# Just to keep the rest of the code shorter.
|
||||
bcolls = self.arm.collections
|
||||
|
||||
self.assertEqual([], list(bcolls), "By default an Armature should have no collections")
|
||||
|
||||
# Build a hierarchy.
|
||||
root1 = bcolls.new('root1')
|
||||
r1_child1 = bcolls.new('r1_child1', parent=root1)
|
||||
r1_child2 = bcolls.new('r1_child2', parent=root1)
|
||||
root2 = bcolls.new('root2')
|
||||
r2_child1 = bcolls.new('r2_child1', parent=root2)
|
||||
r2_child2 = bcolls.new('r2_child2', parent=root2)
|
||||
|
||||
# Check getting the parent.
|
||||
self.assertEqual(root1, r1_child1.parent)
|
||||
self.assertEqual(root1, r1_child2.parent)
|
||||
self.assertEqual(root2, r2_child1.parent)
|
||||
self.assertEqual(root2, r2_child2.parent)
|
||||
|
||||
# Move r1_child1 to be a child of root2 by assigning the parent.
|
||||
r1_child1.parent = root2
|
||||
self.assertEqual(root2, r1_child1.parent)
|
||||
|
||||
# Check the sibling order.
|
||||
self.assertEqual([r2_child1, r2_child2, r1_child1], list(root2.children))
|
||||
|
||||
# Make r1_child1 a root.
|
||||
r1_child1.parent = None
|
||||
self.assertIsNone(r1_child1.parent)
|
||||
|
||||
def test_bone_collection_bones(self):
|
||||
# Build a hierarchy on the armature.
|
||||
bcolls = self.arm.collections
|
||||
|
||||
Reference in New Issue
Block a user