Anim: Don't use keying sets when inserting keyframes during autokeying

Prior to this PR, the autokeying system used keying sets
to insert keyframes where required.

With the functions introduced in #113504
the code can be simplified and made to not rely on keying sets,
allowing autokeying to also insert keys by rna path directly.

This also removes all the code related to "Insert Needed" from autokeying.
The insert key functions deal with that now, all that is needed is to pass
in the flag.

Part of #113278

Pull Request: https://projects.blender.org/blender/blender/pulls/115522
This commit is contained in:
Christoph Lendenfeld
2023-12-14 09:04:09 +01:00
committed by Christoph Lendenfeld
parent a8e13994b8
commit 92ad16ab90
4 changed files with 78 additions and 151 deletions
+2 -7
View File
@@ -142,13 +142,10 @@ bool is_autokey_flag(const Scene *scene, eKeyInsert_Flag flag);
*/
bool autokeyframe_cfra_can_key(const Scene *scene, ID *id);
void autokeyframe_object(
bContext *C, Scene *scene, ViewLayer *view_layer, Object *ob, eTfmMode tmode);
void autokeyframe_object(bContext *C, Scene *scene, Object *ob);
/**
* Auto-keyframing feature - for objects
*
* \param tmode: A transform mode.
*
* \note Context may not always be available,
* so must check before using it as it's a luxury for a few cases.
*/
@@ -157,14 +154,12 @@ bool autokeyframe_pchan(bContext *C, Scene *scene, Object *ob, bPoseChannel *pch
/**
* Auto-keyframing feature - for poses/pose-channels
*
* \param tmode: A transform mode.
*
* targetless_ik: has targetless ik been done on any channels?
*
* \note Context may not always be available,
* so must check before using it as it's a luxury for a few cases.
*/
void autokeyframe_pose(bContext *C, Scene *scene, Object *ob, int tmode, short targetless_ik);
void autokeyframe_pose(bContext *C, Scene *scene, Object *ob, short targetless_ik);
/**
* Use for auto-key-framing.
* \param only_if_property_keyed: if true, auto-key-framing only creates keyframes on already keyed
+72 -140
View File
@@ -82,10 +82,20 @@ bool autokeyframe_cfra_can_key(const Scene *scene, ID *id)
return true;
}
void autokeyframe_object(
bContext *C, Scene *scene, ViewLayer *view_layer, Object *ob, const eTfmMode tmode)
static std::string get_rotation_mode_path(const eRotationModes rotmode)
{
switch (rotmode) {
case ROT_MODE_QUAT:
return "rotation_quaternion";
case ROT_MODE_AXISANGLE:
return "rotation_axis_angle";
default:
return "rotation_euler";
}
}
void autokeyframe_object(bContext *C, Scene *scene, Object *ob)
{
/* TODO: this should probably be done per channel instead. */
ID *id = &ob->id;
if (!autokeyframe_cfra_can_key(scene, id)) {
return;
@@ -96,10 +106,9 @@ void autokeyframe_object(
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
depsgraph, BKE_scene_frame_get(scene));
eInsertKeyFlags flag = eInsertKeyFlags(0);
/* Get flags used for inserting keyframes. */
flag = ANIM_get_keyframing_flags(scene, true);
const eInsertKeyFlags flag = ANIM_get_keyframing_flags(scene, true);
/* Add data-source override for the object. */
blender::Vector<PointerRNA> sources;
@@ -112,9 +121,10 @@ void autokeyframe_object(
*/
ANIM_apply_keyingset(
C, &sources, active_ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
return;
}
else if (is_autokey_flag(scene, AUTOKEY_FLAG_INSERTAVAILABLE)) {
if (is_autokey_flag(scene, AUTOKEY_FLAG_INSERTAVAILABLE)) {
/* Only key on available channels. */
AnimData *adt = ob->adt;
ToolSettings *ts = scene->toolsettings;
@@ -134,64 +144,22 @@ void autokeyframe_object(
flag);
}
}
return;
}
else if (is_autokey_flag(scene, AUTOKEY_FLAG_INSERTNEEDED)) {
bool do_loc = false, do_rot = false, do_scale = false;
const float scene_frame = BKE_scene_frame_get(scene);
std::string rotation_rna_path = get_rotation_mode_path(eRotationModes(ob->rotmode));
Vector<std::string> rna_paths = {"location", rotation_rna_path, "scale"};
Main *bmain = CTX_data_main(C);
/* Filter the conditions when this happens (assume that curarea->spacetype==SPACE_VIE3D). */
if (tmode == TFM_TRANSLATION) {
do_loc = true;
}
else if (ELEM(tmode, TFM_ROTATION, TFM_TRACKBALL)) {
if (scene->toolsettings->transform_pivot_point == V3D_AROUND_ACTIVE) {
BKE_view_layer_synced_ensure(scene, view_layer);
if (ob != BKE_view_layer_active_object_get(view_layer)) {
do_loc = true;
}
}
else if (scene->toolsettings->transform_pivot_point == V3D_AROUND_CURSOR) {
do_loc = true;
}
if ((scene->toolsettings->transform_flag & SCE_XFORM_AXIS_ALIGN) == 0) {
do_rot = true;
}
}
else if (tmode == TFM_RESIZE) {
if (scene->toolsettings->transform_pivot_point == V3D_AROUND_ACTIVE) {
BKE_view_layer_synced_ensure(scene, view_layer);
if (ob != BKE_view_layer_active_object_get(view_layer)) {
do_loc = true;
}
}
else if (scene->toolsettings->transform_pivot_point == V3D_AROUND_CURSOR) {
do_loc = true;
}
if ((scene->toolsettings->transform_flag & SCE_XFORM_AXIS_ALIGN) == 0) {
do_scale = true;
}
}
if (do_loc) {
KeyingSet *ks = ANIM_builtin_keyingset_get_named(ANIM_KS_LOCATION_ID);
ANIM_apply_keyingset(C, &sources, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
if (do_rot) {
KeyingSet *ks = ANIM_builtin_keyingset_get_named(ANIM_KS_ROTATION_ID);
ANIM_apply_keyingset(C, &sources, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
if (do_scale) {
KeyingSet *ks = ANIM_builtin_keyingset_get_named(ANIM_KS_SCALING_ID);
ANIM_apply_keyingset(C, &sources, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
}
/* Insert keyframe in all (transform) channels. */
else {
KeyingSet *ks = ANIM_builtin_keyingset_get_named(ANIM_KS_LOC_ROT_SCALE_ID);
ANIM_apply_keyingset(C, &sources, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
for (PointerRNA ptr : sources) {
insert_key_rna(&ptr,
rna_paths.as_span(),
scene_frame,
flag,
eBezTriple_KeyframeType(scene->toolsettings->keyframe_type),
bmain,
reports);
}
}
@@ -231,7 +199,7 @@ bool autokeyframe_pchan(bContext *C, Scene *scene, Object *ob, bPoseChannel *pch
return true;
}
void autokeyframe_pose(bContext *C, Scene *scene, Object *ob, int tmode, short targetless_ik)
void autokeyframe_pose(bContext *C, Scene *scene, Object *ob, short targetless_ik)
{
Main *bmain = CTX_data_main(C);
ID *id = &ob->id;
@@ -247,16 +215,16 @@ void autokeyframe_pose(bContext *C, Scene *scene, Object *ob, int tmode, short t
ToolSettings *ts = scene->toolsettings;
KeyingSet *active_ks = ANIM_scene_get_active_keyingset(scene);
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
depsgraph, BKE_scene_frame_get(scene));
eInsertKeyFlags flag = eInsertKeyFlags(0);
const float scene_frame = BKE_scene_frame_get(scene);
const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
scene_frame);
/* flag is initialized from UserPref keyframing settings
* - special exception for targetless IK - INSERTKEY_MATRIX keyframes should get
* visual keyframes even if flag not set, as it's not that useful otherwise
* (for quick animation recording)
*/
flag = ANIM_get_keyframing_flags(scene, true);
eInsertKeyFlags flag = ANIM_get_keyframing_flags(scene, true);
if (targetless_ik) {
flag |= INSERTKEY_MATRIX;
@@ -278,87 +246,51 @@ void autokeyframe_pose(bContext *C, Scene *scene, Object *ob, int tmode, short t
/* Run the active Keying Set on the current data-source. */
ANIM_apply_keyingset(
C, &sources, active_ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
continue;
}
/* only insert into available channels? */
else if (blender::animrig::is_autokey_flag(scene, AUTOKEY_FLAG_INSERTAVAILABLE)) {
if (act) {
LISTBASE_FOREACH (FCurve *, fcu, &act->curves) {
/* only insert keyframes for this F-Curve if it affects the current bone */
char pchan_name[sizeof(pchan->name)];
if (!BLI_str_quoted_substr(fcu->rna_path, "bones[", pchan_name, sizeof(pchan_name))) {
continue;
}
if (blender::animrig::is_autokey_flag(scene, AUTOKEY_FLAG_INSERTAVAILABLE)) {
if (!act) {
continue;
}
LISTBASE_FOREACH (FCurve *, fcu, &act->curves) {
/* only insert keyframes for this F-Curve if it affects the current bone */
char pchan_name[sizeof(pchan->name)];
if (!BLI_str_quoted_substr(fcu->rna_path, "bones[", pchan_name, sizeof(pchan_name))) {
continue;
}
/* only if bone name matches too...
* NOTE: this will do constraints too, but those are ok to do here too?
*/
if (STREQ(pchan_name, pchan->name)) {
blender::animrig::insert_keyframe(bmain,
reports,
id,
act,
((fcu->grp) ? (fcu->grp->name) : (nullptr)),
fcu->rna_path,
fcu->array_index,
&anim_eval_context,
eBezTriple_KeyframeType(ts->keyframe_type),
flag);
}
/* only if bone name matches too...
* NOTE: this will do constraints too, but those are ok to do here too?
*/
if (STREQ(pchan_name, pchan->name)) {
blender::animrig::insert_keyframe(bmain,
reports,
id,
act,
((fcu->grp) ? (fcu->grp->name) : (nullptr)),
fcu->rna_path,
fcu->array_index,
&anim_eval_context,
eBezTriple_KeyframeType(ts->keyframe_type),
flag);
}
}
continue;
}
/* only insert keyframe if needed? */
else if (blender::animrig::is_autokey_flag(scene, AUTOKEY_FLAG_INSERTNEEDED)) {
bool do_loc = false, do_rot = false, do_scale = false;
/* Filter the conditions when this happens
* (assume that 'curarea->spacetype == SPACE_VIEW3D'). */
if (tmode == TFM_TRANSLATION) {
if (targetless_ik) {
do_rot = true;
}
else {
do_loc = true;
}
}
else if (ELEM(tmode, TFM_ROTATION, TFM_TRACKBALL)) {
if (ELEM(scene->toolsettings->transform_pivot_point, V3D_AROUND_CURSOR, V3D_AROUND_ACTIVE))
{
do_loc = true;
}
if ((scene->toolsettings->transform_flag & SCE_XFORM_AXIS_ALIGN) == 0) {
do_rot = true;
}
}
else if (tmode == TFM_RESIZE) {
if (ELEM(scene->toolsettings->transform_pivot_point, V3D_AROUND_CURSOR, V3D_AROUND_ACTIVE))
{
do_loc = true;
}
if ((scene->toolsettings->transform_flag & SCE_XFORM_AXIS_ALIGN) == 0) {
do_scale = true;
}
}
if (do_loc) {
KeyingSet *ks = ANIM_builtin_keyingset_get_named(ANIM_KS_LOCATION_ID);
ANIM_apply_keyingset(C, &sources, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
if (do_rot) {
KeyingSet *ks = ANIM_builtin_keyingset_get_named(ANIM_KS_ROTATION_ID);
ANIM_apply_keyingset(C, &sources, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
if (do_scale) {
KeyingSet *ks = ANIM_builtin_keyingset_get_named(ANIM_KS_SCALING_ID);
ANIM_apply_keyingset(C, &sources, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
}
/* insert keyframe in all (transform) channels */
else {
KeyingSet *ks = ANIM_builtin_keyingset_get_named(ANIM_KS_LOC_ROT_SCALE_ID);
ANIM_apply_keyingset(C, &sources, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
Main *bmain = CTX_data_main(C);
std::string rotation_rna_path = get_rotation_mode_path(eRotationModes(pchan->rotmode));
Vector<std::string> rna_paths = {"location", rotation_rna_path, "scale"};
for (PointerRNA &ptr : sources) {
insert_key_rna(&ptr,
rna_paths,
scene_frame,
flag,
eBezTriple_KeyframeType(scene->toolsettings->keyframe_type),
bmain,
reports);
}
}
}
@@ -1326,7 +1326,7 @@ static void recalcData_pose(TransInfo *t)
int targetless_ik = (t->flag & T_AUTOIK);
animrecord_check_state(t, &ob->id);
blender::animrig::autokeyframe_pose(t->context, t->scene, ob, t->mode, targetless_ik);
blender::animrig::autokeyframe_pose(t->context, t->scene, ob, targetless_ik);
}
if (motionpath_need_update_pose(t->scene, ob)) {
@@ -1589,7 +1589,7 @@ static void special_aftertrans_update__pose(bContext *C, TransInfo *t)
/* automatic inserting of keys and unkeyed tagging -
* only if transform wasn't canceled (or TFM_DUMMY) */
if (!canceled && (t->mode != TFM_DUMMY)) {
blender::animrig::autokeyframe_pose(C, t->scene, ob, t->mode, targetless_ik);
blender::animrig::autokeyframe_pose(C, t->scene, ob, targetless_ik);
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
}
else {
@@ -780,7 +780,7 @@ static void recalcData_objects(TransInfo *t)
* (FPoints) instead of keyframes? */
if ((t->animtimer) && blender::animrig::is_autokey_on(t->scene)) {
animrecord_check_state(t, &ob->id);
blender::animrig::autokeyframe_object(t->context, t->scene, t->view_layer, ob, t->mode);
blender::animrig::autokeyframe_object(t->context, t->scene, ob);
}
motionpath_update |= motionpath_need_update_object(t->scene, ob);
@@ -855,7 +855,7 @@ static void special_aftertrans_update__object(bContext *C, TransInfo *t)
/* Set auto-key if necessary. */
if (!canceled) {
blender::animrig::autokeyframe_object(C, t->scene, t->view_layer, ob, t->mode);
blender::animrig::autokeyframe_object(C, t->scene, ob);
}
motionpath_update |= motionpath_need_update_object(t->scene, ob);