diff --git a/tests/python/bl_animation_armature.py b/tests/python/bl_animation_armature.py index caf8e493821..4f66ea8d81d 100644 --- a/tests/python/bl_animation_armature.py +++ b/tests/python/bl_animation_armature.py @@ -29,17 +29,36 @@ class BoneCollectionTest(unittest.TestCase): return arm_ob, arm - def add_bones(self, arm_ob: bpy.types.Object) -> None: - # Switch to edit mode to add some bones. + def add_bones(self, arm_ob: bpy.types.Object) -> dict[str, bpy.types.Bone]: + """Add some test bones to the armature.""" + # Switch to edit mode to add some bones. bpy.context.view_layer.objects.active = arm_ob bpy.ops.object.mode_set(mode='EDIT') + self.assertEqual('EDIT', arm_ob.mode, 'Armature should be in edit mode now') + arm = arm_ob.data + bone_names = ('root', 'child_L', 'child_R', 'child_L_L', 'child_L_R', 'child_R_L', 'child_R_R') try: - pass + for bone_name in bone_names: + ebone = arm.edit_bones.new(name=bone_name) + # Bones have to have a length, or they will be removed when exiting edit mode. + ebone.tail = (1, 0, 0) + + arm.edit_bones['child_L'].parent = arm.edit_bones['root'] + arm.edit_bones['child_R'].parent = arm.edit_bones['root'] + arm.edit_bones['child_L_L'].parent = arm.edit_bones['child_L'] + arm.edit_bones['child_L_R'].parent = arm.edit_bones['child_L'] + arm.edit_bones['child_R_L'].parent = arm.edit_bones['child_R'] + arm.edit_bones['child_R_R'].parent = arm.edit_bones['child_R'] + finally: bpy.ops.object.mode_set(mode='OBJECT') + # Return the bones, not the editbones. + return {bone_name: arm.bones[bone_name] + for bone_name in bone_names} + def test_bone_collection_api(self): # Just to keep the rest of the code shorter. bcolls = self.arm.collections @@ -92,6 +111,30 @@ 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_bone_collection_bones(self): + # Build a hierarchy on the armature. + bcolls = self.arm.collections + bcoll_root = bcolls.new('root') + bcoll_child1 = bcolls.new('child1', parent=bcoll_root) + bcoll_child2 = bcolls.new('child2', parent=bcoll_root) + + # Add bones to the armature & assign to collections. + bone_dict = self.add_bones(self.arm_ob) + bcoll_root.assign(bone_dict['root']) + + bcoll_child1_bone_names = ('child_L', 'child_L_L', 'child_L_R') + for bone_name in bcoll_child1_bone_names: + bcoll_child1.assign(bone_dict[bone_name]) + + bcoll_child2_bone_names = ('child_R', 'child_R_L', 'child_R_R') + for bone_name in bcoll_child2_bone_names: + bcoll_child2.assign(bone_dict[bone_name]) + + # Check that the `.bones` property returns the expected ones. + self.assertEqual([self.arm.bones['root']], list(bcoll_root.bones)) + self.assertEqual(set(bcoll_child1_bone_names), {b.name for b in bcoll_child1.bones}) + self.assertEqual(set(bcoll_child2_bone_names), {b.name for b in bcoll_child2.bones}) + def test_bone_collection_armature_join(self): other_arm_ob, other_arm = self.create_armature()