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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/animation')
-rw-r--r--source/blender/editors/animation/CMakeLists.txt2
-rw-r--r--source/blender/editors/animation/anim_draw.c24
-rw-r--r--source/blender/editors/animation/anim_filter.c4
-rw-r--r--source/blender/editors/animation/anim_ipo_utils.c22
-rw-r--r--source/blender/editors/animation/anim_markers.c2
-rw-r--r--source/blender/editors/animation/anim_motion_paths.c64
-rw-r--r--source/blender/editors/animation/fmodifier_ui.c5
-rw-r--r--source/blender/editors/animation/keyframes_draw.c765
-rw-r--r--source/blender/editors/animation/keyframes_general.c10
-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.c4
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, &current_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, &current_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);