Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmélie Fondevilla <afonde>2022-06-30 16:16:05 +0300
committerSybren A. Stüvel <sybren@blender.org>2022-06-30 16:20:18 +0300
commit92d7f9ac56e0ff1e65c364487542dfb7c32a0a67 (patch)
tree3ebfbcd3dea61891613409cccdb6b996096b1203 /source/blender/editors/space_action/action_select.c
parent416aef4e13ccc30e82ecaa691f26af54dbd5ee7e (diff)
Animation: Add GP layers in regular Dopesheet
Grease Pencil animation channels are now also shown in the Dopesheet mode of the Dopesheet editor and in the Timeline. Grease pencil related events are now listened not only by container `SACTCONT_GPENCIL` (Grease Pencil Dopesheet), but also `SACTCONT_DOPESHEET` (main Dopesheet), and `SACTCONT_TIMELINE` (timeline). A new Animation Filter flag was added: `ANIMFILTER_FCURVESONLY`. For now this only filters out Grease Pencil Layer channels. **Implemented:** - Preview range set: now only considers selected Grease Pencil keyframes when `onlySel` parameter is true. Not only this allows the operator to work with grease pencil keyframes in main dopesheet, but it also fixes the operator in the Grease Pencil dopesheet. - Translation: allocation (and freeing) of specific memory for translation of Grease Pencil keyframes. - Copy/Paste: call to both Fcurve and GPencil operators, to allow for mixed selection. Errors are only reported when both the FCurve and GPencil functions fail to paste anything. - Keyframe Type change and Insert Keyframe: removed some code here to unify Grease Pencil dopesheet and main dopesheet code. - Jump, Snap, Mirror, Select all/box/lasso/circle, Select left/right, Clickselect: account for Grease Pencil channels within the channels loop, no need for `ANIMFILTER_FCURVESONLY` there. **Not Implemented:** - Graph-related operators. The filter `ANIMFILTER_FCURVESONLY` is naively added to all graph-related operators, meaning more-or-less all operators that used `ANIMFILTER_CURVE_VISIBLE`. - Select linked: is for F-curves channel only - Select more/less: not yet implemented for grease pencil layers. - Clean Keys, Sample, Extrapolation, Interpolation, Easing, and Handle type change: work on Fcurve-channels only, so the `ANIMFILTER_FCURVESONLY` filter is activated Graying out these operators (when no fcurve keyframe is selected) can be done with custom poll functions BUT may affect performance. This is NOT done in this patch. **Dopesheet Summary Selection:** The main summary of the dopesheet now also takes into account Grease Pencil keyframes, using some nasty copy/pasting of code, as explained [on devtalk](https://devtalk.blender.org/t/gpencil-layers-integration-in-main-dopesheet-selection-issue/24527). It works, but may be improved, providing some deeper changes. Reviewed By: mendio, pepeland, sybren Maniphest Tasks: T97477 Differential Revision: https://developer.blender.org/D15003
Diffstat (limited to 'source/blender/editors/space_action/action_select.c')
-rw-r--r--source/blender/editors/space_action/action_select.c222
1 files changed, 112 insertions, 110 deletions
diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c
index aff888818e0..f5dc2104d66 100644
--- a/source/blender/editors/space_action/action_select.c
+++ b/source/blender/editors/space_action/action_select.c
@@ -235,13 +235,7 @@ static void deselect_action_keys(bAnimContext *ac, short test, short sel)
KeyframeEditFunc test_cb, sel_cb;
/* determine type-based settings */
- if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS);
- }
- else {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/ |
- ANIMFILTER_NODUPLIS);
- }
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS);
/* filter data */
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
@@ -416,7 +410,7 @@ static void box_select_elem(
break;
}
- if (ale->type == ANIMTYPE_SUMMARY && ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
+ if (ale->type == ANIMTYPE_SUMMARY) {
ListBase anim_data = {NULL, NULL};
ANIM_animdata_filter(ac, &anim_data, ANIMFILTER_DATA_VISIBLE, ac->data, ac->datatype);
@@ -428,8 +422,10 @@ static void box_select_elem(
ANIM_animdata_freelist(&anim_data);
}
- ANIM_animchannel_keyframes_loop(
- &sel_data->ked, ac->ads, ale, sel_data->ok_cb, sel_data->select_cb, NULL);
+ if (!ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
+ ANIM_animchannel_keyframes_loop(
+ &sel_data->ked, ac->ads, ale, sel_data->ok_cb, sel_data->select_cb, NULL);
+ }
}
}
}
@@ -658,7 +654,7 @@ static void region_select_elem(RegionSelectData *sel_data, bAnimListElem *ale, b
break;
}
- if (ale->type == ANIMTYPE_SUMMARY && ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
+ if (ale->type == ANIMTYPE_SUMMARY) {
ListBase anim_data = {NULL, NULL};
ANIM_animdata_filter(ac, &anim_data, ANIMFILTER_DATA_VISIBLE, ac->data, ac->datatype);
@@ -670,8 +666,10 @@ static void region_select_elem(RegionSelectData *sel_data, bAnimListElem *ale, b
ANIM_animdata_freelist(&anim_data);
}
- ANIM_animchannel_keyframes_loop(
- &sel_data->ked, ac->ads, ale, sel_data->ok_cb, sel_data->select_cb, NULL);
+ if (!ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
+ ANIM_animchannel_keyframes_loop(
+ &sel_data->ked, ac->ads, ale, sel_data->ok_cb, sel_data->select_cb, NULL);
+ }
}
}
}
@@ -946,28 +944,36 @@ static void markers_selectkeys_between(bAnimContext *ac)
ked.f2 = max;
/* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY */ |
- ANIMFILTER_NODUPLIS);
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* select keys in-between */
for (ale = anim_data.first; ale; ale = ale->next) {
- AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+ switch (ale->type) {
+ case ANIMTYPE_GPLAYER:
+ ED_gpencil_layer_frames_select_box(ale->data, min, max, SELECT_ADD);
+ ale->update |= ANIM_UPDATE_DEPS;
+ break;
- if (adt) {
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
- }
- else if (ale->type == ANIMTYPE_GPLAYER) {
- ED_gpencil_layer_frames_select_box(ale->data, min, max, SELECT_ADD);
- ale->update |= ANIM_UPDATE_DEPS;
- }
- else if (ale->type == ANIMTYPE_MASKLAYER) {
- ED_masklayer_frames_select_box(ale->data, min, max, SELECT_ADD);
- }
- else {
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
+ case ANIMTYPE_MASKLAYER:
+ ED_masklayer_frames_select_box(ale->data, min, max, SELECT_ADD);
+ break;
+
+ case ANIMTYPE_FCURVE: {
+ AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+ if (adt) {
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
+ }
+ else {
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
+ }
+ break;
+ }
+
+ default:
+ BLI_assert_msg(false, "Keys cannot be selected into this animation type.");
}
}
@@ -1000,11 +1006,16 @@ static void columnselect_action_keys(bAnimContext *ac, short mode)
}
}
else {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/);
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
for (ale = anim_data.first; ale; ale = ale->next) {
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, bezt_to_cfraelem, NULL);
+ if (ale->datatype == ALE_GPFRAME) {
+ ED_gpencil_layer_make_cfra_list(ale->data, &ked.list, 1);
+ }
+ else {
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, bezt_to_cfraelem, NULL);
+ }
}
}
ANIM_animdata_freelist(&anim_data);
@@ -1033,12 +1044,7 @@ static void columnselect_action_keys(bAnimContext *ac, short mode)
/* loop through all of the keys and select additional keyframes
* based on the keys found to be selected above
*/
- if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE);
- }
- else {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/);
- }
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
for (ale = anim_data.first; ale; ale = ale->next) {
@@ -1144,7 +1150,7 @@ static int actkeys_select_linked_exec(bContext *C, wmOperator *UNUSED(op))
}
/* loop through all of the keys and select additional keyframes based on these */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/ |
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FCURVESONLY |
ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
@@ -1200,7 +1206,7 @@ static void select_moreless_action_keys(bAnimContext *ac, short mode)
build_cb = ANIM_editkeyframes_buildselmap(mode);
/* loop through all of the keys and select additional keyframes based on these */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/ |
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FCURVESONLY |
ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
@@ -1354,33 +1360,36 @@ static void actkeys_select_leftright(bAnimContext *ac, short leftright, short se
}
/* filter data */
- if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS);
- }
- else {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/ |
- ANIMFILTER_NODUPLIS);
- }
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* select keys */
for (ale = anim_data.first; ale; ale = ale->next) {
- AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+ switch (ale->type) {
+ case ANIMTYPE_GPLAYER:
+ ED_gpencil_layer_frames_select_box(ale->data, ked.f1, ked.f2, select_mode);
+ ale->update |= ANIM_UPDATE_DEPS;
+ break;
- if (adt) {
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
- }
- else if (ale->type == ANIMTYPE_GPLAYER) {
- ED_gpencil_layer_frames_select_box(ale->data, ked.f1, ked.f2, select_mode);
- ale->update |= ANIM_UPDATE_DEPS;
- }
- else if (ale->type == ANIMTYPE_MASKLAYER) {
- ED_masklayer_frames_select_box(ale->data, ked.f1, ked.f2, select_mode);
- }
- else {
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
+ case ANIMTYPE_MASKLAYER:
+ ED_masklayer_frames_select_box(ale->data, ked.f1, ked.f2, select_mode);
+ break;
+
+ case ANIMTYPE_FCURVE: {
+ AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+ if (adt) {
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
+ }
+ else {
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
+ }
+ break;
+ }
+
+ default:
+ BLI_assert_msg(false, "Keys cannot be selected into this animation type.");
}
}
@@ -1539,29 +1548,29 @@ static void actkeys_mselect_single(bAnimContext *ac,
ED_mask_select_frame(ale->data, selx, select_mode);
}
else {
- if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK) && (ale->type == ANIMTYPE_SUMMARY) &&
- (ale->datatype == ALE_ALL)) {
+ if (ale->type == ANIMTYPE_SUMMARY && ale->datatype == ALE_ALL) {
ListBase anim_data = {NULL, NULL};
int filter;
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY */ |
- ANIMFILTER_NODUPLIS);
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- for (ale = anim_data.first; ale; ale = ale->next) {
- if (ale->type == ANIMTYPE_GPLAYER) {
- ED_gpencil_select_frame(ale->data, selx, select_mode);
- ale->update |= ANIM_UPDATE_DEPS;
+ /* Loop over all keys that are represented by this summary key. */
+ LISTBASE_FOREACH (bAnimListElem *, ale2, &anim_data) {
+ if (ale2->type == ANIMTYPE_GPLAYER) {
+ ED_gpencil_select_frame(ale2->data, selx, select_mode);
+ ale2->update |= ANIM_UPDATE_DEPS;
}
- else if (ale->type == ANIMTYPE_MASKLAYER) {
- ED_mask_select_frame(ale->data, selx, select_mode);
+ else if (ale2->type == ANIMTYPE_MASKLAYER) {
+ ED_mask_select_frame(ale2->data, selx, select_mode);
}
}
ANIM_animdata_update(ac, &anim_data);
ANIM_animdata_freelist(&anim_data);
}
- else {
+
+ if (!ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
ANIM_animchannel_keyframes_loop(&ked, ac->ads, ale, ok_cb, select_cb, NULL);
}
}
@@ -1588,35 +1597,29 @@ static void actkeys_mselect_column(bAnimContext *ac, short select_mode, float se
/* loop through all of the keys and select additional keyframes
* based on the keys found to be selected above
*/
- if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY */ |
- ANIMFILTER_NODUPLIS);
- }
- else {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS);
- }
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
for (ale = anim_data.first; ale; ale = ale->next) {
- AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-
- /* set frame for validation callback to refer to */
- if (adt) {
- ked.f1 = BKE_nla_tweakedit_remap(adt, selx, NLATIME_CONVERT_UNMAP);
- }
- else {
- ked.f1 = selx;
- }
-
/* select elements with frame number matching cfra */
if (ale->type == ANIMTYPE_GPLAYER) {
- ED_gpencil_select_frame(ale->key_data, selx, select_mode);
+ ED_gpencil_select_frame(ale->data, selx, select_mode);
ale->update |= ANIM_UPDATE_DEPS;
}
else if (ale->type == ANIMTYPE_MASKLAYER) {
- ED_mask_select_frame(ale->key_data, selx, select_mode);
+ ED_mask_select_frame(ale->data, selx, select_mode);
}
else {
+ AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+
+ /* set frame for validation callback to refer to */
+ if (adt) {
+ ked.f1 = BKE_nla_tweakedit_remap(adt, selx, NLATIME_CONVERT_UNMAP);
+ }
+ else {
+ ked.f1 = selx;
+ }
+
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
}
}
@@ -1645,29 +1648,28 @@ static void actkeys_mselect_channel_only(bAnimContext *ac, bAnimListElem *ale, s
ED_mask_select_frames(ale->data, select_mode);
}
else {
- if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK) && (ale->type == ANIMTYPE_SUMMARY) &&
- (ale->datatype == ALE_ALL)) {
+ if (ale->type == ANIMTYPE_SUMMARY && ale->datatype == ALE_ALL) {
ListBase anim_data = {NULL, NULL};
int filter;
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY */ |
- ANIMFILTER_NODUPLIS);
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- for (ale = anim_data.first; ale; ale = ale->next) {
- if (ale->type == ANIMTYPE_GPLAYER) {
- ED_gpencil_select_frames(ale->data, select_mode);
- ale->update |= ANIM_UPDATE_DEPS;
+ LISTBASE_FOREACH (bAnimListElem *, ale2, &anim_data) {
+ if (ale2->type == ANIMTYPE_GPLAYER) {
+ ED_gpencil_select_frames(ale2->data, select_mode);
+ ale2->update |= ANIM_UPDATE_DEPS;
}
- else if (ale->type == ANIMTYPE_MASKLAYER) {
- ED_mask_select_frames(ale->data, select_mode);
+ else if (ale2->type == ANIMTYPE_MASKLAYER) {
+ ED_mask_select_frames(ale2->data, select_mode);
}
}
ANIM_animdata_update(ac, &anim_data);
ANIM_animdata_freelist(&anim_data);
}
- else {
+
+ if (!ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
ANIM_animchannel_keyframes_loop(NULL, ac->ads, ale, NULL, select_cb, NULL);
}
}
@@ -1734,6 +1736,12 @@ static int mouse_action_keys(bAnimContext *ac,
fcu->flag |= FCURVE_SELECTED;
ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, fcu, ale->type);
}
+ else if (ale->type == ANIMTYPE_GPLAYER) {
+ bGPdata *gpd = (bGPdata *)ale->id;
+ bGPDlayer *gpl = ale->data;
+
+ ED_gpencil_set_active_channel(gpd, gpl);
+ }
}
}
else if (ac->datatype == ANIMCONT_GPENCIL) {
@@ -1745,13 +1753,7 @@ static int mouse_action_keys(bAnimContext *ac,
bGPdata *gpd = (bGPdata *)ale->id;
bGPDlayer *gpl = ale->data;
- gpl->flag |= GP_LAYER_SELECT;
- /* Update other layer status. */
- if (BKE_gpencil_layer_active_get(gpd) != gpl) {
- BKE_gpencil_layer_active_set(gpd, gpl);
- BKE_gpencil_layer_autolock_set(gpd, false);
- WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
- }
+ ED_gpencil_set_active_channel(gpd, gpl);
}
}
else if (ac->datatype == ANIMCONT_MASK) {