diff options
22 files changed, 547 insertions, 456 deletions
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index 9eeabf2d05e..7dac1286526 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -3123,7 +3123,7 @@ static bAnimChannelType ACF_DSSIMULATION = { /* TODO: just get this from RNA? */ static int acf_dsgpencil_icon(bAnimListElem *UNUSED(ale)) { - return ICON_GREASEPENCIL; + return ICON_OUTLINER_DATA_GREASEPENCIL; } /* Get the appropriate flag(s) for the setting when it is valid. */ diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index b223a1493fd..8464f280c29 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -2033,7 +2033,7 @@ static void setflag_anim_channels(bAnimContext *ac, if ((ac->spacetype == SPACE_GRAPH) && (ac->regiontype != RGN_TYPE_CHANNELS)) { /* graph editor (case 2) */ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS | ANIMFILTER_CURVE_VISIBLE | - ANIMFILTER_NODUPLIS); + ANIMFILTER_FCURVESONLY | ANIMFILTER_NODUPLIS); } else { /* standard case */ diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index a75944fa2f2..e20932fa53e 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -1925,6 +1925,9 @@ static size_t animdata_filter_ds_gpencil( tmp_items += animfilter_block_data(ac, &tmp_data, ads, &gpd->id, filter_mode); /* add Grease Pencil layers */ + if (!(filter_mode & ANIMFILTER_FCURVESONLY)) { + tmp_items += animdata_filter_gpencil_layers_data(&tmp_data, ads, gpd, filter_mode); + } /* TODO: do these need a separate expander? * XXX: what order should these go in? */ diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index 00e2f221117..30f500f9674 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -1217,11 +1217,11 @@ const EnumPropertyItem rna_enum_keyframe_paste_merge_items[] = { {0, NULL, 0, NULL, NULL}, }; -short paste_animedit_keys(bAnimContext *ac, - ListBase *anim_data, - const eKeyPasteOffset offset_mode, - const eKeyMergeMode merge_mode, - bool flip) +eKeyPasteError paste_animedit_keys(bAnimContext *ac, + ListBase *anim_data, + const eKeyPasteOffset offset_mode, + const eKeyMergeMode merge_mode, + bool flip) { bAnimListElem *ale; @@ -1235,13 +1235,11 @@ short paste_animedit_keys(bAnimContext *ac, /* check if buffer is empty */ if (BLI_listbase_is_empty(&animcopybuf)) { - BKE_report(ac->reports, RPT_ERROR, "No animation data in buffer to paste"); - return -1; + return KEYFRAME_PASTE_NOTHING_TO_PASTE; } if (BLI_listbase_is_empty(anim_data)) { - BKE_report(ac->reports, RPT_ERROR, "No selected F-Curves to paste into"); - return -1; + return KEYFRAME_PASTE_NOWHERE_TO_PASTE; } /* methods of offset */ @@ -1335,7 +1333,7 @@ short paste_animedit_keys(bAnimContext *ac, ANIM_animdata_update(ac, anim_data); - return 0; + return KEYFRAME_PASTE_OK; } /* **************************************************** */ diff --git a/source/blender/editors/gpencil/editaction_gpencil.c b/source/blender/editors/gpencil/editaction_gpencil.c index 949043e4be1..c7d0d9e0e35 100644 --- a/source/blender/editors/gpencil/editaction_gpencil.c +++ b/source/blender/editors/gpencil/editaction_gpencil.c @@ -214,6 +214,18 @@ void ED_gpencil_layer_frames_select_region(KeyframeEditData *ked, } } +void ED_gpencil_set_active_channel(bGPdata *gpd, bGPDlayer *gpl) +{ + 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); + } +} + /* ***************************************** */ /* Frame Editing Tools */ @@ -316,8 +328,13 @@ bool ED_gpencil_anim_copybuf_copy(bAnimContext *ac) filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); - /* assume that each of these is a GP layer */ for (ale = anim_data.first; ale; ale = ale->next) { + /* This function only deals with grease pencil layer frames. + * This check is needed in the case of a call from the main dopesheet. */ + if (ale->type != ANIMTYPE_GPLAYER) { + continue; + } + ListBase copied_frames = {NULL, NULL}; bGPDlayer *gpl = (bGPDlayer *)ale->data; @@ -359,14 +376,8 @@ bool ED_gpencil_anim_copybuf_copy(bAnimContext *ac) /* clean up */ ANIM_animdata_freelist(&anim_data); - /* check if anything ended up in the buffer */ - if (ELEM(NULL, gpencil_anim_copybuf.first, gpencil_anim_copybuf.last)) { - BKE_report(ac->reports, RPT_ERROR, "No keyframes copied to keyframes copy/paste buffer"); - return false; - } - /* report success */ - return true; + return !BLI_listbase_is_empty(&gpencil_anim_copybuf); } bool ED_gpencil_anim_copybuf_paste(bAnimContext *ac, const short offset_mode) @@ -381,7 +392,6 @@ bool ED_gpencil_anim_copybuf_paste(bAnimContext *ac, const short offset_mode) /* check if buffer is empty */ if (BLI_listbase_is_empty(&gpencil_anim_copybuf)) { - BKE_report(ac->reports, RPT_ERROR, "No data in buffer to paste"); return false; } @@ -414,6 +424,11 @@ bool ED_gpencil_anim_copybuf_paste(bAnimContext *ac, const short offset_mode) /* from selected channels */ for (ale = anim_data.first; ale; ale = ale->next) { + /* only deal with GPlayers (case of calls from general dopesheet) */ + if (ale->type != ANIMTYPE_GPLAYER) { + continue; + } + bGPDlayer *gpld = (bGPDlayer *)ale->data; bGPDlayer *gpls = NULL; bGPDframe *gpfs, *gpf; diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index da40eef87fd..ac3b4133007 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -324,11 +324,15 @@ typedef enum eAnimFilter_Flags { /** duplicate entries for animation data attached to multi-user blocks must not occur */ ANIMFILTER_NODUPLIS = (1 << 11), + /** avoid channel that does not have any F-curve data */ + ANIMFILTER_FCURVESONLY = (1 << 12), + /** for checking if we should keep some collapsed channel around (internal use only!) */ ANIMFILTER_TMP_PEEK = (1 << 30), /** Ignore ONLYSEL flag from #bDopeSheet.filterflag (internal use only!) */ ANIMFILTER_TMP_IGNORE_ONLYSEL = (1u << 31), + } eAnimFilter_Flags; /** \} */ diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h index d844bd59c9d..b6488d6da56 100644 --- a/source/blender/editors/include/ED_gpencil.h +++ b/source/blender/editors/include/ED_gpencil.h @@ -281,6 +281,11 @@ void ED_gpencil_select_frames(struct bGPDlayer *gpl, short select_mode); void ED_gpencil_select_frame(struct bGPDlayer *gpl, int selx, short select_mode); /** + * Set the layer's channel as active + */ +void ED_gpencil_set_active_channel(struct bGPdata *gpd, struct bGPDlayer *gpl); + +/** * Delete selected frames. */ bool ED_gpencil_layer_frames_delete(struct bGPDlayer *gpl); diff --git a/source/blender/editors/include/ED_keyframes_edit.h b/source/blender/editors/include/ED_keyframes_edit.h index 163797d395d..9596c3a7fed 100644 --- a/source/blender/editors/include/ED_keyframes_edit.h +++ b/source/blender/editors/include/ED_keyframes_edit.h @@ -229,6 +229,16 @@ typedef enum eKeyMergeMode { KEYFRAME_PASTE_MERGE_OVER_RANGE_ALL, } eKeyMergeMode; +/* Possible errors occurring while pasting keys. */ +typedef enum eKeyPasteError { + /* No errors occurred */ + KEYFRAME_PASTE_OK, + /* Nothing was copied */ + KEYFRAME_PASTE_NOTHING_TO_PASTE, + /* No F-curves was selected to paste into*/ + KEYFRAME_PASTE_NOWHERE_TO_PASTE +} eKeyPasteError; + /** \} */ /* -------------------------------------------------------------------- */ @@ -416,11 +426,11 @@ void sample_fcurve(struct FCurve *fcu); void ANIM_fcurves_copybuf_free(void); short copy_animedit_keys(struct bAnimContext *ac, ListBase *anim_data); -short paste_animedit_keys(struct bAnimContext *ac, - ListBase *anim_data, - eKeyPasteOffset offset_mode, - eKeyMergeMode merge_mode, - bool flip); +eKeyPasteError paste_animedit_keys(struct bAnimContext *ac, + ListBase *anim_data, + eKeyPasteOffset offset_mode, + eKeyMergeMode merge_mode, + bool flip); /* ************************************************ */ diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c index fe69759481b..239113c28a4 100644 --- a/source/blender/editors/screen/screen_context.c +++ b/source/blender/editors/screen/screen_context.c @@ -995,7 +995,7 @@ static eContextResult screen_ctx_sel_actions_impl(const bContext *C, switch (ac.spacetype) { case SPACE_GRAPH: - filter |= ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_SEL; + filter |= ANIMFILTER_FCURVESONLY | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_SEL; break; case SPACE_ACTION: @@ -1059,8 +1059,9 @@ static eContextResult screen_ctx_sel_edit_fcurves_(const bContext *C, ListBase anim_data = {NULL, NULL}; int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_NODUPLIS) | - (ac.spacetype == SPACE_GRAPH ? ANIMFILTER_CURVE_VISIBLE : - ANIMFILTER_LIST_VISIBLE) | + (ac.spacetype == SPACE_GRAPH ? + (ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY) : + ANIMFILTER_LIST_VISIBLE) | extra_filter; ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); @@ -1104,7 +1105,7 @@ static eContextResult screen_ctx_active_editable_fcurve(const bContext *C, ListBase anim_data = {NULL, NULL}; int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_ACTIVE | ANIMFILTER_FOREDIT | - ANIMFILTER_CURVE_VISIBLE); + ANIMFILTER_FCURVESONLY | ANIMFILTER_CURVE_VISIBLE); ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); @@ -1130,8 +1131,9 @@ static eContextResult screen_ctx_selected_editable_keyframes(const bContext *C, /* Use keyframes from editable selected FCurves. */ int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_NODUPLIS | ANIMFILTER_FOREDIT | ANIMFILTER_SEL) | - (ac.spacetype == SPACE_GRAPH ? ANIMFILTER_CURVE_VISIBLE : - ANIMFILTER_LIST_VISIBLE); + (ac.spacetype == SPACE_GRAPH ? + (ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY) : + ANIMFILTER_LIST_VISIBLE); ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index 87a271543d1..2ac10736eea 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -158,8 +158,7 @@ static bool get_keyframe_extents(bAnimContext *ac, float *min, float *max, const /* get data to filter, from Action or Dopesheet */ /* XXX: what is sel doing here?! * Commented it, was breaking things (eg. the "auto preview range" tool). */ - filter = (ANIMFILTER_DATA_VISIBLE | - ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_SEL */ /*| ANIMFILTER_CURVESONLY*/ | + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_SEL */ | ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); @@ -178,10 +177,12 @@ static bool get_keyframe_extents(bAnimContext *ac, float *min, float *max, const /* Find gp-frame which is less than or equal to current-frame. */ for (gpf = gpl->frames.first; gpf; gpf = gpf->next) { - const float framenum = (float)gpf->framenum; - *min = min_ff(*min, framenum); - *max = max_ff(*max, framenum); - found = true; + if (!onlySel || (gpf->flag & GP_FRAME_SELECT)) { + const float framenum = (float)gpf->framenum; + *min = min_ff(*min, framenum); + *max = max_ff(*max, framenum); + found = true; + } } } else if (ale->datatype == ALE_MASKLAY) { @@ -498,7 +499,7 @@ static short copy_action_keys(bAnimContext *ac) ANIM_fcurves_copybuf_free(); /* filter data */ - 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); @@ -511,13 +512,13 @@ static short copy_action_keys(bAnimContext *ac) return ok; } -static short paste_action_keys(bAnimContext *ac, - const eKeyPasteOffset offset_mode, - const eKeyMergeMode merge_mode, - bool flip) +static eKeyPasteError paste_action_keys(bAnimContext *ac, + const eKeyPasteOffset offset_mode, + const eKeyMergeMode merge_mode, + bool flip) { ListBase anim_data = {NULL, NULL}; - int filter, ok = 0; + int filter; /* filter data * - First time we try to filter more strictly, allowing only selected channels @@ -525,15 +526,15 @@ static short paste_action_keys(bAnimContext *ac, * - Second time, we loosen things up if nothing was found the first time, allowing * users to just paste keyframes back into the original curve again T31670. */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | - ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | + ANIMFILTER_FCURVESONLY | ANIMFILTER_NODUPLIS); if (ANIM_animdata_filter(ac, &anim_data, filter | ANIMFILTER_SEL, ac->data, ac->datatype) == 0) { ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); } /* paste keyframes */ - ok = paste_animedit_keys(ac, &anim_data, offset_mode, merge_mode, flip); + const eKeyPasteError ok = paste_animedit_keys(ac, &anim_data, offset_mode, merge_mode, flip); /* clean up */ ANIM_animdata_freelist(&anim_data); @@ -555,7 +556,8 @@ static int actkeys_copy_exec(bContext *C, wmOperator *op) /* copy keyframes */ if (ac.datatype == ANIMCONT_GPENCIL) { if (ED_gpencil_anim_copybuf_copy(&ac) == false) { - /* Nothing got copied - An error about this should be been logged already */ + /* check if anything ended up in the buffer */ + BKE_report(op->reports, RPT_ERROR, "No keyframes copied to keyframes copy/paste buffer"); return OPERATOR_CANCELLED; } } @@ -565,7 +567,11 @@ static int actkeys_copy_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } else { - if (copy_action_keys(&ac)) { + /* Both copy function needs to be evaluated to account for mixed selection */ + const short kf_empty = copy_action_keys(&ac); + const bool gpf_ok = ED_gpencil_anim_copybuf_copy(&ac); + + if (kf_empty && !gpf_ok) { BKE_report(op->reports, RPT_ERROR, "No keyframes copied to keyframes copy/paste buffer"); return OPERATOR_CANCELLED; } @@ -597,6 +603,8 @@ static int actkeys_paste_exec(bContext *C, wmOperator *op) const eKeyMergeMode merge_mode = RNA_enum_get(op->ptr, "merge"); const bool flipped = RNA_boolean_get(op->ptr, "flipped"); + bool gpframes_inbuf = false; + /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) { return OPERATOR_CANCELLED; @@ -608,7 +616,7 @@ static int actkeys_paste_exec(bContext *C, wmOperator *op) /* paste keyframes */ if (ac.datatype == ANIMCONT_GPENCIL) { if (ED_gpencil_anim_copybuf_paste(&ac, offset_mode) == false) { - /* An error occurred - Reports should have been fired already */ + BKE_report(op->reports, RPT_ERROR, "No data in buffer to paste"); return OPERATOR_CANCELLED; } } @@ -620,14 +628,31 @@ static int actkeys_paste_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } else { + /* Both paste function needs to be evaluated to account for mixed selection */ + const eKeyPasteError kf_empty = paste_action_keys(&ac, offset_mode, merge_mode, flipped); /* non-zero return means an error occurred while trying to paste */ - if (paste_action_keys(&ac, offset_mode, merge_mode, flipped)) { - return OPERATOR_CANCELLED; + gpframes_inbuf = ED_gpencil_anim_copybuf_paste(&ac, offset_mode); + + /* Only report an error if nothing was pasted, i.e. when both FCurve and GPencil failed. */ + if (!gpframes_inbuf) { + switch (kf_empty) { + case KEYFRAME_PASTE_OK: + /* FCurve paste was ok, so it's all good. */ + break; + + case KEYFRAME_PASTE_NOWHERE_TO_PASTE: + BKE_report(op->reports, RPT_ERROR, "No selected F-Curves to paste into"); + return OPERATOR_CANCELLED; + + case KEYFRAME_PASTE_NOTHING_TO_PASTE: + BKE_report(op->reports, RPT_ERROR, "No data in buffer to paste"); + return OPERATOR_CANCELLED; + } } } /* Grease Pencil needs extra update to refresh the added keyframes. */ - if (ac.datatype == ANIMCONT_GPENCIL) { + if (ac.datatype == ANIMCONT_GPENCIL || gpframes_inbuf) { WM_event_add_notifier(C, NC_GPENCIL | ND_DATA, NULL); } /* set notifier that keyframes have changed */ @@ -697,94 +722,86 @@ static const EnumPropertyItem prop_actkeys_insertkey_types[] = { {0, NULL, 0, NULL, NULL}, }; -/* this function is responsible for inserting new keyframes */ -static void insert_action_keys(bAnimContext *ac, short mode) +static void insert_gpencil_key(bAnimContext *ac, + bAnimListElem *ale, + const eGP_GetFrame_Mode add_frame_mode, + bGPdata **gpd_old) { - ListBase anim_data = {NULL, NULL}; - ListBase nla_cache = {NULL, NULL}; - bAnimListElem *ale; - int filter; + Scene *scene = ac->scene; + bGPdata *gpd = (bGPdata *)ale->id; + bGPDlayer *gpl = (bGPDlayer *)ale->data; + BKE_gpencil_layer_frame_get(gpl, CFRA, add_frame_mode); + /* Check if the gpd changes to tag only once. */ + if (gpd != *gpd_old) { + BKE_gpencil_tag(gpd); + *gpd_old = gpd; + } +} + +static void insert_fcurve_key(bAnimContext *ac, + bAnimListElem *ale, + const AnimationEvalContext anim_eval_context, + eInsertKeyFlags flag, + ListBase *nla_cache) +{ + FCurve *fcu = (FCurve *)ale->key_data; ReportList *reports = ac->reports; Scene *scene = ac->scene; ToolSettings *ts = scene->toolsettings; - eInsertKeyFlags flag; - /* filter data */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | - ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS); - if (mode == 2) { - filter |= ANIMFILTER_SEL; - } - else if (mode == 3) { - filter |= ANIMFILTER_ACTGROUPED; + /* Read value from property the F-Curve represents, or from the curve only? + * - ale->id != NULL: + * Typically, this means that we have enough info to try resolving the path. + * + * - ale->owner != NULL: + * If this is set, then the path may not be resolvable from the ID alone, + * so it's easier for now to just read the F-Curve directly. + * (TODO: add the full-blown PointerRNA relative parsing case here...) + */ + if (ale->id && !ale->owner) { + insert_keyframe(ac->bmain, + reports, + ale->id, + NULL, + ((fcu->grp) ? (fcu->grp->name) : (NULL)), + fcu->rna_path, + fcu->array_index, + &anim_eval_context, + ts->keyframe_type, + nla_cache, + flag); } + else { + AnimData *adt = ANIM_nla_mapping_get(ac, ale); - ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); - - /* Init keyframing flag. */ - flag = ANIM_get_keyframing_flags(scene, true); - - /* insert keyframes */ - const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(ac->depsgraph, - (float)CFRA); - for (ale = anim_data.first; ale; ale = ale->next) { - FCurve *fcu = (FCurve *)ale->key_data; - - /* Read value from property the F-Curve represents, or from the curve only? - * - ale->id != NULL: - * Typically, this means that we have enough info to try resolving the path. - * - * - ale->owner != NULL: - * If this is set, then the path may not be resolvable from the ID alone, - * so it's easier for now to just read the F-Curve directly. - * (TODO: add the full-blown PointerRNA relative parsing case here...) - */ - if (ale->id && !ale->owner) { - insert_keyframe(ac->bmain, - reports, - ale->id, - NULL, - ((fcu->grp) ? (fcu->grp->name) : (NULL)), - fcu->rna_path, - fcu->array_index, - &anim_eval_context, - ts->keyframe_type, - &nla_cache, - flag); - } - else { - AnimData *adt = ANIM_nla_mapping_get(ac, ale); - - /* adjust current frame for NLA-scaling */ - float cfra = anim_eval_context.eval_time; - if (adt) { - cfra = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP); - } - - const float curval = evaluate_fcurve(fcu, cfra); - insert_vert_fcurve(fcu, cfra, curval, ts->keyframe_type, 0); + /* adjust current frame for NLA-scaling */ + float cfra = anim_eval_context.eval_time; + if (adt) { + cfra = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP); } - ale->update |= ANIM_UPDATE_DEFAULT; + const float curval = evaluate_fcurve(fcu, cfra); + insert_vert_fcurve(fcu, cfra, curval, ts->keyframe_type, 0); } - BKE_animsys_free_nla_keyframing_context_cache(&nla_cache); - - ANIM_animdata_update(ac, &anim_data); - ANIM_animdata_freelist(&anim_data); + ale->update |= ANIM_UPDATE_DEFAULT; } -/* this function is for inserting new grease pencil frames */ -static void insert_gpencil_keys(bAnimContext *ac, short mode) +/* this function is responsible for inserting new keyframes */ +static void insert_action_keys(bAnimContext *ac, short mode) { ListBase anim_data = {NULL, NULL}; + ListBase nla_cache = {NULL, NULL}; bAnimListElem *ale; int filter; Scene *scene = ac->scene; ToolSettings *ts = scene->toolsettings; + eInsertKeyFlags flag; + eGP_GetFrame_Mode add_frame_mode; + bGPdata *gpd_old = NULL; /* filter data */ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | @@ -792,30 +809,43 @@ static void insert_gpencil_keys(bAnimContext *ac, short mode) if (mode == 2) { filter |= ANIMFILTER_SEL; } + else if (mode == 3) { + filter |= ANIMFILTER_ACTGROUPED; + } ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); - /* add a copy or a blank frame? */ + /* Init keyframing flag. */ + flag = ANIM_get_keyframing_flags(scene, true); + + /* GPLayers specific flags */ if (ts->gpencil_flags & GP_TOOL_FLAG_RETAIN_LAST) { - add_frame_mode = GP_GETFRAME_ADD_COPY; /* XXX: actframe may not be what we want? */ + add_frame_mode = GP_GETFRAME_ADD_COPY; } else { add_frame_mode = GP_GETFRAME_ADD_NEW; } - /* Insert gp frames. */ - bGPdata *gpd_old = NULL; + /* insert keyframes */ + const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(ac->depsgraph, + (float)CFRA); for (ale = anim_data.first; ale; ale = ale->next) { - bGPdata *gpd = (bGPdata *)ale->id; - bGPDlayer *gpl = (bGPDlayer *)ale->data; - BKE_gpencil_layer_frame_get(gpl, CFRA, add_frame_mode); - /* Check if the gpd changes to tag only once. */ - if (gpd != gpd_old) { - BKE_gpencil_tag(gpd); - gpd_old = gpd; + switch (ale->type) { + case ANIMTYPE_GPLAYER: + insert_gpencil_key(ac, ale, add_frame_mode, &gpd_old); + break; + + case ANIMTYPE_FCURVE: + insert_fcurve_key(ac, ale, anim_eval_context, flag, &nla_cache); + break; + + default: + BLI_assert_msg(false, "Keys cannot be inserted into this animation type."); } } + BKE_animsys_free_nla_keyframing_context_cache(&nla_cache); + ANIM_animdata_update(ac, &anim_data); ANIM_animdata_freelist(&anim_data); } @@ -841,12 +871,7 @@ static int actkeys_insertkey_exec(bContext *C, wmOperator *op) mode = RNA_enum_get(op->ptr, "type"); /* insert keyframes */ - if (ac.datatype == ANIMCONT_GPENCIL) { - insert_gpencil_keys(&ac, mode); - } - else { - insert_action_keys(&ac, mode); - } + insert_action_keys(&ac, mode); /* set notifier that keyframes have changed */ if (ac.datatype == ANIMCONT_GPENCIL) { @@ -886,14 +911,8 @@ static bool duplicate_action_keys(bAnimContext *ac) bool changed = false; /* filter data */ - if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) { - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | - ANIMFILTER_NODUPLIS); - } - else { - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | - ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS); - } + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | + ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* loop through filtered data and delete selected keys */ @@ -968,14 +987,8 @@ static bool delete_action_keys(bAnimContext *ac) bool changed_final = false; /* filter data */ - if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) { - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | - ANIMFILTER_NODUPLIS); - } - else { - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | - ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS); - } + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | + ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* loop through filtered data and delete selected keys */ @@ -1063,7 +1076,7 @@ static void clean_action_keys(bAnimContext *ac, float thresh, bool clean_chan) /* filter data */ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | - ANIMFILTER_SEL /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS); + ANIMFILTER_SEL | ANIMFILTER_FCURVESONLY | ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* loop through filtered data and clean curves */ @@ -1139,8 +1152,8 @@ static void sample_action_keys(bAnimContext *ac) int filter; /* filter data */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | - ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | + ANIMFILTER_FCURVESONLY | ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* Loop through filtered data and add keys between selected keyframes on every frame. */ @@ -1238,7 +1251,7 @@ static void setexpo_action_keys(bAnimContext *ac, short mode) /* filter data */ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | - ANIMFILTER_SEL /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS); + ANIMFILTER_SEL | ANIMFILTER_FCURVESONLY | ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* loop through setting mode per F-Curve */ @@ -1352,7 +1365,8 @@ static int actkeys_ipo_exec(bContext *C, wmOperator *op) /* set handle type */ ANIM_animdata_keyframe_callback(&ac, (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | - ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS), + ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS | + ANIMFILTER_FCURVESONLY), ANIM_editkeyframes_ipo(mode)); /* set notifier that keyframe properties have changed */ @@ -1401,7 +1415,8 @@ static int actkeys_easing_exec(bContext *C, wmOperator *op) /* set handle type */ ANIM_animdata_keyframe_callback(&ac, (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | - ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS), + ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS | + ANIMFILTER_FCURVESONLY), ANIM_editkeyframes_easing(mode)); /* set notifier that keyframe properties have changed */ @@ -1444,8 +1459,8 @@ static void sethandles_action_keys(bAnimContext *ac, short mode) KeyframeEditFunc sel_cb = ANIM_editkeyframes_ok(BEZT_OK_SELECTED); /* filter data */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | - ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | + ANIMFILTER_FCURVESONLY | ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* Loop through setting flags for handles @@ -1527,8 +1542,8 @@ static void setkeytype_action_keys(bAnimContext *ac, short mode) KeyframeEditFunc set_cb = ANIM_editkeyframes_keytype(mode); /* filter data */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | - ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | + ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* Loop through setting BezTriple interpolation @@ -1536,32 +1551,19 @@ static void setkeytype_action_keys(bAnimContext *ac, short mode) * Currently that's not necessary here. */ for (ale = anim_data.first; ale; ale = ale->next) { - ANIM_fcurve_keyframes_loop(NULL, ale->key_data, NULL, set_cb, NULL); - - ale->update |= ANIM_UPDATE_DEPS | ANIM_UPDATE_HANDLES; - } - - ANIM_animdata_update(ac, &anim_data); - ANIM_animdata_freelist(&anim_data); -} - -/* this function is responsible for setting the keyframe type for Grease Pencil frames */ -static void setkeytype_gpencil_keys(bAnimContext *ac, short mode) -{ - ListBase anim_data = {NULL, NULL}; - bAnimListElem *ale; - int filter; + switch (ale->type) { + case ANIMTYPE_GPLAYER: + ED_gpencil_layer_frames_keytype_set(ale->data, mode); + ale->update |= ANIM_UPDATE_DEPS; + break; - /* filter data */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | - ANIMFILTER_NODUPLIS); - ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); + case ANIMTYPE_FCURVE: + ANIM_fcurve_keyframes_loop(NULL, ale->key_data, NULL, set_cb, NULL); + ale->update |= ANIM_UPDATE_DEPS | ANIM_UPDATE_HANDLES; + break; - /* loop through each layer */ - for (ale = anim_data.first; ale; ale = ale->next) { - if (ale->type == ANIMTYPE_GPLAYER) { - ED_gpencil_layer_frames_keytype_set(ale->data, mode); - ale->update |= ANIM_UPDATE_DEPS; + default: + BLI_assert_msg(false, "Keytype cannot be set into this animation type."); } } @@ -1590,12 +1592,7 @@ static int actkeys_keytype_exec(bContext *C, wmOperator *op) mode = RNA_enum_get(op->ptr, "type"); /* set handle type */ - if (ac.datatype == ANIMCONT_GPENCIL) { - setkeytype_gpencil_keys(&ac, mode); - } - else { - setkeytype_action_keys(&ac, mode); - } + setkeytype_action_keys(&ac, mode); /* set notifier that keyframe properties have changed */ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL); @@ -1653,19 +1650,44 @@ static int actkeys_framejump_exec(bContext *C, wmOperator *UNUSED(op)) /* init edit data */ /* loop over action data, averaging values */ - 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) { - 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, NULL, bezt_calc_average, NULL); - ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1); - } - else { - ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, bezt_calc_average, NULL); + switch (ale->datatype) { + case ALE_GPFRAME: { + bGPDlayer *gpl = ale->data; + bGPDframe *gpf; + + for (gpf = gpl->frames.first; gpf; gpf = gpf->next) { + /* only if selected */ + if (!(gpf->flag & GP_FRAME_SELECT)) { + continue; + } + /* store average time in float 1 (only do rounding at last step) */ + ked.f1 += gpf->framenum; + + /* increment number of items */ + ked.i1++; + } + break; + } + + case ALE_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, NULL, bezt_calc_average, NULL); + ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1); + } + else { + ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, bezt_calc_average, NULL); + } + break; + } + + default: + BLI_assert_msg(false, "Cannot jump to keyframe into this animation type."); } } @@ -1742,8 +1764,8 @@ static void snap_action_keys(bAnimContext *ac, short mode) filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT); } else { - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | - ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | + ANIMFILTER_NODUPLIS); } ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); @@ -1876,14 +1898,8 @@ static void mirror_action_keys(bAnimContext *ac, short mode) } /* filter data */ - if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) { - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | - ANIMFILTER_NODUPLIS); - } - else { - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | - ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS); - } + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | + ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* mirror keyframes */ 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) { diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c index 09163842587..3e3905e5263 100644 --- a/source/blender/editors/space_action/space_action.c +++ b/source/blender/editors/space_action/space_action.c @@ -506,8 +506,8 @@ static void action_listener(const wmSpaceTypeListenerParams *params) /* context changes */ switch (wmn->category) { case NC_GPENCIL: - /* only handle these events in GPencil mode for performance considerations */ - if (saction->mode == SACTCONT_GPENCIL) { + /* only handle these events for containers in which GPencil frames are displayed */ + if (ELEM(saction->mode, SACTCONT_GPENCIL, SACTCONT_DOPESHEET, SACTCONT_TIMELINE)) { if (wmn->action == NA_EDITED) { ED_area_tag_redraw(area); } diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c index a946ce22139..608a1f4d73e 100644 --- a/source/blender/editors/space_graph/graph_draw.c +++ b/source/blender/editors/space_graph/graph_draw.c @@ -1348,7 +1348,7 @@ void graph_draw_curves(bAnimContext *ac, SpaceGraph *sipo, ARegion *region, shor int filter; /* build list of curves to draw */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY); filter |= ((sel) ? (ANIMFILTER_SEL) : (ANIMFILTER_UNSEL)); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); @@ -1393,7 +1393,8 @@ void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *region) size_t items; /* build list of channels to draw */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS | + ANIMFILTER_FCURVESONLY); items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* Update max-extent of channels here (taking into account scrollers): diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index cfc4fcf8dad..324da039daa 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -109,8 +109,8 @@ static void insert_graph_keys(bAnimContext *ac, eGraphKeys_InsertKey_Types mode) eInsertKeyFlags flag = 0; /* Filter data. */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | - ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | + ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); if (mode & GRAPHKEYS_INSERTKEY_SEL) { filter |= ANIMFILTER_SEL; } @@ -457,7 +457,8 @@ static short copy_graph_keys(bAnimContext *ac) * - First time we try to filter more strictly, allowing only selected channels * to allow copying animation between channels. */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | + ANIMFILTER_NODUPLIS); if (ANIM_animdata_filter(ac, &anim_data, filter | ANIMFILTER_SEL, ac->data, ac->datatype) == 0) { ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); @@ -472,13 +473,13 @@ static short copy_graph_keys(bAnimContext *ac) return ok; } -static short paste_graph_keys(bAnimContext *ac, - const eKeyPasteOffset offset_mode, - const eKeyMergeMode merge_mode, - bool flip) +static eKeyPasteError paste_graph_keys(bAnimContext *ac, + const eKeyPasteOffset offset_mode, + const eKeyMergeMode merge_mode, + bool flip) { ListBase anim_data = {NULL, NULL}; - int filter, ok = 0; + int filter; /* Filter data * - First time we try to filter more strictly, allowing only selected channels @@ -486,15 +487,15 @@ static short paste_graph_keys(bAnimContext *ac, * - Second time, we loosen things up if nothing was found the first time, allowing * users to just paste keyframes back into the original curve again T31670. */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | - ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | + ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); if (ANIM_animdata_filter(ac, &anim_data, filter | ANIMFILTER_SEL, ac->data, ac->datatype) == 0) { ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); } /* Paste keyframes. */ - ok = paste_animedit_keys(ac, &anim_data, offset_mode, merge_mode, flip); + const eKeyPasteError ok = paste_animedit_keys(ac, &anim_data, offset_mode, merge_mode, flip); /* Clean up. */ ANIM_animdata_freelist(&anim_data); @@ -554,9 +555,18 @@ static int graphkeys_paste_exec(bContext *C, wmOperator *op) /* Ac.reports by default will be the global reports list, which won't show warnings. */ ac.reports = op->reports; - /* Paste keyframes - non-zero return means an error occurred while trying to paste. */ - if (paste_graph_keys(&ac, offset_mode, merge_mode, flipped)) { - return OPERATOR_CANCELLED; + const eKeyPasteError kf_empty = paste_graph_keys(&ac, offset_mode, merge_mode, flipped); + switch (kf_empty) { + case KEYFRAME_PASTE_OK: + break; + + case KEYFRAME_PASTE_NOWHERE_TO_PASTE: + BKE_report(op->reports, RPT_ERROR, "No selected F-Curves to paste into"); + return OPERATOR_CANCELLED; + + case KEYFRAME_PASTE_NOTHING_TO_PASTE: + BKE_report(op->reports, RPT_ERROR, "No data in buffer to paste"); + return OPERATOR_CANCELLED; } /* Set notifier that keyframes have changed. */ @@ -631,8 +641,8 @@ static bool duplicate_graph_keys(bAnimContext *ac) bool changed = false; /* Filter data. */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | - ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | + ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* Loop through filtered data and delete selected keys. */ @@ -702,8 +712,8 @@ static bool delete_graph_keys(bAnimContext *ac) bool changed_final = false; /* Filter data. */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | - ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | + ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* Loop through filtered data and delete selected keys. */ @@ -785,8 +795,8 @@ static void clean_graph_keys(bAnimContext *ac, float thresh, bool clean_chan) int filter; /* Filter data. */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | - ANIMFILTER_SEL | ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | + ANIMFILTER_FOREDIT | ANIMFILTER_SEL | ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* Loop through filtered data and clean curves. */ @@ -862,8 +872,8 @@ static void bake_graph_curves(bAnimContext *ac, int start, int end) int filter; /* Filter data. */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_SEL | - ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | + ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* Loop through filtered data and add keys between selected keyframes on every frame. */ @@ -949,8 +959,8 @@ static void unbake_graph_curves(bAnimContext *ac, int start, int end) bAnimListElem *ale; /* Filter data. */ - const int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_SEL | - ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); + const int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | + ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* Loop through filtered data and add keys between selected keyframes on every frame. */ @@ -1100,8 +1110,8 @@ static int graphkeys_sound_bake_exec(bContext *C, wmOperator *op) end = CFRA + sbi.length - 1; /* Filter anim channels. */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_SEL | - ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | + ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); /* Loop through all selected F-Curves, replacing its data with the sound samples. */ @@ -1267,8 +1277,8 @@ static void sample_graph_keys(bAnimContext *ac) int filter; /* filter data */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | - ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | + ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* Loop through filtered data and add keys between selected keyframes on every frame. */ @@ -1364,8 +1374,8 @@ static void setexpo_graph_keys(bAnimContext *ac, short mode) int filter; /* Filter data. */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_SEL | - ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | + ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* Loop through setting mode per F-Curve. */ @@ -1469,8 +1479,8 @@ static void setipo_graph_keys(bAnimContext *ac, short mode) KeyframeEditFunc set_cb = ANIM_editkeyframes_ipo(mode); /* Filter data. */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | - ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | + ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* Loop through setting BezTriple interpolation @@ -1547,8 +1557,8 @@ static void seteasing_graph_keys(bAnimContext *ac, short mode) KeyframeEditFunc set_cb = ANIM_editkeyframes_easing(mode); /* Filter data. */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | - ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | + ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* Loop through setting BezTriple easing. @@ -1625,8 +1635,8 @@ static void sethandles_graph_keys(bAnimContext *ac, short mode) KeyframeEditFunc sel_cb = ANIM_editkeyframes_ok(BEZT_OK_SELECTED); /* Filter data. */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | - ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | + ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* Loop through setting flags for handles. @@ -1945,7 +1955,7 @@ static int graphkeys_euler_filter_exec(bContext *C, wmOperator *op) /* Step 1: extract only the rotation f-curves. */ const int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_CURVE_VISIBLE | - ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); + ANIMFILTER_FCURVESONLY | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); ListBase anim_data = {NULL, NULL}; ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); @@ -2056,7 +2066,8 @@ static KeyframeEditData sum_selected_keyframes(bAnimContext *ac) memset(&ked, 0, sizeof(KeyframeEditData)); /* Loop over action data, averaging values. */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | + ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); for (ale = anim_data.first; ale; ale = ale->next) { @@ -2240,8 +2251,8 @@ static void snap_graph_keys(bAnimContext *ac, short mode) float cursor_value = 0.0f; /* Filter data. */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | - ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | + ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* Init custom data for iterating over keyframes. */ @@ -2361,8 +2372,8 @@ static const EnumPropertyItem prop_graphkeys_equalize_handles_sides[] = { static void equalize_graph_keys(bAnimContext *ac, int mode, float handle_length, bool flatten) { /* Filter data. */ - const int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | - ANIMFILTER_NODUPLIS); + const int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | + ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); ListBase anim_data = {NULL, NULL}; ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); @@ -2523,8 +2534,8 @@ static void mirror_graph_keys(bAnimContext *ac, short mode) edit_cb = ANIM_editkeyframes_mirror(mode); /* Filter data. */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | - ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | + ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* Mirror keyframes. */ @@ -2620,8 +2631,8 @@ static int graphkeys_smooth_exec(bContext *C, wmOperator *UNUSED(op)) } /* Filter data. */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | - ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | + ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); /* Smooth keyframes. */ @@ -2720,7 +2731,8 @@ static int graph_fmodifier_add_exec(bContext *C, wmOperator *op) type = RNA_enum_get(op->ptr, "type"); /* Filter data. */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS | + ANIMFILTER_FCURVESONLY); if (RNA_boolean_get(op->ptr, "only_active")) { /* FIXME: enforce in this case only a single channel to get handled? */ filter |= ANIMFILTER_ACTIVE; @@ -2875,14 +2887,14 @@ static int graph_fmodifier_paste_exec(bContext *C, wmOperator *op) /* Filter data. */ if (RNA_boolean_get(op->ptr, "only_active")) { /* This should be the default (for buttons) - Just paste to the active FCurve. */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_ACTIVE | ANIMFILTER_FOREDIT | - ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FCURVESONLY | ANIMFILTER_ACTIVE | + ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); } else { /* This is only if the operator gets called from a hotkey or search - * Paste to all visible curves. */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_SEL | - ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | + ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); } ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); @@ -3065,7 +3077,8 @@ static int graph_driver_delete_invalid_exec(bContext *C, wmOperator *op) /* NOTE: We might need a scene update to evaluate the driver flags. */ /* Filter data. */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | + ANIMFILTER_NODUPLIS); ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); /* Find invalid drivers. */ diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c index 128925d4591..158f2eae88f 100644 --- a/source/blender/editors/space_graph/graph_ops.c +++ b/source/blender/editors/space_graph/graph_ops.c @@ -234,14 +234,16 @@ static int graphview_curves_hide_exec(bContext *C, wmOperator *op) /* get list of all channels that selection may need to be flushed to * - hierarchy must not affect what we have access to here... */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS | ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FCURVESONLY | ANIMFILTER_LIST_CHANNELS | + ANIMFILTER_NODUPLIS); ANIM_animdata_filter(&ac, &all_data, filter, ac.data, ac.datatype); /* filter data * - of the remaining visible curves, we want to hide the ones that are * selected/unselected (depending on "unselected" prop) */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FCURVESONLY | ANIMFILTER_CURVE_VISIBLE | + ANIMFILTER_NODUPLIS); if (unselected) { filter |= ANIMFILTER_UNSEL; } @@ -275,7 +277,8 @@ static int graphview_curves_hide_exec(bContext *C, wmOperator *op) /* unhide selected */ if (unselected) { /* turn off requirement for visible */ - filter = ANIMFILTER_SEL | ANIMFILTER_NODUPLIS | ANIMFILTER_LIST_CHANNELS; + filter = ANIMFILTER_SEL | ANIMFILTER_NODUPLIS | ANIMFILTER_LIST_CHANNELS | + ANIMFILTER_FCURVESONLY; /* flushing has been done */ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); @@ -344,13 +347,15 @@ static int graphview_curves_reveal_exec(bContext *C, wmOperator *op) /* get list of all channels that selection may need to be flushed to * - hierarchy must not affect what we have access to here... */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS | ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS | ANIMFILTER_NODUPLIS | + ANIMFILTER_FCURVESONLY); ANIM_animdata_filter(&ac, &all_data, filter, ac.data, ac.datatype); /* filter data * - just go through all visible channels, ensuring that everything is set to be curve-visible */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS | + ANIMFILTER_FCURVESONLY); ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); for (ale = anim_data.first; ale; ale = ale->next) { diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c index e71c5114b0a..70f9e4a60d9 100644 --- a/source/blender/editors/space_graph/graph_select.c +++ b/source/blender/editors/space_graph/graph_select.c @@ -172,7 +172,8 @@ static void get_nearest_fcurve_verts_list(bAnimContext *ac, const int mval[2], L * - if the option to only show keyframes that belong to selected F-Curves is enabled, * include the 'only selected' flag... */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | + ANIMFILTER_NODUPLIS | ANIMFILTER_FCURVESONLY); if (sipo->flag & SIPO_SELCUVERTSONLY) { /* FIXME: this should really be check for by the filtering code... */ filter |= ANIMFILTER_SEL; @@ -342,7 +343,8 @@ void deselect_graph_keys(bAnimContext *ac, bool test, short sel, bool do_channel KeyframeEditFunc test_cb, sel_cb; /* determine type-based settings */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | + ANIMFILTER_NODUPLIS); /* filter data */ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); @@ -498,7 +500,8 @@ static rctf initialize_box_select_coords(const bAnimContext *ac, const rctf *rec static int initialize_animdata_selection_filter(const SpaceGraph *sipo) { - int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS); + int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | + ANIMFILTER_NODUPLIS); if (sipo->flag & SIPO_SELCUVERTSONLY) { filter |= ANIMFILTER_FOREDIT | ANIMFILTER_SELEDIT; } @@ -1150,7 +1153,8 @@ static void markers_selectkeys_between(bAnimContext *ac) ked.f2 = max; /* filter data */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | + ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* select keys in-between */ @@ -1189,7 +1193,8 @@ static void columnselect_graph_keys(bAnimContext *ac, short mode) /* build list of columns */ switch (mode) { case GRAPHKEYS_COLUMNSEL_KEYS: /* list of selected keys */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | + ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); for (ale = anim_data.first; ale; ale = ale->next) { @@ -1222,7 +1227,8 @@ static void columnselect_graph_keys(bAnimContext *ac, short mode) /* loop through all of the keys and select additional keyframes * based on the keys found to be selected above */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | + ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); for (ale = anim_data.first; ale; ale = ale->next) { @@ -1314,7 +1320,8 @@ static int graphkeys_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_CURVE_VISIBLE | ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | + ANIMFILTER_NODUPLIS); ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); for (ale = anim_data.first; ale; ale = ale->next) { @@ -1372,7 +1379,8 @@ static void select_moreless_graph_keys(bAnimContext *ac, short mode) memset(&ked, 0, sizeof(KeyframeEditData)); /* loop through all of the keys and select additional keyframes based on these */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | + ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); for (ale = anim_data.first; ale; ale = ale->next) { @@ -1521,7 +1529,7 @@ static void graphkeys_select_leftright(bAnimContext *ac, short leftright, short } /* filter data */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_NODUPLIS | ANIMFILTER_FCURVESONLY); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* select keys */ @@ -1797,7 +1805,8 @@ static int mouse_graph_keys(bAnimContext *ac, * otherwise the active flag won't be set T26452. */ if (!run_modal && (nvi->fcu->flag & FCURVE_SELECTED) && something_was_selected) { /* NOTE: Sync the filter flags with findnearest_fcurve_vert. */ - int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS); + int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | + ANIMFILTER_NODUPLIS); ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, nvi->fcu, nvi->ctype); } @@ -1873,7 +1882,8 @@ static int graphkeys_mselect_column(bAnimContext *ac, /* loop through all of the keys and select additional keyframes * based on the keys found to be selected above */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | + ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); for (ale = anim_data.first; ale; ale = ale->next) { diff --git a/source/blender/editors/space_graph/graph_slider_ops.c b/source/blender/editors/space_graph/graph_slider_ops.c index 313f6ca1561..f3d92911155 100644 --- a/source/blender/editors/space_graph/graph_slider_ops.c +++ b/source/blender/editors/space_graph/graph_slider_ops.c @@ -48,8 +48,8 @@ /* Used to obtain a list of animation channels for the operators to work on. */ #define OPERATOR_DATA_FILTER \ - (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_SEL | \ - ANIMFILTER_NODUPLIS) + (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | \ + ANIMFILTER_FOREDIT | ANIMFILTER_SEL | ANIMFILTER_NODUPLIS) /* This data type is only used for modal operation. */ typedef struct tGraphSliderOp { diff --git a/source/blender/editors/space_graph/graph_utils.c b/source/blender/editors/space_graph/graph_utils.c index d8baa4c643d..a813e6ae245 100644 --- a/source/blender/editors/space_graph/graph_utils.c +++ b/source/blender/editors/space_graph/graph_utils.c @@ -131,7 +131,7 @@ bool graphop_visible_keyframes_poll(bContext *C) /* loop over the visible (selection doesn't matter) F-Curves, and see if they're suitable * stopping on the first successful match */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY); items = ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); if (items == 0) { return found; @@ -183,7 +183,8 @@ bool graphop_editable_keyframes_poll(bContext *C) /* loop over the editable F-Curves, and see if they're suitable * stopping on the first successful match */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVE_VISIBLE); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVE_VISIBLE | + ANIMFILTER_FCURVESONLY); items = ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); if (items == 0) { CTX_wm_operator_poll_msg_set(C, "There is no animation data to operate on"); @@ -286,7 +287,8 @@ bool graphop_selected_fcurve_poll(bContext *C) /* Get the editable + selected F-Curves, and as long as we got some, we can return. * NOTE: curve-visible flag isn't included, * otherwise selecting a curve via list to edit is too cumbersome. */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT | + ANIMFILTER_FCURVESONLY); items = ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); if (items == 0) { return false; diff --git a/source/blender/editors/space_graph/graph_view.c b/source/blender/editors/space_graph/graph_view.c index 18465018d35..f80c7c17c3a 100644 --- a/source/blender/editors/space_graph/graph_view.c +++ b/source/blender/editors/space_graph/graph_view.c @@ -56,7 +56,8 @@ void get_graph_keyframe_extents(bAnimContext *ac, int filter; /* Get data to filter, from Dopesheet. */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | + ANIMFILTER_NODUPLIS); if (sipo->flag & SIPO_SELCUVERTSONLY) { filter |= ANIMFILTER_SEL; } @@ -398,8 +399,8 @@ static void create_ghost_curves(bAnimContext *ac, int start, int end) } /* Filter data. */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_SEL | - ANIMFILTER_NODUPLIS); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | + ANIMFILTER_SEL | ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* Loop through filtered data and add keys between selected keyframes on every frame. */ diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 76573c85d52..049d1b6a90e 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -463,6 +463,8 @@ typedef struct TransDataContainer { int data_len; /** Total number of transformed data_mirror. */ int data_mirror_len; + /** Total number of transformed gp-frames. */ + int data_gpf_len; struct Object *obedit; diff --git a/source/blender/editors/transform/transform_convert_action.c b/source/blender/editors/transform/transform_convert_action.c index 71c245cd512..ba62f6f1fea 100644 --- a/source/blender/editors/transform/transform_convert_action.c +++ b/source/blender/editors/transform/transform_convert_action.c @@ -311,6 +311,7 @@ void createTransActionData(bContext *C, TransInfo *t) const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0; int count = 0; + int gpf_count = 0; float cfra; float ypos = 1.0f / ((ysize / xsize) * (xmask / ymask)) * BLI_rctf_cent_y(&t->region->v2d.cur); @@ -320,12 +321,7 @@ void createTransActionData(bContext *C, TransInfo *t) } /* filter data */ - if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) { - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT); - } - else { - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/); - } + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT); ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); /* which side of the current frame should be allowed */ @@ -365,13 +361,16 @@ void createTransActionData(bContext *C, TransInfo *t) } if (adt_count > 0) { + if (ELEM(ale->type, ANIMTYPE_GPLAYER, ANIMTYPE_MASKLAYER)) { + gpf_count += adt_count; + } count += adt_count; ale->tag = true; } } /* stop if trying to build list if nothing selected */ - if (count == 0) { + if (count == 0 && gpf_count == 0) { /* cleanup temp list */ ANIM_animdata_freelist(&anim_data); return; @@ -387,8 +386,9 @@ void createTransActionData(bContext *C, TransInfo *t) td = tc->data; td2d = tc->data_2d; - if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) { - tc->custom.type.data = tfd = MEM_callocN(sizeof(tGPFtransdata) * count, "tGPFtransdata"); + if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK, ANIMCONT_DOPESHEET, ANIMCONT_TIMELINE)) { + tc->data_gpf_len = gpf_count; + tc->custom.type.data = tfd = MEM_callocN(sizeof(tGPFtransdata) * gpf_count, "tGPFtransdata"); tc->custom.type.use_free = true; } @@ -558,8 +558,9 @@ static void flushTransIntFrameActionData(TransInfo *t) TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); tGPFtransdata *tfd = tc->custom.type.data; - /* flush data! */ - for (int i = 0; i < tc->data_len; i++, tfd++) { + /* flush data! + * Expects data_gpf_len to be set in the data container. */ + for (int i = 0; i < tc->data_gpf_len; i++, tfd++) { *(tfd->sdata) = round_fl_to_int(tfd->val); } } @@ -589,7 +590,7 @@ void recalcData_actedit(TransInfo *t) ANIM_animdata_context_getdata(&ac); /* perform flush */ - if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) { + if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK, ANIMCONT_DOPESHEET, ANIMCONT_TIMELINE)) { /* flush transform values back to actual coordinates */ flushTransIntFrameActionData(t); } @@ -735,7 +736,7 @@ static void posttrans_action_clean(bAnimContext *ac, bAction *act) int filter; /* filter data */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_FCURVESONLY); ANIM_animdata_filter(ac, &anim_data, filter, act, ANIMCONT_ACTION); /* loop through relevant data, removing keyframes as appropriate @@ -776,32 +777,44 @@ void special_aftertrans_update__actedit(bContext *C, TransInfo *t) if (ELEM(ac.datatype, ANIMCONT_DOPESHEET, ANIMCONT_SHAPEKEY, ANIMCONT_TIMELINE)) { ListBase anim_data = {NULL, NULL}; bAnimListElem *ale; - short filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/); + short filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT); /* get channels to work on */ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); - /* these should all be F-Curves */ for (ale = anim_data.first; ale; ale = ale->next) { - AnimData *adt = ANIM_nla_mapping_get(&ac, ale); - FCurve *fcu = (FCurve *)ale->key_data; - - /* 3 cases here for curve cleanups: - * 1) NOTRANSKEYCULL on -> cleanup of duplicates shouldn't be done - * 2) canceled == 0 -> user confirmed the transform, - * so duplicates should be removed - * 3) canceled + duplicate -> user canceled the transform, - * but we made duplicates, so get rid of these - */ - if ((saction->flag & SACTION_NOTRANSKEYCULL) == 0 && ((canceled == 0) || (duplicate))) { - if (adt) { - ANIM_nla_mapping_apply_fcurve(adt, fcu, 0, 0); - posttrans_fcurve_clean(fcu, SELECT, false); /* only use handles in graph editor */ - ANIM_nla_mapping_apply_fcurve(adt, fcu, 1, 0); - } - else { - posttrans_fcurve_clean(fcu, SELECT, false); /* only use handles in graph editor */ + switch (ale->datatype) { + case ALE_GPFRAME: + ale->id->tag &= ~LIB_TAG_DOIT; + posttrans_gpd_clean((bGPdata *)ale->id); + break; + + case ALE_FCURVE: { + AnimData *adt = ANIM_nla_mapping_get(&ac, ale); + FCurve *fcu = (FCurve *)ale->key_data; + + /* 3 cases here for curve cleanups: + * 1) NOTRANSKEYCULL on -> cleanup of duplicates shouldn't be done + * 2) canceled == 0 -> user confirmed the transform, + * so duplicates should be removed + * 3) canceled + duplicate -> user canceled the transform, + * but we made duplicates, so get rid of these + */ + if ((saction->flag & SACTION_NOTRANSKEYCULL) == 0 && ((canceled == 0) || (duplicate))) { + if (adt) { + ANIM_nla_mapping_apply_fcurve(adt, fcu, 0, 0); + posttrans_fcurve_clean(fcu, SELECT, false); /* only use handles in graph editor */ + ANIM_nla_mapping_apply_fcurve(adt, fcu, 1, 0); + } + else { + posttrans_fcurve_clean(fcu, SELECT, false); /* only use handles in graph editor */ + } + } + break; } + + default: + BLI_assert_msg(false, "Keys cannot be transformed into this animation type."); } } @@ -847,15 +860,8 @@ void special_aftertrans_update__actedit(bContext *C, TransInfo *t) LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) { if (ale->datatype == ALE_GPFRAME) { - ale->id->tag |= LIB_TAG_DOIT; - } - } - LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) { - if (ale->datatype == ALE_GPFRAME) { - if (ale->id->tag & LIB_TAG_DOIT) { - ale->id->tag &= ~LIB_TAG_DOIT; - posttrans_gpd_clean((bGPdata *)ale->id); - } + ale->id->tag &= ~LIB_TAG_DOIT; + posttrans_gpd_clean((bGPdata *)ale->id); } } ANIM_animdata_freelist(&anim_data); @@ -878,15 +884,8 @@ void special_aftertrans_update__actedit(bContext *C, TransInfo *t) LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) { if (ale->datatype == ALE_MASKLAY) { - ale->id->tag |= LIB_TAG_DOIT; - } - } - LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) { - if (ale->datatype == ALE_MASKLAY) { - if (ale->id->tag & LIB_TAG_DOIT) { - ale->id->tag &= ~LIB_TAG_DOIT; - posttrans_mask_clean((Mask *)ale->id); - } + ale->id->tag &= ~LIB_TAG_DOIT; + posttrans_mask_clean((Mask *)ale->id); } } ANIM_animdata_freelist(&anim_data); diff --git a/source/blender/editors/transform/transform_convert_graph.c b/source/blender/editors/transform/transform_convert_graph.c index 2039daee386..1444268baf5 100644 --- a/source/blender/editors/transform/transform_convert_graph.c +++ b/source/blender/editors/transform/transform_convert_graph.c @@ -232,7 +232,8 @@ void createTransGraphEditData(bContext *C, TransInfo *t) anim_map_flag |= ANIM_get_normalization_flags(&ac); /* filter data */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVE_VISIBLE); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVE_VISIBLE | + ANIMFILTER_FCURVESONLY); ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); /* which side of the current frame should be allowed */ @@ -915,7 +916,8 @@ void recalcData_graphedit(TransInfo *t) flushTransGraphData(t); /* get curves to check if a re-sort is needed */ - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVE_VISIBLE); + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVE_VISIBLE | + ANIMFILTER_FCURVESONLY); ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); /* now test if there is a need to re-sort */ @@ -975,7 +977,8 @@ void special_aftertrans_update__graph(bContext *C, TransInfo *t) if (ac.datatype) { ListBase anim_data = {NULL, NULL}; bAnimListElem *ale; - short filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVE_VISIBLE); + short filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVE_VISIBLE | + ANIMFILTER_FCURVESONLY); /* get channels to work on */ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); |