Anim: support layered Actions when symmetrizing Action Constraint

The Symmetrize Action operator also updates Action Constraints, and even
alters its Action to have identical (but mirrored) F-Curves for the bones.
This now uses the new API for layered Actions, (hopefully) correctly
storing the F-Curves and Action Groups.

I suspect there is still a bug in there, but that's now equally there for
legacy & layered Actions.

Pull Request: https://projects.blender.org/blender/blender/pulls/128039
This commit is contained in:
Sybren A. Stüvel
2024-09-23 17:02:53 +02:00
committed by Gitea
parent 82e757e61d
commit 2286868298

View File

@@ -439,7 +439,6 @@ static void updateDuplicateActionConstraintSettings(
EditBone *dup_bone, EditBone *orig_bone, Object *ob, bPoseChannel *pchan, bConstraint *curcon)
{
bActionConstraint *act_con = (bActionConstraint *)curcon->data;
bAction *act = (bAction *)act_con->act;
float mat[4][4];
@@ -512,18 +511,22 @@ static void updateDuplicateActionConstraintSettings(
/* See if there is any channels that uses this bone */
bAction *act = (bAction *)act_con->act;
if (act) {
blender::animrig::Action &action = act->wrap();
blender::animrig::ChannelBag *cbag = blender::animrig::channelbag_for_action_slot(
action, act_con->action_slot_handle);
/* Create a copy and mirror the animation */
Vector<FCurve *> fcurves = blender::animrig::fcurve_find_in_action_slot_filtered(
act, act_con->action_slot_handle, "pose.bones[", orig_bone->name);
for (const FCurve *old_curve : fcurves) {
FCurve *new_curve = BKE_fcurve_copy(old_curve);
bActionGroup *agrp;
char *old_path = new_curve->rna_path;
new_curve->rna_path = BLI_string_replaceN(old_path, orig_bone->name, dup_bone->name);
MEM_freeN(old_path);
/* FIXME: deal with the case where this F-Curve already exists. */
/* Flip the animation */
int i;
BezTriple *bezt;
@@ -558,14 +561,21 @@ static void updateDuplicateActionConstraintSettings(
}
}
/* Make sure that a action group name for the new bone exists */
agrp = BKE_action_group_find_name(act, dup_bone->name);
if (agrp == nullptr) {
agrp = action_groups_add_new(act, dup_bone->name);
if (action.is_action_legacy()) {
/* Make sure that a action group name for the new bone exists */
bActionGroup *agrp = BKE_action_group_find_name(act, dup_bone->name);
if (agrp == nullptr) {
agrp = action_groups_add_new(act, dup_bone->name);
}
BLI_assert(agrp != nullptr);
action_groups_add_channel(act, agrp, new_curve);
continue;
}
BLI_assert(agrp != nullptr);
action_groups_add_channel(act, agrp, new_curve);
BLI_assert_msg(cbag, "If there are F-Curves for this slot, there should be a channelbag");
bActionGroup &agrp = cbag->channel_group_ensure(dup_bone->name);
cbag->fcurve_append(*new_curve);
cbag->fcurve_assign_to_channel_group(*new_curve, agrp);
}
}