Anim: Insert keyframes without keying sets

When animators want to key something in the viewport,
the code needs to know *which properties* should be keyed of that selected thing.
So far that was done with keying sets, and a pop-up that let's
you choose the keying set to use. You can get rid of the popup by
choosing a keying set ahead of time. But that is also not always desirable.

That pop-up is quite confusing and gives way too many options.
To simplify this process this PR adds a User Preference option to choose one or more of:
* Location
* Rotation
* Scale
* Rotation Mode
* Custom Properties

Now whenever the `I` key is pressed in the viewport,
and no keying set is enabled, it reads the preferences for which channels to insert.

# User Facing changes
* The popup will not be shown when pressing the hotkey,
 but you can still explicitly use keying sets by going to the menu
* Which channels are keyed is defined by a User Preference setting under animation
* when a keying set is used explicitly, the User Preference settings are ignored

Part of #113278

Pull Request: https://projects.blender.org/blender/blender/pulls/113504
This commit is contained in:
Christoph Lendenfeld
2023-11-21 15:38:01 +01:00
committed by Christoph Lendenfeld
parent 78d9267a56
commit a99e419b6e
12 changed files with 375 additions and 29 deletions
+42 -2
View File
@@ -51,6 +51,16 @@ def _insert_by_name_test(insert_key: str, expected_paths: list):
return match
def _insert_from_user_preference_test(enabled_user_pref_fields: set, expected_paths: list):
keyed_object = _create_animation_object()
bpy.context.preferences.edit.key_insert_channels = enabled_user_pref_fields
with bpy.context.temp_override(**_get_view3d_context()):
bpy.ops.anim.keyframe_insert()
match = _fcurve_paths_match(keyed_object.animation_data.action.fcurves, expected_paths)
bpy.data.objects.remove(keyed_object, do_unlink=True)
return match
def _get_keying_set(scene, name: str):
return scene.keying_sets_all[scene.keying_sets_all.find(name)]
@@ -90,6 +100,13 @@ class InsertKeyTest(AbstractKeyframingTest, unittest.TestCase):
_insert_with_keying_set_test("Location, Rotation & Scale", ["location", "rotation_euler", "scale"])
)
def test_insert_from_user_preferences(self):
self.assertTrue(_insert_from_user_preference_test({"LOCATION"}, ["location"]))
self.assertTrue(_insert_from_user_preference_test({"ROTATION"}, ["rotation_euler"]))
self.assertTrue(_insert_from_user_preference_test({"SCALE"}, ["scale"]))
self.assertTrue(_insert_from_user_preference_test(
{"LOCATION", "ROTATION", "SCALE"}, ["location", "rotation_euler", "scale"]))
class VisualKeyingTest(AbstractKeyframingTest, unittest.TestCase):
""" Check if visual keying produces the correct keyframe values. """
@@ -130,7 +147,7 @@ class VisualKeyingTest(AbstractKeyframingTest, unittest.TestCase):
bpy.data.objects.remove(target, do_unlink=True)
bpy.data.objects.remove(constrained, do_unlink=True)
def test_visual_location_user_pref(self):
def test_visual_location_user_pref_override(self):
# When enabling the user preference setting,
# the normal keying sets behave like their visual keying set counterpart.
bpy.context.preferences.edit.use_visual_keying = True
@@ -151,6 +168,27 @@ class VisualKeyingTest(AbstractKeyframingTest, unittest.TestCase):
bpy.data.objects.remove(constrained, do_unlink=True)
bpy.context.preferences.edit.use_visual_keying = False
def test_visual_location_user_pref(self):
target = _create_animation_object()
t_value = 1
target.location = (t_value, t_value, t_value)
constrained = _create_animation_object()
constraint = constrained.constraints.new("COPY_LOCATION")
constraint.target = target
bpy.context.preferences.edit.use_visual_keying = True
bpy.context.preferences.edit.key_insert_channels = {"LOCATION"}
with bpy.context.temp_override(**_get_view3d_context()):
bpy.ops.anim.keyframe_insert()
for fcurve in constrained.animation_data.action.fcurves:
self.assertEqual(fcurve.keyframe_points[0].co.y, t_value)
bpy.data.objects.remove(target, do_unlink=True)
bpy.data.objects.remove(constrained, do_unlink=True)
bpy.context.preferences.edit.use_visual_keying = False
class CycleAwareKeyingTest(AbstractKeyframingTest, unittest.TestCase):
""" Check if cycle aware keying remaps the keyframes correctly and adds fcurve modifiers. """
@@ -175,8 +213,10 @@ class CycleAwareKeyingTest(AbstractKeyframingTest, unittest.TestCase):
bpy.ops.anim.keyframe_insert_by_name(type="Location")
# Will be mapped to frame 3.
# This will insert the key based on the user preference settings.
bpy.context.preferences.edit.key_insert_channels = {"LOCATION"}
bpy.context.scene.frame_set(22)
bpy.ops.anim.keyframe_insert_by_name(type="Location")
bpy.ops.anim.keyframe_insert()
# Will be mapped to frame 9.
bpy.context.scene.frame_set(-10)