Anim: fix bug in action.fcurves.clear() corrupting F-Curve groups
Calling `action.fcurves.clear()` would clear the F-Curves, but didn't update the F-Curve groups. This meant that the groups data still had their original length & offsets into the F-Curves array, causing subsequent F-Curve creation to crash Blender. The unit test for this also covers the previous commit. Pull Request: https://projects.blender.org/blender/blender/pulls/128375
This commit is contained in:
@@ -13,6 +13,16 @@ blender -b --factory-startup --python tests/python/bl_animation_keyframing.py --
|
||||
"""
|
||||
|
||||
|
||||
def enable_experimental_animation_baklava():
|
||||
bpy.context.preferences.view.show_developer_ui = True
|
||||
bpy.context.preferences.experimental.use_animation_baklava = True
|
||||
|
||||
|
||||
def disable_experimental_animation_baklava():
|
||||
bpy.context.preferences.view.show_developer_ui = False
|
||||
bpy.context.preferences.experimental.use_animation_baklava = False
|
||||
|
||||
|
||||
def _fcurve_paths_match(fcurves: list, expected_paths: list) -> bool:
|
||||
data_paths = list(set([fcurve.data_path for fcurve in fcurves]))
|
||||
data_paths.sort()
|
||||
@@ -191,6 +201,57 @@ class InsertKeyTest(AbstractKeyframingTest, unittest.TestCase):
|
||||
self.assertFalse(fcurve.keyframe_points[0].select_control_point)
|
||||
self.assertTrue(fcurve.keyframe_points[1].select_control_point)
|
||||
|
||||
def test_keyframe_insert_py_func(self):
|
||||
# Create a Bézier curve.
|
||||
curve_data = bpy.data.curves.new("Curve", 'CURVE')
|
||||
spline = curve_data.splines.new('BEZIER')
|
||||
spline.bezier_points.add(2)
|
||||
spline.bezier_points[0].co = (-1, 0, 0)
|
||||
spline.bezier_points[1].co = (1, 0, 0)
|
||||
|
||||
curve_object = bpy.data.objects.new("Curve", curve_data)
|
||||
bpy.context.scene.collection.objects.link(curve_object)
|
||||
|
||||
# Test on ID sub-data.
|
||||
# self.assertTrue(curve_data.splines[0].bezier_points[0].keyframe_insert('co'))
|
||||
|
||||
# cu_fcurves = curve_data.animation_data.action.fcurves
|
||||
|
||||
# self.assertEqual(len(cu_fcurves), 3,
|
||||
# "Keying 'location' without any array index should have created 3 F-Curves")
|
||||
# self.assertEqual(3 * ['splines[0].bezier_points[0].co'], [fcurve.data_path for fcurve in cu_fcurves])
|
||||
# self.assertEqual([0, 1, 2], [fcurve.array_index for fcurve in cu_fcurves])
|
||||
|
||||
# Test on the Object directly.
|
||||
self.assertTrue(curve_object.keyframe_insert('rotation_quaternion', index=-1))
|
||||
|
||||
ob_fcurves = curve_object.animation_data.action.fcurves
|
||||
|
||||
self.assertEqual(len(ob_fcurves), 4,
|
||||
"Keying 'rotation_quaternion' with index=-1 should have created 4 F-Curves")
|
||||
self.assertEqual(4 * ['rotation_quaternion'], [fcurve.data_path for fcurve in ob_fcurves])
|
||||
self.assertEqual([0, 1, 2, 3], [fcurve.array_index for fcurve in ob_fcurves])
|
||||
|
||||
ob_fcurves.clear()
|
||||
|
||||
self.assertTrue(curve_object.keyframe_insert('scale', index=2))
|
||||
self.assertEqual(len(ob_fcurves), 1,
|
||||
"Keying 'scale' with index=2 should have created 1 F-Curve")
|
||||
self.assertEqual('scale', ob_fcurves[0].data_path)
|
||||
self.assertEqual(2, ob_fcurves[0].array_index)
|
||||
|
||||
|
||||
class LayeredInsertKeyTest(InsertKeyTest):
|
||||
@classmethod
|
||||
def setUpClass(cls) -> None:
|
||||
enable_experimental_animation_baklava()
|
||||
super().setUpClass()
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls) -> None:
|
||||
disable_experimental_animation_baklava()
|
||||
super().tearDownClass()
|
||||
|
||||
|
||||
class VisualKeyingTest(AbstractKeyframingTest, unittest.TestCase):
|
||||
""" Check if visual keying produces the correct keyframe values. """
|
||||
|
||||
Reference in New Issue
Block a user