Fix #100115: Show non "Relative" animation keys in the shapekey action editor

Because the shapekey editor is trying to have a more fancy UI with
sliders on each "Relative" shapekey value, all other animatible
properties were not drawn.

This patch now makes it possible to easily work with actions that have
non "Relative" keys. Before this was almost impossible as the user could
not see what action they had selected or which non relative keys were in
them as the UI would think that the action was empty.

While working on this I also noticed that there are some other
properties in relative mode that is not in the action editor either
(Range Min/Max). I added a TODO about that in the code as one would
probably want to group those together in a nice way with either
respective shapekey.

Pull Request: https://projects.blender.org/blender/blender/pulls/121829
This commit is contained in:
Sebastian Parborg
2024-05-21 14:05:36 +02:00
committed by Sebastian Parborg
parent ba1356e339
commit 7ff8a7b173

View File

@@ -105,7 +105,6 @@ static Key *actedit_get_shapekeys(bAnimContext *ac)
Scene *scene = ac->scene;
ViewLayer *view_layer = ac->view_layer;
Object *ob;
Key *key;
BKE_view_layer_synced_ensure(scene, view_layer);
ob = BKE_view_layer_active_object_get(view_layer);
@@ -117,15 +116,7 @@ static Key *actedit_get_shapekeys(bAnimContext *ac)
// if (saction->pin) { return nullptr; }
/* shapekey data is stored with geometry data */
key = BKE_key_from_object(ob);
if (key) {
if (key->type == KEY_RELATIVE) {
return key;
}
}
return nullptr;
return BKE_key_from_object(ob);
}
/* Get data being edited in Action Editor (depending on current 'mode') */
@@ -1687,29 +1678,53 @@ static size_t animdata_filter_shapekey(bAnimContext *ac,
if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
bDopeSheet *ads = ac->ads;
/* loop through the channels adding ShapeKeys as appropriate */
LISTBASE_FOREACH (KeyBlock *, kb, &key->block) {
/* skip the first one, since that's the non-animatable basis */
if (kb == key->block.first) {
continue;
}
if (key->type == KEY_RELATIVE) {
/* TODO: This currently doesn't take into account the animatable "Range Min/Max" keys on the
* keyblocks. */
/* Skip shapekey if the name doesn't match the filter string. */
if (ads != nullptr && ads->searchstr[0] != '\0' &&
name_matches_dopesheet_filter(ads, kb->name) == false)
/* loop through the channels adding ShapeKeys as appropriate */
LISTBASE_FOREACH (KeyBlock *, kb, &key->block) {
/* skip the first one, since that's the non-animatable basis */
if (kb == key->block.first) {
continue;
}
/* Skip shapekey if the name doesn't match the filter string. */
if (ads != nullptr && ads->searchstr[0] != '\0' &&
name_matches_dopesheet_filter(ads, kb->name) == false)
{
continue;
}
/* only work with this channel and its subchannels if it is editable */
if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_SHAPEKEY(kb)) {
/* Only include this track if selected in a way consistent
* with the filtering requirements. */
if (ANIMCHANNEL_SELOK(SEL_SHAPEKEY(kb))) {
/* TODO: consider 'active' too? */
/* owner-id here must be key so that the F-Curve can be resolved... */
ANIMCHANNEL_NEW_CHANNEL(kb, ANIMTYPE_SHAPEKEY, key, nullptr);
}
}
}
}
else {
/* key->type == KEY_NORMAL */
if (!key->adt || !key->adt->action) {
return 0;
}
bAction *action = key->adt->action;
FCurve *first_fcu = static_cast<FCurve *>(action->curves.first);
for (FCurve *fcu = first_fcu;
(fcu = animfilter_fcurve_next(
ads, fcu, ANIMTYPE_FCURVE, filter_mode, nullptr, (ID *)key));
fcu = fcu->next)
{
continue;
}
/* only work with this channel and its subchannels if it is editable */
if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_SHAPEKEY(kb)) {
/* Only include this track if selected in a way consistent
* with the filtering requirements. */
if (ANIMCHANNEL_SELOK(SEL_SHAPEKEY(kb))) {
/* TODO: consider 'active' too? */
/* owner-id here must be key so that the F-Curve can be resolved... */
ANIMCHANNEL_NEW_CHANNEL(kb, ANIMTYPE_SHAPEKEY, key, nullptr);
/* Check if this is a "KEY_NORMAL" type keyframe */
if (STREQ(fcu->rna_path, "eval_time") || BLI_str_endswith(fcu->rna_path, ".interpolation"))
{
ANIMCHANNEL_NEW_CHANNEL(fcu, ANIMTYPE_FCURVE, (ID *)key, &action->id);
}
}
}