diff options
Diffstat (limited to 'source/blender/editors/animation')
-rw-r--r-- | source/blender/editors/animation/CMakeLists.txt | 2 | ||||
-rw-r--r-- | source/blender/editors/animation/anim_draw.c | 24 | ||||
-rw-r--r-- | source/blender/editors/animation/anim_filter.c | 4 | ||||
-rw-r--r-- | source/blender/editors/animation/anim_ipo_utils.c | 22 | ||||
-rw-r--r-- | source/blender/editors/animation/anim_markers.c | 2 | ||||
-rw-r--r-- | source/blender/editors/animation/anim_motion_paths.c | 64 | ||||
-rw-r--r-- | source/blender/editors/animation/fmodifier_ui.c | 5 | ||||
-rw-r--r-- | source/blender/editors/animation/keyframes_draw.c | 765 | ||||
-rw-r--r-- | source/blender/editors/animation/keyframes_general.c | 10 | ||||
-rw-r--r-- | source/blender/editors/animation/keyframes_keylist.cc (renamed from source/blender/editors/animation/keyframes_keylist.c) | 394 | ||||
-rw-r--r-- | source/blender/editors/animation/time_scrub_ui.c | 4 |
11 files changed, 803 insertions, 493 deletions
diff --git a/source/blender/editors/animation/CMakeLists.txt b/source/blender/editors/animation/CMakeLists.txt index 7a53b54b5a4..d9f52d90766 100644 --- a/source/blender/editors/animation/CMakeLists.txt +++ b/source/blender/editors/animation/CMakeLists.txt @@ -47,7 +47,7 @@ set(SRC keyframes_draw.c keyframes_edit.c keyframes_general.c - keyframes_keylist.c + keyframes_keylist.cc keyframing.c keyingsets.c time_scrub_ui.c diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c index baf8adf28d0..6d272bfc180 100644 --- a/source/blender/editors/animation/anim_draw.c +++ b/source/blender/editors/animation/anim_draw.c @@ -494,17 +494,14 @@ static bool find_prev_next_keyframes(struct bContext *C, int *r_nextfra, int *r_ Object *ob = CTX_data_active_object(C); Mask *mask = CTX_data_edit_mask(C); bDopeSheet ads = {NULL}; - DLRBT_Tree keys; - ActKeyColumn *aknext, *akprev; + struct AnimKeylist *keylist = ED_keylist_create(); + const ActKeyColumn *aknext, *akprev; float cfranext, cfraprev; bool donenext = false, doneprev = false; int nextcount = 0, prevcount = 0; cfranext = cfraprev = (float)(CFRA); - /* init binarytree-list for getting keyframes */ - BLI_dlrbTree_init(&keys); - /* seed up dummy dopesheet context with flags to perform necessary filtering */ if ((scene->flag & SCE_KEYS_NO_SELONLY) == 0) { /* only selected channels are included */ @@ -512,22 +509,23 @@ static bool find_prev_next_keyframes(struct bContext *C, int *r_nextfra, int *r_ } /* populate tree with keyframe nodes */ - scene_to_keylist(&ads, scene, &keys, 0); - gpencil_to_keylist(&ads, scene->gpd, &keys, false); + scene_to_keylist(&ads, scene, keylist, 0); + gpencil_to_keylist(&ads, scene->gpd, keylist, false); if (ob) { - ob_to_keylist(&ads, ob, &keys, 0); - gpencil_to_keylist(&ads, ob->data, &keys, false); + ob_to_keylist(&ads, ob, keylist, 0); + gpencil_to_keylist(&ads, ob->data, keylist, false); } if (mask) { MaskLayer *masklay = BKE_mask_layer_active(mask); - mask_to_keylist(&ads, masklay, &keys); + mask_to_keylist(&ads, masklay, keylist); } + /* TODO(jbakker): Keylists are ordered, no need to do any searching at all. */ /* find matching keyframe in the right direction */ do { - aknext = (ActKeyColumn *)BLI_dlrbTree_search_next(&keys, compare_ak_cfraPtr, &cfranext); + aknext = ED_keylist_find_next(keylist, cfranext); if (aknext) { if (CFRA == (int)aknext->cfra) { @@ -545,7 +543,7 @@ static bool find_prev_next_keyframes(struct bContext *C, int *r_nextfra, int *r_ } while ((aknext != NULL) && (donenext == false)); do { - akprev = (ActKeyColumn *)BLI_dlrbTree_search_prev(&keys, compare_ak_cfraPtr, &cfraprev); + akprev = ED_keylist_find_prev(keylist, cfraprev); if (akprev) { if (CFRA == (int)akprev->cfra) { @@ -562,7 +560,7 @@ static bool find_prev_next_keyframes(struct bContext *C, int *r_nextfra, int *r_ } while ((akprev != NULL) && (doneprev == false)); /* free temp stuff */ - BLI_dlrbTree_free(&keys); + ED_keylist_free(keylist); /* any success? */ if (doneprev || donenext) { diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index b2d387ea898..020518b5813 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -1892,7 +1892,7 @@ static size_t animdata_filter_gpencil(bAnimContext *ac, } /* outliner restrict-flag */ - if (ob->restrictflag & OB_RESTRICT_VIEWPORT) { + if (ob->visibility_flag & OB_HIDE_VIEWPORT) { continue; } } @@ -3098,7 +3098,7 @@ static bool animdata_filter_base_is_ok(bDopeSheet *ads, Base *base, int filter_m } /* outliner restrict-flag */ - if (ob->restrictflag & OB_RESTRICT_VIEWPORT) { + if (ob->visibility_flag & OB_HIDE_VIEWPORT) { return false; } } diff --git a/source/blender/editors/animation/anim_ipo_utils.c b/source/blender/editors/animation/anim_ipo_utils.c index 5992545bdbe..eda87cf1897 100644 --- a/source/blender/editors/animation/anim_ipo_utils.c +++ b/source/blender/editors/animation/anim_ipo_utils.c @@ -134,6 +134,28 @@ int getname_anim_fcurve(char *name, ID *id, FCurve *fcu) else { structname = RNA_struct_ui_name(ptr.type); } + + /* For the VSE, a strip's 'Transform' or 'Crop' is a nested (under Sequence) struct, but + * displaying the struct name alone is no meaningful information (and also cannot be + * filtered well), same for modifiers. So display strip name alongside as well. */ + if (GS(ptr.owner_id->name) == ID_SCE) { + if (BLI_str_startswith(fcu->rna_path, "sequence_editor.sequences_all[\"")) { + if (strstr(fcu->rna_path, ".transform.") || strstr(fcu->rna_path, ".crop.") || + strstr(fcu->rna_path, ".modifiers[")) { + char *stripname = BLI_str_quoted_substrN(fcu->rna_path, "sequences_all["); + const char *structname_all = BLI_sprintfN( + "%s : %s", stripname ? stripname : "", structname); + if (free_structname) { + MEM_freeN((void *)structname); + } + if (stripname) { + MEM_freeN(stripname); + } + structname = structname_all; + free_structname = 1; + } + } + } } /* Property Name is straightforward */ diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c index cfcea950955..0de3f429bc7 100644 --- a/source/blender/editors/animation/anim_markers.c +++ b/source/blender/editors/animation/anim_markers.c @@ -445,7 +445,7 @@ static void draw_marker_name(const uchar *text_color, if (marker->camera) { Object *camera = marker->camera; name = camera->id.name + 2; - if (camera->restrictflag & OB_RESTRICT_RENDER) { + if (camera->visibility_flag & OB_HIDE_RENDER) { final_text_color[3] = 100; } } diff --git a/source/blender/editors/animation/anim_motion_paths.c b/source/blender/editors/animation/anim_motion_paths.c index bddd5dbff55..d976f5f72ad 100644 --- a/source/blender/editors/animation/anim_motion_paths.c +++ b/source/blender/editors/animation/anim_motion_paths.c @@ -55,7 +55,7 @@ typedef struct MPathTarget { bMotionPath *mpath; /* motion path in question */ - DLRBT_Tree keys; /* temp, to know where the keyframes are */ + struct AnimKeylist *keylist; /* temp, to know where the keyframes are */ /* Original (Source Objects) */ Object *ob; /* source object */ @@ -187,7 +187,7 @@ static void motionpaths_calc_bake_targets(ListBase *targets, int cframe) float mframe = (float)(cframe); /* Tag if it's a keyframe */ - if (BLI_dlrbTree_search_exact(&mpt->keys, compare_ak_cfraPtr, &mframe)) { + if (ED_keylist_find_exact(mpt->keylist, mframe)) { mpv->flag |= MOTIONPATH_VERT_KEY; } else { @@ -234,52 +234,55 @@ static void motionpath_get_global_framerange(ListBase *targets, int *r_sfra, int } } -static int motionpath_get_prev_keyframe(MPathTarget *mpt, DLRBT_Tree *fcu_keys, int current_frame) +/* TODO(jbakker): Remove complexity, keylists are ordered. */ +static int motionpath_get_prev_keyframe(MPathTarget *mpt, + struct AnimKeylist *keylist, + int current_frame) { if (current_frame <= mpt->mpath->start_frame) { return mpt->mpath->start_frame; } float current_frame_float = current_frame; - DLRBT_Node *node = BLI_dlrbTree_search_prev(fcu_keys, compare_ak_cfraPtr, ¤t_frame_float); - if (node == NULL) { + const ActKeyColumn *ak = ED_keylist_find_prev(keylist, current_frame_float); + if (ak == NULL) { return mpt->mpath->start_frame; } - ActKeyColumn *key_data = (ActKeyColumn *)node; - return key_data->cfra; + return ak->cfra; } static int motionpath_get_prev_prev_keyframe(MPathTarget *mpt, - DLRBT_Tree *fcu_keys, + struct AnimKeylist *keylist, int current_frame) { - int frame = motionpath_get_prev_keyframe(mpt, fcu_keys, current_frame); - return motionpath_get_prev_keyframe(mpt, fcu_keys, frame); + int frame = motionpath_get_prev_keyframe(mpt, keylist, current_frame); + return motionpath_get_prev_keyframe(mpt, keylist, frame); } -static int motionpath_get_next_keyframe(MPathTarget *mpt, DLRBT_Tree *fcu_keys, int current_frame) +static int motionpath_get_next_keyframe(MPathTarget *mpt, + struct AnimKeylist *keylist, + int current_frame) { if (current_frame >= mpt->mpath->end_frame) { return mpt->mpath->end_frame; } float current_frame_float = current_frame; - DLRBT_Node *node = BLI_dlrbTree_search_next(fcu_keys, compare_ak_cfraPtr, ¤t_frame_float); - if (node == NULL) { + const ActKeyColumn *ak = ED_keylist_find_next(keylist, current_frame_float); + if (ak == NULL) { return mpt->mpath->end_frame; } - ActKeyColumn *key_data = (ActKeyColumn *)node; - return key_data->cfra; + return ak->cfra; } static int motionpath_get_next_next_keyframe(MPathTarget *mpt, - DLRBT_Tree *fcu_keys, + struct AnimKeylist *keylist, int current_frame) { - int frame = motionpath_get_next_keyframe(mpt, fcu_keys, current_frame); - return motionpath_get_next_keyframe(mpt, fcu_keys, frame); + int frame = motionpath_get_next_keyframe(mpt, keylist, current_frame); + return motionpath_get_next_keyframe(mpt, keylist, frame); } static bool motionpath_check_can_use_keyframe_range(MPathTarget *UNUSED(mpt), @@ -324,17 +327,16 @@ static void motionpath_calculate_update_range(MPathTarget *mpt, * Could be optimized further by storing some flags about which channels has been modified so * we ignore all others (which can potentially make an update range unnecessary wide). */ for (FCurve *fcu = fcurve_list->first; fcu != NULL; fcu = fcu->next) { - DLRBT_Tree fcu_keys; - BLI_dlrbTree_init(&fcu_keys); - fcurve_to_keylist(adt, fcu, &fcu_keys, 0); + struct AnimKeylist *keylist = ED_keylist_create(); + fcurve_to_keylist(adt, fcu, keylist, 0); - int fcu_sfra = motionpath_get_prev_prev_keyframe(mpt, &fcu_keys, current_frame); - int fcu_efra = motionpath_get_next_next_keyframe(mpt, &fcu_keys, current_frame); + int fcu_sfra = motionpath_get_prev_prev_keyframe(mpt, keylist, current_frame); + int fcu_efra = motionpath_get_next_next_keyframe(mpt, keylist, current_frame); /* Extend range further, since acceleration compensation propagates even further away. */ if (fcu->auto_smoothing != FCURVE_SMOOTH_NONE) { - fcu_sfra = motionpath_get_prev_prev_keyframe(mpt, &fcu_keys, fcu_sfra); - fcu_efra = motionpath_get_next_next_keyframe(mpt, &fcu_keys, fcu_efra); + fcu_sfra = motionpath_get_prev_prev_keyframe(mpt, keylist, fcu_sfra); + fcu_efra = motionpath_get_next_next_keyframe(mpt, keylist, fcu_efra); } if (fcu_sfra <= fcu_efra) { @@ -342,14 +344,14 @@ static void motionpath_calculate_update_range(MPathTarget *mpt, *r_efra = max_ii(*r_efra, fcu_efra); } - BLI_dlrbTree_free(&fcu_keys); + ED_keylist_free(keylist); } } static void motionpath_free_free_tree_data(ListBase *targets) { LISTBASE_FOREACH (MPathTarget *, mpt, targets) { - BLI_dlrbTree_free(&mpt->keys); + ED_keylist_free(mpt->keylist); } } @@ -418,7 +420,7 @@ void animviz_calc_motionpaths(Depsgraph *depsgraph, AnimData *adt = BKE_animdata_from_id(&mpt->ob_eval->id); /* build list of all keyframes in active action for object or pchan */ - BLI_dlrbTree_init(&mpt->keys); + mpt->keylist = ED_keylist_create(); ListBase *fcurve_list = NULL; if (adt) { @@ -433,12 +435,12 @@ void animviz_calc_motionpaths(Depsgraph *depsgraph, if (agrp) { fcurve_list = &agrp->channels; - agroup_to_keylist(adt, agrp, &mpt->keys, 0); + agroup_to_keylist(adt, agrp, mpt->keylist, 0); } } else { fcurve_list = &adt->action->curves; - action_to_keylist(adt, adt->action, &mpt->keys, 0); + action_to_keylist(adt, adt->action, mpt->keylist, 0); } } @@ -502,7 +504,7 @@ void animviz_calc_motionpaths(Depsgraph *depsgraph, avs->recalc &= ~ANIMVIZ_RECALC_PATHS; /* Clean temp data */ - BLI_dlrbTree_free(&mpt->keys); + ED_keylist_free(mpt->keylist); /* Free previous batches to force update. */ GPU_VERTBUF_DISCARD_SAFE(mpath->points_vbo); diff --git a/source/blender/editors/animation/fmodifier_ui.c b/source/blender/editors/animation/fmodifier_ui.c index 31552330071..40871fba2be 100644 --- a/source/blender/editors/animation/fmodifier_ui.c +++ b/source/blender/editors/animation/fmodifier_ui.c @@ -672,10 +672,7 @@ static void fmod_envelope_deletepoint_cb(bContext *UNUSED(C), void *fcm_dv, void } else { /* just free array, since the only vert was deleted */ - if (env->data) { - MEM_freeN(env->data); - env->data = NULL; - } + MEM_SAFE_FREE(env->data); env->totvert = 0; } } diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index 4f512c9d7ca..61918871b90 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -25,6 +25,8 @@ #include <float.h> +#include "MEM_guardedalloc.h" + #include "BLI_dlrbTree.h" #include "BLI_listbase.h" #include "BLI_rect.h" @@ -55,11 +57,7 @@ void draw_keyframe_shape(float x, short key_type, short mode, float alpha, - uint pos_id, - uint size_id, - uint color_id, - uint outline_color_id, - uint flags_id, + const KeyframeShaderBindings *sh_bindings, short handle_type, short extreme_type) { @@ -176,354 +174,563 @@ void draw_keyframe_shape(float x, } } - immAttr1f(size_id, size); - immAttr4ubv(color_id, fill_col); - immAttr4ubv(outline_color_id, outline_col); - immAttr1u(flags_id, flags); - immVertex2f(pos_id, x, y); + immAttr1f(sh_bindings->size_id, size); + immAttr4ubv(sh_bindings->color_id, fill_col); + immAttr4ubv(sh_bindings->outline_color_id, outline_col); + immAttr1u(sh_bindings->flags_id, flags); + immVertex2f(sh_bindings->pos_id, x, y); } -static void draw_keylist(View2D *v2d, - DLRBT_Tree *keys, - float ypos, - float yscale_fac, - bool channelLocked, - int saction_flag) -{ - if (keys == NULL) { - return; - } - - const float icon_sz = U.widget_unit * 0.5f * yscale_fac; - const float half_icon_sz = 0.5f * icon_sz; - const float smaller_sz = 0.35f * icon_sz; - const float ipo_sz = 0.1f * icon_sz; - const float gpencil_sz = smaller_sz * 0.8f; - const float screenspace_margin = (0.35f * (float)UI_UNIT_X) / UI_view2d_scale_get_x(v2d); +/* Common attributes shared between the draw calls. */ +typedef struct DrawKeylistUIData { + float alpha; + float icon_sz; + float half_icon_sz; + float smaller_sz; + float ipo_sz; + float gpencil_sz; + float screenspace_margin; + float sel_color[4]; + float unsel_color[4]; + float sel_mhcol[4]; + float unsel_mhcol[4]; + float ipo_color[4]; + float ipo_color_mix[4]; + /* Show interpolation and handle type? */ + bool show_ipo; +} DrawKeylistUIData; + +static void draw_keylist_ui_data_init(DrawKeylistUIData *ctx, + View2D *v2d, + float yscale_fac, + bool channel_locked, + eSAction_Flag saction_flag) +{ /* locked channels are less strongly shown, as feedback for locked channels in DopeSheet */ /* TODO: allow this opacity factor to be themed? */ - float alpha = channelLocked ? 0.25f : 1.0f; + ctx->alpha = channel_locked ? 0.25f : 1.0f; + + ctx->icon_sz = U.widget_unit * 0.5f * yscale_fac; + ctx->half_icon_sz = 0.5f * ctx->icon_sz; + ctx->smaller_sz = 0.35f * ctx->icon_sz; + ctx->ipo_sz = 0.1f * ctx->icon_sz; + ctx->gpencil_sz = ctx->smaller_sz * 0.8f; + ctx->screenspace_margin = (0.35f * (float)UI_UNIT_X) / UI_view2d_scale_get_x(v2d); + + ctx->show_ipo = (saction_flag & SACTION_SHOW_INTERPOLATION) != 0; + + UI_GetThemeColor4fv(TH_STRIP_SELECT, ctx->sel_color); + UI_GetThemeColor4fv(TH_STRIP, ctx->unsel_color); + UI_GetThemeColor4fv(TH_DOPESHEET_IPOLINE, ctx->ipo_color); + + ctx->sel_color[3] *= ctx->alpha; + ctx->unsel_color[3] *= ctx->alpha; + ctx->ipo_color[3] *= ctx->alpha; + + copy_v4_v4(ctx->sel_mhcol, ctx->sel_color); + ctx->sel_mhcol[3] *= 0.8f; + copy_v4_v4(ctx->unsel_mhcol, ctx->unsel_color); + ctx->unsel_mhcol[3] *= 0.8f; + copy_v4_v4(ctx->ipo_color_mix, ctx->ipo_color); + ctx->ipo_color_mix[3] *= 0.5f; +} - /* Show interpolation and handle type? */ - bool show_ipo = (saction_flag & SACTION_SHOW_INTERPOLATION) != 0; - /* draw keyblocks */ - float sel_color[4], unsel_color[4]; - float sel_mhcol[4], unsel_mhcol[4]; - float ipo_color[4], ipo_color_mix[4]; - - /* cache colors first */ - UI_GetThemeColor4fv(TH_STRIP_SELECT, sel_color); - UI_GetThemeColor4fv(TH_STRIP, unsel_color); - UI_GetThemeColor4fv(TH_DOPESHEET_IPOLINE, ipo_color); - - sel_color[3] *= alpha; - unsel_color[3] *= alpha; - ipo_color[3] *= alpha; - - copy_v4_v4(sel_mhcol, sel_color); - sel_mhcol[3] *= 0.8f; - copy_v4_v4(unsel_mhcol, unsel_color); - unsel_mhcol[3] *= 0.8f; - copy_v4_v4(ipo_color_mix, ipo_color); - ipo_color_mix[3] *= 0.5f; - - LISTBASE_FOREACH (ActKeyColumn *, ab, keys) { - /* Draw grease pencil bars between keyframes. */ - if ((ab->next != NULL) && (ab->block.flag & ACTKEYBLOCK_FLAG_GPENCIL)) { - UI_draw_roundbox_corner_set(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT); - float size = 1.0f; - switch (ab->next->key_type) { - case BEZT_KEYTYPE_BREAKDOWN: - case BEZT_KEYTYPE_MOVEHOLD: - case BEZT_KEYTYPE_JITTER: - size *= 0.5f; - break; - case BEZT_KEYTYPE_KEYFRAME: - size *= 0.8f; - break; - default: - break; - } - UI_draw_roundbox_4fv( - &(const rctf){ - .xmin = ab->cfra, - .xmax = min_ff(ab->next->cfra - (screenspace_margin * size), ab->next->cfra), - .ymin = ypos - gpencil_sz, - .ymax = ypos + gpencil_sz, - }, - true, - 0.25f * (float)UI_UNIT_X, - (ab->block.sel) ? sel_mhcol : unsel_mhcol); - } - else { - /* Draw other types. */ - UI_draw_roundbox_corner_set(UI_CNR_NONE); - - int valid_hold = actkeyblock_get_valid_hold(ab); - if (valid_hold != 0) { - if ((valid_hold & ACTKEYBLOCK_FLAG_STATIC_HOLD) == 0) { - /* draw "moving hold" long-keyframe block - slightly smaller */ - UI_draw_roundbox_4fv( - &(const rctf){ - .xmin = ab->cfra, - .xmax = ab->next->cfra, - .ymin = ypos - smaller_sz, - .ymax = ypos + smaller_sz, - }, - true, - 3.0f, - (ab->block.sel) ? sel_mhcol : unsel_mhcol); - } - else { - /* draw standard long-keyframe block */ - UI_draw_roundbox_4fv( - &(const rctf){ - .xmin = ab->cfra, - .xmax = ab->next->cfra, - .ymin = ypos - half_icon_sz, - .ymax = ypos + half_icon_sz, - }, - true, - 3.0f, - (ab->block.sel) ? sel_color : unsel_color); - } - } - if (show_ipo && actkeyblock_is_valid(ab) && (ab->block.flag & ACTKEYBLOCK_FLAG_NON_BEZIER)) { - /* draw an interpolation line */ - UI_draw_roundbox_4fv( - &(const rctf){ - .xmin = ab->cfra, - .xmax = ab->next->cfra, - .ymin = ypos - ipo_sz, - .ymax = ypos + ipo_sz, - }, - true, - 3.0f, - (ab->block.conflict & ACTKEYBLOCK_FLAG_NON_BEZIER) ? ipo_color_mix : ipo_color); - } - } +static void draw_keylist_block_gpencil(const DrawKeylistUIData *ctx, + const ActKeyColumn *ab, + float ypos) +{ + UI_draw_roundbox_corner_set(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT); + float size = 1.0f; + switch (ab->next->key_type) { + case BEZT_KEYTYPE_BREAKDOWN: + case BEZT_KEYTYPE_MOVEHOLD: + case BEZT_KEYTYPE_JITTER: + size *= 0.5f; + break; + case BEZT_KEYTYPE_KEYFRAME: + size *= 0.8f; + break; + default: + break; } + UI_draw_roundbox_4fv( + &(const rctf){ + .xmin = ab->cfra, + .xmax = min_ff(ab->next->cfra - (ctx->screenspace_margin * size), ab->next->cfra), + .ymin = ypos - ctx->gpencil_sz, + .ymax = ypos + ctx->gpencil_sz, + }, + true, + 0.25f * (float)UI_UNIT_X, + (ab->block.sel) ? ctx->sel_mhcol : ctx->unsel_mhcol); +} - GPU_blend(GPU_BLEND_ALPHA); +static void draw_keylist_block_moving_hold(const DrawKeylistUIData *ctx, + const ActKeyColumn *ab, + float ypos) +{ - /* count keys */ - uint key_len = 0; - LISTBASE_FOREACH (ActKeyColumn *, ak, keys) { - /* Optimization: if keyframe doesn't appear within 5 units (screenspace) - * in visible area, don't draw. - * This might give some improvements, - * since we current have to flip between view/region matrices. - */ - if (IN_RANGE_INCL(ak->cfra, v2d->cur.xmin, v2d->cur.xmax)) { - key_len++; - } - } + UI_draw_roundbox_4fv( + &(const rctf){ + .xmin = ab->cfra, + .xmax = ab->next->cfra, + .ymin = ypos - ctx->smaller_sz, + .ymax = ypos + ctx->smaller_sz, + }, + true, + 3.0f, + (ab->block.sel) ? ctx->sel_mhcol : ctx->unsel_mhcol); +} + +static void draw_keylist_block_standard(const DrawKeylistUIData *ctx, + const ActKeyColumn *ab, + float ypos) +{ + UI_draw_roundbox_4fv( + &(const rctf){ + .xmin = ab->cfra, + .xmax = ab->next->cfra, + .ymin = ypos - ctx->half_icon_sz, + .ymax = ypos + ctx->half_icon_sz, + }, + true, + 3.0f, + (ab->block.sel) ? ctx->sel_color : ctx->unsel_color); +} + +static void draw_keylist_block_interpolation_line(const DrawKeylistUIData *ctx, + const ActKeyColumn *ab, + float ypos) +{ + UI_draw_roundbox_4fv( + &(const rctf){ + .xmin = ab->cfra, + .xmax = ab->next->cfra, + .ymin = ypos - ctx->ipo_sz, + .ymax = ypos + ctx->ipo_sz, + }, + true, + 3.0f, + (ab->block.conflict & ACTKEYBLOCK_FLAG_NON_BEZIER) ? ctx->ipo_color_mix : ctx->ipo_color); +} + +static void draw_keylist_block(const DrawKeylistUIData *ctx, const ActKeyColumn *ab, float ypos) +{ - if (key_len > 0) { - /* draw keys */ - GPUVertFormat *format = immVertexFormat(); - uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - uint size_id = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); - uint color_id = GPU_vertformat_attr_add( - format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); - uint outline_color_id = GPU_vertformat_attr_add( - format, "outlineColor", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); - uint flags_id = GPU_vertformat_attr_add(format, "flags", GPU_COMP_U32, 1, GPU_FETCH_INT); - - GPU_program_point_size(true); - immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND); - immUniform1f("outline_scale", 1.0f); - immUniform2f("ViewportSize", BLI_rcti_size_x(&v2d->mask) + 1, BLI_rcti_size_y(&v2d->mask) + 1); - immBegin(GPU_PRIM_POINTS, key_len); - - short handle_type = KEYFRAME_HANDLE_NONE, extreme_type = KEYFRAME_EXTREME_NONE; - - LISTBASE_FOREACH (ActKeyColumn *, ak, keys) { - if (IN_RANGE_INCL(ak->cfra, v2d->cur.xmin, v2d->cur.xmax)) { - if (show_ipo) { - handle_type = ak->handle_type; - } - if (saction_flag & SACTION_SHOW_EXTREMES) { - extreme_type = ak->extreme_type; - } - - draw_keyframe_shape(ak->cfra, - ypos, - icon_sz, - (ak->sel & SELECT), - ak->key_type, - KEYFRAME_SHAPE_BOTH, - alpha, - pos_id, - size_id, - color_id, - outline_color_id, - flags_id, - handle_type, - extreme_type); + /* Draw grease pencil bars between keyframes. */ + if ((ab->next != NULL) && (ab->block.flag & ACTKEYBLOCK_FLAG_GPENCIL)) { + draw_keylist_block_gpencil(ctx, ab, ypos); + } + else { + /* Draw other types. */ + UI_draw_roundbox_corner_set(UI_CNR_NONE); + + int valid_hold = actkeyblock_get_valid_hold(ab); + if (valid_hold != 0) { + if ((valid_hold & ACTKEYBLOCK_FLAG_STATIC_HOLD) == 0) { + /* draw "moving hold" long-keyframe block - slightly smaller */ + draw_keylist_block_moving_hold(ctx, ab, ypos); + } + else { + /* draw standard long-keyframe block */ + draw_keylist_block_standard(ctx, ab, ypos); } } - - immEnd(); - GPU_program_point_size(false); - immUnbindProgram(); + if (ctx->show_ipo && actkeyblock_is_valid(ab) && + (ab->block.flag & ACTKEYBLOCK_FLAG_NON_BEZIER)) { + /* draw an interpolation line */ + draw_keylist_block_interpolation_line(ctx, ab, ypos); + } } - - GPU_blend(GPU_BLEND_NONE); } -/* *************************** Channel Drawing Funcs *************************** */ - -void draw_summary_channel( - View2D *v2d, bAnimContext *ac, float ypos, float yscale_fac, int saction_flag) +static void draw_keylist_blocks(const DrawKeylistUIData *ctx, + const ListBase * /*ActKeyColumn*/ columns, + float ypos) { - DLRBT_Tree keys; - - saction_flag &= ~SACTION_SHOW_EXTREMES; + LISTBASE_FOREACH (ActKeyColumn *, ab, columns) { + draw_keylist_block(ctx, ab, ypos); + } +} - BLI_dlrbTree_init(&keys); +static bool draw_keylist_is_visible_key(const View2D *v2d, const ActKeyColumn *ak) +{ + return IN_RANGE_INCL(ak->cfra, v2d->cur.xmin, v2d->cur.xmax); +} - summary_to_keylist(ac, &keys, saction_flag); +static void draw_keylist_keys(const DrawKeylistUIData *ctx, + View2D *v2d, + const KeyframeShaderBindings *sh_bindings, + const ListBase * /*ActKeyColumn*/ keys, + float ypos, + eSAction_Flag saction_flag) +{ + short handle_type = KEYFRAME_HANDLE_NONE, extreme_type = KEYFRAME_EXTREME_NONE; - draw_keylist(v2d, &keys, ypos, yscale_fac, false, saction_flag); + LISTBASE_FOREACH (ActKeyColumn *, ak, keys) { + if (draw_keylist_is_visible_key(v2d, ak)) { + if (ctx->show_ipo) { + handle_type = ak->handle_type; + } + if (saction_flag & SACTION_SHOW_EXTREMES) { + extreme_type = ak->extreme_type; + } - BLI_dlrbTree_free(&keys); + draw_keyframe_shape(ak->cfra, + ypos, + ctx->icon_sz, + (ak->sel & SELECT), + ak->key_type, + KEYFRAME_SHAPE_BOTH, + ctx->alpha, + sh_bindings, + handle_type, + extreme_type); + } + } } -void draw_scene_channel( - View2D *v2d, bDopeSheet *ads, Scene *sce, float ypos, float yscale_fac, int saction_flag) +/* *************************** Drawing Stack *************************** */ +typedef enum eAnimKeylistDrawListElemType { + ANIM_KEYLIST_SUMMARY, + ANIM_KEYLIST_SCENE, + ANIM_KEYLIST_OBJECT, + ANIM_KEYLIST_FCURVE, + ANIM_KEYLIST_ACTION, + ANIM_KEYLIST_AGROUP, + ANIM_KEYLIST_GP_LAYER, + ANIM_KEYLIST_MASK_LAYER, +} eAnimKeylistDrawListElemType; + +typedef struct AnimKeylistDrawListElem { + struct AnimKeylistDrawListElem *next, *prev; + struct AnimKeylist *keylist; + eAnimKeylistDrawListElemType type; + + float yscale_fac; + float ypos; + eSAction_Flag saction_flag; + bool channel_locked; + + bAnimContext *ac; + bDopeSheet *ads; + Scene *sce; + Object *ob; + AnimData *adt; + FCurve *fcu; + bAction *act; + bActionGroup *agrp; + bGPDlayer *gpl; + MaskLayer *masklay; + +} AnimKeylistDrawListElem; + +static void ED_keylist_draw_list_elem_build_keylist(AnimKeylistDrawListElem *elem) { - DLRBT_Tree keys; + switch (elem->type) { + case ANIM_KEYLIST_SUMMARY: { + summary_to_keylist(elem->ac, elem->keylist, elem->saction_flag); + break; + } + case ANIM_KEYLIST_SCENE: { + scene_to_keylist(elem->ads, elem->sce, elem->keylist, elem->saction_flag); + break; + } + case ANIM_KEYLIST_OBJECT: { + ob_to_keylist(elem->ads, elem->ob, elem->keylist, elem->saction_flag); + break; + } + case ANIM_KEYLIST_FCURVE: { + fcurve_to_keylist(elem->adt, elem->fcu, elem->keylist, elem->saction_flag); + break; + } + case ANIM_KEYLIST_ACTION: { + action_to_keylist(elem->adt, elem->act, elem->keylist, elem->saction_flag); + break; + } + case ANIM_KEYLIST_AGROUP: { + agroup_to_keylist(elem->adt, elem->agrp, elem->keylist, elem->saction_flag); + break; + } + case ANIM_KEYLIST_GP_LAYER: { + gpl_to_keylist(elem->ads, elem->gpl, elem->keylist); + break; + } + case ANIM_KEYLIST_MASK_LAYER: { + mask_to_keylist(elem->ads, elem->masklay, elem->keylist); + break; + } + } +} - saction_flag &= ~SACTION_SHOW_EXTREMES; +static void ED_keylist_draw_list_elem_draw_blocks(AnimKeylistDrawListElem *elem, View2D *v2d) +{ + DrawKeylistUIData ctx; + draw_keylist_ui_data_init(&ctx, v2d, elem->yscale_fac, elem->channel_locked, elem->saction_flag); - BLI_dlrbTree_init(&keys); + const ListBase *keys = ED_keylist_listbase(elem->keylist); + draw_keylist_blocks(&ctx, keys, elem->ypos); +} - scene_to_keylist(ads, sce, &keys, saction_flag); +static void ED_keylist_draw_list_elem_draw_keys(AnimKeylistDrawListElem *elem, + View2D *v2d, + const KeyframeShaderBindings *sh_bindings) +{ + DrawKeylistUIData ctx; + draw_keylist_ui_data_init(&ctx, v2d, elem->yscale_fac, elem->channel_locked, elem->saction_flag); + const ListBase *keys = ED_keylist_listbase(elem->keylist); + draw_keylist_keys(&ctx, v2d, sh_bindings, keys, elem->ypos, elem->saction_flag); +} - draw_keylist(v2d, &keys, ypos, yscale_fac, false, saction_flag); +typedef struct AnimKeylistDrawList { + ListBase /* AnimKeylistDrawListElem*/ channels; +} AnimKeylistDrawList; - BLI_dlrbTree_free(&keys); +AnimKeylistDrawList *ED_keylist_draw_list_create(void) +{ + return MEM_callocN(sizeof(AnimKeylistDrawList), __func__); } -void draw_object_channel( - View2D *v2d, bDopeSheet *ads, Object *ob, float ypos, float yscale_fac, int saction_flag) +static void ED_keylist_draw_list_build_keylists(AnimKeylistDrawList *draw_list) { - DLRBT_Tree keys; - - saction_flag &= ~SACTION_SHOW_EXTREMES; - - BLI_dlrbTree_init(&keys); + LISTBASE_FOREACH (AnimKeylistDrawListElem *, elem, &draw_list->channels) { + ED_keylist_draw_list_elem_build_keylist(elem); + } +} - ob_to_keylist(ads, ob, &keys, saction_flag); +static void ED_keylist_draw_list_draw_blocks(AnimKeylistDrawList *draw_list, View2D *v2d) +{ + LISTBASE_FOREACH (AnimKeylistDrawListElem *, elem, &draw_list->channels) { + ED_keylist_draw_list_elem_draw_blocks(elem, v2d); + } +} - draw_keylist(v2d, &keys, ypos, yscale_fac, false, saction_flag); +static int ED_keylist_draw_keylist_visible_key_len(const View2D *v2d, + const ListBase * /*ActKeyColumn*/ keys) +{ + /* count keys */ + uint len = 0; - BLI_dlrbTree_free(&keys); + LISTBASE_FOREACH (ActKeyColumn *, ak, keys) { + /* Optimization: if keyframe doesn't appear within 5 units (screenspace) + * in visible area, don't draw. + * This might give some improvements, + * since we current have to flip between view/region matrices. + */ + if (draw_keylist_is_visible_key(v2d, ak)) { + len++; + } + } + return len; } -void draw_fcurve_channel( - View2D *v2d, AnimData *adt, FCurve *fcu, float ypos, float yscale_fac, int saction_flag) +static int ED_keylist_draw_list_visible_key_len(const AnimKeylistDrawList *draw_list, + const View2D *v2d) { - DLRBT_Tree keys; + uint len = 0; + LISTBASE_FOREACH (AnimKeylistDrawListElem *, elem, &draw_list->channels) { + const ListBase *keys = ED_keylist_listbase(elem->keylist); + len += ED_keylist_draw_keylist_visible_key_len(v2d, keys); + } + return len; +} - bool locked = (fcu->flag & FCURVE_PROTECTED) || - ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) || - ((adt && adt->action) && ID_IS_LINKED(adt->action)); +static void ED_keylist_draw_list_draw_keys(AnimKeylistDrawList *draw_list, View2D *v2d) +{ + const int visible_key_len = ED_keylist_draw_list_visible_key_len(draw_list, v2d); + if (visible_key_len == 0) { + return; + } - BLI_dlrbTree_init(&keys); + GPU_blend(GPU_BLEND_ALPHA); - fcurve_to_keylist(adt, fcu, &keys, saction_flag); + GPUVertFormat *format = immVertexFormat(); + KeyframeShaderBindings sh_bindings; + + sh_bindings.pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + sh_bindings.size_id = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); + sh_bindings.color_id = GPU_vertformat_attr_add( + format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); + sh_bindings.outline_color_id = GPU_vertformat_attr_add( + format, "outlineColor", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); + sh_bindings.flags_id = GPU_vertformat_attr_add(format, "flags", GPU_COMP_U32, 1, GPU_FETCH_INT); + + GPU_program_point_size(true); + immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND); + immUniform1f("outline_scale", 1.0f); + immUniform2f("ViewportSize", BLI_rcti_size_x(&v2d->mask) + 1, BLI_rcti_size_y(&v2d->mask) + 1); + immBegin(GPU_PRIM_POINTS, visible_key_len); + + LISTBASE_FOREACH (AnimKeylistDrawListElem *, elem, &draw_list->channels) { + ED_keylist_draw_list_elem_draw_keys(elem, v2d, &sh_bindings); + } - draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag); + immEnd(); + GPU_program_point_size(false); + immUnbindProgram(); - BLI_dlrbTree_free(&keys); + GPU_blend(GPU_BLEND_NONE); } -void draw_agroup_channel( - View2D *v2d, AnimData *adt, bActionGroup *agrp, float ypos, float yscale_fac, int saction_flag) +static void ED_keylist_draw_list_draw(AnimKeylistDrawList *draw_list, View2D *v2d) { - DLRBT_Tree keys; + ED_keylist_draw_list_draw_blocks(draw_list, v2d); + ED_keylist_draw_list_draw_keys(draw_list, v2d); +} - bool locked = (agrp->flag & AGRP_PROTECTED) || - ((adt && adt->action) && ID_IS_LINKED(adt->action)); +void ED_keylist_draw_list_flush(AnimKeylistDrawList *draw_list, View2D *v2d) +{ + ED_keylist_draw_list_build_keylists(draw_list); + ED_keylist_draw_list_draw(draw_list, v2d); +} - BLI_dlrbTree_init(&keys); +void ED_keylist_draw_list_free(AnimKeylistDrawList *draw_list) +{ + LISTBASE_FOREACH (AnimKeylistDrawListElem *, elem, &draw_list->channels) { + ED_keylist_free(elem->keylist); + } + BLI_freelistN(&draw_list->channels); + MEM_freeN(draw_list); +} - agroup_to_keylist(adt, agrp, &keys, saction_flag); +static AnimKeylistDrawListElem *ed_keylist_draw_list_add_elem( + AnimKeylistDrawList *draw_list, + eAnimKeylistDrawListElemType elem_type, + float ypos, + float yscale_fac, + eSAction_Flag saction_flag) +{ + AnimKeylistDrawListElem *draw_elem = MEM_callocN(sizeof(AnimKeylistDrawListElem), __func__); + BLI_addtail(&draw_list->channels, draw_elem); + draw_elem->type = elem_type; + draw_elem->keylist = ED_keylist_create(); + draw_elem->ypos = ypos; + draw_elem->yscale_fac = yscale_fac; + draw_elem->saction_flag = saction_flag; + return draw_elem; +} - draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag); +/* *************************** Channel Drawing Funcs *************************** */ - BLI_dlrbTree_free(&keys); +void draw_summary_channel(struct AnimKeylistDrawList *draw_list, + bAnimContext *ac, + float ypos, + float yscale_fac, + int saction_flag) +{ + saction_flag &= ~SACTION_SHOW_EXTREMES; + AnimKeylistDrawListElem *draw_elem = ed_keylist_draw_list_add_elem( + draw_list, ANIM_KEYLIST_SUMMARY, ypos, yscale_fac, saction_flag); + draw_elem->ac = ac; } -void draw_action_channel( - View2D *v2d, AnimData *adt, bAction *act, float ypos, float yscale_fac, int saction_flag) +void draw_scene_channel(AnimKeylistDrawList *draw_list, + bDopeSheet *ads, + Scene *sce, + float ypos, + float yscale_fac, + int saction_flag) { - DLRBT_Tree keys; - - bool locked = (act && ID_IS_LINKED(act)); - saction_flag &= ~SACTION_SHOW_EXTREMES; + AnimKeylistDrawListElem *draw_elem = ed_keylist_draw_list_add_elem( + draw_list, ANIM_KEYLIST_SCENE, ypos, yscale_fac, saction_flag); + draw_elem->ads = ads; + draw_elem->sce = sce; +} - BLI_dlrbTree_init(&keys); +void draw_object_channel(AnimKeylistDrawList *draw_list, + bDopeSheet *ads, + Object *ob, + float ypos, + float yscale_fac, + int saction_flag) +{ + saction_flag &= ~SACTION_SHOW_EXTREMES; + AnimKeylistDrawListElem *draw_elem = ed_keylist_draw_list_add_elem( + draw_list, ANIM_KEYLIST_OBJECT, ypos, yscale_fac, saction_flag); + draw_elem->ads = ads; + draw_elem->ob = ob; +} - action_to_keylist(adt, act, &keys, saction_flag); +void draw_fcurve_channel(AnimKeylistDrawList *draw_list, + AnimData *adt, + FCurve *fcu, + float ypos, + float yscale_fac, + int saction_flag) +{ + const bool locked = (fcu->flag & FCURVE_PROTECTED) || + ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) || + ((adt && adt->action) && ID_IS_LINKED(adt->action)); + + AnimKeylistDrawListElem *draw_elem = ed_keylist_draw_list_add_elem( + draw_list, ANIM_KEYLIST_FCURVE, ypos, yscale_fac, saction_flag); + draw_elem->adt = adt; + draw_elem->fcu = fcu; + draw_elem->channel_locked = locked; +} - draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag); +void draw_agroup_channel(AnimKeylistDrawList *draw_list, + AnimData *adt, + bActionGroup *agrp, + float ypos, + float yscale_fac, + int saction_flag) +{ + bool locked = (agrp->flag & AGRP_PROTECTED) || + ((adt && adt->action) && ID_IS_LINKED(adt->action)); - BLI_dlrbTree_free(&keys); + AnimKeylistDrawListElem *draw_elem = ed_keylist_draw_list_add_elem( + draw_list, ANIM_KEYLIST_AGROUP, ypos, yscale_fac, saction_flag); + draw_elem->adt = adt; + draw_elem->agrp = agrp; + draw_elem->channel_locked = locked; } -void draw_gpencil_channel( - View2D *v2d, bDopeSheet *ads, bGPdata *gpd, float ypos, float yscale_fac, int saction_flag) +void draw_action_channel(AnimKeylistDrawList *draw_list, + AnimData *adt, + bAction *act, + float ypos, + float yscale_fac, + int saction_flag) { - DLRBT_Tree keys; - + const bool locked = (act && ID_IS_LINKED(act)); saction_flag &= ~SACTION_SHOW_EXTREMES; - BLI_dlrbTree_init(&keys); - - gpencil_to_keylist(ads, gpd, &keys, false); - - draw_keylist(v2d, &keys, ypos, yscale_fac, false, saction_flag); - - BLI_dlrbTree_free(&keys); + AnimKeylistDrawListElem *draw_elem = ed_keylist_draw_list_add_elem( + draw_list, ANIM_KEYLIST_ACTION, ypos, yscale_fac, saction_flag); + draw_elem->adt = adt; + draw_elem->act = act; + draw_elem->channel_locked = locked; } -void draw_gpl_channel( - View2D *v2d, bDopeSheet *ads, bGPDlayer *gpl, float ypos, float yscale_fac, int saction_flag) +void draw_gpl_channel(AnimKeylistDrawList *draw_list, + bDopeSheet *ads, + bGPDlayer *gpl, + float ypos, + float yscale_fac, + int saction_flag) { - DLRBT_Tree keys; - bool locked = (gpl->flag & GP_LAYER_LOCKED) != 0; - - BLI_dlrbTree_init(&keys); - - gpl_to_keylist(ads, gpl, &keys); - - draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag); - - BLI_dlrbTree_free(&keys); + AnimKeylistDrawListElem *draw_elem = ed_keylist_draw_list_add_elem( + draw_list, ANIM_KEYLIST_GP_LAYER, ypos, yscale_fac, saction_flag); + draw_elem->ads = ads; + draw_elem->gpl = gpl; + draw_elem->channel_locked = locked; } -void draw_masklay_channel(View2D *v2d, +void draw_masklay_channel(AnimKeylistDrawList *draw_list, bDopeSheet *ads, MaskLayer *masklay, float ypos, float yscale_fac, int saction_flag) { - DLRBT_Tree keys; - bool locked = (masklay->flag & MASK_LAYERFLAG_LOCKED) != 0; - - BLI_dlrbTree_init(&keys); - - mask_to_keylist(ads, masklay, &keys); - - draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag); - - BLI_dlrbTree_free(&keys); + AnimKeylistDrawListElem *draw_elem = ed_keylist_draw_list_add_elem( + draw_list, ANIM_KEYLIST_MASK_LAYER, ypos, yscale_fac, saction_flag); + draw_elem->ads = ads; + draw_elem->masklay = masklay; + draw_elem->channel_locked = locked; } diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index eb91afa5c84..75ce62d5e27 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -92,10 +92,7 @@ void delete_fcurve_key(FCurve *fcu, int index, bool do_recalc) fcu->totvert--; if (fcu->totvert == 0) { - if (fcu->bezt) { - MEM_freeN(fcu->bezt); - } - fcu->bezt = NULL; + MEM_SAFE_FREE(fcu->bezt); } /* recalc handles - only if it won't cause problems */ @@ -136,10 +133,7 @@ bool delete_fcurve_keys(FCurve *fcu) void clear_fcurve_keys(FCurve *fcu) { - if (fcu->bezt) { - MEM_freeN(fcu->bezt); - } - fcu->bezt = NULL; + MEM_SAFE_FREE(fcu->bezt); fcu->totvert = 0; } diff --git a/source/blender/editors/animation/keyframes_keylist.c b/source/blender/editors/animation/keyframes_keylist.cc index 47ed2b56300..f6ade11a517 100644 --- a/source/blender/editors/animation/keyframes_keylist.c +++ b/source/blender/editors/animation/keyframes_keylist.cc @@ -23,15 +23,16 @@ /* System includes ----------------------------------------------------- */ -#include <float.h> -#include <math.h> -#include <stdlib.h> -#include <string.h> +#include <cfloat> +#include <cmath> +#include <cstdlib> +#include <cstring> #include "MEM_guardedalloc.h" #include "BLI_dlrbTree.h" #include "BLI_listbase.h" +#include "BLI_range.h" #include "BLI_utildefines.h" #include "DNA_anim_types.h" @@ -46,16 +47,97 @@ #include "ED_anim_api.h" #include "ED_keyframes_keylist.h" +extern "C" { /* *************************** Keyframe Processing *************************** */ +struct AnimKeylist { + DLRBT_Tree keys; +}; + +static void ED_keylist_init(AnimKeylist *keylist) +{ + BLI_dlrbTree_init(&keylist->keys); +} + +AnimKeylist *ED_keylist_create(void) +{ + AnimKeylist *keylist = static_cast<AnimKeylist *>(MEM_callocN(sizeof(AnimKeylist), __func__)); + ED_keylist_init(keylist); + return keylist; +} + +void ED_keylist_free(AnimKeylist *keylist) +{ + BLI_assert(keylist); + BLI_dlrbTree_free(&keylist->keys); + MEM_freeN(keylist); +} + +const ActKeyColumn *ED_keylist_find_exact(const AnimKeylist *keylist, float cfra) +{ + return (const ActKeyColumn *)BLI_dlrbTree_search_exact( + &keylist->keys, compare_ak_cfraPtr, &cfra); +} + +const ActKeyColumn *ED_keylist_find_next(const AnimKeylist *keylist, float cfra) +{ + return (const ActKeyColumn *)BLI_dlrbTree_search_next(&keylist->keys, compare_ak_cfraPtr, &cfra); +} + +const ActKeyColumn *ED_keylist_find_prev(const AnimKeylist *keylist, float cfra) +{ + return (const ActKeyColumn *)BLI_dlrbTree_search_prev(&keylist->keys, compare_ak_cfraPtr, &cfra); +} + +/* TODO(jbakker): Should we change this to use `ED_keylist_find_next(keys, min_fra)` and only check + * boundary of `max_fra`. */ +const ActKeyColumn *ED_keylist_find_any_between(const AnimKeylist *keylist, + const Range2f frame_range) +{ + for (const ActKeyColumn *ak = static_cast<const ActKeyColumn *>(keylist->keys.root); ak; + ak = static_cast<const ActKeyColumn *>((ak->cfra < frame_range.min) ? ak->right : + ak->left)) { + if (range2f_in_range(&frame_range, ak->cfra)) { + return ak; + } + } + return nullptr; +} + +bool ED_keylist_is_empty(const struct AnimKeylist *keylist) +{ + return keylist->keys.root == nullptr; +} + +const struct ListBase *ED_keylist_listbase(const AnimKeylist *keylist) +{ + return (ListBase *)&keylist->keys; +} + +bool ED_keylist_frame_range(const struct AnimKeylist *keylist, Range2f *r_frame_range) +{ + BLI_assert(r_frame_range); + + if (ED_keylist_is_empty(keylist)) { + return false; + } + + const ActKeyColumn *first_column = (const ActKeyColumn *)keylist->keys.first; + r_frame_range->min = first_column->cfra; + + const ActKeyColumn *last_column = (const ActKeyColumn *)keylist->keys.last; + r_frame_range->max = last_column->cfra; + + return true; +} /* ActKeyColumns (Keyframe Columns) ------------------------------------------ */ -BLI_INLINE bool is_cfra_eq(float a, float b) +BLI_INLINE bool is_cfra_eq(const float a, const float b) { return IS_EQT(a, b, BEZT_BINARYSEARCH_THRESH); } -BLI_INLINE bool is_cfra_lt(float a, float b) +BLI_INLINE bool is_cfra_lt(const float a, const float b) { return (b - a) > BEZT_BINARYSEARCH_THRESH; } @@ -65,8 +147,8 @@ BLI_INLINE bool is_cfra_lt(float a, float b) short compare_ak_cfraPtr(void *node, void *data) { ActKeyColumn *ak = (ActKeyColumn *)node; - const float *cframe = data; - float val = *cframe; + const float *cframe = static_cast<const float *>(data); + const float val = *cframe; if (is_cfra_eq(val, ak->cfra)) { return 0; @@ -81,16 +163,16 @@ short compare_ak_cfraPtr(void *node, void *data) /* --------------- */ /* Set of references to three logically adjacent keys. */ -typedef struct BezTripleChain { +struct BezTripleChain { /* Current keyframe. */ BezTriple *cur; - /* Logical neighbors. May be NULL. */ + /* Logical neighbors. May be nullptr. */ BezTriple *prev, *next; -} BezTripleChain; +}; /* Categorize the interpolation & handle type of the keyframe. */ -static eKeyframeHandleDrawOpts bezt_handle_type(BezTriple *bezt) +static eKeyframeHandleDrawOpts bezt_handle_type(const BezTriple *bezt) { if (bezt->h1 == HD_AUTO_ANIM && bezt->h2 == HD_AUTO_ANIM) { return KEYFRAME_HANDLE_AUTO_CLAMP; @@ -110,14 +192,14 @@ static eKeyframeHandleDrawOpts bezt_handle_type(BezTriple *bezt) /* Determine if the keyframe is an extreme by comparing with neighbors. * Ends of fixed-value sections and of the whole curve are also marked. */ -static eKeyframeExtremeDrawOpts bezt_extreme_type(BezTripleChain *chain) +static eKeyframeExtremeDrawOpts bezt_extreme_type(const BezTripleChain *chain) { - if (chain->prev == NULL && chain->next == NULL) { + if (chain->prev == nullptr && chain->next == nullptr) { return KEYFRAME_EXTREME_NONE; } /* Keyframe values for the current one and neighbors. */ - float cur_y = chain->cur->vec[1][1]; + const float cur_y = chain->cur->vec[1][1]; float prev_y = cur_y, next_y = cur_y; if (chain->prev && !IS_EQF(cur_y, chain->prev->vec[1][1])) { @@ -138,22 +220,24 @@ static eKeyframeExtremeDrawOpts bezt_extreme_type(BezTripleChain *chain) } /* Bezier handle values for the overshoot check. */ - bool l_bezier = chain->prev && chain->prev->ipo == BEZT_IPO_BEZ; - bool r_bezier = chain->next && chain->cur->ipo == BEZT_IPO_BEZ; - float handle_l = l_bezier ? chain->cur->vec[0][1] : cur_y; - float handle_r = r_bezier ? chain->cur->vec[2][1] : cur_y; + const bool l_bezier = chain->prev && chain->prev->ipo == BEZT_IPO_BEZ; + const bool r_bezier = chain->next && chain->cur->ipo == BEZT_IPO_BEZ; + const float handle_l = l_bezier ? chain->cur->vec[0][1] : cur_y; + const float handle_r = r_bezier ? chain->cur->vec[2][1] : cur_y; /* Detect extremes. One of the neighbors is allowed to be equal to current. */ if (prev_y < cur_y || next_y < cur_y) { - bool is_overshoot = (handle_l > cur_y || handle_r > cur_y); + const bool is_overshoot = (handle_l > cur_y || handle_r > cur_y); - return KEYFRAME_EXTREME_MAX | (is_overshoot ? KEYFRAME_EXTREME_MIXED : 0); + return static_cast<eKeyframeExtremeDrawOpts>(KEYFRAME_EXTREME_MAX | + (is_overshoot ? KEYFRAME_EXTREME_MIXED : 0)); } if (prev_y > cur_y || next_y > cur_y) { - bool is_overshoot = (handle_l < cur_y || handle_r < cur_y); + const bool is_overshoot = (handle_l < cur_y || handle_r < cur_y); - return KEYFRAME_EXTREME_MIN | (is_overshoot ? KEYFRAME_EXTREME_MIXED : 0); + return static_cast<eKeyframeExtremeDrawOpts>(KEYFRAME_EXTREME_MIN | + (is_overshoot ? KEYFRAME_EXTREME_MIXED : 0)); } return KEYFRAME_EXTREME_NONE; @@ -162,7 +246,7 @@ static eKeyframeExtremeDrawOpts bezt_extreme_type(BezTripleChain *chain) /* Comparator callback used for ActKeyColumns and BezTripleChain */ static short compare_ak_bezt(void *node, void *data) { - BezTripleChain *chain = data; + BezTripleChain *chain = static_cast<BezTripleChain *>(data); return compare_ak_cfraPtr(node, &chain->cur->vec[1][0]); } @@ -170,9 +254,10 @@ static short compare_ak_bezt(void *node, void *data) /* New node callback used for building ActKeyColumns from BezTripleChain */ static DLRBT_Node *nalloc_ak_bezt(void *data) { - ActKeyColumn *ak = MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumn"); - BezTripleChain *chain = data; - BezTriple *bezt = chain->cur; + ActKeyColumn *ak = static_cast<ActKeyColumn *>( + MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumn")); + const BezTripleChain *chain = static_cast<const BezTripleChain *>(data); + const BezTriple *bezt = chain->cur; /* store settings based on state of BezTriple */ ak->cfra = bezt->vec[1][0]; @@ -190,9 +275,9 @@ static DLRBT_Node *nalloc_ak_bezt(void *data) /* Node updater callback used for building ActKeyColumns from BezTripleChain */ static void nupdate_ak_bezt(void *node, void *data) { - ActKeyColumn *ak = node; - BezTripleChain *chain = data; - BezTriple *bezt = chain->cur; + ActKeyColumn *ak = static_cast<ActKeyColumn *>(node); + const BezTripleChain *chain = static_cast<const BezTripleChain *>(data); + const BezTriple *bezt = chain->cur; /* set selection status and 'touched' status */ if (BEZT_ISSEL_ANY(bezt)) { @@ -209,10 +294,10 @@ static void nupdate_ak_bezt(void *node, void *data) } /* For interpolation type, select the highest value (enum is sorted). */ - ak->handle_type = MAX2(ak->handle_type, bezt_handle_type(bezt)); + ak->handle_type = MAX2((eKeyframeHandleDrawOpts)ak->handle_type, bezt_handle_type(bezt)); /* For extremes, detect when combining different states. */ - char new_extreme = bezt_extreme_type(chain); + const char new_extreme = bezt_extreme_type(chain); if (new_extreme != ak->extreme_type) { /* Replace the flat status without adding mixed. */ @@ -230,7 +315,7 @@ static void nupdate_ak_bezt(void *node, void *data) /* Comparator callback used for ActKeyColumns and GPencil frame */ static short compare_ak_gpframe(void *node, void *data) { - bGPDframe *gpf = (bGPDframe *)data; + const bGPDframe *gpf = (bGPDframe *)data; float frame = gpf->framenum; return compare_ak_cfraPtr(node, &frame); @@ -239,8 +324,9 @@ static short compare_ak_gpframe(void *node, void *data) /* New node callback used for building ActKeyColumns from GPencil frames */ static DLRBT_Node *nalloc_ak_gpframe(void *data) { - ActKeyColumn *ak = MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumnGPF"); - bGPDframe *gpf = (bGPDframe *)data; + ActKeyColumn *ak = static_cast<ActKeyColumn *>( + MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumnGPF")); + const bGPDframe *gpf = (bGPDframe *)data; /* store settings based on state of BezTriple */ ak->cfra = gpf->framenum; @@ -261,7 +347,7 @@ static DLRBT_Node *nalloc_ak_gpframe(void *data) static void nupdate_ak_gpframe(void *node, void *data) { ActKeyColumn *ak = (ActKeyColumn *)node; - bGPDframe *gpf = (bGPDframe *)data; + const bGPDframe *gpf = (bGPDframe *)data; /* set selection status and 'touched' status */ if (gpf->flag & GP_FRAME_SELECT) { @@ -283,7 +369,7 @@ static void nupdate_ak_gpframe(void *node, void *data) /* Comparator callback used for ActKeyColumns and GPencil frame */ static short compare_ak_masklayshape(void *node, void *data) { - MaskLayerShape *masklay_shape = (MaskLayerShape *)data; + const MaskLayerShape *masklay_shape = (const MaskLayerShape *)data; float frame = masklay_shape->frame; return compare_ak_cfraPtr(node, &frame); @@ -292,8 +378,9 @@ static short compare_ak_masklayshape(void *node, void *data) /* New node callback used for building ActKeyColumns from GPencil frames */ static DLRBT_Node *nalloc_ak_masklayshape(void *data) { - ActKeyColumn *ak = MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumnGPF"); - MaskLayerShape *masklay_shape = (MaskLayerShape *)data; + ActKeyColumn *ak = static_cast<ActKeyColumn *>( + MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumnGPF")); + const MaskLayerShape *masklay_shape = (const MaskLayerShape *)data; /* store settings based on state of BezTriple */ ak->cfra = masklay_shape->frame; @@ -309,7 +396,7 @@ static DLRBT_Node *nalloc_ak_masklayshape(void *data) static void nupdate_ak_masklayshape(void *node, void *data) { ActKeyColumn *ak = (ActKeyColumn *)node; - MaskLayerShape *masklay_shape = (MaskLayerShape *)data; + const MaskLayerShape *masklay_shape = (const MaskLayerShape *)data; /* set selection status and 'touched' status */ if (masklay_shape->flag & MASK_SHAPE_SELECT) { @@ -323,33 +410,33 @@ static void nupdate_ak_masklayshape(void *node, void *data) /* --------------- */ /* Add the given BezTriple to the given 'list' of Keyframes */ -static void add_bezt_to_keycolumns_list(DLRBT_Tree *keys, BezTripleChain *bezt) +static void add_bezt_to_keycolumns_list(AnimKeylist *keylist, BezTripleChain *bezt) { - if (ELEM(NULL, keys, bezt)) { + if (ELEM(nullptr, keylist, bezt)) { return; } - BLI_dlrbTree_add(keys, compare_ak_bezt, nalloc_ak_bezt, nupdate_ak_bezt, bezt); + BLI_dlrbTree_add(&keylist->keys, compare_ak_bezt, nalloc_ak_bezt, nupdate_ak_bezt, bezt); } /* Add the given GPencil Frame to the given 'list' of Keyframes */ -static void add_gpframe_to_keycolumns_list(DLRBT_Tree *keys, bGPDframe *gpf) +static void add_gpframe_to_keycolumns_list(AnimKeylist *keylist, bGPDframe *gpf) { - if (ELEM(NULL, keys, gpf)) { + if (ELEM(nullptr, keylist, gpf)) { return; } - BLI_dlrbTree_add(keys, compare_ak_gpframe, nalloc_ak_gpframe, nupdate_ak_gpframe, gpf); + BLI_dlrbTree_add(&keylist->keys, compare_ak_gpframe, nalloc_ak_gpframe, nupdate_ak_gpframe, gpf); } /* Add the given MaskLayerShape Frame to the given 'list' of Keyframes */ -static void add_masklay_to_keycolumns_list(DLRBT_Tree *keys, MaskLayerShape *masklay_shape) +static void add_masklay_to_keycolumns_list(AnimKeylist *keylist, MaskLayerShape *masklay_shape) { - if (ELEM(NULL, keys, masklay_shape)) { + if (ELEM(nullptr, keylist, masklay_shape)) { return; } - BLI_dlrbTree_add(keys, + BLI_dlrbTree_add(&keylist->keys, compare_ak_masklayshape, nalloc_ak_masklayshape, nupdate_ak_masklayshape, @@ -360,7 +447,9 @@ static void add_masklay_to_keycolumns_list(DLRBT_Tree *keys, MaskLayerShape *mas static const ActKeyBlockInfo dummy_keyblock = {0}; -static void compute_keyblock_data(ActKeyBlockInfo *info, BezTriple *prev, BezTriple *beztn) +static void compute_keyblock_data(ActKeyBlockInfo *info, + const BezTriple *prev, + const BezTriple *beztn) { memset(info, 0, sizeof(ActKeyBlockInfo)); @@ -423,34 +512,34 @@ static void add_keyblock_info(ActKeyColumn *col, const ActKeyBlockInfo *block) } } -static void add_bezt_to_keyblocks_list(DLRBT_Tree *keys, BezTriple *bezt, int bezt_len) +static void add_bezt_to_keyblocks_list(AnimKeylist *keylist, BezTriple *bezt, const int bezt_len) { - ActKeyColumn *col = keys->first; + ActKeyColumn *col = static_cast<ActKeyColumn *>(keylist->keys.first); if (bezt && bezt_len >= 2) { ActKeyBlockInfo block; /* Find the first key column while inserting dummy blocks. */ - for (; col != NULL && is_cfra_lt(col->cfra, bezt[0].vec[1][0]); col = col->next) { + for (; col != nullptr && is_cfra_lt(col->cfra, bezt[0].vec[1][0]); col = col->next) { add_keyblock_info(col, &dummy_keyblock); } - BLI_assert(col != NULL); + BLI_assert(col != nullptr); /* Insert real blocks. */ - for (int v = 1; col != NULL && v < bezt_len; v++, bezt++) { + for (int v = 1; col != nullptr && v < bezt_len; v++, bezt++) { /* Wrong order of bezier keys: resync position. */ if (is_cfra_lt(bezt[1].vec[1][0], bezt[0].vec[1][0])) { /* Backtrack to find the right location. */ if (is_cfra_lt(bezt[1].vec[1][0], col->cfra)) { ActKeyColumn *newcol = (ActKeyColumn *)BLI_dlrbTree_search_exact( - keys, compare_ak_cfraPtr, &bezt[1].vec[1][0]); + &keylist->keys, compare_ak_cfraPtr, &bezt[1].vec[1][0]); - if (newcol != NULL) { + if (newcol != nullptr) { col = newcol; /* The previous keyblock is garbage too. */ - if (col->prev != NULL) { + if (col->prev != nullptr) { add_keyblock_info(col->prev, &dummy_keyblock); } } @@ -467,16 +556,16 @@ static void add_bezt_to_keyblocks_list(DLRBT_Tree *keys, BezTriple *bezt, int be compute_keyblock_data(&block, bezt, bezt + 1); - for (; col != NULL && is_cfra_lt(col->cfra, bezt[1].vec[1][0]); col = col->next) { + for (; col != nullptr && is_cfra_lt(col->cfra, bezt[1].vec[1][0]); col = col->next) { add_keyblock_info(col, &block); } - BLI_assert(col != NULL); + BLI_assert(col != nullptr); } } /* Insert dummy blocks at the end. */ - for (; col != NULL; col = col->next) { + for (; col != nullptr; col = col->next) { add_keyblock_info(col, &dummy_keyblock); } } @@ -486,28 +575,28 @@ static void add_bezt_to_keyblocks_list(DLRBT_Tree *keys, BezTriple *bezt, int be * This must be called even by animation sources that don't generate * keyblocks to keep the data structure consistent after adding columns. */ -static void update_keyblocks(DLRBT_Tree *keys, BezTriple *bezt, int bezt_len) +static void update_keyblocks(AnimKeylist *keylist, BezTriple *bezt, const int bezt_len) { /* Recompute the prev/next linked list. */ - BLI_dlrbTree_linkedlist_sync(keys); + BLI_dlrbTree_linkedlist_sync(&keylist->keys); /* Find the curve count */ int max_curve = 0; - LISTBASE_FOREACH (ActKeyColumn *, col, keys) { + LISTBASE_FOREACH (ActKeyColumn *, col, &keylist->keys) { max_curve = MAX2(max_curve, col->totcurve); } /* Propagate blocks to inserted keys */ - ActKeyColumn *prev_ready = NULL; + ActKeyColumn *prev_ready = nullptr; - LISTBASE_FOREACH (ActKeyColumn *, col, keys) { + LISTBASE_FOREACH (ActKeyColumn *, col, &keylist->keys) { /* Pre-existing column. */ if (col->totcurve > 0) { prev_ready = col; } /* Newly inserted column, so copy block data from previous. */ - else if (prev_ready != NULL) { + else if (prev_ready != nullptr) { col->totblock = prev_ready->totblock; memcpy(&col->block, &prev_ready->block, sizeof(ActKeyBlockInfo)); } @@ -516,18 +605,18 @@ static void update_keyblocks(DLRBT_Tree *keys, BezTriple *bezt, int bezt_len) } /* Add blocks on top */ - add_bezt_to_keyblocks_list(keys, bezt, bezt_len); + add_bezt_to_keyblocks_list(keylist, bezt, bezt_len); } /* --------- */ -bool actkeyblock_is_valid(ActKeyColumn *ac) +bool actkeyblock_is_valid(const ActKeyColumn *ac) { - return ac != NULL && ac->next != NULL && ac->totblock > 0; + return ac != nullptr && ac->next != nullptr && ac->totblock > 0; } /* Checks if ActKeyBlock should exist... */ -int actkeyblock_get_valid_hold(ActKeyColumn *ac) +int actkeyblock_get_valid_hold(const ActKeyColumn *ac) { /* check that block is valid */ if (!actkeyblock_is_valid(ac)) { @@ -540,34 +629,32 @@ int actkeyblock_get_valid_hold(ActKeyColumn *ac) /* *************************** Keyframe List Conversions *************************** */ -void summary_to_keylist(bAnimContext *ac, DLRBT_Tree *keys, int saction_flag) +void summary_to_keylist(bAnimContext *ac, AnimKeylist *keylist, const int saction_flag) { if (ac) { - ListBase anim_data = {NULL, NULL}; - bAnimListElem *ale; - int filter; + ListBase anim_data = {nullptr, nullptr}; /* get F-Curves to take keyframes from */ - filter = ANIMFILTER_DATA_VISIBLE; - ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); + const eAnimFilter_Flags filter = ANIMFILTER_DATA_VISIBLE; + ANIM_animdata_filter( + ac, &anim_data, filter, ac->data, static_cast<eAnimCont_Types>(ac->datatype)); /* loop through each F-Curve, grabbing the keyframes */ - for (ale = anim_data.first; ale; ale = ale->next) { + LISTBASE_FOREACH (const bAnimListElem *, ale, &anim_data) { /* Why not use all #eAnim_KeyType here? * All of the other key types are actually "summaries" themselves, * and will just end up duplicating stuff that comes up through * standard filtering of just F-Curves. Given the way that these work, * there isn't really any benefit at all from including them. - Aligorith */ - switch (ale->datatype) { case ALE_FCURVE: - fcurve_to_keylist(ale->adt, ale->data, keys, saction_flag); + fcurve_to_keylist(ale->adt, static_cast<FCurve *>(ale->data), keylist, saction_flag); break; case ALE_MASKLAY: - mask_to_keylist(ac->ads, ale->data, keys); + mask_to_keylist(ac->ads, static_cast<MaskLayer *>(ale->data), keylist); break; case ALE_GPFRAME: - gpl_to_keylist(ac->ads, ale->data, keys); + gpl_to_keylist(ac->ads, static_cast<bGPDlayer *>(ale->data), keylist); break; default: // printf("%s: datatype %d unhandled\n", __func__, ale->datatype); @@ -579,16 +666,14 @@ void summary_to_keylist(bAnimContext *ac, DLRBT_Tree *keys, int saction_flag) } } -void scene_to_keylist(bDopeSheet *ads, Scene *sce, DLRBT_Tree *keys, int saction_flag) +void scene_to_keylist(bDopeSheet *ads, Scene *sce, AnimKeylist *keylist, const int saction_flag) { - bAnimContext ac = {NULL}; - ListBase anim_data = {NULL, NULL}; - bAnimListElem *ale; - int filter; + bAnimContext ac = {nullptr}; + ListBase anim_data = {nullptr, nullptr}; - bAnimListElem dummychan = {NULL}; + bAnimListElem dummychan = {nullptr}; - if (sce == NULL) { + if (sce == nullptr) { return; } @@ -603,28 +688,27 @@ void scene_to_keylist(bDopeSheet *ads, Scene *sce, DLRBT_Tree *keys, int saction ac.datatype = ANIMCONT_CHANNEL; /* get F-Curves to take keyframes from */ - filter = ANIMFILTER_DATA_VISIBLE; /* curves only */ - ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); + const eAnimFilter_Flags filter = ANIMFILTER_DATA_VISIBLE; /* curves only */ + ANIM_animdata_filter( + &ac, &anim_data, filter, ac.data, static_cast<eAnimCont_Types>(ac.datatype)); /* loop through each F-Curve, grabbing the keyframes */ - for (ale = anim_data.first; ale; ale = ale->next) { - fcurve_to_keylist(ale->adt, ale->data, keys, saction_flag); + LISTBASE_FOREACH (const bAnimListElem *, ale, &anim_data) { + fcurve_to_keylist(ale->adt, static_cast<FCurve *>(ale->data), keylist, saction_flag); } ANIM_animdata_freelist(&anim_data); } -void ob_to_keylist(bDopeSheet *ads, Object *ob, DLRBT_Tree *keys, int saction_flag) +void ob_to_keylist(bDopeSheet *ads, Object *ob, AnimKeylist *keylist, const int saction_flag) { - bAnimContext ac = {NULL}; - ListBase anim_data = {NULL, NULL}; - bAnimListElem *ale; - int filter; + bAnimContext ac = {nullptr}; + ListBase anim_data = {nullptr, nullptr}; - bAnimListElem dummychan = {NULL}; - Base dummybase = {NULL}; + bAnimListElem dummychan = {nullptr}; + Base dummybase = {nullptr}; - if (ob == NULL) { + if (ob == nullptr) { return; } @@ -641,12 +725,13 @@ void ob_to_keylist(bDopeSheet *ads, Object *ob, DLRBT_Tree *keys, int saction_fl ac.datatype = ANIMCONT_CHANNEL; /* get F-Curves to take keyframes from */ - filter = ANIMFILTER_DATA_VISIBLE; /* curves only */ - ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); + const eAnimFilter_Flags filter = ANIMFILTER_DATA_VISIBLE; /* curves only */ + ANIM_animdata_filter( + &ac, &anim_data, filter, ac.data, static_cast<eAnimCont_Types>(ac.datatype)); /* loop through each F-Curve, grabbing the keyframes */ - for (ale = anim_data.first; ale; ale = ale->next) { - fcurve_to_keylist(ale->adt, ale->data, keys, saction_flag); + LISTBASE_FOREACH (const bAnimListElem *, ale, &anim_data) { + fcurve_to_keylist(ale->adt, static_cast<FCurve *>(ale->data), keylist, saction_flag); } ANIM_animdata_freelist(&anim_data); @@ -654,44 +739,45 @@ void ob_to_keylist(bDopeSheet *ads, Object *ob, DLRBT_Tree *keys, int saction_fl void cachefile_to_keylist(bDopeSheet *ads, CacheFile *cache_file, - DLRBT_Tree *keys, - int saction_flag) + AnimKeylist *keylist, + const int saction_flag) { - if (cache_file == NULL) { + if (cache_file == nullptr) { return; } /* create a dummy wrapper data to work with */ - bAnimListElem dummychan = {NULL}; + bAnimListElem dummychan = {nullptr}; dummychan.type = ANIMTYPE_DSCACHEFILE; dummychan.data = cache_file; dummychan.id = &cache_file->id; dummychan.adt = cache_file->adt; - bAnimContext ac = {NULL}; + bAnimContext ac = {nullptr}; ac.ads = ads; ac.data = &dummychan; ac.datatype = ANIMCONT_CHANNEL; /* get F-Curves to take keyframes from */ - ListBase anim_data = {NULL, NULL}; - int filter = ANIMFILTER_DATA_VISIBLE; /* curves only */ - ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); + ListBase anim_data = {nullptr, nullptr}; + const eAnimFilter_Flags filter = ANIMFILTER_DATA_VISIBLE; /* curves only */ + ANIM_animdata_filter( + &ac, &anim_data, filter, ac.data, static_cast<eAnimCont_Types>(ac.datatype)); /* loop through each F-Curve, grabbing the keyframes */ - LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) { - fcurve_to_keylist(ale->adt, ale->data, keys, saction_flag); + LISTBASE_FOREACH (const bAnimListElem *, ale, &anim_data) { + fcurve_to_keylist(ale->adt, static_cast<FCurve *>(ale->data), keylist, saction_flag); } ANIM_animdata_freelist(&anim_data); } -void fcurve_to_keylist(AnimData *adt, FCurve *fcu, DLRBT_Tree *keys, int saction_flag) +void fcurve_to_keylist(AnimData *adt, FCurve *fcu, AnimKeylist *keylist, const int saction_flag) { if (fcu && fcu->totvert && fcu->bezt) { /* apply NLA-mapping (if applicable) */ if (adt) { - ANIM_nla_mapping_apply_fcurve(adt, fcu, 0, 0); + ANIM_nla_mapping_apply_fcurve(adt, fcu, false, false); } /* Check if the curve is cyclic. */ @@ -699,95 +785,95 @@ void fcurve_to_keylist(AnimData *adt, FCurve *fcu, DLRBT_Tree *keys, int saction bool do_extremes = (saction_flag & SACTION_SHOW_EXTREMES) != 0; /* loop through beztriples, making ActKeysColumns */ - BezTripleChain chain = {0}; + BezTripleChain chain = {nullptr}; for (int v = 0; v < fcu->totvert; v++) { chain.cur = &fcu->bezt[v]; /* Neighbor keys, accounting for being cyclic. */ if (do_extremes) { - chain.prev = (v > 0) ? &fcu->bezt[v - 1] : is_cyclic ? &fcu->bezt[fcu->totvert - 2] : NULL; - chain.next = (v + 1 < fcu->totvert) ? &fcu->bezt[v + 1] : is_cyclic ? &fcu->bezt[1] : NULL; + chain.prev = (v > 0) ? &fcu->bezt[v - 1] : + is_cyclic ? &fcu->bezt[fcu->totvert - 2] : + nullptr; + chain.next = (v + 1 < fcu->totvert) ? &fcu->bezt[v + 1] : + is_cyclic ? &fcu->bezt[1] : + nullptr; } - add_bezt_to_keycolumns_list(keys, &chain); + add_bezt_to_keycolumns_list(keylist, &chain); } /* Update keyblocks. */ - update_keyblocks(keys, fcu->bezt, fcu->totvert); + update_keyblocks(keylist, fcu->bezt, fcu->totvert); /* unapply NLA-mapping if applicable */ if (adt) { - ANIM_nla_mapping_apply_fcurve(adt, fcu, 1, 0); + ANIM_nla_mapping_apply_fcurve(adt, fcu, true, false); } } } -void agroup_to_keylist(AnimData *adt, bActionGroup *agrp, DLRBT_Tree *keys, int saction_flag) +void agroup_to_keylist(AnimData *adt, + bActionGroup *agrp, + AnimKeylist *keylist, + const int saction_flag) { - FCurve *fcu; - if (agrp) { /* loop through F-Curves */ - for (fcu = agrp->channels.first; fcu && fcu->grp == agrp; fcu = fcu->next) { - fcurve_to_keylist(adt, fcu, keys, saction_flag); + LISTBASE_FOREACH (FCurve *, fcu, &agrp->channels) { + if (fcu->grp != agrp) { + break; + } + fcurve_to_keylist(adt, fcu, keylist, saction_flag); } } } -void action_to_keylist(AnimData *adt, bAction *act, DLRBT_Tree *keys, int saction_flag) +void action_to_keylist(AnimData *adt, bAction *act, AnimKeylist *keylist, const int saction_flag) { - FCurve *fcu; - if (act) { /* loop through F-Curves */ - for (fcu = act->curves.first; fcu; fcu = fcu->next) { - fcurve_to_keylist(adt, fcu, keys, saction_flag); + LISTBASE_FOREACH (FCurve *, fcu, &act->curves) { + fcurve_to_keylist(adt, fcu, keylist, saction_flag); } } } -void gpencil_to_keylist(bDopeSheet *ads, bGPdata *gpd, DLRBT_Tree *keys, const bool active) +void gpencil_to_keylist(bDopeSheet *ads, bGPdata *gpd, AnimKeylist *keylist, const bool active) { - bGPDlayer *gpl; - - if (gpd && keys) { + if (gpd && keylist) { /* for now, just aggregate out all the frames, but only for visible layers */ - for (gpl = gpd->layers.last; gpl; gpl = gpl->prev) { + LISTBASE_FOREACH_BACKWARD (bGPDlayer *, gpl, &gpd->layers) { if ((gpl->flag & GP_LAYER_HIDE) == 0) { if ((!active) || ((active) && (gpl->flag & GP_LAYER_SELECT))) { - gpl_to_keylist(ads, gpl, keys); + gpl_to_keylist(ads, gpl, keylist); } } } } } -void gpl_to_keylist(bDopeSheet *UNUSED(ads), bGPDlayer *gpl, DLRBT_Tree *keys) +void gpl_to_keylist(bDopeSheet *UNUSED(ads), bGPDlayer *gpl, AnimKeylist *keylist) { - bGPDframe *gpf; - - if (gpl && keys) { + if (gpl && keylist) { /* Although the frames should already be in an ordered list, * they are not suitable for displaying yet. */ - for (gpf = gpl->frames.first; gpf; gpf = gpf->next) { - add_gpframe_to_keycolumns_list(keys, gpf); + LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) { + add_gpframe_to_keycolumns_list(keylist, gpf); } - update_keyblocks(keys, NULL, 0); + update_keyblocks(keylist, nullptr, 0); } } -void mask_to_keylist(bDopeSheet *UNUSED(ads), MaskLayer *masklay, DLRBT_Tree *keys) +void mask_to_keylist(bDopeSheet *UNUSED(ads), MaskLayer *masklay, AnimKeylist *keylist) { - MaskLayerShape *masklay_shape; - - if (masklay && keys) { - for (masklay_shape = masklay->splines_shapes.first; masklay_shape; - masklay_shape = masklay_shape->next) { - add_masklay_to_keycolumns_list(keys, masklay_shape); + if (masklay && keylist) { + LISTBASE_FOREACH (MaskLayerShape *, masklay_shape, &masklay->splines_shapes) { + add_masklay_to_keycolumns_list(keylist, masklay_shape); } - update_keyblocks(keys, NULL, 0); + update_keyblocks(keylist, nullptr, 0); } } +} diff --git a/source/blender/editors/animation/time_scrub_ui.c b/source/blender/editors/animation/time_scrub_ui.c index 6af033f3cf2..8aeb6a57124 100644 --- a/source/blender/editors/animation/time_scrub_ui.c +++ b/source/blender/editors/animation/time_scrub_ui.c @@ -244,6 +244,10 @@ void ED_time_scrub_channel_search_draw(const bContext *C, ARegion *region, bDope UI_block_align_end(block); UI_block_layout_resolve(block, NULL, NULL); + /* Make sure the events are consumed from the search and don't reach other UI blocks since this + * is drawn on top of animation-channels. */ + UI_block_flag_enable(block, UI_BLOCK_CLIP_EVENTS); + UI_block_bounds_set_normal(block, 0); UI_block_end(C, block); UI_block_draw(C, block); |