Blender cannot handle bones with (near) zero length. Prior to this
commit such bones were deleted when exiting Armature Edit mode. Now
they are kept and elongated so that they are numerically stable (or at
least they should be, given the threshold to the length that was
already in place).
To avoid the elongation from impacting the position of child bones,
they are disconnected from the tiny bone.
Apart from that it's quite nice for users that Blender no longer
silently deletes bones, this is also useful for the USD importer, as
it can import bones and expect them to exist afterwards (see
#147048).
Note: this only impacts armatures with bones of length ≤ 0.000001
units.
Pull Request: https://projects.blender.org/blender/blender/pulls/147814
The bone collection unit tests in Python were failing, but this failure
was not propagated to `ctest` and thus went unnoticed.
Both issues are now fixed.
Instead of moving bone collections by absolute index, they can now be
moved by manipulating `.child_number`. This is the relative index of the
bone collection within the list of its siblings.
This replaces the much more cumbersome `collections.move_to_parent()`
function. Since that function is now no longer necessary (it's been
replaced by assignment to `.parent` and `.child_number`), it's removed
from RNA. Note that this function was never part of even a beta build of
Blender.
Moving a bone collection to another parent is now possible in Python by
assigning to `bone_collection.parent`.
Thanks to Sergey for the implementation.
Add a `bone_collection.bones_recursive` property that returns the set of
bones assigned to that bone collection or any of its child collections.
This property is implemented in Python, as that made it considerably
simpler to create the set semantics.
Use `bpy.ops.wm.read_homefile(use_factory_startup=True)` to load the
default 'homefile'. Otherwise Blender will load the saved-as-default file,
which can be quite different from the default startup file.
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.
Add a Python unit test that covers some of the armature/bone collections.
Some of these tests cover the same functionality as the C++ tests, albeit
via the Python/RNA API.
Another test was added to check that joining armatures works as expected.